Create protocol reader when creating context
parent
58caf62a52
commit
6d207ea98e
9
async.c
9
async.c
|
@ -136,11 +136,6 @@ redisAsyncContext *redisAsyncConnectUnix(const char *path) {
|
|||
return ac;
|
||||
}
|
||||
|
||||
int redisAsyncSetReplyObjectFunctions(redisAsyncContext *ac, redisReplyObjectFunctions *fn) {
|
||||
redisContext *c = &(ac->c);
|
||||
return redisSetReplyObjectFunctions(c,fn);
|
||||
}
|
||||
|
||||
int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) {
|
||||
if (ac->onConnect == NULL) {
|
||||
ac->onConnect = fn;
|
||||
|
@ -375,7 +370,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
|
|||
|
||||
if (cb.fn != NULL) {
|
||||
__redisRunCallback(ac,&cb,reply);
|
||||
c->fn->freeObject(reply);
|
||||
c->reader->fn->freeObject(reply);
|
||||
|
||||
/* Proceed with free'ing when redisAsyncFree() was called. */
|
||||
if (c->flags & REDIS_FREEING) {
|
||||
|
@ -387,7 +382,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
|
|||
* or there were no callbacks to begin with. Either way, don't
|
||||
* abort with an error, but simply ignore it because the client
|
||||
* doesn't know what the server will spit out over the wire. */
|
||||
c->fn->freeObject(reply);
|
||||
c->reader->fn->freeObject(reply);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
async.h
1
async.h
|
@ -103,7 +103,6 @@ typedef struct redisAsyncContext {
|
|||
/* Functions that proxy to hiredis */
|
||||
redisAsyncContext *redisAsyncConnect(const char *ip, int port);
|
||||
redisAsyncContext *redisAsyncConnectUnix(const char *path);
|
||||
int redisAsyncSetReplyObjectFunctions(redisAsyncContext *ac, redisReplyObjectFunctions *fn);
|
||||
int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
|
||||
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
|
||||
void redisAsyncDisconnect(redisAsyncContext *ac);
|
||||
|
|
30
hiredis.c
30
hiredis.c
|
@ -840,12 +840,16 @@ void __redisSetError(redisContext *c, int type, const sds errstr) {
|
|||
}
|
||||
|
||||
static redisContext *redisContextInit(void) {
|
||||
redisContext *c = calloc(sizeof(redisContext),1);
|
||||
redisContext *c;
|
||||
|
||||
c = calloc(1,sizeof(redisContext));
|
||||
if (c == NULL)
|
||||
return NULL;
|
||||
|
||||
c->err = 0;
|
||||
c->errstr = NULL;
|
||||
c->obuf = sdsempty();
|
||||
c->fn = &defaultFunctions;
|
||||
c->reader = NULL;
|
||||
c->reader = redisReplyReaderCreate();
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -913,24 +917,6 @@ int redisSetTimeout(redisContext *c, struct timeval tv) {
|
|||
return REDIS_ERR;
|
||||
}
|
||||
|
||||
/* Set the replyObjectFunctions to use. Returns REDIS_ERR when the reader
|
||||
* was already initialized and the function set could not be re-set.
|
||||
* Return REDIS_OK when they could be set. */
|
||||
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn) {
|
||||
if (c->reader != NULL)
|
||||
return REDIS_ERR;
|
||||
c->fn = fn;
|
||||
return REDIS_OK;
|
||||
}
|
||||
|
||||
/* Helper function to lazily create a reply reader. */
|
||||
static void __redisCreateReplyReader(redisContext *c) {
|
||||
if (c->reader == NULL) {
|
||||
c->reader = redisReplyReaderCreate();
|
||||
assert(redisReplyReaderSetReplyObjectFunctions(c->reader,c->fn) == REDIS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use this function to handle a read event on the descriptor. It will try
|
||||
* and read some bytes from the socket and feed them to the reply parser.
|
||||
*
|
||||
|
@ -951,7 +937,6 @@ int redisBufferRead(redisContext *c) {
|
|||
sdsnew("Server closed the connection"));
|
||||
return REDIS_ERR;
|
||||
} else {
|
||||
__redisCreateReplyReader(c);
|
||||
redisReplyReaderFeed(c->reader,buf,nread);
|
||||
}
|
||||
return REDIS_OK;
|
||||
|
@ -993,7 +978,6 @@ int redisBufferWrite(redisContext *c, int *done) {
|
|||
/* Internal helper function to try and get a reply from the reader,
|
||||
* or set an error in the context otherwise. */
|
||||
int redisGetReplyFromReader(redisContext *c, void **reply) {
|
||||
__redisCreateReplyReader(c);
|
||||
if (redisReplyReaderGetReply(c->reader,reply) == REDIS_ERR) {
|
||||
__redisSetError(c,REDIS_ERR_PROTOCOL,
|
||||
sdsnew(((redisReader*)c->reader)->errstr));
|
||||
|
|
10
hiredis.h
10
hiredis.h
|
@ -152,15 +152,12 @@ int redisFormatCommandArgv(char **target, int argc, const char **argv, const siz
|
|||
|
||||
/* Context for a connection to Redis */
|
||||
typedef struct redisContext {
|
||||
int err; /* Error flags, 0 when there is no error */
|
||||
char *errstr; /* String representation of error when applicable */
|
||||
int fd;
|
||||
int flags;
|
||||
char *obuf; /* Write buffer */
|
||||
int err; /* Error flags, 0 when there is no error */
|
||||
char *errstr; /* String representation of error when applicable */
|
||||
|
||||
/* Function set for reply buildup and reply reader */
|
||||
redisReplyObjectFunctions *fn;
|
||||
void *reader;
|
||||
redisReader *reader; /* Protocol reader */
|
||||
} redisContext;
|
||||
|
||||
redisContext *redisConnect(const char *ip, int port);
|
||||
|
@ -170,7 +167,6 @@ redisContext *redisConnectUnix(const char *path);
|
|||
redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv);
|
||||
redisContext *redisConnectUnixNonBlock(const char *path);
|
||||
int redisSetTimeout(redisContext *c, struct timeval tv);
|
||||
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn);
|
||||
void redisFree(redisContext *c);
|
||||
int redisBufferRead(redisContext *c);
|
||||
int redisBufferWrite(redisContext *c, int *done);
|
||||
|
|
8
test.c
8
test.c
|
@ -268,7 +268,7 @@ static void test_blocking_connection(void) {
|
|||
}
|
||||
|
||||
static void test_reply_reader(void) {
|
||||
void *reader;
|
||||
redisReader *reader;
|
||||
void *reply;
|
||||
char *err;
|
||||
int ret;
|
||||
|
@ -308,7 +308,7 @@ static void test_reply_reader(void) {
|
|||
|
||||
test("Works with NULL functions for reply: ");
|
||||
reader = redisReplyReaderCreate();
|
||||
redisReplyReaderSetReplyObjectFunctions(reader,NULL);
|
||||
reader->fn = NULL;
|
||||
redisReplyReaderFeed(reader,(char*)"+OK\r\n",5);
|
||||
ret = redisReplyReaderGetReply(reader,&reply);
|
||||
test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
|
||||
|
@ -316,7 +316,7 @@ static void test_reply_reader(void) {
|
|||
|
||||
test("Works when a single newline (\\r\\n) covers two calls to feed: ");
|
||||
reader = redisReplyReaderCreate();
|
||||
redisReplyReaderSetReplyObjectFunctions(reader,NULL);
|
||||
reader->fn = NULL;
|
||||
redisReplyReaderFeed(reader,(char*)"+OK\r",4);
|
||||
ret = redisReplyReaderGetReply(reader,&reply);
|
||||
assert(ret == REDIS_OK && reply == NULL);
|
||||
|
@ -327,7 +327,7 @@ static void test_reply_reader(void) {
|
|||
|
||||
test("Don't reset state after protocol error: ");
|
||||
reader = redisReplyReaderCreate();
|
||||
redisReplyReaderSetReplyObjectFunctions(reader,NULL);
|
||||
reader->fn = NULL;
|
||||
redisReplyReaderFeed(reader,(char*)"x",1);
|
||||
ret = redisReplyReaderGetReply(reader,&reply);
|
||||
assert(ret == REDIS_ERR);
|
||||
|
|
Loading…
Reference in New Issue