From 99bc2e75a12838110242e192334c67150222cc9c Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Wed, 24 Sep 2025 16:04:08 +0200 Subject: [PATCH] Extern : - aggiunta libreria hiredis 1.3.0. --- hiredis/Include/alloc.h | 96 +++++++++ hiredis/Include/async.h | 152 +++++++++++++++ hiredis/Include/hiredis.h | 363 +++++++++++++++++++++++++++++++++++ hiredis/Include/read.h | 129 +++++++++++++ hiredis/Include/sds.h | 280 +++++++++++++++++++++++++++ hiredis/Include/sockcompat.h | 95 +++++++++ hiredis/Lib/hiredisD32.lib | Bin 0 -> 34440 bytes hiredis/Lib/hiredisD64.lib | Bin 0 -> 33664 bytes hiredis/Lib/hiredisR32.lib | Bin 0 -> 32886 bytes hiredis/Lib/hiredisR64.lib | Bin 0 -> 32152 bytes 10 files changed, 1115 insertions(+) create mode 100644 hiredis/Include/alloc.h create mode 100644 hiredis/Include/async.h create mode 100644 hiredis/Include/hiredis.h create mode 100644 hiredis/Include/read.h create mode 100644 hiredis/Include/sds.h create mode 100644 hiredis/Include/sockcompat.h create mode 100644 hiredis/Lib/hiredisD32.lib create mode 100644 hiredis/Lib/hiredisD64.lib create mode 100644 hiredis/Lib/hiredisR32.lib create mode 100644 hiredis/Lib/hiredisR64.lib diff --git a/hiredis/Include/alloc.h b/hiredis/Include/alloc.h new file mode 100644 index 0000000..771f9fe --- /dev/null +++ b/hiredis/Include/alloc.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020, Michael Grunder + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HIREDIS_ALLOC_H +#define HIREDIS_ALLOC_H + +#include /* for size_t */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure pointing to our actually configured allocators */ +typedef struct hiredisAllocFuncs { + void *(*mallocFn)(size_t); + void *(*callocFn)(size_t,size_t); + void *(*reallocFn)(void*,size_t); + char *(*strdupFn)(const char*); + void (*freeFn)(void*); +} hiredisAllocFuncs; + +hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *ha); +void hiredisResetAllocators(void); + +#ifndef _WIN32 + +/* Hiredis' configured allocator function pointer struct */ +extern hiredisAllocFuncs hiredisAllocFns; + +static inline void *hi_malloc(size_t size) { + return hiredisAllocFns.mallocFn(size); +} + +static inline void *hi_calloc(size_t nmemb, size_t size) { + /* Overflow check as the user can specify any arbitrary allocator */ + if (SIZE_MAX / size < nmemb) + return NULL; + + return hiredisAllocFns.callocFn(nmemb, size); +} + +static inline void *hi_realloc(void *ptr, size_t size) { + return hiredisAllocFns.reallocFn(ptr, size); +} + +static inline char *hi_strdup(const char *str) { + return hiredisAllocFns.strdupFn(str); +} + +static inline void hi_free(void *ptr) { + hiredisAllocFns.freeFn(ptr); +} + +#else + +void *hi_malloc(size_t size); +void *hi_calloc(size_t nmemb, size_t size); +void *hi_realloc(void *ptr, size_t size); +char *hi_strdup(const char *str); +void hi_free(void *ptr); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* HIREDIS_ALLOC_H */ diff --git a/hiredis/Include/async.h b/hiredis/Include/async.h new file mode 100644 index 0000000..4f94660 --- /dev/null +++ b/hiredis/Include/async.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_ASYNC_H +#define __HIREDIS_ASYNC_H +#include "hiredis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ +struct dict; /* dictionary header is included in async.c */ + +/* Reply callback prototype and container */ +typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); +typedef struct redisCallback { + struct redisCallback *next; /* simple singly linked list */ + redisCallbackFn *fn; + int pending_subs; + int unsubscribe_sent; + void *privdata; +} redisCallback; + +/* List of callbacks for either regular replies or pub/sub */ +typedef struct redisCallbackList { + redisCallback *head, *tail; +} redisCallbackList; + +/* Connection callback prototypes */ +typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); +typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); +typedef void (redisConnectCallbackNC)(struct redisAsyncContext *, int status); +typedef void(redisTimerCallback)(void *timer, void *privdata); + +/* Context for an async connection to Redis */ +typedef struct redisAsyncContext { + /* Hold the regular context, so it can be realloc'ed. */ + redisContext c; + + /* Setup error flags so they can be used directly. */ + int err; + char *errstr; + + /* Not used by hiredis */ + void *data; + void (*dataCleanup)(void *privdata); + + /* Event library data and hooks */ + struct { + void *data; + + /* Hooks that are called when the library expects to start + * reading/writing. These functions should be idempotent. */ + void (*addRead)(void *privdata); + void (*delRead)(void *privdata); + void (*addWrite)(void *privdata); + void (*delWrite)(void *privdata); + void (*cleanup)(void *privdata); + void (*scheduleTimer)(void *privdata, struct timeval tv); + } ev; + + /* Called when either the connection is terminated due to an error or per + * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ + redisDisconnectCallback *onDisconnect; + + /* Called when the first write event was received. */ + redisConnectCallback *onConnect; + redisConnectCallbackNC *onConnectNC; + + /* Regular command callbacks */ + redisCallbackList replies; + + /* Address used for connect() */ + struct sockaddr *saddr; + size_t addrlen; + + /* Subscription callbacks */ + struct { + redisCallbackList replies; + struct dict *channels; + struct dict *patterns; + int pending_unsubs; + } sub; + + /* Any configured RESP3 PUSH handler */ + redisAsyncPushFn *push_cb; +} redisAsyncContext; + +/* Functions that proxy to hiredis */ +redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options); +redisAsyncContext *redisAsyncConnect(const char *ip, int port); +redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); +redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, + const char *source_addr); +redisAsyncContext *redisAsyncConnectUnix(const char *path); +int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); +int redisAsyncSetConnectCallbackNC(redisAsyncContext *ac, redisConnectCallbackNC *fn); +int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); + +redisAsyncPushFn *redisAsyncSetPushCallback(redisAsyncContext *ac, redisAsyncPushFn *fn); +int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv); +void redisAsyncDisconnect(redisAsyncContext *ac); +void redisAsyncFree(redisAsyncContext *ac); + +/* Handle read/write events */ +void redisAsyncHandleRead(redisAsyncContext *ac); +void redisAsyncHandleWrite(redisAsyncContext *ac); +void redisAsyncHandleTimeout(redisAsyncContext *ac); +void redisAsyncRead(redisAsyncContext *ac); +void redisAsyncWrite(redisAsyncContext *ac); + +/* Command functions for an async context. Write the command to the + * output buffer and register the provided callback. */ +int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); +int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); +int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); +int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hiredis/Include/hiredis.h b/hiredis/Include/hiredis.h new file mode 100644 index 0000000..302a7ac --- /dev/null +++ b/hiredis/Include/hiredis.h @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2014, Pieter Noordhuis + * Copyright (c) 2015, Matt Stancliff , + * Jan-Erik Rediger + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __HIREDIS_H +#define __HIREDIS_H +#include "read.h" +#include /* for va_list */ +#ifndef _MSC_VER +#include /* for struct timeval */ +#else +struct timeval; /* forward declaration */ +typedef intptr_t ssize_t; +#endif +#include /* uintXX_t, etc */ +#include "sds.h" /* for sds */ +#include "alloc.h" /* for allocation wrappers */ + +#define HIREDIS_MAJOR 1 +#define HIREDIS_MINOR 3 +#define HIREDIS_PATCH 0 +#define HIREDIS_SONAME 1.3.0 + +/* Connection type can be blocking or non-blocking and is set in the + * least significant bit of the flags field in redisContext. */ +#define REDIS_BLOCK 0x1 + +/* Connection may be disconnected before being free'd. The second bit + * in the flags field is set when the context is connected. */ +#define REDIS_CONNECTED 0x2 + +/* The async API might try to disconnect cleanly and flush the output + * buffer and read all subsequent replies before disconnecting. + * This flag means no new commands can come in and the connection + * should be terminated once all replies have been read. */ +#define REDIS_DISCONNECTING 0x4 + +/* Flag specific to the async API which means that the context should be clean + * up as soon as possible. */ +#define REDIS_FREEING 0x8 + +/* Flag that is set when an async callback is executed. */ +#define REDIS_IN_CALLBACK 0x10 + +/* Flag that is set when the async context has one or more subscriptions. */ +#define REDIS_SUBSCRIBED 0x20 + +/* Flag that is set when monitor mode is active */ +#define REDIS_MONITORING 0x40 + +/* Flag that is set when we should set SO_REUSEADDR before calling bind() */ +#define REDIS_REUSEADDR 0x80 + +/* Flag that is set when the async connection supports push replies. */ +#define REDIS_SUPPORTS_PUSH 0x100 + +/** + * Flag that indicates the user does not want the context to + * be automatically freed upon error + */ +#define REDIS_NO_AUTO_FREE 0x200 + +/* Flag that indicates the user does not want replies to be automatically freed */ +#define REDIS_NO_AUTO_FREE_REPLIES 0x400 + +/* Flags to prefer IPv6 or IPv4 when doing DNS lookup. (If both are set, + * AF_UNSPEC is used.) */ +#define REDIS_PREFER_IPV4 0x800 +#define REDIS_PREFER_IPV6 0x1000 + +#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ + +/* number of times we retry to connect in the case of EADDRNOTAVAIL and + * SO_REUSEADDR is being used. */ +#define REDIS_CONNECT_RETRIES 10 + +/* Forward declarations for structs defined elsewhere */ +struct redisAsyncContext; +struct redisContext; + +/* RESP3 push helpers and callback prototypes */ +#define redisIsPushReply(r) (((redisReply*)(r))->type == REDIS_REPLY_PUSH) +typedef void (redisPushFn)(void *, void *); +typedef void (redisAsyncPushFn)(struct redisAsyncContext *, void *); + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the reply object returned by redisCommand() */ +typedef struct redisReply { + int type; /* REDIS_REPLY_* */ + long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ + double dval; /* The double when type is REDIS_REPLY_DOUBLE */ + size_t len; /* Length of string */ + char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING + REDIS_REPLY_VERB, REDIS_REPLY_DOUBLE (in additional to dval), + and REDIS_REPLY_BIGNUM. */ + char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null + terminated 3 character content type, such as "txt". */ + size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ + struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ +} redisReply; + +redisReader *redisReaderCreate(void); + +/* Function to free the reply objects hiredis returns by default. */ +void freeReplyObject(void *reply); + +/* Functions to format a command according to the protocol. */ +int redisvFormatCommand(char **target, const char *format, va_list ap); +int redisFormatCommand(char **target, const char *format, ...); +long long redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); +long long redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); +void redisFreeCommand(char *cmd); +void redisFreeSdsCommand(sds cmd); + +enum redisConnectionType { + REDIS_CONN_TCP, + REDIS_CONN_UNIX, + REDIS_CONN_USERFD +}; + +struct redisSsl; + +#define REDIS_OPT_NONBLOCK 0x01 +#define REDIS_OPT_REUSEADDR 0x02 +#define REDIS_OPT_NOAUTOFREE 0x04 /* Don't automatically free the async + * object on a connection failure, or + * other implicit conditions. Only free + * on an explicit call to disconnect() + * or free() */ +#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08 /* Don't automatically intercept and + * free RESP3 PUSH replies. */ +#define REDIS_OPT_NOAUTOFREEREPLIES 0x10 /* Don't automatically free replies. */ +#define REDIS_OPT_PREFER_IPV4 0x20 /* Prefer IPv4 in DNS lookups. */ +#define REDIS_OPT_PREFER_IPV6 0x40 /* Prefer IPv6 in DNS lookups. */ +#define REDIS_OPT_PREFER_IP_UNSPEC (REDIS_OPT_PREFER_IPV4 | REDIS_OPT_PREFER_IPV6) +#define REDIS_OPT_SET_SOCK_CLOEXEC 0x80 /* Set SOCK_CLOEXEC on socket file descriptor. */ + +/* In Unix systems a file descriptor is a regular signed int, with -1 + * representing an invalid descriptor. In Windows it is a SOCKET + * (32- or 64-bit unsigned integer depending on the architecture), where + * all bits set (~0) is INVALID_SOCKET. */ +#ifndef _WIN32 +typedef int redisFD; +#define REDIS_INVALID_FD -1 +#else +#ifdef _WIN64 +typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */ +#else +typedef unsigned long redisFD; /* SOCKET = 32-bit UINT_PTR */ +#endif +#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */ +#endif + +typedef struct { + /* + * the type of connection to use. This also indicates which + * `endpoint` member field to use + */ + int type; + /* bit field of REDIS_OPT_xxx */ + int options; + /* timeout value for connect operation. If NULL, no timeout is used */ + const struct timeval *connect_timeout; + /* timeout value for commands. If NULL, no timeout is used. This can be + * updated at runtime with redisSetTimeout/redisAsyncSetTimeout. */ + const struct timeval *command_timeout; + union { + /** use this field for tcp/ip connections */ + struct { + const char *source_addr; + const char *ip; + int port; + } tcp; + /** use this field for unix domain sockets */ + const char *unix_socket; + /** + * use this field to have hiredis operate an already-open + * file descriptor */ + redisFD fd; + } endpoint; + + /* Optional user defined data/destructor */ + void *privdata; + void (*free_privdata)(void *); + + /* A user defined PUSH message callback */ + redisPushFn *push_cb; + redisAsyncPushFn *async_push_cb; +} redisOptions; + +/** + * Helper macros to initialize options to their specified fields. + */ +#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) do { \ + (opts)->type = REDIS_CONN_TCP; \ + (opts)->endpoint.tcp.ip = ip_; \ + (opts)->endpoint.tcp.port = port_; \ + } while(0) + +#define REDIS_OPTIONS_SET_UNIX(opts, path) do { \ + (opts)->type = REDIS_CONN_UNIX; \ + (opts)->endpoint.unix_socket = path; \ + } while(0) + +#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) do { \ + (opts)->privdata = data; \ + (opts)->free_privdata = dtor; \ + } while(0) + +typedef struct redisContextFuncs { + void (*close)(struct redisContext *); + void (*free_privctx)(void *); + void (*async_read)(struct redisAsyncContext *); + void (*async_write)(struct redisAsyncContext *); + + /* Read/Write data to the underlying communication stream, returning the + * number of bytes read/written. In the event of an unrecoverable error + * these functions shall return a value < 0. In the event of a + * recoverable error, they should return 0. */ + ssize_t (*read)(struct redisContext *, char *, size_t); + ssize_t (*write)(struct redisContext *); +} redisContextFuncs; + + +/* Context for a connection to Redis */ +typedef struct redisContext { + const redisContextFuncs *funcs; /* Function table */ + + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + redisFD fd; + int flags; + char *obuf; /* Write buffer */ + redisReader *reader; /* Protocol reader */ + + enum redisConnectionType connection_type; + struct timeval *connect_timeout; + struct timeval *command_timeout; + + struct { + char *host; + char *source_addr; + int port; + } tcp; + + struct { + char *path; + } unix_sock; + + /* For non-blocking connect */ + struct sockaddr *saddr; + size_t addrlen; + + /* Optional data and corresponding destructor users can use to provide + * context to a given redisContext. Not used by hiredis. */ + void *privdata; + void (*free_privdata)(void *); + + /* Internal context pointer presently used by hiredis to manage + * SSL connections. */ + void *privctx; + + /* An optional RESP3 PUSH handler */ + redisPushFn *push_cb; +} redisContext; + +redisContext *redisConnectWithOptions(const redisOptions *options); +redisContext *redisConnect(const char *ip, int port); +redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); +redisContext *redisConnectNonBlock(const char *ip, int port); +redisContext *redisConnectBindNonBlock(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port, + const char *source_addr); +redisContext *redisConnectUnix(const char *path); +redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); +redisContext *redisConnectUnixNonBlock(const char *path); +redisContext *redisConnectFd(redisFD fd); + +/** + * Reconnect the given context using the saved information. + * + * This re-uses the exact same connect options as in the initial connection. + * host, ip (or path), timeout and bind address are reused, + * flags are used unmodified from the existing context. + * + * Returns REDIS_OK on successful connect or REDIS_ERR otherwise. + */ +int redisReconnect(redisContext *c); + +redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn); +int redisSetTimeout(redisContext *c, const struct timeval tv); +int redisEnableKeepAlive(redisContext *c); +int redisEnableKeepAliveWithInterval(redisContext *c, int interval); +int redisSetTcpUserTimeout(redisContext *c, unsigned int timeout); +void redisFree(redisContext *c); +redisFD redisFreeKeepFd(redisContext *c); +int redisBufferRead(redisContext *c); +int redisBufferWrite(redisContext *c, int *done); + +/* In a blocking context, this function first checks if there are unconsumed + * replies to return and returns one if so. Otherwise, it flushes the output + * buffer to the socket and reads until it has a reply. In a non-blocking + * context, it will return unconsumed replies until there are no more. */ +int redisGetReply(redisContext *c, void **reply); +int redisGetReplyFromReader(redisContext *c, void **reply); + +/* Write a formatted command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); + +/* Write a command to the output buffer. Use these functions in blocking mode + * to get a pipeline of commands. */ +int redisvAppendCommand(redisContext *c, const char *format, va_list ap); +int redisAppendCommand(redisContext *c, const char *format, ...); +int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +/* Issue a command to Redis. In a blocking context, it is identical to calling + * redisAppendCommand, followed by redisGetReply. The function will return + * NULL if there was an error in performing the request, otherwise it will + * return the reply. In a non-blocking context, it is identical to calling + * only redisAppendCommand and will always return NULL. */ +void *redisvCommand(redisContext *c, const char *format, va_list ap); +void *redisCommand(redisContext *c, const char *format, ...); +void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hiredis/Include/read.h b/hiredis/Include/read.h new file mode 100644 index 0000000..2d74d77 --- /dev/null +++ b/hiredis/Include/read.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2009-2011, Salvatore Sanfilippo + * Copyright (c) 2010-2011, Pieter Noordhuis + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __HIREDIS_READ_H +#define __HIREDIS_READ_H +#include /* for size_t */ + +#define REDIS_ERR -1 +#define REDIS_OK 0 + +/* When an error occurs, the err flag in a context is set to hold the type of + * error that occurred. REDIS_ERR_IO means there was an I/O error and you + * should use the "errno" variable to find out what is wrong. + * For other values, the "errstr" field will hold a description. */ +#define REDIS_ERR_IO 1 /* Error in read or write */ +#define REDIS_ERR_EOF 3 /* End of file */ +#define REDIS_ERR_PROTOCOL 4 /* Protocol error */ +#define REDIS_ERR_OOM 5 /* Out of memory */ +#define REDIS_ERR_TIMEOUT 6 /* Timed out */ +#define REDIS_ERR_OTHER 2 /* Everything else... */ + +#define REDIS_REPLY_STRING 1 +#define REDIS_REPLY_ARRAY 2 +#define REDIS_REPLY_INTEGER 3 +#define REDIS_REPLY_NIL 4 +#define REDIS_REPLY_STATUS 5 +#define REDIS_REPLY_ERROR 6 +#define REDIS_REPLY_DOUBLE 7 +#define REDIS_REPLY_BOOL 8 +#define REDIS_REPLY_MAP 9 +#define REDIS_REPLY_SET 10 +#define REDIS_REPLY_ATTR 11 +#define REDIS_REPLY_PUSH 12 +#define REDIS_REPLY_BIGNUM 13 +#define REDIS_REPLY_VERB 14 + +/* Default max unused reader buffer. */ +#define REDIS_READER_MAX_BUF (1024*16) + +/* Default multi-bulk element limit */ +#define REDIS_READER_MAX_ARRAY_ELEMENTS ((1LL<<32) - 1) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct redisReadTask { + int type; + long long elements; /* number of elements in multibulk container */ + int idx; /* index in parent (array) object */ + void *obj; /* holds user-generated value for a read task */ + struct redisReadTask *parent; /* parent task */ + void *privdata; /* user-settable arbitrary field */ +} redisReadTask; + +typedef struct redisReplyObjectFunctions { + void *(*createString)(const redisReadTask*, char*, size_t); + void *(*createArray)(const redisReadTask*, size_t); + void *(*createInteger)(const redisReadTask*, long long); + void *(*createDouble)(const redisReadTask*, double, char*, size_t); + void *(*createNil)(const redisReadTask*); + void *(*createBool)(const redisReadTask*, int); + void (*freeObject)(void*); +} redisReplyObjectFunctions; + +typedef struct redisReader { + int err; /* Error flags, 0 when there is no error */ + char errstr[128]; /* String representation of error when applicable */ + + char *buf; /* Read buffer */ + size_t pos; /* Buffer cursor */ + size_t len; /* Buffer length */ + size_t maxbuf; /* Max length of unused buffer */ + long long maxelements; /* Max multi-bulk elements */ + + redisReadTask **task; + int tasks; + + int ridx; /* Index of current read task */ + void *reply; /* Temporary reply pointer */ + + redisReplyObjectFunctions *fn; + void *privdata; +} redisReader; + +/* Public API for the protocol parser. */ +redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); +void redisReaderFree(redisReader *r); +int redisReaderFeed(redisReader *r, const char *buf, size_t len); +int redisReaderGetReply(redisReader *r, void **reply); + +#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) +#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) +#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hiredis/Include/sds.h b/hiredis/Include/sds.h new file mode 100644 index 0000000..d8e22a0 --- /dev/null +++ b/hiredis/Include/sds.h @@ -0,0 +1,280 @@ +/* SDSLib 2.0 -- A C dynamic strings library + * + * Copyright (c) 2006-2015, Salvatore Sanfilippo + * Copyright (c) 2015, Oran Agra + * Copyright (c) 2015, Redis Labs, Inc + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SDS_H +#define __SDS_H + +#define SDS_MAX_PREALLOC (1024*1024) +#ifdef _MSC_VER +typedef intptr_t ssize_t; +#define SSIZE_MAX INTPTR_MAX +#ifndef __clang__ +#define __attribute__(x) +#endif +#endif + +#include +#include +#include + +typedef char *sds; + +/* Note: sdshdr5 is never used, we just access the flags byte directly. + * However is here to document the layout of type 5 SDS strings. */ +struct __attribute__ ((__packed__)) sdshdr5 { + unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr8 { + uint8_t len; /* used */ + uint8_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr16 { + uint16_t len; /* used */ + uint16_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr32 { + uint32_t len; /* used */ + uint32_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; +struct __attribute__ ((__packed__)) sdshdr64 { + uint64_t len; /* used */ + uint64_t alloc; /* excluding the header and null terminator */ + unsigned char flags; /* 3 lsb of type, 5 unused bits */ + char buf[]; +}; + +#define SDS_TYPE_5 0 +#define SDS_TYPE_8 1 +#define SDS_TYPE_16 2 +#define SDS_TYPE_32 3 +#define SDS_TYPE_64 4 +#define SDS_TYPE_MASK 7 +#define SDS_TYPE_BITS 3 +#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))); +#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)))) +#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS) + +static inline size_t sdslen(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->len; + case SDS_TYPE_16: + return SDS_HDR(16,s)->len; + case SDS_TYPE_32: + return SDS_HDR(32,s)->len; + case SDS_TYPE_64: + return SDS_HDR(64,s)->len; + } + return 0; +} + +static inline size_t sdsavail(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: { + return 0; + } + case SDS_TYPE_8: { + SDS_HDR_VAR(8,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_16: { + SDS_HDR_VAR(16,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_32: { + SDS_HDR_VAR(32,s); + return sh->alloc - sh->len; + } + case SDS_TYPE_64: { + SDS_HDR_VAR(64,s); + return sh->alloc - sh->len; + } + } + return 0; +} + +static inline void sdssetlen(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + *fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS)); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len = (uint8_t)newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len = (uint16_t)newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len = (uint32_t)newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len = (uint64_t)newlen; + break; + } +} + +static inline void sdsinclen(sds s, size_t inc) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + { + unsigned char *fp = ((unsigned char*)s)-1; + unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc; + *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); + } + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->len += (uint8_t)inc; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->len += (uint16_t)inc; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->len += (uint32_t)inc; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->len += (uint64_t)inc; + break; + } +} + +/* sdsalloc() = sdsavail() + sdslen() */ +static inline size_t sdsalloc(const sds s) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + return SDS_TYPE_5_LEN(flags); + case SDS_TYPE_8: + return SDS_HDR(8,s)->alloc; + case SDS_TYPE_16: + return SDS_HDR(16,s)->alloc; + case SDS_TYPE_32: + return SDS_HDR(32,s)->alloc; + case SDS_TYPE_64: + return SDS_HDR(64,s)->alloc; + } + return 0; +} + +static inline void sdssetalloc(sds s, size_t newlen) { + unsigned char flags = s[-1]; + switch(flags&SDS_TYPE_MASK) { + case SDS_TYPE_5: + /* Nothing to do, this type has no total allocation info. */ + break; + case SDS_TYPE_8: + SDS_HDR(8,s)->alloc = (uint8_t)newlen; + break; + case SDS_TYPE_16: + SDS_HDR(16,s)->alloc = (uint16_t)newlen; + break; + case SDS_TYPE_32: + SDS_HDR(32,s)->alloc = (uint32_t)newlen; + break; + case SDS_TYPE_64: + SDS_HDR(64,s)->alloc = (uint64_t)newlen; + break; + } +} + +sds sdsnewlen(const void *init, size_t initlen); +sds sdsnew(const char *init); +sds sdsempty(void); +sds sdsdup(const sds s); +void sdsfree(sds s); +sds sdsgrowzero(sds s, size_t len); +sds sdscatlen(sds s, const void *t, size_t len); +sds sdscat(sds s, const char *t); +sds sdscatsds(sds s, const sds t); +sds sdscpylen(sds s, const char *t, size_t len); +sds sdscpy(sds s, const char *t); + +sds sdscatvprintf(sds s, const char *fmt, va_list ap); +#ifdef __GNUC__ +sds sdscatprintf(sds s, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +#else +sds sdscatprintf(sds s, const char *fmt, ...); +#endif + +sds sdscatfmt(sds s, char const *fmt, ...); +sds sdstrim(sds s, const char *cset); +int sdsrange(sds s, ssize_t start, ssize_t end); +void sdsupdatelen(sds s); +void sdsclear(sds s); +int sdscmp(const sds s1, const sds s2); +sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count); +void sdsfreesplitres(sds *tokens, int count); +void sdstolower(sds s); +void sdstoupper(sds s); +sds sdsfromlonglong(long long value); +sds sdscatrepr(sds s, const char *p, size_t len); +sds *sdssplitargs(const char *line, int *argc); +sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); +sds sdsjoin(char **argv, int argc, char *sep); +sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen); + +/* Low level functions exposed to the user API */ +sds sdsMakeRoomFor(sds s, size_t addlen); +void sdsIncrLen(sds s, int incr); +sds sdsRemoveFreeSpace(sds s); +size_t sdsAllocSize(sds s); +void *sdsAllocPtr(sds s); + +/* Export the allocator used by SDS to the program using SDS. + * Sometimes the program SDS is linked to, may use a different set of + * allocators, but may want to allocate or free things that SDS will + * respectively free or allocate. */ +void *sds_malloc(size_t size); +void *sds_realloc(void *ptr, size_t size); +void sds_free(void *ptr); + +#ifdef REDIS_TEST +int sdsTest(int argc, char *argv[]); +#endif + +#endif diff --git a/hiredis/Include/sockcompat.h b/hiredis/Include/sockcompat.h new file mode 100644 index 0000000..624095e --- /dev/null +++ b/hiredis/Include/sockcompat.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019, Marcus Geelnard + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SOCKCOMPAT_H +#define __SOCKCOMPAT_H + +#ifndef _WIN32 +/* For POSIX systems we use the standard BSD socket API. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +/* For Windows we use winsock. */ +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 /* To get WSAPoll etc. */ +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +typedef intptr_t ssize_t; +#endif + +/* Emulate the parts of the BSD socket API that we need (override the winsock signatures). */ +int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); +const char *win32_gai_strerror(int errcode); +void win32_freeaddrinfo(struct addrinfo *res); +SOCKET win32_socket(int domain, int type, int protocol); +int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp); +int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); +int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen); +int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen); +int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen); +int win32_close(SOCKET fd); +ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags); +ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags); +typedef ULONG nfds_t; +int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout); + +int win32_redisKeepAlive(SOCKET sockfd, int interval_ms); + +#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION +#define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res) +#undef gai_strerror +#define gai_strerror(errcode) win32_gai_strerror(errcode) +#define freeaddrinfo(res) win32_freeaddrinfo(res) +#define socket(domain, type, protocol) win32_socket(domain, type, protocol) +#define ioctl(fd, request, argp) win32_ioctl(fd, request, argp) +#define bind(sockfd, addr, addrlen) win32_bind(sockfd, addr, addrlen) +#define connect(sockfd, addr, addrlen) win32_connect(sockfd, addr, addrlen) +#define getsockopt(sockfd, level, optname, optval, optlen) win32_getsockopt(sockfd, level, optname, optval, optlen) +#define setsockopt(sockfd, level, optname, optval, optlen) win32_setsockopt(sockfd, level, optname, optval, optlen) +#define close(fd) win32_close(fd) +#define recv(sockfd, buf, len, flags) win32_recv(sockfd, buf, len, flags) +#define send(sockfd, buf, len, flags) win32_send(sockfd, buf, len, flags) +#define poll(fds, nfds, timeout) win32_poll(fds, nfds, timeout) +#endif /* REDIS_SOCKCOMPAT_IMPLEMENTATION */ +#endif /* _WIN32 */ + +#endif /* __SOCKCOMPAT_H */ diff --git a/hiredis/Lib/hiredisD32.lib b/hiredis/Lib/hiredisD32.lib new file mode 100644 index 0000000000000000000000000000000000000000..1966b747c05d7d693d04df3952b68be361108d24 GIT binary patch literal 34440 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 literal 0 HcmV?d00001 diff --git a/hiredis/Lib/hiredisR32.lib b/hiredis/Lib/hiredisR32.lib new file mode 100644 index 0000000000000000000000000000000000000000..f4d415c8257a70b94c4475c171219791ad2e22ce GIT binary patch literal 32886 zcmeHPdz4hgng2jVL?FIJR2&g`1rdgs;h{kWhT%PoGlM9iO;7ionTDS3rn_f&s%TWy zpwR?#T+hbUB)fVxIf=SSPL^YQLEMPMSHviqm}FU0f{7v;q6qta^}1Dct6%i^U*??O z)UB_+s$act)mL@<{7b{>NXOKE7gv~n7mYXl(l<^#OsuM&z#o_O1L!pzV9KunEANhP%)u9OS5rV)}@gQw4sG zE~0*nz=P-_W(^Y9j4on!AA$Ag68_3D2h(EMjV@yD5`j0+Ma*ju*p4n@{uF^n(M2p6 zDewTgh=zdzo6top>@Psih(^o@1LmQTu#e;Nr2q^sqKjy%6WD?-q8WJ@?nf8V(pTUn zbPH&ozT=px#%-Wb-SOE|#M9tB{)Hg89C%oo7A??A-H3SiyG z5X&(g2CVDlgxwq~t^{Cs7F|Rf<1t{IIHI$+Kpb5Hwh19oCxCq_fk+M(xD8#xevZ@< z00vAug;+U8U^BXe!yIX>Ck9MAjmXpsJdQ3Ri|I4miZ05%>YRi1mX6FwS}cmWOa1 z_8kUn^Xm}T&ldP8x`-P_3w#G%#0G4i4ShqQISU#WHnoK6W;V}gn$y^_uqo6LOMB5+ zrfEVYghCCA=Fbo6zzx02VJf4iyCo(7w;Zrys%4DOl zWGI!6C9-XyWGWj=vQQSOfKG_ztTvVM644pS&dzWmD(OP*Fd@yXNkr;mnMg8`@FH0| zP9T)WYWA`-)9GZ|Qn$sC$&*8w1TPPSOdqd`wzTIpd8zoCg{{jOeLx_p%v&9b#@b`q zP&OID>VZ&4Kq4zQgjI?4i7GMmsKO|H7Q!Etywi^(A5~b|^8?kh3e9BG(XJFrQ$ETt z-dntkmt}1o&L-2?+OmV#aw8U2r6Z0d?~>)xu1&XhgQJgdc_3DOGTj-@W<9@~ zX=K4bJwEj&)j4@ALzF{T&!DCs%pVUF9a&G`=-YvS=`k8CImE#{vBW6O;#jt$$?M8s zhjK>N!gHjuC=pxjh|I+~;!vs!<=hb9HA3wa^l|RT)TMTeV0-%Uf?ZJHC4WMGC9*%kdl`HZyG^wf|{Ovm@2?1@5~CN4iDe@txx6PXVruBimms+S{L zaFai%<>y8x@uk5S+O#QB4$PRE+)qhQpJMnSZVoD(>a=!bBQO}Bg3W1KWXT9{$8&P# z;mdlf<@7_%+Y-U$h|I1l%w*Lxa>ZowoUzR2(2{et3I)?#5J@e{cp`|o45pIop^E@wA8;^C%2`C`V9fP{WoJ7`3 zcZcJm#jV(;hL#e4d7FzdOO{Jpo2QHzf!T_OHb*nYbjBLX9i%h*ONV-U)j$F(=eop7 zh3Z#LL=;sDEImJ;qAE#O7i#*mye!+b2uRq1=RR2tLCh?mL8r2uYVSSf;HEe$?&WvGZj_dPFNckV?Jh$yW}K#sxt=Y+55^$pYHJiIvANqZJjEBJ?dd`QFM&N9`!J3)!}JMpRSSiQoLR;I)BzfF`mp2 zd(^|aWpX@m<@I&qURb2fpZt(cT>DToa(!tE#|}x!)upP0sWoN^nMns@FjvL!I#XGm zl6X=fs@eF1AHWJmIZkLCn>qvTiZJtlM-r z(ay(#cv7)g#e~!CoJ{kX8Zu?3V5Xf-#*?e)Rg0Nb&nk8{*@YHT87iLr&~&VmM`RC5 z-X-e<(^SuXC|gp>EOq%lp`rS+eBknK-!Q5@@~~C0#DvOFD>F;!&w6Ntzx{cz@EGCp zbtE*TSJ$Dw7>-8K-rR;AiYuBjUAsLTLko4<;w^K5 zs!F13#*&dNE_FG%@aW;GWLyRFXFW9SMbOg8BlBl7G#bljt1YQ#O7$2SG`7q1__G=6 zmw~61$x$jQs;9~>d`EGzT2n1gR__IXUrzxzd?~=BsQ@q50o;8Vz`$t$HzN)q;+pDf0myMT}ek@Bm_91HdLk|Apux`ZQu1h<%8qmt+1Abxi>@m0LhMB>y#nBMMAKsAK}^RpvnLTXR{{JOF$T}Let;N$HNYc?A$TVBAmX%ZkQdSC zT0Hwg{29>{0(cHlwG7}#h;zaKcOVWT+FAkLMl?h)Z-}W;Odm1S1NauAZyV+xaR3o* z$Fd{lcVPYzV`G?qMBn9@Z^UlIl`8w3Nbhda2sMjVhNsE zJ&PE#66+js7}1tSeMEf*;Bmy@EWoXZ4-red0Jb5n!#g^OVvjE72?098;8H82q-!DN^Mm%yd)HJA#Q!8E9a=`aK8 zU?$YVESL>*U@pvq`LF;QU?DWZ<4O|N$SO#Heg$P8! zgEnY~4v4{WSOIb9gajlZ1uG#98OTBxbi*oG4QpU6tb_G%9b6ALzy`PxZi27F&2S6c z3LD`zxE=0*Z@?zF6Yhd*k*|BWvauT#OyvDQlr4Q@%&F_ABxr zly)G#5ghZtwQ<*D9cmVHD$6!OHjy~7X4MbWr{cf6^b!qFM-FR=Jo*v z)`kHk&a+ImqvA)_`blbK#Hy`$94inzh!OU=dW;u)U(Z{on{F~ZSJVS z;~G{TvY`Yk3VXb$NNG|kMyG_sE<2A%Xc}D{3NCX8D?_ko#T-0o3?-f?=`jl(6&bq0 zKC5-td_Y33XUvW?j=L z=HMe38GD?4zTsAK7}>A@#9!VqgvMqa2pD6{3Zpvpj}x>soCY>F?-(J0>6C{yTL%Do z!uEVb6O_yFNAe=<_FB?TE3Fh3Hoa>p<+rVyioxlk1UtEw6iuC8nj6rmSu~?~Kr63} zJD@GAz~~4~Uc|Hyu*S_daq=#%?9v)d{?1RKj$U896bks`25 zo^tP`@0zszQm)&bLXPtvn~20+P`-FKZ|w$U{KcxtgDZU=Xl!}{B0U*nqoZrGbtK>7 zIK}if%5~|HulEAcjJ28{s&8d{X}+S>vo`Q`^^J=yRc{$PKtJ%-wkf_EHj!9G`Wuvd zp@DmPe!+4iU~Wf@v>n;jGpuhuSUlr)8T7^&F zGUN`idy0sx?qUePzY!2w(00hSB)2Y+nRO?U4|YB+AP_@a`m4=>%!C%kwgnEkHUN-? zA~;q0()64gu&N@zm(=GMzgas zQGfZ2t5xPvHz(B12n;b6%jgf>bU>MSm(r7bnbLDwyTQPg!ze^oyPzNsSy3tvQ@M_Q z)c_?d!>FW|x}@b_8IV^5{7V5cVR`EBpY!wAKE|g9f9c8u`T;!({N*ZojB|MOvn*-n z$o{ev1GOV`nG^qvTw8vkD)UJtwdBMA<7itRWUJF^RM3`|8CiSUa*{6_TeUN1^MqM; zRjx<1;V&Dx%v>-EnSSJ}MCxdlON>KZ{RG!MuZ=oRXU!AXz@qwin(&2Hx84 zn#(iZs%2$SpQQ1o|7qi`O3F#^HR%y3>7R>iis@eacm8`ANuys$+WbLi9 z(gMlf#X;G;l|kOW?|EfM1@a!F@#0#K@69Yi(_479sdAL_j6EY?rIC3o@fo%dGxeir zOGoL3esA0nD&29!MvDdA)?yKw-om9*Q>oT>k}Vg$dp`2@A-;eq$7CqIgjMpDuQ4W` zyXB3+$Vj(f@RMHorLje2dJC7WN=|kf(=D?a-y4KXeFYO+l9~xyJ+ufOM~RM%_THru zogjF`+PqvQ$4LM71N(NJjZFOnlU(^*R3*O{dM?lo9crnhkYRXh6p zsO@{+sX(UwScBLj*hY$Nl<2~QNnm-4;B$=VQNOwKEt46$A&Rm*Vvusvzk5PX&?flbYduX-y6=LOeYnV;T=5*BXCr|D@LN$Dno0FMC z%H^$bjQDB)HSx$8RJj-P7!4+kV_zf+6hTO8~wOwCD*1;xgp-H3kR#w08 zWV!s>z$`>P%^;{RL zw82}%rnhi!u6B%})-fw~(ij@z;^j7Nlg6s^B3K=5`e|&@v(%>NnXF{Xw$d+s)VRj% z%fH{djmB(+$%jh|ablxR)2zal+=E^7wrV!kbh`^ z-=8*eRe+hF!mVB7SiQb`@n4=9jrDselgg@z!pyGO^2E*OeN1C{Sb#alkSe*o zU90sG@pt!EAnS!DYtM`(NBtgm)8uW$H(c>)XSwCps^e{N+K0XVMmypW7N4_#rPrvV z2S4`7e{ZE(YNTQe97UH~P6z7+k49f6)=?&_e$rhgtIL|Q=iv9ABWucNpH&>BTV$oz ztfMWxg_T>WEx&5BxfaJIGrG!m#`qK~-x!V2xiBu7t;X@DIlN-Tp;1`Ai)=RIqCvSe zJJIn*|JT*?-k~FyvH6&DE|AR}6*2oc%KqR(3lGp+_F_8+cu&Gizx21PYqq`NV9U!i z+m5sO)ZL1*Ssgw2^WOjYDfQs-Hmhp`&?9}SZ}NpNs83b87<;U&uHE}nC#2t|-TMR= zGxen$uQjvY3->113U$LrReNZKT4i(R+4A%R@8t)ddW(3gUA#S2UPr%rWXLZ+rae!M z&Z}M2k(YSPG9JZ9a#)9U|Kh0+$T~DJ2RB_3Dwo&Q#>emI{R-9fq#V4iA!X*Hh`!~p z4GI9{T@406v2bbo`fpG<_+#I;x8K0jz<7s+ld`;!Rx=d!ZaOvZ##!>U1 z-Z*3*m3wL~R+`h)6}Ga=?XWpN{I?VLlg;@ul>_r$RN0)4Qg2>!-gfHe)7+drvf^{? z|32C^Y%lHqYAxPo^NOEUWYb%CWV=pi=Dqd!AL)cZLepEgE~_1L^x0>&92katGYvk!4efziGN)q= zeSe?ILqm|WUU906j%M-}dEpYe-hK~#I{W~={bmK&wA-O&@>V<6>CL0QxtG@IvlXv@ z`P8B-`Mp!^sMViNZFz}mb&ldwms>45(_6S!UHiTFUplml_Oo+!wjQzcxym+Vz`4Jr zvdz=koQ8=~%jUA4-rn}s7i1xruh;@te@&W_`)Re~9PPu7{X6M=X@O#;>XhH~SrnGH za2vWTn6;Na`zl#58=Q>vvh*)5TLmt?$2u%rPoBABdj;|@wD{S@Xp7MF7A~)AZk_VO zNn44p(dO%kw})eHeR^iwR+?KcxA=N$wsXxo>t;Rw8O=IP8mGK9Zr0&ZyssRmg(nYw zW_p(dsSZA&I*-zf5b=D$_GtV}r z^s+ie$>I-&uob}-2CsVqW0t#!QR3*e>G%6=r(U~Q@mU`Qm?S07MAeS=9DGmYO={08 zHO@Sj2uiP4$NO^GEv36<9~QiP7IH2V zocx2EvY8w$H=ydASE=Q~lF5B(u=HNy=>Hqvd3Znd|5nMB}R)a zI}^Dgf(t(;vc^^E?_1a2cVle&i?sKR`aJZ#lUW4ITSSQ*?}69{8@?bW&u5~~h{|Ph zyjh3!JMtOL9c@07_}<7OE4^1Zdf<-THHWANw)<@CYp}Ap9Ci4Q)RU|ZJA5vjhs&)) z*AD6GVGqAbZ?l-sBtK@e3TAqX=o^mtV$0++x6^#FT(Yrm<;;|iqQ5)F)#+Or-=J}| zLNejEcwYw3#LeH`Lp*WGgWvj<&Ex11+j`x*helPW&(jm5%29JyZ~4;>Dp5i((Wi=K zm&nl{T^f&LsxAEu;uyncU-|i`G={qcm-tGz+)_DKFfV%FK1?mO zN-(L9fXn4_%oj`g|NAF2U#u2f^o_Aa(<8O_o5RCjqS{;I^Yp|F=$M&aIPuOmX=Yk0 znD{5sWtYjZg86K~pFW@!%sRp3e}Y{$o1<5pKjPkZs8_7l*?OW59ph@>f7G${`gMX! zenDP#xg1=>FZuafG={HNT>J;u%jR;-OY6^{{t3-XH%Kn}0^TAry+zEmjxyc&*^Pgv zGHnn%@&kJ_?W0&LIeOt){X@T}UU;MAQa>$UHk+dckGwkiC91)j7@K>+Zt@mUgO1sD z!~?(CM)SqjiO2u_0W)c<>55=-wAD(8zDI3!GcoaB8el(fU{RGm3p&Q|*1PMOZRQrA zi~oFrMP_;nm&>&``0e!@_tM_rR*g&iI)j;f$+hUR<&9gp?*+17Z1mZTAAhhYORh~9 z=hLefZ6(gzd`{!XCCcV>^#8*T?qJ^o-L7$JKVD%`n%*MX(eZ|!`2MNe=`{KdgHirA zhRJXgGm4{^{@dE&yXj5y4WE(!_J&1fdJC7%Wz*YPamoMD=-cFTv7h!Z(>{uFIY#;~ ze)-%1;=0r4Vm}>HE|=>r%-5HWew|K8?$Wu8pC&1n)m586oBG0QRKjoitn8;x%H?w1 olIVW(lDDZ}-mP<~pH?ZC(PeEu_n8HMp*P(<8YBPd7Mtz=0X09E2LJ#7 literal 0 HcmV?d00001 diff --git a/hiredis/Lib/hiredisR64.lib b/hiredis/Lib/hiredisR64.lib new file mode 100644 index 0000000000000000000000000000000000000000..6b42c22828f380e6a3152ebaa1efff9e56a3378d GIT binary patch literal 32152 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 literal 0 HcmV?d00001