Drop dependency on sds.h for exposed API

This commit is contained in:
Pieter Noordhuis 2010-10-30 17:47:19 +02:00
parent 1e7f5ae6bd
commit 171b5a24d4
3 changed files with 31 additions and 25 deletions

View File

@ -52,7 +52,7 @@ typedef struct redisReader {
unsigned int rpos; /* list cursor */ unsigned int rpos; /* list cursor */
} redisReader; } redisReader;
static redisReply *createReplyObject(int type, sds reply); static redisReply *createReplyObject(int type);
static void *createStringObject(redisReadTask *task, char *str, size_t len); static void *createStringObject(redisReadTask *task, char *str, size_t len);
static void *createArrayObject(redisReadTask *task, int elements); static void *createArrayObject(redisReadTask *task, int elements);
static void *createIntegerObject(redisReadTask *task, long long value); static void *createIntegerObject(redisReadTask *task, long long value);
@ -75,12 +75,11 @@ static void redisOOM(void) {
} }
/* Create a reply object */ /* Create a reply object */
static redisReply *createReplyObject(int type, sds reply) { static redisReply *createReplyObject(int type) {
redisReply *r = calloc(sizeof(*r),1); redisReply *r = calloc(sizeof(*r),1);
if (!r) redisOOM(); if (!r) redisOOM();
r->type = type; r->type = type;
r->reply = reply;
return r; return r;
} }
@ -98,19 +97,27 @@ void freeReplyObject(void *reply) {
free(r->element); free(r->element);
break; break;
default: default:
if (r->reply != NULL) if (r->str != NULL)
sdsfree(r->reply); free(r->str);
break; break;
} }
free(r); free(r);
} }
static void *createStringObject(redisReadTask *task, char *str, size_t len) { static void *createStringObject(redisReadTask *task, char *str, size_t len) {
redisReply *r = createReplyObject(task->type,sdsnewlen(str,len)); redisReply *r = createReplyObject(task->type);
char *value = malloc(len+1);
if (!value) redisOOM();
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);
/* Copy string value */
memcpy(value,str,len);
value[len] = '\0';
r->str = value;
r->len = len;
/* for API compat, set STATUS to STRING */ /* for API compat, set STATUS to STRING */
if (task->type == REDIS_REPLY_STATUS) if (task->type == REDIS_REPLY_STATUS)
r->type = REDIS_REPLY_STRING; r->type = REDIS_REPLY_STRING;
@ -124,7 +131,7 @@ static void *createStringObject(redisReadTask *task, char *str, size_t len) {
} }
static void *createArrayObject(redisReadTask *task, int elements) { static void *createArrayObject(redisReadTask *task, int elements) {
redisReply *r = createReplyObject(REDIS_REPLY_ARRAY,NULL); redisReply *r = createReplyObject(REDIS_REPLY_ARRAY);
r->elements = elements; r->elements = elements;
if ((r->element = calloc(sizeof(redisReply*),elements)) == NULL) if ((r->element = calloc(sizeof(redisReply*),elements)) == NULL)
redisOOM(); redisOOM();
@ -137,7 +144,7 @@ static void *createArrayObject(redisReadTask *task, int elements) {
} }
static void *createIntegerObject(redisReadTask *task, long long value) { static void *createIntegerObject(redisReadTask *task, long long value) {
redisReply *r = createReplyObject(REDIS_REPLY_INTEGER,NULL); redisReply *r = createReplyObject(REDIS_REPLY_INTEGER);
r->integer = value; r->integer = value;
if (task->parent) { if (task->parent) {
redisReply *parent = task->parent; redisReply *parent = task->parent;
@ -148,7 +155,7 @@ static void *createIntegerObject(redisReadTask *task, long long value) {
} }
static void *createNilObject(redisReadTask *task) { static void *createNilObject(redisReadTask *task) {
redisReply *r = createReplyObject(REDIS_REPLY_NIL,NULL); redisReply *r = createReplyObject(REDIS_REPLY_NIL);
if (task->parent) { if (task->parent) {
redisReply *parent = task->parent; redisReply *parent = task->parent;
assert(parent->type == REDIS_REPLY_ARRAY); assert(parent->type == REDIS_REPLY_ARRAY);

View File

@ -49,13 +49,12 @@
#define REDIS_REPLY_NIL 4 #define REDIS_REPLY_NIL 4
#define REDIS_REPLY_STATUS 5 #define REDIS_REPLY_STATUS 5
#include "sds.h"
/* This is the reply object returned by redisCommand() */ /* This is the reply object returned by redisCommand() */
typedef struct redisReply { typedef struct redisReply {
int type; /* REDIS_REPLY_* */ int type; /* REDIS_REPLY_* */
long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
char *reply; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ int len; /* Length of string */
char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
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;
@ -97,8 +96,8 @@ typedef struct redisCallback {
typedef struct redisContext { typedef struct redisContext {
int fd; int fd;
int flags; int flags;
sds error; /* Error object is set when in erronous state */ char *error; /* Error object is set when in erronous state */
sds obuf; /* Write buffer */ char *obuf; /* Write buffer */
/* Function set for reply buildup and reply reader */ /* Function set for reply buildup and reply reader */
redisReplyObjectFunctions *fn; redisReplyObjectFunctions *fn;

22
test.c
View File

@ -36,7 +36,7 @@ static void test_blocking_connection() {
test("Returns I/O error when the connection is lost: "); test("Returns I/O error when the connection is lost: ");
reply = redisCommand(c,"QUIT"); reply = redisCommand(c,"QUIT");
test_cond(redisCommand(c,"PING") == NULL && test_cond(redisCommand(c,"PING") == NULL &&
strcasecmp(reply->reply,"OK") == 0 && strcasecmp(reply->str,"OK") == 0 &&
strcmp(c->error,"read: Server closed the connection") == 0); strcmp(c->error,"read: Server closed the connection") == 0);
freeReplyObject(reply); freeReplyObject(reply);
redisFree(c); redisFree(c);
@ -45,7 +45,7 @@ static void test_blocking_connection() {
test("Is able to deliver commands: "); test("Is able to deliver commands: ");
reply = redisCommand(c,"PING"); reply = redisCommand(c,"PING");
test_cond(reply->type == REDIS_REPLY_STRING && test_cond(reply->type == REDIS_REPLY_STRING &&
strcasecmp(reply->reply,"pong") == 0) strcasecmp(reply->str,"pong") == 0)
freeReplyObject(reply); freeReplyObject(reply);
/* Switch to DB 9 for testing, now that we know we can chat. */ /* Switch to DB 9 for testing, now that we know we can chat. */
@ -66,7 +66,7 @@ static void test_blocking_connection() {
test("Is a able to send commands verbatim: "); test("Is a able to send commands verbatim: ");
reply = redisCommand(c,"SET foo bar"); reply = redisCommand(c,"SET foo bar");
test_cond (reply->type == REDIS_REPLY_STRING && test_cond (reply->type == REDIS_REPLY_STRING &&
strcasecmp(reply->reply,"ok") == 0) strcasecmp(reply->str,"ok") == 0)
freeReplyObject(reply); freeReplyObject(reply);
test("%%s String interpolation works: "); test("%%s String interpolation works: ");
@ -74,7 +74,7 @@ static void test_blocking_connection() {
freeReplyObject(reply); freeReplyObject(reply);
reply = redisCommand(c,"GET foo"); reply = redisCommand(c,"GET foo");
test_cond(reply->type == REDIS_REPLY_STRING && test_cond(reply->type == REDIS_REPLY_STRING &&
strcmp(reply->reply,"hello world") == 0); strcmp(reply->str,"hello world") == 0);
freeReplyObject(reply); freeReplyObject(reply);
test("%%b String interpolation works: "); test("%%b String interpolation works: ");
@ -82,10 +82,10 @@ static void test_blocking_connection() {
freeReplyObject(reply); freeReplyObject(reply);
reply = redisCommand(c,"GET foo"); reply = redisCommand(c,"GET foo");
test_cond(reply->type == REDIS_REPLY_STRING && test_cond(reply->type == REDIS_REPLY_STRING &&
memcmp(reply->reply,"hello\x00world",11) == 0) memcmp(reply->str,"hello\x00world",11) == 0)
test("Binary reply length is correct: "); test("Binary reply length is correct: ");
test_cond(sdslen(reply->reply) == 11) test_cond(reply->len == 11)
freeReplyObject(reply); freeReplyObject(reply);
test("Can parse nil replies: "); test("Can parse nil replies: ");
@ -105,8 +105,8 @@ static void test_blocking_connection() {
reply = redisCommand(c,"LRANGE mylist 0 -1"); reply = redisCommand(c,"LRANGE mylist 0 -1");
test_cond(reply->type == REDIS_REPLY_ARRAY && test_cond(reply->type == REDIS_REPLY_ARRAY &&
reply->elements == 2 && reply->elements == 2 &&
!memcmp(reply->element[0]->reply,"bar",3) && !memcmp(reply->element[0]->str,"bar",3) &&
!memcmp(reply->element[1]->reply,"foo",3)) !memcmp(reply->element[1]->str,"foo",3))
freeReplyObject(reply); freeReplyObject(reply);
/* m/e with multi bulk reply *before* other reply. /* m/e with multi bulk reply *before* other reply.
@ -120,10 +120,10 @@ static void test_blocking_connection() {
reply->elements == 2 && reply->elements == 2 &&
reply->element[0]->type == REDIS_REPLY_ARRAY && reply->element[0]->type == REDIS_REPLY_ARRAY &&
reply->element[0]->elements == 2 && reply->element[0]->elements == 2 &&
!memcmp(reply->element[0]->element[0]->reply,"bar",3) && !memcmp(reply->element[0]->element[0]->str,"bar",3) &&
!memcmp(reply->element[0]->element[1]->reply,"foo",3) && !memcmp(reply->element[0]->element[1]->str,"foo",3) &&
reply->element[1]->type == REDIS_REPLY_STRING && reply->element[1]->type == REDIS_REPLY_STRING &&
strcasecmp(reply->element[1]->reply,"pong") == 0); strcasecmp(reply->element[1]->str,"pong") == 0);
freeReplyObject(reply); freeReplyObject(reply);
} }