read: Add support for the RESP3 bignum type

master
Alex Smith 2020-10-16 18:35:58 -04:00 committed by michael-grunder
parent c6646cb192
commit 83c1450425
4 changed files with 36 additions and 2 deletions

View File

@ -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) {

View File

@ -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
View File

@ -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
View File

@ -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) {