diff --git a/hiredis.c b/hiredis.c index 7fbe016..f1ade93 100644 --- a/hiredis.c +++ b/hiredis.c @@ -52,7 +52,7 @@ typedef struct redisReader { unsigned int rpos; /* list cursor */ } redisReader; -static redisReply *createReplyObject(int type, sds reply); +static redisReply *createReplyObject(int type); static void *createStringObject(redisReadTask *task, char *str, size_t len); static void *createArrayObject(redisReadTask *task, int elements); static void *createIntegerObject(redisReadTask *task, long long value); @@ -75,12 +75,11 @@ static void redisOOM(void) { } /* Create a reply object */ -static redisReply *createReplyObject(int type, sds reply) { +static redisReply *createReplyObject(int type) { redisReply *r = calloc(sizeof(*r),1); if (!r) redisOOM(); r->type = type; - r->reply = reply; return r; } @@ -98,19 +97,27 @@ void freeReplyObject(void *reply) { free(r->element); break; default: - if (r->reply != NULL) - sdsfree(r->reply); + if (r->str != NULL) + free(r->str); break; } free(r); } static void *createStringObject(redisReadTask *task, char *str, size_t len) { - redisReply *r = createReplyObject(task->type,sdsnewlen(str,len)); + redisReply *r = createReplyObject(task->type); + char *value = malloc(len+1); + if (!value) redisOOM(); assert(task->type == REDIS_REPLY_ERROR || task->type == REDIS_REPLY_STATUS || task->type == REDIS_REPLY_STRING); + /* Copy string value */ + memcpy(value,str,len); + value[len] = '\0'; + r->str = value; + r->len = len; + /* for API compat, set STATUS to STRING */ if (task->type == REDIS_REPLY_STATUS) r->type = REDIS_REPLY_STRING; @@ -124,7 +131,7 @@ static void *createStringObject(redisReadTask *task, char *str, size_t len) { } static void *createArrayObject(redisReadTask *task, int elements) { - redisReply *r = createReplyObject(REDIS_REPLY_ARRAY,NULL); + redisReply *r = createReplyObject(REDIS_REPLY_ARRAY); r->elements = elements; if ((r->element = calloc(sizeof(redisReply*),elements)) == NULL) redisOOM(); @@ -137,7 +144,7 @@ static void *createArrayObject(redisReadTask *task, int elements) { } static void *createIntegerObject(redisReadTask *task, long long value) { - redisReply *r = createReplyObject(REDIS_REPLY_INTEGER,NULL); + redisReply *r = createReplyObject(REDIS_REPLY_INTEGER); r->integer = value; if (task->parent) { redisReply *parent = task->parent; @@ -148,7 +155,7 @@ static void *createIntegerObject(redisReadTask *task, long long value) { } static void *createNilObject(redisReadTask *task) { - redisReply *r = createReplyObject(REDIS_REPLY_NIL,NULL); + redisReply *r = createReplyObject(REDIS_REPLY_NIL); if (task->parent) { redisReply *parent = task->parent; assert(parent->type == REDIS_REPLY_ARRAY); diff --git a/hiredis.h b/hiredis.h index 58b9066..39f10c6 100644 --- a/hiredis.h +++ b/hiredis.h @@ -49,13 +49,12 @@ #define REDIS_REPLY_NIL 4 #define REDIS_REPLY_STATUS 5 -#include "sds.h" - /* 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 */ - char *reply; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ + int len; /* Length of string */ + char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ } redisReply; @@ -97,8 +96,8 @@ typedef struct redisCallback { typedef struct redisContext { int fd; int flags; - sds error; /* Error object is set when in erronous state */ - sds obuf; /* Write buffer */ + char *error; /* Error object is set when in erronous state */ + char *obuf; /* Write buffer */ /* Function set for reply buildup and reply reader */ redisReplyObjectFunctions *fn; diff --git a/test.c b/test.c index c91f9d8..5bddf04 100644 --- a/test.c +++ b/test.c @@ -36,7 +36,7 @@ static void test_blocking_connection() { test("Returns I/O error when the connection is lost: "); reply = redisCommand(c,"QUIT"); test_cond(redisCommand(c,"PING") == NULL && - strcasecmp(reply->reply,"OK") == 0 && + strcasecmp(reply->str,"OK") == 0 && strcmp(c->error,"read: Server closed the connection") == 0); freeReplyObject(reply); redisFree(c); @@ -45,7 +45,7 @@ static void test_blocking_connection() { test("Is able to deliver commands: "); reply = redisCommand(c,"PING"); test_cond(reply->type == REDIS_REPLY_STRING && - strcasecmp(reply->reply,"pong") == 0) + strcasecmp(reply->str,"pong") == 0) freeReplyObject(reply); /* Switch to DB 9 for testing, now that we know we can chat. */ @@ -66,7 +66,7 @@ static void test_blocking_connection() { test("Is a able to send commands verbatim: "); reply = redisCommand(c,"SET foo bar"); test_cond (reply->type == REDIS_REPLY_STRING && - strcasecmp(reply->reply,"ok") == 0) + strcasecmp(reply->str,"ok") == 0) freeReplyObject(reply); test("%%s String interpolation works: "); @@ -74,7 +74,7 @@ static void test_blocking_connection() { freeReplyObject(reply); reply = redisCommand(c,"GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && - strcmp(reply->reply,"hello world") == 0); + strcmp(reply->str,"hello world") == 0); freeReplyObject(reply); test("%%b String interpolation works: "); @@ -82,10 +82,10 @@ static void test_blocking_connection() { freeReplyObject(reply); reply = redisCommand(c,"GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && - memcmp(reply->reply,"hello\x00world",11) == 0) + memcmp(reply->str,"hello\x00world",11) == 0) test("Binary reply length is correct: "); - test_cond(sdslen(reply->reply) == 11) + test_cond(reply->len == 11) freeReplyObject(reply); test("Can parse nil replies: "); @@ -105,8 +105,8 @@ static void test_blocking_connection() { reply = redisCommand(c,"LRANGE mylist 0 -1"); test_cond(reply->type == REDIS_REPLY_ARRAY && reply->elements == 2 && - !memcmp(reply->element[0]->reply,"bar",3) && - !memcmp(reply->element[1]->reply,"foo",3)) + !memcmp(reply->element[0]->str,"bar",3) && + !memcmp(reply->element[1]->str,"foo",3)) freeReplyObject(reply); /* m/e with multi bulk reply *before* other reply. @@ -120,10 +120,10 @@ static void test_blocking_connection() { reply->elements == 2 && reply->element[0]->type == REDIS_REPLY_ARRAY && reply->element[0]->elements == 2 && - !memcmp(reply->element[0]->element[0]->reply,"bar",3) && - !memcmp(reply->element[0]->element[1]->reply,"foo",3) && + !memcmp(reply->element[0]->element[0]->str,"bar",3) && + !memcmp(reply->element[0]->element[1]->str,"foo",3) && reply->element[1]->type == REDIS_REPLY_STRING && - strcasecmp(reply->element[1]->reply,"pong") == 0); + strcasecmp(reply->element[1]->str,"pong") == 0); freeReplyObject(reply); }