summaryrefslogtreecommitdiff
path: root/deps/hiredis/hiredis.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/hiredis/hiredis.c')
-rw-r--r--deps/hiredis/hiredis.c180
1 files changed, 97 insertions, 83 deletions
diff --git a/deps/hiredis/hiredis.c b/deps/hiredis/hiredis.c
index 51f22a665..91086f6f6 100644
--- a/deps/hiredis/hiredis.c
+++ b/deps/hiredis/hiredis.c
@@ -96,6 +96,8 @@ void freeReplyObject(void *reply) {
switch(r->type) {
case REDIS_REPLY_INTEGER:
+ case REDIS_REPLY_NIL:
+ case REDIS_REPLY_BOOL:
break; /* Nothing to free */
case REDIS_REPLY_ARRAY:
case REDIS_REPLY_MAP:
@@ -112,6 +114,7 @@ void freeReplyObject(void *reply) {
case REDIS_REPLY_STRING:
case REDIS_REPLY_DOUBLE:
case REDIS_REPLY_VERB:
+ case REDIS_REPLY_BIGNUM:
hi_free(r->str);
break;
}
@@ -129,7 +132,8 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len
assert(task->type == REDIS_REPLY_ERROR ||
task->type == REDIS_REPLY_STATUS ||
task->type == REDIS_REPLY_STRING ||
- task->type == REDIS_REPLY_VERB);
+ task->type == REDIS_REPLY_VERB ||
+ task->type == REDIS_REPLY_BIGNUM);
/* Copy string value */
if (task->type == REDIS_REPLY_VERB) {
@@ -235,12 +239,14 @@ static void *createDoubleObject(const redisReadTask *task, double value, char *s
* decimal string conversion artifacts. */
memcpy(r->str, str, len);
r->str[len] = '\0';
+ r->len = len;
if (task->parent) {
parent = task->parent->obj;
assert(parent->type == REDIS_REPLY_ARRAY ||
parent->type == REDIS_REPLY_MAP ||
- parent->type == REDIS_REPLY_SET);
+ parent->type == REDIS_REPLY_SET ||
+ parent->type == REDIS_REPLY_PUSH);
parent->element[task->idx] = r;
}
return r;
@@ -277,7 +283,8 @@ static void *createBoolObject(const redisReadTask *task, int bval) {
parent = task->parent->obj;
assert(parent->type == REDIS_REPLY_ARRAY ||
parent->type == REDIS_REPLY_MAP ||
- parent->type == REDIS_REPLY_SET);
+ parent->type == REDIS_REPLY_SET ||
+ parent->type == REDIS_REPLY_PUSH);
parent->element[task->idx] = r;
}
return r;
@@ -306,7 +313,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
const char *c = format;
char *cmd = NULL; /* final command */
int pos; /* position in final command */
- hisds curarg, newarg; /* current argument */
+ sds curarg, newarg; /* current argument */
int touched = 0; /* was the current argument touched? */
char **curargv = NULL, **newargv = NULL;
int argc = 0;
@@ -319,7 +326,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
return -1;
/* Build the command string accordingly to protocol */
- curarg = hi_sdsempty();
+ curarg = sdsempty();
if (curarg == NULL)
return -1;
@@ -331,15 +338,15 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
if (newargv == NULL) goto memory_err;
curargv = newargv;
curargv[argc++] = curarg;
- totlen += bulklen(hi_sdslen(curarg));
+ totlen += bulklen(sdslen(curarg));
/* curarg is put in argv so it can be overwritten. */
- curarg = hi_sdsempty();
+ curarg = sdsempty();
if (curarg == NULL) goto memory_err;
touched = 0;
}
} else {
- newarg = hi_sdscatlen(curarg,c,1);
+ newarg = sdscatlen(curarg,c,1);
if (newarg == NULL) goto memory_err;
curarg = newarg;
touched = 1;
@@ -356,16 +363,16 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
arg = va_arg(ap,char*);
size = strlen(arg);
if (size > 0)
- newarg = hi_sdscatlen(curarg,arg,size);
+ newarg = sdscatlen(curarg,arg,size);
break;
case 'b':
arg = va_arg(ap,char*);
size = va_arg(ap,size_t);
if (size > 0)
- newarg = hi_sdscatlen(curarg,arg,size);
+ newarg = sdscatlen(curarg,arg,size);
break;
case '%':
- newarg = hi_sdscat(curarg,"%");
+ newarg = sdscat(curarg,"%");
break;
default:
/* Try to detect printf format */
@@ -453,7 +460,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
if (_l < sizeof(_format)-2) {
memcpy(_format,c,_l);
_format[_l] = '\0';
- newarg = hi_sdscatvprintf(curarg,_format,_cpy);
+ newarg = sdscatvprintf(curarg,_format,_cpy);
/* Update current position (note: outer blocks
* increment c twice so compensate here) */
@@ -480,9 +487,9 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
if (newargv == NULL) goto memory_err;
curargv = newargv;
curargv[argc++] = curarg;
- totlen += bulklen(hi_sdslen(curarg));
+ totlen += bulklen(sdslen(curarg));
} else {
- hi_sdsfree(curarg);
+ sdsfree(curarg);
}
/* Clear curarg because it was put in curargv or was free'd. */
@@ -497,10 +504,10 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
pos = sprintf(cmd,"*%d\r\n",argc);
for (j = 0; j < argc; j++) {
- pos += sprintf(cmd+pos,"$%zu\r\n",hi_sdslen(curargv[j]));
- memcpy(cmd+pos,curargv[j],hi_sdslen(curargv[j]));
- pos += hi_sdslen(curargv[j]);
- hi_sdsfree(curargv[j]);
+ pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));
+ memcpy(cmd+pos,curargv[j],sdslen(curargv[j]));
+ pos += sdslen(curargv[j]);
+ sdsfree(curargv[j]);
cmd[pos++] = '\r';
cmd[pos++] = '\n';
}
@@ -522,11 +529,11 @@ memory_err:
cleanup:
if (curargv) {
while(argc--)
- hi_sdsfree(curargv[argc]);
+ sdsfree(curargv[argc]);
hi_free(curargv);
}
- hi_sdsfree(curarg);
+ sdsfree(curarg);
hi_free(cmd);
return error_type;
@@ -559,19 +566,18 @@ int redisFormatCommand(char **target, const char *format, ...) {
return len;
}
-/* Format a command according to the Redis protocol using an hisds string and
- * hi_sdscatfmt for the processing of arguments. This function takes the
+/* Format a command according to the Redis protocol using an sds string and
+ * sdscatfmt for the processing of arguments. This function takes the
* number of arguments, an array with arguments and an array with their
* lengths. If the latter is set to NULL, strlen will be used to compute the
* argument lengths.
*/
-int redisFormatSdsCommandArgv(hisds *target, int argc, const char **argv,
- const size_t *argvlen)
+long long redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,
+ const size_t *argvlen)
{
- hisds cmd, aux;
- unsigned long long totlen;
+ sds cmd, aux;
+ unsigned long long totlen, len;
int j;
- size_t len;
/* Abort on a NULL target */
if (target == NULL)
@@ -585,36 +591,36 @@ int redisFormatSdsCommandArgv(hisds *target, int argc, const char **argv,
}
/* Use an SDS string for command construction */
- cmd = hi_sdsempty();
+ cmd = sdsempty();
if (cmd == NULL)
return -1;
/* We already know how much storage we need */
- aux = hi_sdsMakeRoomFor(cmd, totlen);
+ aux = sdsMakeRoomFor(cmd, totlen);
if (aux == NULL) {
- hi_sdsfree(cmd);
+ sdsfree(cmd);
return -1;
}
cmd = aux;
/* Construct command */
- cmd = hi_sdscatfmt(cmd, "*%i\r\n", argc);
+ cmd = sdscatfmt(cmd, "*%i\r\n", argc);
for (j=0; j < argc; j++) {
len = argvlen ? argvlen[j] : strlen(argv[j]);
- cmd = hi_sdscatfmt(cmd, "$%u\r\n", len);
- cmd = hi_sdscatlen(cmd, argv[j], len);
- cmd = hi_sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);
+ cmd = sdscatfmt(cmd, "$%U\r\n", len);
+ cmd = sdscatlen(cmd, argv[j], len);
+ cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);
}
- assert(hi_sdslen(cmd)==totlen);
+ assert(sdslen(cmd)==totlen);
*target = cmd;
return totlen;
}
-void redisFreeSdsCommand(hisds cmd) {
- hi_sdsfree(cmd);
+void redisFreeSdsCommand(sds cmd) {
+ sdsfree(cmd);
}
/* Format a command according to the Redis protocol. This function takes the
@@ -622,11 +628,11 @@ void redisFreeSdsCommand(hisds cmd) {
* lengths. If the latter is set to NULL, strlen will be used to compute the
* argument lengths.
*/
-int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
+long long redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
char *cmd = NULL; /* final command */
- int pos; /* position in final command */
- size_t len;
- int totlen, j;
+ size_t pos; /* position in final command */
+ size_t len, totlen;
+ int j;
/* Abort on a NULL target */
if (target == NULL)
@@ -698,7 +704,7 @@ static redisContext *redisContextInit(void) {
c->funcs = &redisContextDefaultFuncs;
- c->obuf = hi_sdsempty();
+ c->obuf = sdsempty();
c->reader = redisReaderCreate();
c->fd = REDIS_INVALID_FD;
@@ -715,7 +721,7 @@ void redisFree(redisContext *c) {
return;
redisNetClose(c);
- hi_sdsfree(c->obuf);
+ sdsfree(c->obuf);
redisReaderFree(c->reader);
hi_free(c->tcp.host);
hi_free(c->tcp.source_addr);
@@ -752,10 +758,10 @@ int redisReconnect(redisContext *c) {
redisNetClose(c);
- hi_sdsfree(c->obuf);
+ sdsfree(c->obuf);
redisReaderFree(c->reader);
- c->obuf = hi_sdsempty();
+ c->obuf = sdsempty();
c->reader = redisReaderCreate();
if (c->obuf == NULL || c->reader == NULL) {
@@ -797,6 +803,9 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
if (options->options & REDIS_OPT_NOAUTOFREE) {
c->flags |= REDIS_NO_AUTO_FREE;
}
+ if (options->options & REDIS_OPT_NOAUTOFREEREPLIES) {
+ c->flags |= REDIS_NO_AUTO_FREE_REPLIES;
+ }
/* Set any user supplied RESP3 PUSH handler or use freeReplyObject
* as a default unless specifically flagged that we don't want one. */
@@ -825,7 +834,7 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
c->fd = options->endpoint.fd;
c->flags |= REDIS_CONNECTED;
} else {
- // Unknown type - FIXME - FREE
+ redisFree(c);
return NULL;
}
@@ -939,13 +948,11 @@ int redisBufferRead(redisContext *c) {
return REDIS_ERR;
nread = c->funcs->read(c, buf, sizeof(buf));
- if (nread > 0) {
- if (redisReaderFeed(c->reader, buf, nread) != REDIS_OK) {
- __redisSetError(c, c->reader->err, c->reader->errstr);
- return REDIS_ERR;
- } else {
- }
- } else if (nread < 0) {
+ if (nread < 0) {
+ return REDIS_ERR;
+ }
+ if (nread > 0 && redisReaderFeed(c->reader, buf, nread) != REDIS_OK) {
+ __redisSetError(c, c->reader->err, c->reader->errstr);
return REDIS_ERR;
}
return REDIS_OK;
@@ -966,22 +973,22 @@ int redisBufferWrite(redisContext *c, int *done) {
if (c->err)
return REDIS_ERR;
- if (hi_sdslen(c->obuf) > 0) {
+ if (sdslen(c->obuf) > 0) {
ssize_t nwritten = c->funcs->write(c);
if (nwritten < 0) {
return REDIS_ERR;
} else if (nwritten > 0) {
- if (nwritten == (ssize_t)hi_sdslen(c->obuf)) {
- hi_sdsfree(c->obuf);
- c->obuf = hi_sdsempty();
+ if (nwritten == (ssize_t)sdslen(c->obuf)) {
+ sdsfree(c->obuf);
+ c->obuf = sdsempty();
if (c->obuf == NULL)
goto oom;
} else {
- if (hi_sdsrange(c->obuf,nwritten,-1) < 0) goto oom;
+ if (sdsrange(c->obuf,nwritten,-1) < 0) goto oom;
}
}
}
- if (done != NULL) *done = (hi_sdslen(c->obuf) == 0);
+ if (done != NULL) *done = (sdslen(c->obuf) == 0);
return REDIS_OK;
oom:
@@ -989,17 +996,6 @@ oom:
return REDIS_ERR;
}
-/* Internal helper function to try and get a reply from the reader,
- * or set an error in the context otherwise. */
-int redisGetReplyFromReader(redisContext *c, void **reply) {
- if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) {
- __redisSetError(c,c->reader->err,c->reader->errstr);
- return REDIS_ERR;
- }
-
- return REDIS_OK;
-}
-
/* Internal helper that returns 1 if the reply was a RESP3 PUSH
* message and we handled it with a user-provided callback. */
static int redisHandledPushReply(redisContext *c, void *reply) {
@@ -1011,12 +1007,34 @@ static int redisHandledPushReply(redisContext *c, void *reply) {
return 0;
}
+/* Get a reply from our reader or set an error in the context. */
+int redisGetReplyFromReader(redisContext *c, void **reply) {
+ if (redisReaderGetReply(c->reader, reply) == REDIS_ERR) {
+ __redisSetError(c,c->reader->err,c->reader->errstr);
+ return REDIS_ERR;
+ }
+
+ return REDIS_OK;
+}
+
+/* Internal helper to get the next reply from our reader while handling
+ * any PUSH messages we encounter along the way. This is separate from
+ * redisGetReplyFromReader so as to not change its behavior. */
+static int redisNextInBandReplyFromReader(redisContext *c, void **reply) {
+ do {
+ if (redisGetReplyFromReader(c, reply) == REDIS_ERR)
+ return REDIS_ERR;
+ } while (redisHandledPushReply(c, *reply));
+
+ return REDIS_OK;
+}
+
int redisGetReply(redisContext *c, void **reply) {
int wdone = 0;
void *aux = NULL;
/* Try to read pending replies */
- if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
+ if (redisNextInBandReplyFromReader(c,&aux) == REDIS_ERR)
return REDIS_ERR;
/* For the blocking context, flush output buffer and read reply */
@@ -1032,12 +1050,8 @@ int redisGetReply(redisContext *c, void **reply) {
if (redisBufferRead(c) == REDIS_ERR)
return REDIS_ERR;
- /* We loop here in case the user has specified a RESP3
- * PUSH handler (e.g. for client tracking). */
- do {
- if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
- return REDIS_ERR;
- } while (redisHandledPushReply(c, aux));
+ if (redisNextInBandReplyFromReader(c,&aux) == REDIS_ERR)
+ return REDIS_ERR;
} while (aux == NULL);
}
@@ -1059,9 +1073,9 @@ int redisGetReply(redisContext *c, void **reply) {
* the reply (or replies in pub/sub).
*/
int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) {
- hisds newbuf;
+ sds newbuf;
- newbuf = hi_sdscatlen(c->obuf,cmd,len);
+ newbuf = sdscatlen(c->obuf,cmd,len);
if (newbuf == NULL) {
__redisSetError(c,REDIS_ERR_OOM,"Out of memory");
return REDIS_ERR;
@@ -1113,8 +1127,8 @@ int redisAppendCommand(redisContext *c, const char *format, ...) {
}
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
- hisds cmd;
- int len;
+ sds cmd;
+ long long len;
len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
if (len == -1) {
@@ -1123,11 +1137,11 @@ int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const s
}
if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
- hi_sdsfree(cmd);
+ sdsfree(cmd);
return REDIS_ERR;
}
- hi_sdsfree(cmd);
+ sdsfree(cmd);
return REDIS_OK;
}