Commit 83c14504 authored by Alex Smith's avatar Alex Smith Committed by michael-grunder
Browse files

read: Add support for the RESP3 bignum type

parent c6646cb1
...@@ -114,6 +114,7 @@ void freeReplyObject(void *reply) { ...@@ -114,6 +114,7 @@ void freeReplyObject(void *reply) {
case REDIS_REPLY_STRING: case REDIS_REPLY_STRING:
case REDIS_REPLY_DOUBLE: case REDIS_REPLY_DOUBLE:
case REDIS_REPLY_VERB: case REDIS_REPLY_VERB:
case REDIS_REPLY_BIGNUM:
hi_free(r->str); hi_free(r->str);
break; break;
} }
...@@ -131,7 +132,8 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len ...@@ -131,7 +132,8 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len
assert(task->type == REDIS_REPLY_ERROR || assert(task->type == REDIS_REPLY_ERROR ||
task->type == REDIS_REPLY_STATUS || task->type == REDIS_REPLY_STATUS ||
task->type == REDIS_REPLY_STRING || task->type == REDIS_REPLY_STRING ||
task->type == REDIS_REPLY_VERB); task->type == REDIS_REPLY_VERB ||
task->type == REDIS_REPLY_BIGNUM);
/* Copy string value */ /* Copy string value */
if (task->type == REDIS_REPLY_VERB) { if (task->type == REDIS_REPLY_VERB) {
......
...@@ -112,7 +112,8 @@ typedef struct redisReply { ...@@ -112,7 +112,8 @@ typedef struct redisReply {
double dval; /* The double when type is REDIS_REPLY_DOUBLE */ double dval; /* The double when type is REDIS_REPLY_DOUBLE */
size_t len; /* Length of string */ size_t len; /* Length of string */
char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
REDIS_REPLY_VERB, and REDIS_REPLY_DOUBLE (in additional to dval). */ REDIS_REPLY_VERB, REDIS_REPLY_DOUBLE (in additional to dval),
and REDIS_REPLY_BIGNUM. */
char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null
terminated 3 character content type, such as "txt". */ terminated 3 character content type, such as "txt". */
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
......
...@@ -337,6 +337,22 @@ static int processLineItem(redisReader *r) { ...@@ -337,6 +337,22 @@ static int processLineItem(redisReader *r) {
obj = r->fn->createBool(cur,bval); obj = r->fn->createBool(cur,bval);
else else
obj = (void*)REDIS_REPLY_BOOL; obj = (void*)REDIS_REPLY_BOOL;
} else if (cur->type == REDIS_REPLY_BIGNUM) {
/* Ensure all characters are decimal digits (with possible leading
* minus sign). */
for (int i = 0; i < len; i++) {
/* XXX Consider: Allow leading '+'? Error on leading '0's? */
if (i == 0 && p[0] == '-') continue;
if (p[i] < '0' || p[i] > '9') {
__redisReaderSetError(r,REDIS_ERR_PROTOCOL,
"Bad bignum value");
return REDIS_ERR;
}
}
if (r->fn && r->fn->createString)
obj = r->fn->createString(cur,p,len);
else
obj = (void*)REDIS_REPLY_BIGNUM;
} else { } else {
/* Type will be error or status. */ /* Type will be error or status. */
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
...@@ -587,6 +603,9 @@ static int processItem(redisReader *r) { ...@@ -587,6 +603,9 @@ static int processItem(redisReader *r) {
case '>': case '>':
cur->type = REDIS_REPLY_PUSH; cur->type = REDIS_REPLY_PUSH;
break; break;
case '(':
cur->type = REDIS_REPLY_BIGNUM;
break;
default: default:
__redisReaderSetErrorProtocolByte(r,*p); __redisReaderSetErrorProtocolByte(r,*p);
return REDIS_ERR; return REDIS_ERR;
...@@ -605,6 +624,7 @@ static int processItem(redisReader *r) { ...@@ -605,6 +624,7 @@ static int processItem(redisReader *r) {
case REDIS_REPLY_DOUBLE: case REDIS_REPLY_DOUBLE:
case REDIS_REPLY_NIL: case REDIS_REPLY_NIL:
case REDIS_REPLY_BOOL: case REDIS_REPLY_BOOL:
case REDIS_REPLY_BIGNUM:
return processLineItem(r); return processLineItem(r);
case REDIS_REPLY_STRING: case REDIS_REPLY_STRING:
case REDIS_REPLY_VERB: case REDIS_REPLY_VERB:
......
...@@ -714,6 +714,17 @@ static void test_reply_reader(void) { ...@@ -714,6 +714,17 @@ static void test_reply_reader(void) {
((redisReply*)reply)->element[4]->integer == 999); ((redisReply*)reply)->element[4]->integer == 999);
freeReplyObject(reply); freeReplyObject(reply);
redisReaderFree(reader); redisReaderFree(reader);
test("Can parse RESP3 bignum: ");
reader = redisReaderCreate();
redisReaderFeed(reader,"(3492890328409238509324850943850943825024385\r\n",46);
ret = redisReaderGetReply(reader,&reply);
test_cond(ret == REDIS_OK &&
((redisReply*)reply)->type == REDIS_REPLY_BIGNUM &&
((redisReply*)reply)->len == 43 &&
!strcmp(((redisReply*)reply)->str,"3492890328409238509324850943850943825024385"));
freeReplyObject(reply);
redisReaderFree(reader);
} }
static void test_free_null(void) { static void test_free_null(void) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment