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); |