read: Add support for the RESP3 bignum type
parent
c6646cb192
commit
83c1450425
|
@ -114,6 +114,7 @@ void freeReplyObject(void *reply) {
|
|||
case REDIS_REPLY_STRING:
|
||||
case REDIS_REPLY_DOUBLE:
|
||||
case REDIS_REPLY_VERB:
|
||||
case REDIS_REPLY_BIGNUM:
|
||||
hi_free(r->str);
|
||||
break;
|
||||
}
|
||||
|
@ -131,7 +132,8 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len
|
|||
assert(task->type == REDIS_REPLY_ERROR ||
|
||||
task->type == REDIS_REPLY_STATUS ||
|
||||
task->type == REDIS_REPLY_STRING ||
|
||||
task->type == REDIS_REPLY_VERB);
|
||||
task->type == REDIS_REPLY_VERB ||
|
||||
task->type == REDIS_REPLY_BIGNUM);
|
||||
|
||||
/* Copy string value */
|
||||
if (task->type == REDIS_REPLY_VERB) {
|
||||
|
|
|
@ -112,7 +112,8 @@ typedef struct redisReply {
|
|||
double dval; /* The double when type is REDIS_REPLY_DOUBLE */
|
||||
size_t len; /* Length of 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
|
||||
terminated 3 character content type, such as "txt". */
|
||||
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
|
||||
|
|
20
read.c
20
read.c
|
@ -337,6 +337,22 @@ static int processLineItem(redisReader *r) {
|
|||
obj = r->fn->createBool(cur,bval);
|
||||
else
|
||||
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 {
|
||||
/* Type will be error or status. */
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
@ -587,6 +603,9 @@ static int processItem(redisReader *r) {
|
|||
case '>':
|
||||
cur->type = REDIS_REPLY_PUSH;
|
||||
break;
|
||||
case '(':
|
||||
cur->type = REDIS_REPLY_BIGNUM;
|
||||
break;
|
||||
default:
|
||||
__redisReaderSetErrorProtocolByte(r,*p);
|
||||
return REDIS_ERR;
|
||||
|
@ -605,6 +624,7 @@ static int processItem(redisReader *r) {
|
|||
case REDIS_REPLY_DOUBLE:
|
||||
case REDIS_REPLY_NIL:
|
||||
case REDIS_REPLY_BOOL:
|
||||
case REDIS_REPLY_BIGNUM:
|
||||
return processLineItem(r);
|
||||
case REDIS_REPLY_STRING:
|
||||
case REDIS_REPLY_VERB:
|
||||
|
|
11
test.c
11
test.c
|
@ -714,6 +714,17 @@ static void test_reply_reader(void) {
|
|||
((redisReply*)reply)->element[4]->integer == 999);
|
||||
freeReplyObject(reply);
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue