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
5cf292cd
Commit
5cf292cd
authored
Nov 26, 2010
by
Pieter Noordhuis
Browse files
Use explicit buffer length field in the reply reader
parent
adb0895e
Changes
1
Show whitespace changes
Inline
Side-by-side
hiredis.c
View file @
5cf292cd
...
...
@@ -44,7 +44,8 @@ typedef struct redisReader {
void
*
reply
;
/* holds temporary reply */
sds
buf
;
/* read buffer */
unsigned
int
pos
;
/* buffer cursor */
size_t
pos
;
/* buffer cursor */
size_t
len
;
/* buffer length */
redisReadTask
rstack
[
3
];
/* stack of read tasks */
int
ridx
;
/* index of stack */
...
...
@@ -163,20 +164,31 @@ static char *readBytes(redisReader *r, unsigned int bytes) {
return
NULL
;
}
static
char
*
seekNewline
(
char
*
s
)
{
/* Find pointer to \r\n without strstr */
while
(
s
!=
NULL
)
{
s
=
strchr
(
s
,
'\r'
);
if
(
s
!=
NULL
)
{
if
(
s
[
1
]
==
'\n'
)
break
;
else
s
++
;
/* Find pointer to \r\n. */
static
char
*
seekNewline
(
char
*
s
,
size_t
len
)
{
int
pos
=
0
;
int
_len
=
len
-
1
;
/* Position should be < len-1 because the character at "pos" should be
* followed by a \n. Note that strchr cannot be used because it doesn't
* allow to search a limited length and the buffer that is being searched
* might not have a trailing NULL character. */
while
(
pos
<
_len
)
{
while
(
pos
<
_len
&&
s
[
pos
]
!=
'\r'
)
pos
++
;
if
(
s
[
pos
]
!=
'\r'
)
{
/* Not found. */
return
NULL
;
}
else
{
break
;
if
(
s
[
pos
+
1
]
==
'\n'
)
{
/* Found. */
return
s
+
pos
;
}
else
{
/* Continue searching. */
pos
++
;
}
}
}
return
s
;
return
NULL
;
}
static
char
*
readLine
(
redisReader
*
r
,
int
*
_len
)
{
...
...
@@ -184,7 +196,7 @@ static char *readLine(redisReader *r, int *_len) {
int
len
;
p
=
r
->
buf
+
r
->
pos
;
s
=
seekNewline
(
p
);
s
=
seekNewline
(
p
,(
r
->
len
-
r
->
pos
)
);
if
(
s
!=
NULL
)
{
len
=
s
-
(
r
->
buf
+
r
->
pos
);
r
->
pos
+=
len
+
2
;
/* skip \r\n */
...
...
@@ -253,7 +265,7 @@ static int processBulkItem(redisReader *r) {
int
success
=
0
;
p
=
r
->
buf
+
r
->
pos
;
s
=
seekNewline
(
p
);
s
=
seekNewline
(
p
,
r
->
len
-
r
->
pos
);
if
(
s
!=
NULL
)
{
p
=
r
->
buf
+
r
->
pos
;
bytelen
=
s
-
(
r
->
buf
+
r
->
pos
)
+
2
;
/* include \r\n */
...
...
@@ -267,7 +279,7 @@ static int processBulkItem(redisReader *r) {
}
else
{
/* Only continue when the buffer contains the entire bulk item. */
bytelen
+=
len
+
2
;
/* include \r\n */
if
(
r
->
pos
+
bytelen
<=
sdslen
(
r
->
buf
)
)
{
if
(
r
->
pos
+
bytelen
<=
r
->
len
)
{
obj
=
r
->
fn
?
r
->
fn
->
createString
(
cur
,
s
+
2
,
len
)
:
(
void
*
)
REDIS_REPLY_STRING
;
success
=
1
;
...
...
@@ -463,8 +475,10 @@ void redisReplyReaderFeed(void *reader, char *buf, size_t len) {
redisReader
*
r
=
reader
;
/* Copy the provided buffer. */
if
(
buf
!=
NULL
&&
len
>=
1
)
if
(
buf
!=
NULL
&&
len
>=
1
)
{
r
->
buf
=
sdscatlen
(
r
->
buf
,
buf
,
len
);
r
->
len
=
sdslen
(
r
->
buf
);
}
}
int
redisReplyReaderGetReply
(
void
*
reader
,
void
**
reply
)
{
...
...
@@ -472,7 +486,7 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
if
(
reply
!=
NULL
)
*
reply
=
NULL
;
/* When the buffer is empty, there will never be a reply. */
if
(
sdslen
(
r
->
buf
)
==
0
)
if
(
r
->
len
==
0
)
return
REDIS_OK
;
/* Set first item to process when the stack is empty. */
...
...
@@ -493,14 +507,15 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
/* Discard the consumed part of the buffer. */
if
(
r
->
pos
>
0
)
{
if
(
r
->
pos
==
sdslen
(
r
->
buf
)
)
{
if
(
r
->
pos
==
r
->
len
)
{
/* sdsrange has a quirck on this edge case. */
sdsfree
(
r
->
buf
);
r
->
buf
=
sdsempty
();
}
else
{
r
->
buf
=
sdsrange
(
r
->
buf
,
r
->
pos
,
sdslen
(
r
->
buf
)
);
r
->
buf
=
sdsrange
(
r
->
buf
,
r
->
pos
,
r
->
len
);
}
r
->
pos
=
0
;
r
->
len
=
sdslen
(
r
->
buf
);
}
/* Emit a reply when there is one. */
...
...
@@ -509,7 +524,7 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
r
->
reply
=
NULL
;
/* Destroy the buffer when it is empty and is quite large. */
if
(
sdslen
(
r
->
buf
)
==
0
&&
sdsavail
(
r
->
buf
)
>
16
*
1024
)
{
if
(
r
->
len
==
0
&&
sdsavail
(
r
->
buf
)
>
16
*
1024
)
{
sdsfree
(
r
->
buf
);
r
->
buf
=
sdsempty
();
r
->
pos
=
0
;
...
...
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