Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
e621f313
Commit
e621f313
authored
Sep 20, 2010
by
Pieter Noordhuis
Browse files
Expose API for streaming bytes to a reply
parent
4ec97f59
Changes
2
Show whitespace changes
Inline
Side-by-side
hiredis.c
View file @
e621f313
...
@@ -38,14 +38,12 @@
...
@@ -38,14 +38,12 @@
#include "sds.h"
#include "sds.h"
typedef
struct
redisReader
{
typedef
struct
redisReader
{
char
*
buf
;
/* read buffer */
sds
buf
;
/* read buffer */
int
len
;
/* buffer length */
unsigned
int
pos
;
/* buffer cursor */
int
avail
;
/* available bytes for consumption */
int
pos
;
/* buffer cursor */
redisReply
**
rlist
;
/* list of items to process */
redisReply
**
rlist
;
/* list of items to process */
int
rlen
;
/* list length */
unsigned
int
rlen
;
/* list length */
int
rpos
;
/* list cursor */
unsigned
int
rpos
;
/* list cursor */
}
redisReader
;
}
redisReader
;
static
redisReply
*
redisReadReply
(
int
fd
);
static
redisReply
*
redisReadReply
(
int
fd
);
...
@@ -105,9 +103,9 @@ static redisReply *redisIOError(void) {
...
@@ -105,9 +103,9 @@ static redisReply *redisIOError(void) {
return
createReplyObject
(
REDIS_REPLY_ERROR
,
sdsnew
(
"I/O error"
));
return
createReplyObject
(
REDIS_REPLY_ERROR
,
sdsnew
(
"I/O error"
));
}
}
static
char
*
readBytes
(
redisReader
*
r
,
int
bytes
)
{
static
char
*
readBytes
(
redisReader
*
r
,
unsigned
int
bytes
)
{
char
*
p
;
char
*
p
;
if
(
r
->
len
-
r
->
pos
>=
bytes
)
{
if
(
sdslen
(
r
->
buf
)
-
r
->
pos
>=
bytes
)
{
p
=
r
->
buf
+
r
->
pos
;
p
=
r
->
buf
+
r
->
pos
;
r
->
pos
+=
bytes
;
r
->
pos
+=
bytes
;
return
p
;
return
p
;
...
@@ -274,56 +272,96 @@ static int processItem(redisReader *r) {
...
@@ -274,56 +272,96 @@ static int processItem(redisReader *r) {
#define READ_BUFFER_SIZE 2048
#define READ_BUFFER_SIZE 2048
static
redisReply
*
redisReadReply
(
int
fd
)
{
static
redisReply
*
redisReadReply
(
int
fd
)
{
void
*
reader
=
redisCreateReplyReader
();
redisReply
*
reply
;
redisReply
*
reply
;
redisReader
r
;
char
buf
[
1024
];
int
bytes
;
int
nread
;
/* setup read buffer */
do
{
r
.
buf
=
malloc
(
READ_BUFFER_SIZE
+
1
);
if
((
nread
=
read
(
fd
,
buf
,
sizeof
(
buf
)))
<=
0
)
{
r
.
len
=
READ_BUFFER_SIZE
;
reply
=
redisIOError
();
r
.
avail
=
0
;
break
;
r
.
pos
=
0
;
}
else
{
reply
=
redisFeedReplyReader
(
reader
,
buf
,
nread
);
/* setup list of items to process */
r
.
rlist
=
malloc
(
sizeof
(
redisReply
*
));
r
.
rlist
[
0
]
=
createReplyObject
(
-
1
,
NULL
);
r
.
rlen
=
1
;
r
.
rpos
=
0
;
while
(
r
.
rpos
<
r
.
rlen
)
{
/* discard the buffer upto pos */
if
(
r
.
pos
>
0
)
{
memmove
(
r
.
buf
,
r
.
buf
+
r
.
pos
,
r
.
len
-
r
.
pos
);
r
.
avail
-=
r
.
pos
;
r
.
pos
=
0
;
}
}
}
while
(
reply
==
NULL
);
/* make sure there is room for at least BUFFER_SIZE */
redisFreeReplyReader
(
reader
);
if
(
r
.
len
-
r
.
avail
<
READ_BUFFER_SIZE
)
{
return
reply
;
r
.
buf
=
realloc
(
r
.
buf
,
r
.
avail
+
READ_BUFFER_SIZE
+
1
);
}
r
.
len
=
r
.
avail
+
READ_BUFFER_SIZE
;
void
*
redisCreateReplyReader
()
{
redisReader
*
r
=
calloc
(
sizeof
(
redisReader
),
1
);
r
->
buf
=
sdsempty
();
return
r
;
}
void
redisFreeReplyReader
(
void
*
reader
)
{
redisReader
*
r
=
reader
;
if
(
r
->
buf
!=
NULL
)
{
sdsfree
(
r
->
buf
);
}
if
(
r
->
rlen
>
0
)
{
freeReplyObject
(
r
->
rlist
[
0
]);
free
(
r
->
rlist
);
}
}
free
(
r
);
}
void
*
redisFeedReplyReader
(
void
*
reader
,
char
*
buf
,
int
len
)
{
redisReader
*
r
=
reader
;
/* read from socket into buffer */
/* Check if we are able to do *something*. */
if
((
bytes
=
read
(
fd
,
r
.
buf
+
r
.
avail
,
READ_BUFFER_SIZE
))
<=
0
)
{
if
(
sdslen
(
r
->
buf
)
==
0
&&
(
buf
==
NULL
||
len
<=
0
))
/* rlist[0] is the "root" reply object */
return
NULL
;
freeReplyObject
(
r
.
rlist
[
0
]);
free
(
r
.
buf
);
/* Copy the provided buffer. */
free
(
r
.
rlist
);
if
(
buf
!=
NULL
&&
len
>=
1
)
return
redisIOError
();
r
->
buf
=
sdscatlen
(
r
->
buf
,
buf
,
len
);
/* Create first item to process when the item list is empty. */
if
(
r
->
rlen
==
0
)
{
r
->
rlist
=
malloc
(
sizeof
(
redisReply
*
));
r
->
rlist
[
0
]
=
createReplyObject
(
-
1
,
NULL
);
r
->
rlen
=
1
;
r
->
rpos
=
0
;
}
}
r
.
avail
+=
bytes
;
r
.
buf
[
r
.
avail
]
=
'\0'
;
/*
p
rocess items in reply */
/*
P
rocess items in reply
.
*/
while
(
r
.
rpos
<
r
.
rlen
)
while
(
r
->
rpos
<
r
->
rlen
)
if
(
processItem
(
&
r
)
<
0
)
if
(
processItem
(
r
)
<
0
)
break
;
break
;
/* Discard the consumed part of the buffer. */
if
(
r
->
pos
>
0
)
{
if
(
r
->
pos
==
sdslen
(
r
->
buf
))
{
/* 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
->
pos
=
0
;
}
}
reply
=
r
.
rlist
[
0
];
free
(
r
.
buf
);
/* Emit a reply when there is one. */
free
(
r
.
rlist
);
if
(
r
->
rpos
==
r
->
rlen
)
{
redisReply
*
reply
=
r
->
rlist
[
0
];
/* Destroy the buffer when it is empty and is quite large. */
if
(
sdslen
(
r
->
buf
)
==
0
&&
sdsavail
(
r
->
buf
)
>
16
*
1024
)
{
sdsfree
(
r
->
buf
);
r
->
buf
=
sdsempty
();
r
->
pos
=
0
;
}
/* Free list of items to process. */
free
(
r
->
rlist
);
r
->
rlen
=
r
->
rpos
=
0
;
return
reply
;
return
reply
;
}
else
{
return
NULL
;
}
}
}
/* Helper function for redisCommand(). It's used to append the next argument
/* Helper function for redisCommand(). It's used to append the next argument
...
...
hiredis.h
View file @
e621f313
...
@@ -51,5 +51,8 @@ typedef struct redisReply {
...
@@ -51,5 +51,8 @@ typedef struct redisReply {
redisReply
*
redisConnect
(
int
*
fd
,
const
char
*
ip
,
int
port
);
redisReply
*
redisConnect
(
int
*
fd
,
const
char
*
ip
,
int
port
);
void
freeReplyObject
(
redisReply
*
r
);
void
freeReplyObject
(
redisReply
*
r
);
redisReply
*
redisCommand
(
int
fd
,
const
char
*
format
,
...);
redisReply
*
redisCommand
(
int
fd
,
const
char
*
format
,
...);
void
*
redisCreateReplyReader
();
void
redisFreeReplyReader
(
void
*
ptr
);
void
*
redisFeedReplyReader
(
void
*
reader
,
char
*
buf
,
int
len
);
#endif
#endif
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