diff options
| author | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2010-11-04 10:54:01 +0100 | 
|---|---|---|
| committer | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2010-11-04 13:15:44 +0100 | 
| commit | 2e5e9a49fd1941296a6c94ca117e33bf2934bcfd (patch) | |
| tree | d50d1d155a133a7917225cfc545a1106181b9028 | |
| parent | e5a8228946611fea64707a32ecc218ff5e89b497 (diff) | |
| download | hiredict-2e5e9a49fd1941296a6c94ca117e33bf2934bcfd.tar.xz | |
Return the reply type when the reply object function set is NULL
| -rw-r--r-- | hiredis.c | 45 | ||||
| -rw-r--r-- | hiredis.h | 3 | ||||
| -rw-r--r-- | test.c | 13 | 
3 files changed, 46 insertions, 15 deletions
| @@ -207,10 +207,14 @@ static int processLineItem(redisReader *r) {      int len;      if ((p = readLine(r,&len)) != NULL) { -        if (cur->type == REDIS_REPLY_INTEGER) { -            obj = r->fn->createInteger(cur,strtoll(p,NULL,10)); +        if (r->fn) { +            if (cur->type == REDIS_REPLY_INTEGER) { +                obj = r->fn->createInteger(cur,strtoll(p,NULL,10)); +            } else { +                obj = r->fn->createString(cur,p,len); +            }          } else { -            obj = r->fn->createString(cur,p,len); +            obj = (void*)(size_t)(cur->type);          }          /* If there is no root yet, register this object as root. */ @@ -238,12 +242,14 @@ static int processBulkItem(redisReader *r) {          if (len < 0) {              /* The nil object can always be created. */ -            obj = r->fn->createNil(cur); +            obj = r->fn ? r->fn->createNil(cur) : +                (void*)REDIS_REPLY_NIL;          } else {              /* Only continue when the buffer contains the entire bulk item. */              bytelen += len+2; /* include \r\n */              if (r->pos+bytelen <= sdslen(r->buf)) { -                obj = r->fn->createString(cur,s+2,len); +                obj = r->fn ? r->fn->createString(cur,s+2,len) : +                    (void*)REDIS_REPLY_STRING;              }          } @@ -268,10 +274,12 @@ static int processMultiBulkItem(redisReader *r) {      if ((p = readLine(r,NULL)) != NULL) {          elements = strtol(p,NULL,10);          if (elements == -1) { -            obj = r->fn->createNil(cur); +            obj = r->fn ? r->fn->createNil(cur) : +                (void*)REDIS_REPLY_NIL;              moveToNextTask(r);          } else { -            obj = r->fn->createArray(cur,elements); +            obj = r->fn ? r->fn->createArray(cur,elements) : +                (void*)REDIS_REPLY_ARRAY;              /* Modify task stack when there are more than 0 elements. */              if (elements > 0) { @@ -348,15 +356,26 @@ static int processItem(redisReader *r) {      }  } -void *redisReplyReaderCreate(redisReplyObjectFunctions *fn) { +void *redisReplyReaderCreate() {      redisReader *r = calloc(sizeof(redisReader),1);      r->error = NULL; -    r->fn = fn == NULL ? &defaultFunctions : fn; +    r->fn = &defaultFunctions;      r->buf = sdsempty();      r->ridx = -1;      return r;  } +/* Set the function set to build the reply. Returns REDIS_OK when there + * is no temporary object and it can be set, REDIS_ERR otherwise. */ +int redisReplyReaderSetReplyObjectFunctions(void *reader, redisReplyObjectFunctions *fn) { +    redisReader *r = reader; +    if (r->reply == NULL) { +        r->fn = fn; +        return REDIS_OK; +    } +    return REDIS_ERR; +} +  /* External libraries wrapping hiredis might need access to the temporary   * variable while the reply is built up. When the reader contains an   * object in between receiving some bytes to parse, this object might @@ -370,7 +389,7 @@ void redisReplyReaderFree(void *reader) {      redisReader *r = reader;      if (r->error != NULL)          sdsfree(r->error); -    if (r->reply != NULL) +    if (r->reply != NULL && r->fn)          r->fn->freeObject(r->reply);      if (r->buf != NULL)          sdsfree(r->buf); @@ -695,8 +714,10 @@ int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn)  /* Helper function to lazily create a reply reader. */  static void __redisCreateReplyReader(redisContext *c) { -    if (c->reader == NULL) -        c->reader = redisReplyReaderCreate(c->fn); +    if (c->reader == NULL) { +        c->reader = redisReplyReaderCreate(); +        assert(redisReplyReaderSetReplyObjectFunctions(c->reader,c->fn) == REDIS_OK); +    }  }  /* Use this function to handle a read event on the descriptor. It will try @@ -110,7 +110,8 @@ typedef struct redisContext {  } redisContext;  void freeReplyObject(void *reply); -void *redisReplyReaderCreate(redisReplyObjectFunctions *fn); +void *redisReplyReaderCreate(); +int redisReplyReaderSetReplyObjectFunctions(void *reader, redisReplyObjectFunctions *fn);  void *redisReplyReaderGetObject(void *reader);  char *redisReplyReaderGetError(void *reader);  void redisReplyReaderFree(void *ptr); @@ -186,11 +186,12 @@ static void test_blocking_connection() {  static void test_reply_reader() {      void *reader; +    void *reply;      char *err;      int ret;      test("Error handling in reply parser: "); -    reader = redisReplyReaderCreate(NULL); +    reader = redisReplyReaderCreate();      redisReplyReaderFeed(reader,(char*)"@foo\r\n",6);      ret = redisReplyReaderGetReply(reader,NULL);      err = redisReplyReaderGetError(reader); @@ -201,7 +202,7 @@ static void test_reply_reader() {      /* when the reply already contains multiple items, they must be free'd       * on an error. valgrind will bark when this doesn't happen. */      test("Memory cleanup in reply parser: "); -    reader = redisReplyReaderCreate(NULL); +    reader = redisReplyReaderCreate();      redisReplyReaderFeed(reader,(char*)"*2\r\n",4);      redisReplyReaderFeed(reader,(char*)"$5\r\nhello\r\n",11);      redisReplyReaderFeed(reader,(char*)"@foo\r\n",6); @@ -210,6 +211,14 @@ static void test_reply_reader() {      test_cond(ret == REDIS_ERR &&                strcasecmp(err,"protocol error, got \"@\" as reply type byte") == 0);      redisReplyReaderFree(reader); + +    test("Works with NULL functions for reply: "); +    reader = redisReplyReaderCreate(); +    redisReplyReaderSetReplyObjectFunctions(reader,NULL); +    redisReplyReaderFeed(reader,(char*)"+OK\r\n",5); +    ret = redisReplyReaderGetReply(reader,&reply); +    test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS); +    redisReplyReaderFree(reader);  }  static void test_throughput() { | 
