RESP3: hiredis: save the original double string.

This commit is contained in:
antirez 2018-12-06 11:43:11 +01:00
parent ee4c355a3e
commit 045b1f6339
4 changed files with 20 additions and 5 deletions

View File

@ -47,7 +47,7 @@ static redisReply *createReplyObject(int type);
static void *createStringObject(const redisReadTask *task, char *str, size_t len); static void *createStringObject(const redisReadTask *task, char *str, size_t len);
static void *createArrayObject(const redisReadTask *task, int elements); static void *createArrayObject(const redisReadTask *task, int elements);
static void *createIntegerObject(const redisReadTask *task, long long value); static void *createIntegerObject(const redisReadTask *task, long long value);
static void *createDoubleObject(const redisReadTask *task, double value); static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len);
static void *createNilObject(const redisReadTask *task); static void *createNilObject(const redisReadTask *task);
/* Default set of functions to build the reply. Keep in mind that such a /* Default set of functions to build the reply. Keep in mind that such a
@ -95,6 +95,7 @@ void freeReplyObject(void *reply) {
case REDIS_REPLY_ERROR: case REDIS_REPLY_ERROR:
case REDIS_REPLY_STATUS: case REDIS_REPLY_STATUS:
case REDIS_REPLY_STRING: case REDIS_REPLY_STRING:
case REDIS_REPLY_DOUBLE:
free(r->str); free(r->str);
break; break;
} }
@ -181,7 +182,7 @@ static void *createIntegerObject(const redisReadTask *task, long long value) {
return r; return r;
} }
static void *createDoubleObject(const redisReadTask *task, double value) { static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len) {
redisReply *r, *parent; redisReply *r, *parent;
r = createReplyObject(REDIS_REPLY_DOUBLE); r = createReplyObject(REDIS_REPLY_DOUBLE);
@ -189,6 +190,19 @@ static void *createDoubleObject(const redisReadTask *task, double value) {
return NULL; return NULL;
r->dval = value; r->dval = value;
r->str = malloc(len+1);
if (r->str == NULL) {
freeReplyObject(r);
return NULL;
}
/* The double reply also has the original protocol string representing a
* double as a null terminated string. This way the caller does not need
* to format back for string conversion, especially since Redis does efforts
* to make the string more human readable avoiding the calssical double
* decimal string conversion artifacts. */
memcpy(r->str, str, len);
r->str[len] = '\0';
if (task->parent) { if (task->parent) {
parent = task->parent->obj; parent = task->parent->obj;

View File

@ -90,7 +90,8 @@ typedef struct redisReply {
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
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 both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
and REDIS_REPLY_DOUBLE (in additionl to dval). */
size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
} redisReply; } redisReply;

2
deps/hiredis/read.c vendored
View File

@ -304,7 +304,7 @@ static int processLineItem(redisReader *r) {
return REDIS_ERR; return REDIS_ERR;
} }
} }
obj = r->fn->createDouble(cur,d); obj = r->fn->createDouble(cur,d,buf,len);
} else { } else {
obj = (void*)REDIS_REPLY_DOUBLE; obj = (void*)REDIS_REPLY_DOUBLE;
} }

2
deps/hiredis/read.h vendored
View File

@ -81,7 +81,7 @@ typedef struct redisReplyObjectFunctions {
void *(*createString)(const redisReadTask*, char*, size_t); void *(*createString)(const redisReadTask*, char*, size_t);
void *(*createArray)(const redisReadTask*, int); void *(*createArray)(const redisReadTask*, int);
void *(*createInteger)(const redisReadTask*, long long); void *(*createInteger)(const redisReadTask*, long long);
void *(*createDouble)(const redisReadTask*, double); void *(*createDouble)(const redisReadTask*, double, char*, size_t);
void *(*createNil)(const redisReadTask*); void *(*createNil)(const redisReadTask*);
void (*freeObject)(void*); void (*freeObject)(void*);
} redisReplyObjectFunctions; } redisReplyObjectFunctions;