summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hiredis.c8
-rw-r--r--read.c7
-rw-r--r--test.c20
3 files changed, 34 insertions, 1 deletions
diff --git a/hiredis.c b/hiredis.c
index 446ceb1..78b2837 100644
--- a/hiredis.c
+++ b/hiredis.c
@@ -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;
diff --git a/read.c b/read.c
index 9c8f869..fa40e61 100644
--- a/read.c
+++ b/read.c
@@ -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);
diff --git a/test.c b/test.c
index 897daf8..d9696f1 100644
--- a/test.c
+++ b/test.c
@@ -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);