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
91de9c97
Commit
91de9c97
authored
Aug 04, 2019
by
Yossi Gottlieb
Browse files
RESP3 support changes from Redis.
This corresponds to commits d5c54f0b..bea09a7f in the redis repository.
parent
a7a1886b
Changes
5
Hide whitespace changes
Inline
Side-by-side
.travis.yml
View file @
91de9c97
...
...
@@ -8,6 +8,12 @@ os:
-
linux
-
osx
branches
:
only
:
-
staging
-
trying
-
master
before_script
:
-
if [ "$TRAVIS_OS_NAME" == "osx" ] ; then brew update; brew install redis; fi
...
...
hiredis.c
View file @
91de9c97
...
...
@@ -48,7 +48,9 @@ static redisReply *createReplyObject(int type);
static
void
*
createStringObject
(
const
redisReadTask
*
task
,
char
*
str
,
size_t
len
);
static
void
*
createArrayObject
(
const
redisReadTask
*
task
,
int
elements
);
static
void
*
createIntegerObject
(
const
redisReadTask
*
task
,
long
long
value
);
static
void
*
createDoubleObject
(
const
redisReadTask
*
task
,
double
value
,
char
*
str
,
size_t
len
);
static
void
*
createNilObject
(
const
redisReadTask
*
task
);
static
void
*
createBoolObject
(
const
redisReadTask
*
task
,
int
bval
);
/* Default set of functions to build the reply. Keep in mind that such a
* function returning NULL is interpreted as OOM. */
...
...
@@ -56,7 +58,9 @@ static redisReplyObjectFunctions defaultFunctions = {
createStringObject
,
createArrayObject
,
createIntegerObject
,
createDoubleObject
,
createNilObject
,
createBoolObject
,
freeReplyObject
};
...
...
@@ -83,6 +87,8 @@ void freeReplyObject(void *reply) {
case
REDIS_REPLY_INTEGER
:
break
;
/* Nothing to free */
case
REDIS_REPLY_ARRAY
:
case
REDIS_REPLY_MAP
:
case
REDIS_REPLY_SET
:
if
(
r
->
element
!=
NULL
)
{
for
(
j
=
0
;
j
<
r
->
elements
;
j
++
)
freeReplyObject
(
r
->
element
[
j
]);
...
...
@@ -92,6 +98,7 @@ void freeReplyObject(void *reply) {
case
REDIS_REPLY_ERROR
:
case
REDIS_REPLY_STATUS
:
case
REDIS_REPLY_STRING
:
case
REDIS_REPLY_DOUBLE
:
free
(
r
->
str
);
break
;
}
...
...
@@ -124,7 +131,9 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len
if
(
task
->
parent
)
{
parent
=
task
->
parent
->
obj
;
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
);
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
||
parent
->
type
==
REDIS_REPLY_MAP
||
parent
->
type
==
REDIS_REPLY_SET
);
parent
->
element
[
task
->
idx
]
=
r
;
}
return
r
;
...
...
@@ -133,7 +142,7 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len
static
void
*
createArrayObject
(
const
redisReadTask
*
task
,
int
elements
)
{
redisReply
*
r
,
*
parent
;
r
=
createReplyObject
(
REDIS_REPLY_ARRAY
);
r
=
createReplyObject
(
task
->
type
);
if
(
r
==
NULL
)
return
NULL
;
...
...
@@ -149,7 +158,9 @@ static void *createArrayObject(const redisReadTask *task, int elements) {
if
(
task
->
parent
)
{
parent
=
task
->
parent
->
obj
;
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
);
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
||
parent
->
type
==
REDIS_REPLY_MAP
||
parent
->
type
==
REDIS_REPLY_SET
);
parent
->
element
[
task
->
idx
]
=
r
;
}
return
r
;
...
...
@@ -166,7 +177,41 @@ static void *createIntegerObject(const redisReadTask *task, long long value) {
if
(
task
->
parent
)
{
parent
=
task
->
parent
->
obj
;
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
);
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
||
parent
->
type
==
REDIS_REPLY_MAP
||
parent
->
type
==
REDIS_REPLY_SET
);
parent
->
element
[
task
->
idx
]
=
r
;
}
return
r
;
}
static
void
*
createDoubleObject
(
const
redisReadTask
*
task
,
double
value
,
char
*
str
,
size_t
len
)
{
redisReply
*
r
,
*
parent
;
r
=
createReplyObject
(
REDIS_REPLY_DOUBLE
);
if
(
r
==
NULL
)
return
NULL
;
r
->
dval
=
value
;
r
->
str
=
malloc
(
len
+
1
);
if
(
r
->
str
==
NULL
)
{
freeReplyObject
(
r
);
return
NULL
;
}
/* The double reply also has the original protocol string representing a
* double as a null terminated string. This way the caller does not need
* to format back for string conversion, especially since Redis does efforts
* to make the string more human readable avoiding the calssical double
* decimal string conversion artifacts. */
memcpy
(
r
->
str
,
str
,
len
);
r
->
str
[
len
]
=
'\0'
;
if
(
task
->
parent
)
{
parent
=
task
->
parent
->
obj
;
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
||
parent
->
type
==
REDIS_REPLY_MAP
||
parent
->
type
==
REDIS_REPLY_SET
);
parent
->
element
[
task
->
idx
]
=
r
;
}
return
r
;
...
...
@@ -181,7 +226,28 @@ static void *createNilObject(const redisReadTask *task) {
if
(
task
->
parent
)
{
parent
=
task
->
parent
->
obj
;
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
);
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
||
parent
->
type
==
REDIS_REPLY_MAP
||
parent
->
type
==
REDIS_REPLY_SET
);
parent
->
element
[
task
->
idx
]
=
r
;
}
return
r
;
}
static
void
*
createBoolObject
(
const
redisReadTask
*
task
,
int
bval
)
{
redisReply
*
r
,
*
parent
;
r
=
createReplyObject
(
REDIS_REPLY_BOOL
);
if
(
r
==
NULL
)
return
NULL
;
r
->
integer
=
bval
!=
0
;
if
(
task
->
parent
)
{
parent
=
task
->
parent
->
obj
;
assert
(
parent
->
type
==
REDIS_REPLY_ARRAY
||
parent
->
type
==
REDIS_REPLY_MAP
||
parent
->
type
==
REDIS_REPLY_SET
);
parent
->
element
[
task
->
idx
]
=
r
;
}
return
r
;
...
...
hiredis.h
View file @
91de9c97
...
...
@@ -101,8 +101,10 @@ extern "C" {
typedef
struct
redisReply
{
int
type
;
/* REDIS_REPLY_* */
long
long
integer
;
/* The integer when type is REDIS_REPLY_INTEGER */
double
dval
;
/* The double when type is REDIS_REPLY_DOUBLE */
size_t
len
;
/* Length of string */
char
*
str
;
/* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
char
*
str
;
/* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
and REDIS_REPLY_DOUBLE (in additionl to dval). */
size_t
elements
;
/* number of elements, for REDIS_REPLY_ARRAY */
struct
redisReply
**
element
;
/* elements vector for REDIS_REPLY_ARRAY */
}
redisReply
;
...
...
read.c
View file @
91de9c97
...
...
@@ -29,9 +29,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "fmacros.h"
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#ifndef _MSC_VER
#include <unistd.h>
...
...
@@ -40,6 +40,7 @@
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include "read.h"
#include "sds.h"
...
...
@@ -243,7 +244,9 @@ static void moveToNextTask(redisReader *r) {
cur
=
&
(
r
->
rstack
[
r
->
ridx
]);
prv
=
&
(
r
->
rstack
[
r
->
ridx
-
1
]);
assert
(
prv
->
type
==
REDIS_REPLY_ARRAY
);
assert
(
prv
->
type
==
REDIS_REPLY_ARRAY
||
prv
->
type
==
REDIS_REPLY_MAP
||
prv
->
type
==
REDIS_REPLY_SET
);
if
(
cur
->
idx
==
prv
->
elements
-
1
)
{
r
->
ridx
--
;
}
else
{
...
...
@@ -276,6 +279,47 @@ static int processLineItem(redisReader *r) {
}
else
{
obj
=
(
void
*
)
REDIS_REPLY_INTEGER
;
}
}
else
if
(
cur
->
type
==
REDIS_REPLY_DOUBLE
)
{
if
(
r
->
fn
&&
r
->
fn
->
createDouble
)
{
char
buf
[
326
],
*
eptr
;
double
d
;
if
((
size_t
)
len
>=
sizeof
(
buf
))
{
__redisReaderSetError
(
r
,
REDIS_ERR_PROTOCOL
,
"Double value is too large"
);
return
REDIS_ERR
;
}
memcpy
(
buf
,
p
,
len
);
buf
[
len
]
=
'\0'
;
if
(
strcasecmp
(
buf
,
",inf"
)
==
0
)
{
d
=
1
.
0
/
0
.
0
;
/* Positive infinite. */
}
else
if
(
strcasecmp
(
buf
,
",-inf"
)
==
0
)
{
d
=
-
1
.
0
/
0
.
0
;
/* Nevative infinite. */
}
else
{
d
=
strtod
((
char
*
)
buf
,
&
eptr
);
if
(
buf
[
0
]
==
'\0'
||
eptr
[
0
]
!=
'\0'
||
isnan
(
d
))
{
__redisReaderSetError
(
r
,
REDIS_ERR_PROTOCOL
,
"Bad double value"
);
return
REDIS_ERR
;
}
}
obj
=
r
->
fn
->
createDouble
(
cur
,
d
,
buf
,
len
);
}
else
{
obj
=
(
void
*
)
REDIS_REPLY_DOUBLE
;
}
}
else
if
(
cur
->
type
==
REDIS_REPLY_NIL
)
{
if
(
r
->
fn
&&
r
->
fn
->
createNil
)
obj
=
r
->
fn
->
createNil
(
cur
);
else
obj
=
(
void
*
)
REDIS_REPLY_NIL
;
}
else
if
(
cur
->
type
==
REDIS_REPLY_BOOL
)
{
int
bval
=
p
[
0
]
==
't'
||
p
[
0
]
==
'T'
;
if
(
r
->
fn
&&
r
->
fn
->
createBool
)
obj
=
r
->
fn
->
createBool
(
cur
,
bval
);
else
obj
=
(
void
*
)
REDIS_REPLY_BOOL
;
}
else
{
/* Type will be error or status. */
if
(
r
->
fn
&&
r
->
fn
->
createString
)
...
...
@@ -458,6 +502,12 @@ static int processItem(redisReader *r) {
case
':'
:
cur
->
type
=
REDIS_REPLY_INTEGER
;
break
;
case
','
:
cur
->
type
=
REDIS_REPLY_DOUBLE
;
break
;
case
'_'
:
cur
->
type
=
REDIS_REPLY_NIL
;
break
;
case
'$'
:
cur
->
type
=
REDIS_REPLY_STRING
;
break
;
...
...
@@ -470,6 +520,9 @@ static int processItem(redisReader *r) {
case
'~'
:
cur
->
type
=
REDIS_REPLY_SET
;
break
;
case
'#'
:
cur
->
type
=
REDIS_REPLY_BOOL
;
break
;
default:
__redisReaderSetErrorProtocolByte
(
r
,
*
p
);
return
REDIS_ERR
;
...
...
@@ -485,6 +538,9 @@ static int processItem(redisReader *r) {
case
REDIS_REPLY_ERROR
:
case
REDIS_REPLY_STATUS
:
case
REDIS_REPLY_INTEGER
:
case
REDIS_REPLY_DOUBLE
:
case
REDIS_REPLY_NIL
:
case
REDIS_REPLY_BOOL
:
return
processLineItem
(
r
);
case
REDIS_REPLY_STRING
:
return
processBulkItem
(
r
);
...
...
read.h
View file @
91de9c97
...
...
@@ -82,7 +82,9 @@ typedef struct redisReplyObjectFunctions {
void
*
(
*
createString
)(
const
redisReadTask
*
,
char
*
,
size_t
);
void
*
(
*
createArray
)(
const
redisReadTask
*
,
int
);
void
*
(
*
createInteger
)(
const
redisReadTask
*
,
long
long
);
void
*
(
*
createDouble
)(
const
redisReadTask
*
,
double
,
char
*
,
size_t
);
void
*
(
*
createNil
)(
const
redisReadTask
*
);
void
*
(
*
createBool
)(
const
redisReadTask
*
,
int
);
void
(
*
freeObject
)(
void
*
);
}
redisReplyObjectFunctions
;
...
...
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