hiredis 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -47
- data/ext/hiredis_ext/connection.c +104 -35
- data/ext/hiredis_ext/extconf.rb +1 -1
- data/ext/hiredis_ext/hiredis_ext.c +4 -2
- data/ext/hiredis_ext/hiredis_ext.h +0 -1
- data/ext/hiredis_ext/reader.c +0 -20
- data/lib/hiredis.rb +2 -10
- data/lib/hiredis/connection.rb +7 -14
- data/lib/hiredis/ext/connection.rb +16 -0
- data/lib/hiredis/ext/reader.rb +2 -0
- data/lib/hiredis/reader.rb +10 -1
- data/lib/hiredis/ruby/connection.rb +113 -0
- data/lib/hiredis/ruby/reader.rb +164 -0
- data/lib/hiredis/version.rb +1 -1
- data/vendor/hiredis/Makefile +4 -5
- data/vendor/hiredis/async.c +2 -0
- data/vendor/hiredis/async.h +3 -3
- data/vendor/hiredis/dict.c +27 -77
- data/vendor/hiredis/dict.h +12 -16
- data/vendor/hiredis/hiredis.c +26 -17
- data/vendor/hiredis/hiredis.h +4 -2
- data/vendor/hiredis/net.c +85 -18
- data/vendor/hiredis/net.h +2 -2
- data/vendor/hiredis/sds.c +129 -4
- data/vendor/hiredis/sds.h +2 -1
- data/vendor/hiredis/test.c +14 -5
- metadata +15 -29
- data/lib/hiredis/em.rb +0 -1
- data/lib/hiredis/em/base.rb +0 -36
- data/lib/hiredis/em/connection.rb +0 -25
data/vendor/hiredis/dict.h
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* Hash
|
1
|
+
/* Hash table implementation.
|
2
2
|
*
|
3
3
|
* This file implements in memory hash tables with insert/del/replace/find/
|
4
4
|
* get-random-element operations. Hash tables will auto resize if needed
|
@@ -111,20 +111,16 @@ typedef struct dictIterator {
|
|
111
111
|
#define dictSize(ht) ((ht)->used)
|
112
112
|
|
113
113
|
/* API */
|
114
|
-
|
115
|
-
|
116
|
-
int
|
117
|
-
int
|
118
|
-
int
|
119
|
-
int
|
120
|
-
void dictRelease(dict *ht);
|
121
|
-
dictEntry * dictFind(dict *ht, const void *key);
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
void dictReleaseIterator(dictIterator *iter);
|
126
|
-
dictEntry *dictGetRandomKey(dict *ht);
|
127
|
-
unsigned int dictGenHashFunction(const unsigned char *buf, int len);
|
128
|
-
void dictEmpty(dict *ht);
|
114
|
+
static unsigned int dictGenHashFunction(const unsigned char *buf, int len);
|
115
|
+
static dict *dictCreate(dictType *type, void *privDataPtr);
|
116
|
+
static int dictExpand(dict *ht, unsigned long size);
|
117
|
+
static int dictAdd(dict *ht, void *key, void *val);
|
118
|
+
static int dictReplace(dict *ht, void *key, void *val);
|
119
|
+
static int dictDelete(dict *ht, const void *key);
|
120
|
+
static void dictRelease(dict *ht);
|
121
|
+
static dictEntry * dictFind(dict *ht, const void *key);
|
122
|
+
static dictIterator *dictGetIterator(dict *ht);
|
123
|
+
static dictEntry *dictNext(dictIterator *iter);
|
124
|
+
static void dictReleaseIterator(dictIterator *iter);
|
129
125
|
|
130
126
|
#endif /* __DICT_H */
|
data/vendor/hiredis/hiredis.c
CHANGED
@@ -434,7 +434,7 @@ static int processItem(redisReader *r) {
|
|
434
434
|
}
|
435
435
|
}
|
436
436
|
|
437
|
-
void *redisReplyReaderCreate() {
|
437
|
+
void *redisReplyReaderCreate(void) {
|
438
438
|
redisReader *r = calloc(sizeof(redisReader),1);
|
439
439
|
r->error = NULL;
|
440
440
|
r->fn = &defaultFunctions;
|
@@ -493,7 +493,7 @@ static void redisSetReplyReaderError(redisReader *r, sds err) {
|
|
493
493
|
if (r->buf != NULL) {
|
494
494
|
sdsfree(r->buf);
|
495
495
|
r->buf = sdsempty();
|
496
|
-
r->pos = 0;
|
496
|
+
r->pos = r->len = 0;
|
497
497
|
}
|
498
498
|
r->ridx = -1;
|
499
499
|
r->error = err;
|
@@ -504,7 +504,7 @@ char *redisReplyReaderGetError(void *reader) {
|
|
504
504
|
return r->error;
|
505
505
|
}
|
506
506
|
|
507
|
-
void redisReplyReaderFeed(void *reader, char *buf, size_t len) {
|
507
|
+
void redisReplyReaderFeed(void *reader, const char *buf, size_t len) {
|
508
508
|
redisReader *r = reader;
|
509
509
|
|
510
510
|
/* Copy the provided buffer. */
|
@@ -538,15 +538,10 @@ int redisReplyReaderGetReply(void *reader, void **reply) {
|
|
538
538
|
if (processItem(r) < 0)
|
539
539
|
break;
|
540
540
|
|
541
|
-
/* Discard
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
sdsfree(r->buf);
|
546
|
-
r->buf = sdsempty();
|
547
|
-
} else {
|
548
|
-
r->buf = sdsrange(r->buf,r->pos,r->len);
|
549
|
-
}
|
541
|
+
/* Discard part of the buffer when we've consumed at least 1k, to avoid
|
542
|
+
* doing unnecessary calls to memmove() in sds.c. */
|
543
|
+
if (r->pos >= 1024) {
|
544
|
+
r->buf = sdsrange(r->buf,r->pos,-1);
|
550
545
|
r->pos = 0;
|
551
546
|
r->len = sdslen(r->buf);
|
552
547
|
}
|
@@ -798,7 +793,7 @@ void __redisSetError(redisContext *c, int type, const sds errstr) {
|
|
798
793
|
}
|
799
794
|
}
|
800
795
|
|
801
|
-
static redisContext *redisContextInit() {
|
796
|
+
static redisContext *redisContextInit(void) {
|
802
797
|
redisContext *c = calloc(sizeof(redisContext),1);
|
803
798
|
c->err = 0;
|
804
799
|
c->errstr = NULL;
|
@@ -826,28 +821,42 @@ void redisFree(redisContext *c) {
|
|
826
821
|
redisContext *redisConnect(const char *ip, int port) {
|
827
822
|
redisContext *c = redisContextInit();
|
828
823
|
c->flags |= REDIS_BLOCK;
|
829
|
-
redisContextConnectTcp(c,ip,port);
|
824
|
+
redisContextConnectTcp(c,ip,port,NULL);
|
825
|
+
return c;
|
826
|
+
}
|
827
|
+
|
828
|
+
redisContext *redisConnectWithTimeout(const char *ip, int port, struct timeval tv) {
|
829
|
+
redisContext *c = redisContextInit();
|
830
|
+
c->flags |= REDIS_BLOCK;
|
831
|
+
redisContextConnectTcp(c,ip,port,&tv);
|
830
832
|
return c;
|
831
833
|
}
|
832
834
|
|
833
835
|
redisContext *redisConnectNonBlock(const char *ip, int port) {
|
834
836
|
redisContext *c = redisContextInit();
|
835
837
|
c->flags &= ~REDIS_BLOCK;
|
836
|
-
redisContextConnectTcp(c,ip,port);
|
838
|
+
redisContextConnectTcp(c,ip,port,NULL);
|
837
839
|
return c;
|
838
840
|
}
|
839
841
|
|
840
842
|
redisContext *redisConnectUnix(const char *path) {
|
841
843
|
redisContext *c = redisContextInit();
|
842
844
|
c->flags |= REDIS_BLOCK;
|
843
|
-
redisContextConnectUnix(c,path);
|
845
|
+
redisContextConnectUnix(c,path,NULL);
|
846
|
+
return c;
|
847
|
+
}
|
848
|
+
|
849
|
+
redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv) {
|
850
|
+
redisContext *c = redisContextInit();
|
851
|
+
c->flags |= REDIS_BLOCK;
|
852
|
+
redisContextConnectUnix(c,path,&tv);
|
844
853
|
return c;
|
845
854
|
}
|
846
855
|
|
847
856
|
redisContext *redisConnectUnixNonBlock(const char *path) {
|
848
857
|
redisContext *c = redisContextInit();
|
849
858
|
c->flags &= ~REDIS_BLOCK;
|
850
|
-
redisContextConnectUnix(c,path);
|
859
|
+
redisContextConnectUnix(c,path,NULL);
|
851
860
|
return c;
|
852
861
|
}
|
853
862
|
|
data/vendor/hiredis/hiredis.h
CHANGED
@@ -129,13 +129,13 @@ typedef struct redisContext {
|
|
129
129
|
} redisContext;
|
130
130
|
|
131
131
|
void freeReplyObject(void *reply);
|
132
|
-
void *redisReplyReaderCreate();
|
132
|
+
void *redisReplyReaderCreate(void);
|
133
133
|
int redisReplyReaderSetReplyObjectFunctions(void *reader, redisReplyObjectFunctions *fn);
|
134
134
|
int redisReplyReaderSetPrivdata(void *reader, void *privdata);
|
135
135
|
void *redisReplyReaderGetObject(void *reader);
|
136
136
|
char *redisReplyReaderGetError(void *reader);
|
137
137
|
void redisReplyReaderFree(void *ptr);
|
138
|
-
void redisReplyReaderFeed(void *reader, char *buf, size_t len);
|
138
|
+
void redisReplyReaderFeed(void *reader, const char *buf, size_t len);
|
139
139
|
int redisReplyReaderGetReply(void *reader, void **reply);
|
140
140
|
|
141
141
|
/* Functions to format a command according to the protocol. */
|
@@ -144,8 +144,10 @@ int redisFormatCommand(char **target, const char *format, ...);
|
|
144
144
|
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
|
145
145
|
|
146
146
|
redisContext *redisConnect(const char *ip, int port);
|
147
|
+
redisContext *redisConnectWithTimeout(const char *ip, int port, struct timeval tv);
|
147
148
|
redisContext *redisConnectNonBlock(const char *ip, int port);
|
148
149
|
redisContext *redisConnectUnix(const char *path);
|
150
|
+
redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv);
|
149
151
|
redisContext *redisConnectUnixNonBlock(const char *path);
|
150
152
|
int redisSetTimeout(redisContext *c, struct timeval tv);
|
151
153
|
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn);
|
data/vendor/hiredis/net.c
CHANGED
@@ -33,6 +33,7 @@
|
|
33
33
|
#include "fmacros.h"
|
34
34
|
#include <sys/types.h>
|
35
35
|
#include <sys/socket.h>
|
36
|
+
#include <sys/select.h>
|
36
37
|
#include <sys/un.h>
|
37
38
|
#include <netinet/in.h>
|
38
39
|
#include <netinet/tcp.h>
|
@@ -67,7 +68,7 @@ static int redisCreateSocket(redisContext *c, int type) {
|
|
67
68
|
return s;
|
68
69
|
}
|
69
70
|
|
70
|
-
static int
|
71
|
+
static int redisSetBlocking(redisContext *c, int fd, int blocking) {
|
71
72
|
int flags;
|
72
73
|
|
73
74
|
/* Set the socket nonblocking.
|
@@ -79,9 +80,15 @@ static int redisSetNonBlock(redisContext *c, int fd) {
|
|
79
80
|
close(fd);
|
80
81
|
return REDIS_ERR;
|
81
82
|
}
|
82
|
-
|
83
|
+
|
84
|
+
if (blocking)
|
85
|
+
flags &= ~O_NONBLOCK;
|
86
|
+
else
|
87
|
+
flags |= O_NONBLOCK;
|
88
|
+
|
89
|
+
if (fcntl(fd, F_SETFL, flags) == -1) {
|
83
90
|
__redisSetError(c,REDIS_ERR_IO,
|
84
|
-
sdscatprintf(sdsempty(), "fcntl(F_SETFL
|
91
|
+
sdscatprintf(sdsempty(), "fcntl(F_SETFL): %s", strerror(errno)));
|
85
92
|
close(fd);
|
86
93
|
return REDIS_ERR;
|
87
94
|
}
|
@@ -93,11 +100,67 @@ static int redisSetTcpNoDelay(redisContext *c, int fd) {
|
|
93
100
|
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
|
94
101
|
__redisSetError(c,REDIS_ERR_IO,
|
95
102
|
sdscatprintf(sdsempty(), "setsockopt(TCP_NODELAY): %s", strerror(errno)));
|
103
|
+
close(fd);
|
96
104
|
return REDIS_ERR;
|
97
105
|
}
|
98
106
|
return REDIS_OK;
|
99
107
|
}
|
100
108
|
|
109
|
+
static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) {
|
110
|
+
struct timeval to;
|
111
|
+
struct timeval *toptr = NULL;
|
112
|
+
fd_set wfd;
|
113
|
+
int err;
|
114
|
+
socklen_t errlen;
|
115
|
+
|
116
|
+
/* Only use timeout when not NULL. */
|
117
|
+
if (timeout != NULL) {
|
118
|
+
to = *timeout;
|
119
|
+
toptr = &to;
|
120
|
+
}
|
121
|
+
|
122
|
+
if (errno == EINPROGRESS) {
|
123
|
+
FD_ZERO(&wfd);
|
124
|
+
FD_SET(fd, &wfd);
|
125
|
+
|
126
|
+
if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) {
|
127
|
+
__redisSetError(c,REDIS_ERR_IO,
|
128
|
+
sdscatprintf(sdsempty(), "select(2): %s", strerror(errno)));
|
129
|
+
close(fd);
|
130
|
+
return REDIS_ERR;
|
131
|
+
}
|
132
|
+
|
133
|
+
if (!FD_ISSET(fd, &wfd)) {
|
134
|
+
errno = ETIMEDOUT;
|
135
|
+
__redisSetError(c,REDIS_ERR_IO,NULL);
|
136
|
+
close(fd);
|
137
|
+
return REDIS_ERR;
|
138
|
+
}
|
139
|
+
|
140
|
+
err = 0;
|
141
|
+
errlen = sizeof(err);
|
142
|
+
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
|
143
|
+
__redisSetError(c,REDIS_ERR_IO,
|
144
|
+
sdscatprintf(sdsempty(), "getsockopt(SO_ERROR): %s", strerror(errno)));
|
145
|
+
close(fd);
|
146
|
+
return REDIS_ERR;
|
147
|
+
}
|
148
|
+
|
149
|
+
if (err) {
|
150
|
+
errno = err;
|
151
|
+
__redisSetError(c,REDIS_ERR_IO,NULL);
|
152
|
+
close(fd);
|
153
|
+
return REDIS_ERR;
|
154
|
+
}
|
155
|
+
|
156
|
+
return REDIS_OK;
|
157
|
+
}
|
158
|
+
|
159
|
+
__redisSetError(c,REDIS_ERR_IO,NULL);
|
160
|
+
close(fd);
|
161
|
+
return REDIS_ERR;
|
162
|
+
}
|
163
|
+
|
101
164
|
int redisContextSetTimeout(redisContext *c, struct timeval tv) {
|
102
165
|
if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) {
|
103
166
|
__redisSetError(c,REDIS_ERR_IO,
|
@@ -112,14 +175,14 @@ int redisContextSetTimeout(redisContext *c, struct timeval tv) {
|
|
112
175
|
return REDIS_OK;
|
113
176
|
}
|
114
177
|
|
115
|
-
int redisContextConnectTcp(redisContext *c, const char *addr, int port) {
|
178
|
+
int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout) {
|
116
179
|
int s;
|
117
180
|
int blocking = (c->flags & REDIS_BLOCK);
|
118
181
|
struct sockaddr_in sa;
|
119
182
|
|
120
|
-
if ((s = redisCreateSocket(c,AF_INET))
|
183
|
+
if ((s = redisCreateSocket(c,AF_INET)) < 0)
|
121
184
|
return REDIS_ERR;
|
122
|
-
if (
|
185
|
+
if (redisSetBlocking(c,s,0) != REDIS_OK)
|
123
186
|
return REDIS_ERR;
|
124
187
|
|
125
188
|
sa.sin_family = AF_INET;
|
@@ -141,30 +204,31 @@ int redisContextConnectTcp(redisContext *c, const char *addr, int port) {
|
|
141
204
|
if (errno == EINPROGRESS && !blocking) {
|
142
205
|
/* This is ok. */
|
143
206
|
} else {
|
144
|
-
|
145
|
-
|
146
|
-
return REDIS_ERR;
|
207
|
+
if (redisContextWaitReady(c,s,timeout) != REDIS_OK)
|
208
|
+
return REDIS_ERR;
|
147
209
|
}
|
148
210
|
}
|
149
211
|
|
150
|
-
|
151
|
-
|
212
|
+
/* Reset socket to be blocking after connect(2). */
|
213
|
+
if (blocking && redisSetBlocking(c,s,1) != REDIS_OK)
|
214
|
+
return REDIS_ERR;
|
215
|
+
|
216
|
+
if (redisSetTcpNoDelay(c,s) != REDIS_OK)
|
152
217
|
return REDIS_ERR;
|
153
|
-
}
|
154
218
|
|
155
219
|
c->fd = s;
|
156
220
|
c->flags |= REDIS_CONNECTED;
|
157
221
|
return REDIS_OK;
|
158
222
|
}
|
159
223
|
|
160
|
-
int redisContextConnectUnix(redisContext *c, const char *path) {
|
224
|
+
int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout) {
|
161
225
|
int s;
|
162
226
|
int blocking = (c->flags & REDIS_BLOCK);
|
163
227
|
struct sockaddr_un sa;
|
164
228
|
|
165
|
-
if ((s = redisCreateSocket(c,AF_LOCAL))
|
229
|
+
if ((s = redisCreateSocket(c,AF_LOCAL)) < 0)
|
166
230
|
return REDIS_ERR;
|
167
|
-
if (
|
231
|
+
if (redisSetBlocking(c,s,0) != REDIS_OK)
|
168
232
|
return REDIS_ERR;
|
169
233
|
|
170
234
|
sa.sun_family = AF_LOCAL;
|
@@ -173,12 +237,15 @@ int redisContextConnectUnix(redisContext *c, const char *path) {
|
|
173
237
|
if (errno == EINPROGRESS && !blocking) {
|
174
238
|
/* This is ok. */
|
175
239
|
} else {
|
176
|
-
|
177
|
-
|
178
|
-
return REDIS_ERR;
|
240
|
+
if (redisContextWaitReady(c,s,timeout) != REDIS_OK)
|
241
|
+
return REDIS_ERR;
|
179
242
|
}
|
180
243
|
}
|
181
244
|
|
245
|
+
/* Reset socket to be blocking after connect(2). */
|
246
|
+
if (blocking && redisSetBlocking(c,s,1) != REDIS_OK)
|
247
|
+
return REDIS_ERR;
|
248
|
+
|
182
249
|
c->fd = s;
|
183
250
|
c->flags |= REDIS_CONNECTED;
|
184
251
|
return REDIS_OK;
|
data/vendor/hiredis/net.h
CHANGED
@@ -40,7 +40,7 @@
|
|
40
40
|
#endif
|
41
41
|
|
42
42
|
int redisContextSetTimeout(redisContext *c, struct timeval tv);
|
43
|
-
int redisContextConnectTcp(redisContext *c, const char *addr, int port);
|
44
|
-
int redisContextConnectUnix(redisContext *c, const char *path);
|
43
|
+
int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout);
|
44
|
+
int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout);
|
45
45
|
|
46
46
|
#endif
|
data/vendor/hiredis/sds.c
CHANGED
@@ -115,6 +115,25 @@ static sds sdsMakeRoomFor(sds s, size_t addlen) {
|
|
115
115
|
return newsh->buf;
|
116
116
|
}
|
117
117
|
|
118
|
+
/* Grow the sds to have the specified length. Bytes that were not part of
|
119
|
+
* the original length of the sds will be set to zero. */
|
120
|
+
sds sdsgrowzero(sds s, size_t len) {
|
121
|
+
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
|
122
|
+
size_t totlen, curlen = sh->len;
|
123
|
+
|
124
|
+
if (len <= curlen) return s;
|
125
|
+
s = sdsMakeRoomFor(s,len-curlen);
|
126
|
+
if (s == NULL) return NULL;
|
127
|
+
|
128
|
+
/* Make sure added region doesn't contain garbage */
|
129
|
+
sh = (void*)(s-(sizeof(struct sdshdr)));
|
130
|
+
memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
|
131
|
+
totlen = sh->len+sh->free;
|
132
|
+
sh->len = len;
|
133
|
+
sh->free = totlen-sh->len;
|
134
|
+
return s;
|
135
|
+
}
|
136
|
+
|
118
137
|
sds sdscatlen(sds s, const void *t, size_t len) {
|
119
138
|
struct sdshdr *sh;
|
120
139
|
size_t curlen = sdslen(s);
|
@@ -222,13 +241,16 @@ sds sdsrange(sds s, int start, int end) {
|
|
222
241
|
}
|
223
242
|
newlen = (start > end) ? 0 : (end-start)+1;
|
224
243
|
if (newlen != 0) {
|
225
|
-
if (start >= (signed)len)
|
226
|
-
|
227
|
-
|
244
|
+
if (start >= (signed)len) {
|
245
|
+
newlen = 0;
|
246
|
+
} else if (end >= (signed)len) {
|
247
|
+
end = len-1;
|
248
|
+
newlen = (start > end) ? 0 : (end-start)+1;
|
249
|
+
}
|
228
250
|
} else {
|
229
251
|
start = 0;
|
230
252
|
}
|
231
|
-
if (start
|
253
|
+
if (start && newlen) memmove(sh->buf, sh->buf+start, newlen);
|
232
254
|
sh->buf[newlen] = 0;
|
233
255
|
sh->free = sh->free+(sh->len-newlen);
|
234
256
|
sh->len = newlen;
|
@@ -477,3 +499,106 @@ err:
|
|
477
499
|
if (current) sdsfree(current);
|
478
500
|
return NULL;
|
479
501
|
}
|
502
|
+
|
503
|
+
#ifdef SDS_TEST_MAIN
|
504
|
+
#include <stdio.h>
|
505
|
+
|
506
|
+
int __failed_tests = 0;
|
507
|
+
int __test_num = 0;
|
508
|
+
#define test_cond(descr,_c) do { \
|
509
|
+
__test_num++; printf("%d - %s: ", __test_num, descr); \
|
510
|
+
if(_c) printf("PASSED\n"); else {printf("FAILED\n"); __failed_tests++;} \
|
511
|
+
} while(0);
|
512
|
+
#define test_report() do { \
|
513
|
+
printf("%d tests, %d passed, %d failed\n", __test_num, \
|
514
|
+
__test_num-__failed_tests, __failed_tests); \
|
515
|
+
if (__failed_tests) { \
|
516
|
+
printf("=== WARNING === We have failed tests here...\n"); \
|
517
|
+
} \
|
518
|
+
} while(0);
|
519
|
+
|
520
|
+
int main(void) {
|
521
|
+
{
|
522
|
+
sds x = sdsnew("foo"), y;
|
523
|
+
|
524
|
+
test_cond("Create a string and obtain the length",
|
525
|
+
sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
|
526
|
+
|
527
|
+
sdsfree(x);
|
528
|
+
x = sdsnewlen("foo",2);
|
529
|
+
test_cond("Create a string with specified length",
|
530
|
+
sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
|
531
|
+
|
532
|
+
x = sdscat(x,"bar");
|
533
|
+
test_cond("Strings concatenation",
|
534
|
+
sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
|
535
|
+
|
536
|
+
x = sdscpy(x,"a");
|
537
|
+
test_cond("sdscpy() against an originally longer string",
|
538
|
+
sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
|
539
|
+
|
540
|
+
x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
|
541
|
+
test_cond("sdscpy() against an originally shorter string",
|
542
|
+
sdslen(x) == 33 &&
|
543
|
+
memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
|
544
|
+
|
545
|
+
sdsfree(x);
|
546
|
+
x = sdscatprintf(sdsempty(),"%d",123);
|
547
|
+
test_cond("sdscatprintf() seems working in the base case",
|
548
|
+
sdslen(x) == 3 && memcmp(x,"123\0",4) ==0)
|
549
|
+
|
550
|
+
sdsfree(x);
|
551
|
+
x = sdstrim(sdsnew("xxciaoyyy"),"xy");
|
552
|
+
test_cond("sdstrim() correctly trims characters",
|
553
|
+
sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
|
554
|
+
|
555
|
+
y = sdsrange(sdsdup(x),1,1);
|
556
|
+
test_cond("sdsrange(...,1,1)",
|
557
|
+
sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
|
558
|
+
|
559
|
+
sdsfree(y);
|
560
|
+
y = sdsrange(sdsdup(x),1,-1);
|
561
|
+
test_cond("sdsrange(...,1,-1)",
|
562
|
+
sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
|
563
|
+
|
564
|
+
sdsfree(y);
|
565
|
+
y = sdsrange(sdsdup(x),-2,-1);
|
566
|
+
test_cond("sdsrange(...,-2,-1)",
|
567
|
+
sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
|
568
|
+
|
569
|
+
sdsfree(y);
|
570
|
+
y = sdsrange(sdsdup(x),2,1);
|
571
|
+
test_cond("sdsrange(...,2,1)",
|
572
|
+
sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
|
573
|
+
|
574
|
+
sdsfree(y);
|
575
|
+
y = sdsrange(sdsdup(x),1,100);
|
576
|
+
test_cond("sdsrange(...,1,100)",
|
577
|
+
sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
|
578
|
+
|
579
|
+
sdsfree(y);
|
580
|
+
y = sdsrange(sdsdup(x),100,100);
|
581
|
+
test_cond("sdsrange(...,100,100)",
|
582
|
+
sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
|
583
|
+
|
584
|
+
sdsfree(y);
|
585
|
+
sdsfree(x);
|
586
|
+
x = sdsnew("foo");
|
587
|
+
y = sdsnew("foa");
|
588
|
+
test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
|
589
|
+
|
590
|
+
sdsfree(y);
|
591
|
+
sdsfree(x);
|
592
|
+
x = sdsnew("bar");
|
593
|
+
y = sdsnew("bar");
|
594
|
+
test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
|
595
|
+
|
596
|
+
sdsfree(y);
|
597
|
+
sdsfree(x);
|
598
|
+
x = sdsnew("aar");
|
599
|
+
y = sdsnew("bar");
|
600
|
+
test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
|
601
|
+
}
|
602
|
+
test_report()
|
603
|
+
}
|
604
|
+
#endif
|