diff options
| -rw-r--r-- | hiredis.c | 8 | ||||
| -rw-r--r-- | read.c | 7 | ||||
| -rw-r--r-- | test.c | 20 | 
3 files changed, 34 insertions, 1 deletions
| @@ -102,6 +102,7 @@ void freeReplyObject(void *reply) {          break; /* Nothing to free */      case REDIS_REPLY_ARRAY:      case REDIS_REPLY_MAP: +    case REDIS_REPLY_ATTR:      case REDIS_REPLY_SET:      case REDIS_REPLY_PUSH:          if (r->element != NULL) { @@ -160,6 +161,7 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len          parent = task->parent->obj;          assert(parent->type == REDIS_REPLY_ARRAY ||                 parent->type == REDIS_REPLY_MAP || +               parent->type == REDIS_REPLY_ATTR ||                 parent->type == REDIS_REPLY_SET ||                 parent->type == REDIS_REPLY_PUSH);          parent->element[task->idx] = r; @@ -192,6 +194,7 @@ static void *createArrayObject(const redisReadTask *task, size_t elements) {          parent = task->parent->obj;          assert(parent->type == REDIS_REPLY_ARRAY ||                 parent->type == REDIS_REPLY_MAP || +               parent->type == REDIS_REPLY_ATTR ||                 parent->type == REDIS_REPLY_SET ||                 parent->type == REDIS_REPLY_PUSH);          parent->element[task->idx] = r; @@ -212,6 +215,8 @@ static void *createIntegerObject(const redisReadTask *task, long long value) {          parent = task->parent->obj;          assert(parent->type == REDIS_REPLY_ARRAY ||                 parent->type == REDIS_REPLY_MAP || +               parent->type == REDIS_REPLY_ATTR || +               parent->type == REDIS_REPLY_SET ||                 parent->type == REDIS_REPLY_SET ||                 parent->type == REDIS_REPLY_PUSH);          parent->element[task->idx] = r; @@ -249,6 +254,7 @@ static void *createDoubleObject(const redisReadTask *task, double value, char *s          parent = task->parent->obj;          assert(parent->type == REDIS_REPLY_ARRAY ||                 parent->type == REDIS_REPLY_MAP || +               parent->type == REDIS_REPLY_ATTR ||                 parent->type == REDIS_REPLY_SET ||                 parent->type == REDIS_REPLY_PUSH);          parent->element[task->idx] = r; @@ -267,6 +273,7 @@ static void *createNilObject(const redisReadTask *task) {          parent = task->parent->obj;          assert(parent->type == REDIS_REPLY_ARRAY ||                 parent->type == REDIS_REPLY_MAP || +               parent->type == REDIS_REPLY_ATTR ||                 parent->type == REDIS_REPLY_SET ||                 parent->type == REDIS_REPLY_PUSH);          parent->element[task->idx] = r; @@ -287,6 +294,7 @@ 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_ATTR ||                 parent->type == REDIS_REPLY_SET ||                 parent->type == REDIS_REPLY_PUSH);          parent->element[task->idx] = r; @@ -250,6 +250,7 @@ static void moveToNextTask(redisReader *r) {          prv = r->task[r->ridx-1];          assert(prv->type == REDIS_REPLY_ARRAY ||                 prv->type == REDIS_REPLY_MAP || +               prv->type == REDIS_REPLY_ATTR ||                 prv->type == REDIS_REPLY_SET ||                 prv->type == REDIS_REPLY_PUSH);          if (cur->idx == prv->elements-1) { @@ -534,7 +535,7 @@ static int processAggregateItem(redisReader *r) {              moveToNextTask(r);          } else { -            if (cur->type == REDIS_REPLY_MAP) elements *= 2; +            if (cur->type == REDIS_REPLY_MAP || cur->type == REDIS_REPLY_ATTR) elements *= 2;              if (r->fn && r->fn->createArray)                  obj = r->fn->createArray(cur,elements); @@ -602,6 +603,9 @@ static int processItem(redisReader *r) {              case '%':                  cur->type = REDIS_REPLY_MAP;                  break; +            case '|': +                cur->type = REDIS_REPLY_ATTR; +                break;              case '~':                  cur->type = REDIS_REPLY_SET;                  break; @@ -642,6 +646,7 @@ static int processItem(redisReader *r) {          return processBulkItem(r);      case REDIS_REPLY_ARRAY:      case REDIS_REPLY_MAP: +	case REDIS_REPLY_ATTR:      case REDIS_REPLY_SET:      case REDIS_REPLY_PUSH:          return processAggregateItem(r); @@ -795,6 +795,26 @@ static void test_reply_reader(void) {      freeReplyObject(reply);      redisReaderFree(reader); +    test("Can parse RESP3 attribute: "); +    reader = redisReaderCreate(); +    redisReaderFeed(reader, "|2\r\n+foo\r\n:123\r\n+bar\r\n#t\r\n",26); +    ret = redisReaderGetReply(reader,&reply); +    test_cond(ret == REDIS_OK && +        ((redisReply*)reply)->type == REDIS_REPLY_ATTR && +        ((redisReply*)reply)->elements == 4 && +        ((redisReply*)reply)->element[0]->type == REDIS_REPLY_STATUS && +        ((redisReply*)reply)->element[0]->len == 3 && +        !strcmp(((redisReply*)reply)->element[0]->str,"foo") && +        ((redisReply*)reply)->element[1]->type == REDIS_REPLY_INTEGER && +        ((redisReply*)reply)->element[1]->integer == 123 && +        ((redisReply*)reply)->element[2]->type == REDIS_REPLY_STATUS && +        ((redisReply*)reply)->element[2]->len == 3 && +        !strcmp(((redisReply*)reply)->element[2]->str,"bar") && +        ((redisReply*)reply)->element[3]->type == REDIS_REPLY_BOOL && +        ((redisReply*)reply)->element[3]->integer); +    freeReplyObject(reply); +    redisReaderFree(reader); +      test("Can parse RESP3 set: ");      reader = redisReaderCreate();      redisReaderFeed(reader, "~5\r\n+orange\r\n$5\r\napple\r\n#f\r\n:100\r\n:999\r\n",40); | 
