1 /* 2 * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> 3 * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> 4 * 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * * Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * * Neither the name of Redis nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without 17 * specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef __HIREDIS_H 33 #define __HIREDIS_H 34 #include <stdio.h> /* for size_t */ 35 #include <stdarg.h> /* for va_list */ 36 #include <sys/time.h> /* for struct timeval */ 37 38 #define HIREDIS_MAJOR 0 39 #define HIREDIS_MINOR 11 40 #define HIREDIS_PATCH 0 41 42 #define REDIS_ERR -1 43 #define REDIS_OK 0 44 45 /* When an error occurs, the err flag in a context is set to hold the type of 46 * error that occured. REDIS_ERR_IO means there was an I/O error and you 47 * should use the "errno" variable to find out what is wrong. 48 * For other values, the "errstr" field will hold a description. */ 49 #define REDIS_ERR_IO 1 /* Error in read or write */ 50 #define REDIS_ERR_EOF 3 /* End of file */ 51 #define REDIS_ERR_PROTOCOL 4 /* Protocol error */ 52 #define REDIS_ERR_OOM 5 /* Out of memory */ 53 #define REDIS_ERR_OTHER 2 /* Everything else... */ 54 55 /* Connection type can be blocking or non-blocking and is set in the 56 * least significant bit of the flags field in redisContext. */ 57 #define REDIS_BLOCK 0x1 58 59 /* Connection may be disconnected before being free'd. The second bit 60 * in the flags field is set when the context is connected. */ 61 #define REDIS_CONNECTED 0x2 62 63 /* The async API might try to disconnect cleanly and flush the output 64 * buffer and read all subsequent replies before disconnecting. 65 * This flag means no new commands can come in and the connection 66 * should be terminated once all replies have been read. */ 67 #define REDIS_DISCONNECTING 0x4 68 69 /* Flag specific to the async API which means that the context should be clean 70 * up as soon as possible. */ 71 #define REDIS_FREEING 0x8 72 73 /* Flag that is set when an async callback is executed. */ 74 #define REDIS_IN_CALLBACK 0x10 75 76 /* Flag that is set when the async context has one or more subscriptions. */ 77 #define REDIS_SUBSCRIBED 0x20 78 79 /* Flag that is set when monitor mode is active */ 80 #define REDIS_MONITORING 0x40 81 82 #define REDIS_REPLY_STRING 1 83 #define REDIS_REPLY_ARRAY 2 84 #define REDIS_REPLY_INTEGER 3 85 #define REDIS_REPLY_NIL 4 86 #define REDIS_REPLY_STATUS 5 87 #define REDIS_REPLY_ERROR 6 88 89 #define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */ 90 91 #define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */ 92 93 #ifdef __cplusplus 94 extern "C" { 95 #endif 96 97 /* This is the reply object returned by redisCommand() */ 98 typedef struct redisReply { 99 int type; /* REDIS_REPLY_* */ 100 long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ 101 int len; /* Length of string */ 102 char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ 103 size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ 104 struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ 105 } redisReply; 106 107 typedef struct redisReadTask { 108 int type; 109 int elements; /* number of elements in multibulk container */ 110 int idx; /* index in parent (array) object */ 111 void *obj; /* holds user-generated value for a read task */ 112 struct redisReadTask *parent; /* parent task */ 113 void *privdata; /* user-settable arbitrary field */ 114 } redisReadTask; 115 116 typedef struct redisReplyObjectFunctions { 117 void *(*createString)(const redisReadTask*, char*, size_t); 118 void *(*createArray)(const redisReadTask*, int); 119 void *(*createInteger)(const redisReadTask*, long long); 120 void *(*createNil)(const redisReadTask*); 121 void (*freeObject)(void*); 122 } redisReplyObjectFunctions; 123 124 /* State for the protocol parser */ 125 typedef struct redisReader { 126 int err; /* Error flags, 0 when there is no error */ 127 char errstr[128]; /* String representation of error when applicable */ 128 129 char *buf; /* Read buffer */ 130 size_t pos; /* Buffer cursor */ 131 size_t len; /* Buffer length */ 132 size_t maxbuf; /* Max length of unused buffer */ 133 134 redisReadTask rstack[9]; 135 int ridx; /* Index of current read task */ 136 void *reply; /* Temporary reply pointer */ 137 138 redisReplyObjectFunctions *fn; 139 void *privdata; 140 } redisReader; 141 142 /* Public API for the protocol parser. */ 143 redisReader *redisReaderCreate(void); 144 void redisReaderFree(redisReader *r); 145 int redisReaderFeed(redisReader *r, const char *buf, size_t len); 146 int redisReaderGetReply(redisReader *r, void **reply); 147 148 /* Backwards compatibility, can be removed on big version bump. */ 149 #define redisReplyReaderCreate redisReaderCreate 150 #define redisReplyReaderFree redisReaderFree 151 #define redisReplyReaderFeed redisReaderFeed 152 #define redisReplyReaderGetReply redisReaderGetReply 153 #define redisReplyReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) 154 #define redisReplyReaderGetObject(_r) (((redisReader*)(_r))->reply) 155 #define redisReplyReaderGetError(_r) (((redisReader*)(_r))->errstr) 156 157 /* Function to free the reply objects hiredis returns by default. */ 158 void freeReplyObject(void *reply); 159 160 /* Functions to format a command according to the protocol. */ 161 int redisvFormatCommand(char **target, const char *format, va_list ap); 162 int redisFormatCommand(char **target, const char *format, ...); 163 int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); 164 165 /* Context for a connection to Redis */ 166 typedef struct redisContext { 167 int err; /* Error flags, 0 when there is no error */ 168 char errstr[128]; /* String representation of error when applicable */ 169 int fd; 170 int flags; 171 char *obuf; /* Write buffer */ 172 redisReader *reader; /* Protocol reader */ 173 } redisContext; 174 175 redisContext *redisConnect(const char *ip, int port); 176 redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv); 177 redisContext *redisConnectNonBlock(const char *ip, int port); 178 redisContext *redisConnectBindNonBlock(const char *ip, int port, const char *source_addr); 179 redisContext *redisConnectUnix(const char *path); 180 redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv); 181 redisContext *redisConnectUnixNonBlock(const char *path); 182 redisContext *redisConnectFd(int fd); 183 int redisSetTimeout(redisContext *c, const struct timeval tv); 184 int redisEnableKeepAlive(redisContext *c); 185 void redisFree(redisContext *c); 186 int redisFreeKeepFd(redisContext *c); 187 int redisBufferRead(redisContext *c); 188 int redisBufferWrite(redisContext *c, int *done); 189 190 /* In a blocking context, this function first checks if there are unconsumed 191 * replies to return and returns one if so. Otherwise, it flushes the output 192 * buffer to the socket and reads until it has a reply. In a non-blocking 193 * context, it will return unconsumed replies until there are no more. */ 194 int redisGetReply(redisContext *c, void **reply); 195 int redisGetReplyFromReader(redisContext *c, void **reply); 196 197 /* Write a formatted command to the output buffer. Use these functions in blocking mode 198 * to get a pipeline of commands. */ 199 int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len); 200 201 /* Write a command to the output buffer. Use these functions in blocking mode 202 * to get a pipeline of commands. */ 203 int redisvAppendCommand(redisContext *c, const char *format, va_list ap); 204 int redisAppendCommand(redisContext *c, const char *format, ...); 205 int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); 206 207 /* Issue a command to Redis. In a blocking context, it is identical to calling 208 * redisAppendCommand, followed by redisGetReply. The function will return 209 * NULL if there was an error in performing the request, otherwise it will 210 * return the reply. In a non-blocking context, it is identical to calling 211 * only redisAppendCommand and will always return NULL. */ 212 void *redisvCommand(redisContext *c, const char *format, va_list ap); 213 void *redisCommand(redisContext *c, const char *format, ...); 214 void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen); 215 216 #ifdef __cplusplus 217 } 218 #endif 219 220 #endif 221