read.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. /*
  2. * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
  3. * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * * Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * * Neither the name of Redis nor the names of its contributors may be used
  16. * to endorse or promote products derived from this software without
  17. * specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include "fmacros.h"
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #ifndef _MSC_VER
  35. #include <unistd.h>
  36. #include <strings.h>
  37. #endif
  38. #include <assert.h>
  39. #include <errno.h>
  40. #include <ctype.h>
  41. #include <limits.h>
  42. #include <math.h>
  43. #include "alloc.h"
  44. #include "read.h"
  45. #include "sds.h"
  46. #include "win32.h"
  47. /* Initial size of our nested reply stack and how much we grow it when needd */
  48. #define REDIS_READER_STACK_SIZE 9
  49. static void __redisReaderSetError(redisReader *r, int type, const char *str) {
  50. size_t len;
  51. if (r->reply != NULL && r->fn && r->fn->freeObject) {
  52. r->fn->freeObject(r->reply);
  53. r->reply = NULL;
  54. }
  55. /* Clear input buffer on errors. */
  56. hi_sdsfree(r->buf);
  57. r->buf = NULL;
  58. r->pos = r->len = 0;
  59. /* Reset task stack. */
  60. r->ridx = -1;
  61. /* Set error. */
  62. r->err = type;
  63. len = strlen(str);
  64. len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1);
  65. memcpy(r->errstr,str,len);
  66. r->errstr[len] = '\0';
  67. }
  68. static size_t chrtos(char *buf, size_t size, char byte) {
  69. size_t len = 0;
  70. switch(byte) {
  71. case '\\':
  72. case '"':
  73. len = snprintf(buf,size,"\"\\%c\"",byte);
  74. break;
  75. case '\n': len = snprintf(buf,size,"\"\\n\""); break;
  76. case '\r': len = snprintf(buf,size,"\"\\r\""); break;
  77. case '\t': len = snprintf(buf,size,"\"\\t\""); break;
  78. case '\a': len = snprintf(buf,size,"\"\\a\""); break;
  79. case '\b': len = snprintf(buf,size,"\"\\b\""); break;
  80. default:
  81. if (isprint(byte))
  82. len = snprintf(buf,size,"\"%c\"",byte);
  83. else
  84. len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte);
  85. break;
  86. }
  87. return len;
  88. }
  89. static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) {
  90. char cbuf[8], sbuf[128];
  91. chrtos(cbuf,sizeof(cbuf),byte);
  92. snprintf(sbuf,sizeof(sbuf),
  93. "Protocol error, got %s as reply type byte", cbuf);
  94. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf);
  95. }
  96. static void __redisReaderSetErrorOOM(redisReader *r) {
  97. __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory");
  98. }
  99. static char *readBytes(redisReader *r, unsigned int bytes) {
  100. char *p;
  101. if (r->len-r->pos >= bytes) {
  102. p = r->buf+r->pos;
  103. r->pos += bytes;
  104. return p;
  105. }
  106. return NULL;
  107. }
  108. /* Find pointer to \r\n. */
  109. static char *seekNewline(char *s, size_t len) {
  110. int pos = 0;
  111. int _len = len-1;
  112. /* Position should be < len-1 because the character at "pos" should be
  113. * followed by a \n. Note that strchr cannot be used because it doesn't
  114. * allow to search a limited length and the buffer that is being searched
  115. * might not have a trailing NULL character. */
  116. while (pos < _len) {
  117. while(pos < _len && s[pos] != '\r') pos++;
  118. if (pos==_len) {
  119. /* Not found. */
  120. return NULL;
  121. } else {
  122. if (s[pos+1] == '\n') {
  123. /* Found. */
  124. return s+pos;
  125. } else {
  126. /* Continue searching. */
  127. pos++;
  128. }
  129. }
  130. }
  131. return NULL;
  132. }
  133. /* Convert a string into a long long. Returns REDIS_OK if the string could be
  134. * parsed into a (non-overflowing) long long, REDIS_ERR otherwise. The value
  135. * will be set to the parsed value when appropriate.
  136. *
  137. * Note that this function demands that the string strictly represents
  138. * a long long: no spaces or other characters before or after the string
  139. * representing the number are accepted, nor zeroes at the start if not
  140. * for the string "0" representing the zero number.
  141. *
  142. * Because of its strictness, it is safe to use this function to check if
  143. * you can convert a string into a long long, and obtain back the string
  144. * from the number without any loss in the string representation. */
  145. static int string2ll(const char *s, size_t slen, long long *value) {
  146. const char *p = s;
  147. size_t plen = 0;
  148. int negative = 0;
  149. unsigned long long v;
  150. if (plen == slen)
  151. return REDIS_ERR;
  152. /* Special case: first and only digit is 0. */
  153. if (slen == 1 && p[0] == '0') {
  154. if (value != NULL) *value = 0;
  155. return REDIS_OK;
  156. }
  157. if (p[0] == '-') {
  158. negative = 1;
  159. p++; plen++;
  160. /* Abort on only a negative sign. */
  161. if (plen == slen)
  162. return REDIS_ERR;
  163. }
  164. /* First digit should be 1-9, otherwise the string should just be 0. */
  165. if (p[0] >= '1' && p[0] <= '9') {
  166. v = p[0]-'0';
  167. p++; plen++;
  168. } else if (p[0] == '0' && slen == 1) {
  169. *value = 0;
  170. return REDIS_OK;
  171. } else {
  172. return REDIS_ERR;
  173. }
  174. while (plen < slen && p[0] >= '0' && p[0] <= '9') {
  175. if (v > (ULLONG_MAX / 10)) /* Overflow. */
  176. return REDIS_ERR;
  177. v *= 10;
  178. if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */
  179. return REDIS_ERR;
  180. v += p[0]-'0';
  181. p++; plen++;
  182. }
  183. /* Return if not all bytes were used. */
  184. if (plen < slen)
  185. return REDIS_ERR;
  186. if (negative) {
  187. if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */
  188. return REDIS_ERR;
  189. if (value != NULL) *value = -v;
  190. } else {
  191. if (v > LLONG_MAX) /* Overflow. */
  192. return REDIS_ERR;
  193. if (value != NULL) *value = v;
  194. }
  195. return REDIS_OK;
  196. }
  197. static char *readLine(redisReader *r, int *_len) {
  198. char *p, *s;
  199. int len;
  200. p = r->buf+r->pos;
  201. s = seekNewline(p,(r->len-r->pos));
  202. if (s != NULL) {
  203. len = s-(r->buf+r->pos);
  204. r->pos += len+2; /* skip \r\n */
  205. if (_len) *_len = len;
  206. return p;
  207. }
  208. return NULL;
  209. }
  210. static void moveToNextTask(redisReader *r) {
  211. redisReadTask *cur, *prv;
  212. while (r->ridx >= 0) {
  213. /* Return a.s.a.p. when the stack is now empty. */
  214. if (r->ridx == 0) {
  215. r->ridx--;
  216. return;
  217. }
  218. cur = r->task[r->ridx];
  219. prv = r->task[r->ridx-1];
  220. assert(prv->type == REDIS_REPLY_ARRAY ||
  221. prv->type == REDIS_REPLY_MAP ||
  222. prv->type == REDIS_REPLY_SET ||
  223. prv->type == REDIS_REPLY_PUSH);
  224. if (cur->idx == prv->elements-1) {
  225. r->ridx--;
  226. } else {
  227. /* Reset the type because the next item can be anything */
  228. assert(cur->idx < prv->elements);
  229. cur->type = -1;
  230. cur->elements = -1;
  231. cur->idx++;
  232. return;
  233. }
  234. }
  235. }
  236. static int processLineItem(redisReader *r) {
  237. redisReadTask *cur = r->task[r->ridx];
  238. void *obj;
  239. char *p;
  240. int len;
  241. if ((p = readLine(r,&len)) != NULL) {
  242. if (cur->type == REDIS_REPLY_INTEGER) {
  243. if (r->fn && r->fn->createInteger) {
  244. long long v;
  245. if (string2ll(p, len, &v) == REDIS_ERR) {
  246. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  247. "Bad integer value");
  248. return REDIS_ERR;
  249. }
  250. obj = r->fn->createInteger(cur,v);
  251. } else {
  252. obj = (void*)REDIS_REPLY_INTEGER;
  253. }
  254. } else if (cur->type == REDIS_REPLY_DOUBLE) {
  255. if (r->fn && r->fn->createDouble) {
  256. char buf[326], *eptr;
  257. double d;
  258. if ((size_t)len >= sizeof(buf)) {
  259. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  260. "Double value is too large");
  261. return REDIS_ERR;
  262. }
  263. memcpy(buf,p,len);
  264. buf[len] = '\0';
  265. if (strcasecmp(buf,",inf") == 0) {
  266. d = INFINITY; /* Positive infinite. */
  267. } else if (strcasecmp(buf,",-inf") == 0) {
  268. d = -INFINITY; /* Negative infinite. */
  269. } else {
  270. d = strtod((char*)buf,&eptr);
  271. if (buf[0] == '\0' || eptr[0] != '\0' || isnan(d)) {
  272. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  273. "Bad double value");
  274. return REDIS_ERR;
  275. }
  276. }
  277. obj = r->fn->createDouble(cur,d,buf,len);
  278. } else {
  279. obj = (void*)REDIS_REPLY_DOUBLE;
  280. }
  281. } else if (cur->type == REDIS_REPLY_NIL) {
  282. if (r->fn && r->fn->createNil)
  283. obj = r->fn->createNil(cur);
  284. else
  285. obj = (void*)REDIS_REPLY_NIL;
  286. } else if (cur->type == REDIS_REPLY_BOOL) {
  287. int bval = p[0] == 't' || p[0] == 'T';
  288. if (r->fn && r->fn->createBool)
  289. obj = r->fn->createBool(cur,bval);
  290. else
  291. obj = (void*)REDIS_REPLY_BOOL;
  292. } else {
  293. /* Type will be error or status. */
  294. if (r->fn && r->fn->createString)
  295. obj = r->fn->createString(cur,p,len);
  296. else
  297. obj = (void*)(size_t)(cur->type);
  298. }
  299. if (obj == NULL) {
  300. __redisReaderSetErrorOOM(r);
  301. return REDIS_ERR;
  302. }
  303. /* Set reply if this is the root object. */
  304. if (r->ridx == 0) r->reply = obj;
  305. moveToNextTask(r);
  306. return REDIS_OK;
  307. }
  308. return REDIS_ERR;
  309. }
  310. static int processBulkItem(redisReader *r) {
  311. redisReadTask *cur = r->task[r->ridx];
  312. void *obj = NULL;
  313. char *p, *s;
  314. long long len;
  315. unsigned long bytelen;
  316. int success = 0;
  317. p = r->buf+r->pos;
  318. s = seekNewline(p,r->len-r->pos);
  319. if (s != NULL) {
  320. p = r->buf+r->pos;
  321. bytelen = s-(r->buf+r->pos)+2; /* include \r\n */
  322. if (string2ll(p, bytelen - 2, &len) == REDIS_ERR) {
  323. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  324. "Bad bulk string length");
  325. return REDIS_ERR;
  326. }
  327. if (len < -1 || (LLONG_MAX > SIZE_MAX && len > (long long)SIZE_MAX)) {
  328. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  329. "Bulk string length out of range");
  330. return REDIS_ERR;
  331. }
  332. if (len == -1) {
  333. /* The nil object can always be created. */
  334. if (r->fn && r->fn->createNil)
  335. obj = r->fn->createNil(cur);
  336. else
  337. obj = (void*)REDIS_REPLY_NIL;
  338. success = 1;
  339. } else {
  340. /* Only continue when the buffer contains the entire bulk item. */
  341. bytelen += len+2; /* include \r\n */
  342. if (r->pos+bytelen <= r->len) {
  343. if ((cur->type == REDIS_REPLY_VERB && len < 4) ||
  344. (cur->type == REDIS_REPLY_VERB && s[5] != ':'))
  345. {
  346. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  347. "Verbatim string 4 bytes of content type are "
  348. "missing or incorrectly encoded.");
  349. return REDIS_ERR;
  350. }
  351. if (r->fn && r->fn->createString)
  352. obj = r->fn->createString(cur,s+2,len);
  353. else
  354. obj = (void*)(long)cur->type;
  355. success = 1;
  356. }
  357. }
  358. /* Proceed when obj was created. */
  359. if (success) {
  360. if (obj == NULL) {
  361. __redisReaderSetErrorOOM(r);
  362. return REDIS_ERR;
  363. }
  364. r->pos += bytelen;
  365. /* Set reply if this is the root object. */
  366. if (r->ridx == 0) r->reply = obj;
  367. moveToNextTask(r);
  368. return REDIS_OK;
  369. }
  370. }
  371. return REDIS_ERR;
  372. }
  373. static int redisReaderGrow(redisReader *r) {
  374. redisReadTask **aux;
  375. int newlen;
  376. /* Grow our stack size */
  377. newlen = r->tasks + REDIS_READER_STACK_SIZE;
  378. aux = hi_realloc(r->task, sizeof(*r->task) * newlen);
  379. if (aux == NULL)
  380. goto oom;
  381. r->task = aux;
  382. /* Allocate new tasks */
  383. for (; r->tasks < newlen; r->tasks++) {
  384. r->task[r->tasks] = hi_calloc(1, sizeof(**r->task));
  385. if (r->task[r->tasks] == NULL)
  386. goto oom;
  387. }
  388. return REDIS_OK;
  389. oom:
  390. __redisReaderSetErrorOOM(r);
  391. return REDIS_ERR;
  392. }
  393. /* Process the array, map and set types. */
  394. static int processAggregateItem(redisReader *r) {
  395. redisReadTask *cur = r->task[r->ridx];
  396. void *obj;
  397. char *p;
  398. long long elements;
  399. int root = 0, len;
  400. /* Set error for nested multi bulks with depth > 7 */
  401. if (r->ridx == r->tasks - 1) {
  402. if (redisReaderGrow(r) == REDIS_ERR)
  403. return REDIS_ERR;
  404. }
  405. if ((p = readLine(r,&len)) != NULL) {
  406. if (string2ll(p, len, &elements) == REDIS_ERR) {
  407. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  408. "Bad multi-bulk length");
  409. return REDIS_ERR;
  410. }
  411. root = (r->ridx == 0);
  412. if (elements < -1 || (LLONG_MAX > SIZE_MAX && elements > SIZE_MAX) ||
  413. (r->maxelements > 0 && elements > r->maxelements))
  414. {
  415. __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
  416. "Multi-bulk length out of range");
  417. return REDIS_ERR;
  418. }
  419. if (elements == -1) {
  420. if (r->fn && r->fn->createNil)
  421. obj = r->fn->createNil(cur);
  422. else
  423. obj = (void*)REDIS_REPLY_NIL;
  424. if (obj == NULL) {
  425. __redisReaderSetErrorOOM(r);
  426. return REDIS_ERR;
  427. }
  428. moveToNextTask(r);
  429. } else {
  430. if (cur->type == REDIS_REPLY_MAP) elements *= 2;
  431. if (r->fn && r->fn->createArray)
  432. obj = r->fn->createArray(cur,elements);
  433. else
  434. obj = (void*)(long)cur->type;
  435. if (obj == NULL) {
  436. __redisReaderSetErrorOOM(r);
  437. return REDIS_ERR;
  438. }
  439. /* Modify task stack when there are more than 0 elements. */
  440. if (elements > 0) {
  441. cur->elements = elements;
  442. cur->obj = obj;
  443. r->ridx++;
  444. r->task[r->ridx]->type = -1;
  445. r->task[r->ridx]->elements = -1;
  446. r->task[r->ridx]->idx = 0;
  447. r->task[r->ridx]->obj = NULL;
  448. r->task[r->ridx]->parent = cur;
  449. r->task[r->ridx]->privdata = r->privdata;
  450. } else {
  451. moveToNextTask(r);
  452. }
  453. }
  454. /* Set reply if this is the root object. */
  455. if (root) r->reply = obj;
  456. return REDIS_OK;
  457. }
  458. return REDIS_ERR;
  459. }
  460. static int processItem(redisReader *r) {
  461. redisReadTask *cur = r->task[r->ridx];
  462. char *p;
  463. /* check if we need to read type */
  464. if (cur->type < 0) {
  465. if ((p = readBytes(r,1)) != NULL) {
  466. switch (p[0]) {
  467. case '-':
  468. cur->type = REDIS_REPLY_ERROR;
  469. break;
  470. case '+':
  471. cur->type = REDIS_REPLY_STATUS;
  472. break;
  473. case ':':
  474. cur->type = REDIS_REPLY_INTEGER;
  475. break;
  476. case ',':
  477. cur->type = REDIS_REPLY_DOUBLE;
  478. break;
  479. case '_':
  480. cur->type = REDIS_REPLY_NIL;
  481. break;
  482. case '$':
  483. cur->type = REDIS_REPLY_STRING;
  484. break;
  485. case '*':
  486. cur->type = REDIS_REPLY_ARRAY;
  487. break;
  488. case '%':
  489. cur->type = REDIS_REPLY_MAP;
  490. break;
  491. case '~':
  492. cur->type = REDIS_REPLY_SET;
  493. break;
  494. case '#':
  495. cur->type = REDIS_REPLY_BOOL;
  496. break;
  497. case '=':
  498. cur->type = REDIS_REPLY_VERB;
  499. break;
  500. case '>':
  501. cur->type = REDIS_REPLY_PUSH;
  502. break;
  503. default:
  504. __redisReaderSetErrorProtocolByte(r,*p);
  505. return REDIS_ERR;
  506. }
  507. } else {
  508. /* could not consume 1 byte */
  509. return REDIS_ERR;
  510. }
  511. }
  512. /* process typed item */
  513. switch(cur->type) {
  514. case REDIS_REPLY_ERROR:
  515. case REDIS_REPLY_STATUS:
  516. case REDIS_REPLY_INTEGER:
  517. case REDIS_REPLY_DOUBLE:
  518. case REDIS_REPLY_NIL:
  519. case REDIS_REPLY_BOOL:
  520. return processLineItem(r);
  521. case REDIS_REPLY_STRING:
  522. case REDIS_REPLY_VERB:
  523. return processBulkItem(r);
  524. case REDIS_REPLY_ARRAY:
  525. case REDIS_REPLY_MAP:
  526. case REDIS_REPLY_SET:
  527. case REDIS_REPLY_PUSH:
  528. return processAggregateItem(r);
  529. default:
  530. assert(NULL);
  531. return REDIS_ERR; /* Avoid warning. */
  532. }
  533. }
  534. redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) {
  535. redisReader *r;
  536. r = hi_calloc(1,sizeof(redisReader));
  537. if (r == NULL)
  538. return NULL;
  539. r->buf = hi_sdsempty();
  540. if (r->buf == NULL)
  541. goto oom;
  542. r->task = hi_calloc(REDIS_READER_STACK_SIZE, sizeof(*r->task));
  543. if (r->task == NULL)
  544. goto oom;
  545. for (; r->tasks < REDIS_READER_STACK_SIZE; r->tasks++) {
  546. r->task[r->tasks] = hi_calloc(1, sizeof(**r->task));
  547. if (r->task[r->tasks] == NULL)
  548. goto oom;
  549. }
  550. r->fn = fn;
  551. r->maxbuf = REDIS_READER_MAX_BUF;
  552. r->maxelements = REDIS_READER_MAX_ARRAY_ELEMENTS;
  553. r->ridx = -1;
  554. return r;
  555. oom:
  556. redisReaderFree(r);
  557. return NULL;
  558. }
  559. void redisReaderFree(redisReader *r) {
  560. if (r == NULL)
  561. return;
  562. if (r->reply != NULL && r->fn && r->fn->freeObject)
  563. r->fn->freeObject(r->reply);
  564. if (r->task) {
  565. /* We know r->task[i] is allocated if i < r->tasks */
  566. for (int i = 0; i < r->tasks; i++) {
  567. hi_free(r->task[i]);
  568. }
  569. hi_free(r->task);
  570. }
  571. hi_sdsfree(r->buf);
  572. hi_free(r);
  573. }
  574. int redisReaderFeed(redisReader *r, const char *buf, size_t len) {
  575. hisds newbuf;
  576. /* Return early when this reader is in an erroneous state. */
  577. if (r->err)
  578. return REDIS_ERR;
  579. /* Copy the provided buffer. */
  580. if (buf != NULL && len >= 1) {
  581. /* Destroy internal buffer when it is empty and is quite large. */
  582. if (r->len == 0 && r->maxbuf != 0 && hi_sdsavail(r->buf) > r->maxbuf) {
  583. hi_sdsfree(r->buf);
  584. r->buf = hi_sdsempty();
  585. if (r->buf == 0) goto oom;
  586. r->pos = 0;
  587. }
  588. newbuf = hi_sdscatlen(r->buf,buf,len);
  589. if (newbuf == NULL) goto oom;
  590. r->buf = newbuf;
  591. r->len = hi_sdslen(r->buf);
  592. }
  593. return REDIS_OK;
  594. oom:
  595. __redisReaderSetErrorOOM(r);
  596. return REDIS_ERR;
  597. }
  598. int redisReaderGetReply(redisReader *r, void **reply) {
  599. /* Default target pointer to NULL. */
  600. if (reply != NULL)
  601. *reply = NULL;
  602. /* Return early when this reader is in an erroneous state. */
  603. if (r->err)
  604. return REDIS_ERR;
  605. /* When the buffer is empty, there will never be a reply. */
  606. if (r->len == 0)
  607. return REDIS_OK;
  608. /* Set first item to process when the stack is empty. */
  609. if (r->ridx == -1) {
  610. r->task[0]->type = -1;
  611. r->task[0]->elements = -1;
  612. r->task[0]->idx = -1;
  613. r->task[0]->obj = NULL;
  614. r->task[0]->parent = NULL;
  615. r->task[0]->privdata = r->privdata;
  616. r->ridx = 0;
  617. }
  618. /* Process items in reply. */
  619. while (r->ridx >= 0)
  620. if (processItem(r) != REDIS_OK)
  621. break;
  622. /* Return ASAP when an error occurred. */
  623. if (r->err)
  624. return REDIS_ERR;
  625. /* Discard part of the buffer when we've consumed at least 1k, to avoid
  626. * doing unnecessary calls to memmove() in sds.c. */
  627. if (r->pos >= 1024) {
  628. if (hi_sdsrange(r->buf,r->pos,-1) < 0) return REDIS_ERR;
  629. r->pos = 0;
  630. r->len = hi_sdslen(r->buf);
  631. }
  632. /* Emit a reply when there is one. */
  633. if (r->ridx == -1) {
  634. if (reply != NULL) {
  635. *reply = r->reply;
  636. } else if (r->reply != NULL && r->fn && r->fn->freeObject) {
  637. r->fn->freeObject(r->reply);
  638. }
  639. r->reply = NULL;
  640. }
  641. return REDIS_OK;
  642. }