Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
2e5e9a49
Commit
2e5e9a49
authored
Nov 04, 2010
by
Pieter Noordhuis
Browse files
Return the reply type when the reply object function set is NULL
parent
e5a82289
Changes
3
Hide whitespace changes
Inline
Side-by-side
hiredis.c
View file @
2e5e9a49
...
@@ -207,10 +207,14 @@ static int processLineItem(redisReader *r) {
...
@@ -207,10 +207,14 @@ static int processLineItem(redisReader *r) {
int
len
;
int
len
;
if
((
p
=
readLine
(
r
,
&
len
))
!=
NULL
)
{
if
((
p
=
readLine
(
r
,
&
len
))
!=
NULL
)
{
if
(
cur
->
type
==
REDIS_REPLY_INTEGER
)
{
if
(
r
->
fn
)
{
obj
=
r
->
fn
->
createInteger
(
cur
,
strtoll
(
p
,
NULL
,
10
));
if
(
cur
->
type
==
REDIS_REPLY_INTEGER
)
{
obj
=
r
->
fn
->
createInteger
(
cur
,
strtoll
(
p
,
NULL
,
10
));
}
else
{
obj
=
r
->
fn
->
createString
(
cur
,
p
,
len
);
}
}
else
{
}
else
{
obj
=
r
->
fn
->
createString
(
cur
,
p
,
len
);
obj
=
(
void
*
)(
size_t
)(
cur
->
type
);
}
}
/* If there is no root yet, register this object as root. */
/* If there is no root yet, register this object as root. */
...
@@ -238,12 +242,14 @@ static int processBulkItem(redisReader *r) {
...
@@ -238,12 +242,14 @@ static int processBulkItem(redisReader *r) {
if
(
len
<
0
)
{
if
(
len
<
0
)
{
/* The nil object can always be created. */
/* The nil object can always be created. */
obj
=
r
->
fn
->
createNil
(
cur
);
obj
=
r
->
fn
?
r
->
fn
->
createNil
(
cur
)
:
(
void
*
)
REDIS_REPLY_NIL
;
}
else
{
}
else
{
/* Only continue when the buffer contains the entire bulk item. */
/* Only continue when the buffer contains the entire bulk item. */
bytelen
+=
len
+
2
;
/* include \r\n */
bytelen
+=
len
+
2
;
/* include \r\n */
if
(
r
->
pos
+
bytelen
<=
sdslen
(
r
->
buf
))
{
if
(
r
->
pos
+
bytelen
<=
sdslen
(
r
->
buf
))
{
obj
=
r
->
fn
->
createString
(
cur
,
s
+
2
,
len
);
obj
=
r
->
fn
?
r
->
fn
->
createString
(
cur
,
s
+
2
,
len
)
:
(
void
*
)
REDIS_REPLY_STRING
;
}
}
}
}
...
@@ -268,10 +274,12 @@ static int processMultiBulkItem(redisReader *r) {
...
@@ -268,10 +274,12 @@ static int processMultiBulkItem(redisReader *r) {
if
((
p
=
readLine
(
r
,
NULL
))
!=
NULL
)
{
if
((
p
=
readLine
(
r
,
NULL
))
!=
NULL
)
{
elements
=
strtol
(
p
,
NULL
,
10
);
elements
=
strtol
(
p
,
NULL
,
10
);
if
(
elements
==
-
1
)
{
if
(
elements
==
-
1
)
{
obj
=
r
->
fn
->
createNil
(
cur
);
obj
=
r
->
fn
?
r
->
fn
->
createNil
(
cur
)
:
(
void
*
)
REDIS_REPLY_NIL
;
moveToNextTask
(
r
);
moveToNextTask
(
r
);
}
else
{
}
else
{
obj
=
r
->
fn
->
createArray
(
cur
,
elements
);
obj
=
r
->
fn
?
r
->
fn
->
createArray
(
cur
,
elements
)
:
(
void
*
)
REDIS_REPLY_ARRAY
;
/* Modify task stack when there are more than 0 elements. */
/* Modify task stack when there are more than 0 elements. */
if
(
elements
>
0
)
{
if
(
elements
>
0
)
{
...
@@ -348,15 +356,26 @@ static int processItem(redisReader *r) {
...
@@ -348,15 +356,26 @@ static int processItem(redisReader *r) {
}
}
}
}
void
*
redisReplyReaderCreate
(
redisReplyObjectFunctions
*
fn
)
{
void
*
redisReplyReaderCreate
()
{
redisReader
*
r
=
calloc
(
sizeof
(
redisReader
),
1
);
redisReader
*
r
=
calloc
(
sizeof
(
redisReader
),
1
);
r
->
error
=
NULL
;
r
->
error
=
NULL
;
r
->
fn
=
fn
==
NULL
?
&
defaultFunctions
:
fn
;
r
->
fn
=
&
defaultFunctions
;
r
->
buf
=
sdsempty
();
r
->
buf
=
sdsempty
();
r
->
ridx
=
-
1
;
r
->
ridx
=
-
1
;
return
r
;
return
r
;
}
}
/* Set the function set to build the reply. Returns REDIS_OK when there
* is no temporary object and it can be set, REDIS_ERR otherwise. */
int
redisReplyReaderSetReplyObjectFunctions
(
void
*
reader
,
redisReplyObjectFunctions
*
fn
)
{
redisReader
*
r
=
reader
;
if
(
r
->
reply
==
NULL
)
{
r
->
fn
=
fn
;
return
REDIS_OK
;
}
return
REDIS_ERR
;
}
/* External libraries wrapping hiredis might need access to the temporary
/* External libraries wrapping hiredis might need access to the temporary
* variable while the reply is built up. When the reader contains an
* variable while the reply is built up. When the reader contains an
* object in between receiving some bytes to parse, this object might
* object in between receiving some bytes to parse, this object might
...
@@ -370,7 +389,7 @@ void redisReplyReaderFree(void *reader) {
...
@@ -370,7 +389,7 @@ void redisReplyReaderFree(void *reader) {
redisReader
*
r
=
reader
;
redisReader
*
r
=
reader
;
if
(
r
->
error
!=
NULL
)
if
(
r
->
error
!=
NULL
)
sdsfree
(
r
->
error
);
sdsfree
(
r
->
error
);
if
(
r
->
reply
!=
NULL
)
if
(
r
->
reply
!=
NULL
&&
r
->
fn
)
r
->
fn
->
freeObject
(
r
->
reply
);
r
->
fn
->
freeObject
(
r
->
reply
);
if
(
r
->
buf
!=
NULL
)
if
(
r
->
buf
!=
NULL
)
sdsfree
(
r
->
buf
);
sdsfree
(
r
->
buf
);
...
@@ -695,8 +714,10 @@ int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn)
...
@@ -695,8 +714,10 @@ int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn)
/* Helper function to lazily create a reply reader. */
/* Helper function to lazily create a reply reader. */
static
void
__redisCreateReplyReader
(
redisContext
*
c
)
{
static
void
__redisCreateReplyReader
(
redisContext
*
c
)
{
if
(
c
->
reader
==
NULL
)
if
(
c
->
reader
==
NULL
)
{
c
->
reader
=
redisReplyReaderCreate
(
c
->
fn
);
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
/* Use this function to handle a read event on the descriptor. It will try
...
...
hiredis.h
View file @
2e5e9a49
...
@@ -110,7 +110,8 @@ typedef struct redisContext {
...
@@ -110,7 +110,8 @@ typedef struct redisContext {
}
redisContext
;
}
redisContext
;
void
freeReplyObject
(
void
*
reply
);
void
freeReplyObject
(
void
*
reply
);
void
*
redisReplyReaderCreate
(
redisReplyObjectFunctions
*
fn
);
void
*
redisReplyReaderCreate
();
int
redisReplyReaderSetReplyObjectFunctions
(
void
*
reader
,
redisReplyObjectFunctions
*
fn
);
void
*
redisReplyReaderGetObject
(
void
*
reader
);
void
*
redisReplyReaderGetObject
(
void
*
reader
);
char
*
redisReplyReaderGetError
(
void
*
reader
);
char
*
redisReplyReaderGetError
(
void
*
reader
);
void
redisReplyReaderFree
(
void
*
ptr
);
void
redisReplyReaderFree
(
void
*
ptr
);
...
...
test.c
View file @
2e5e9a49
...
@@ -186,11 +186,12 @@ static void test_blocking_connection() {
...
@@ -186,11 +186,12 @@ static void test_blocking_connection() {
static
void
test_reply_reader
()
{
static
void
test_reply_reader
()
{
void
*
reader
;
void
*
reader
;
void
*
reply
;
char
*
err
;
char
*
err
;
int
ret
;
int
ret
;
test
(
"Error handling in reply parser: "
);
test
(
"Error handling in reply parser: "
);
reader
=
redisReplyReaderCreate
(
NULL
);
reader
=
redisReplyReaderCreate
();
redisReplyReaderFeed
(
reader
,(
char
*
)
"@foo
\r\n
"
,
6
);
redisReplyReaderFeed
(
reader
,(
char
*
)
"@foo
\r\n
"
,
6
);
ret
=
redisReplyReaderGetReply
(
reader
,
NULL
);
ret
=
redisReplyReaderGetReply
(
reader
,
NULL
);
err
=
redisReplyReaderGetError
(
reader
);
err
=
redisReplyReaderGetError
(
reader
);
...
@@ -201,7 +202,7 @@ static void test_reply_reader() {
...
@@ -201,7 +202,7 @@ static void test_reply_reader() {
/* when the reply already contains multiple items, they must be free'd
/* when the reply already contains multiple items, they must be free'd
* on an error. valgrind will bark when this doesn't happen. */
* on an error. valgrind will bark when this doesn't happen. */
test
(
"Memory cleanup in reply parser: "
);
test
(
"Memory cleanup in reply parser: "
);
reader
=
redisReplyReaderCreate
(
NULL
);
reader
=
redisReplyReaderCreate
();
redisReplyReaderFeed
(
reader
,(
char
*
)
"*2
\r\n
"
,
4
);
redisReplyReaderFeed
(
reader
,(
char
*
)
"*2
\r\n
"
,
4
);
redisReplyReaderFeed
(
reader
,(
char
*
)
"$5
\r\n
hello
\r\n
"
,
11
);
redisReplyReaderFeed
(
reader
,(
char
*
)
"$5
\r\n
hello
\r\n
"
,
11
);
redisReplyReaderFeed
(
reader
,(
char
*
)
"@foo
\r\n
"
,
6
);
redisReplyReaderFeed
(
reader
,(
char
*
)
"@foo
\r\n
"
,
6
);
...
@@ -210,6 +211,14 @@ static void test_reply_reader() {
...
@@ -210,6 +211,14 @@ static void test_reply_reader() {
test_cond
(
ret
==
REDIS_ERR
&&
test_cond
(
ret
==
REDIS_ERR
&&
strcasecmp
(
err
,
"protocol error, got
\"
@
\"
as reply type byte"
)
==
0
);
strcasecmp
(
err
,
"protocol error, got
\"
@
\"
as reply type byte"
)
==
0
);
redisReplyReaderFree
(
reader
);
redisReplyReaderFree
(
reader
);
test
(
"Works with NULL functions for reply: "
);
reader
=
redisReplyReaderCreate
();
redisReplyReaderSetReplyObjectFunctions
(
reader
,
NULL
);
redisReplyReaderFeed
(
reader
,(
char
*
)
"+OK
\r\n
"
,
5
);
ret
=
redisReplyReaderGetReply
(
reader
,
&
reply
);
test_cond
(
ret
==
REDIS_OK
&&
reply
==
(
void
*
)
REDIS_REPLY_STATUS
);
redisReplyReaderFree
(
reader
);
}
}
static
void
test_throughput
()
{
static
void
test_throughput
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment