Commit a866667f authored by Pieter Noordhuis's avatar Pieter Noordhuis
Browse files

Add total bulk/multi bulk size to protocol_t

parent b852caf3
...@@ -28,8 +28,8 @@ ...@@ -28,8 +28,8 @@
__tmp->coff = 0; \ __tmp->coff = 0; \
__tmp->clen = 0; \ __tmp->clen = 0; \
__tmp->type = 0; \ __tmp->type = 0; \
__tmp->remaining = -1; \ __tmp->size = -1; \
__tmp->cursor = 0; \ __tmp->cursor = -1; \
__tmp->data = NULL; \ __tmp->data = NULL; \
} while(0) } while(0)
...@@ -199,9 +199,11 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -199,9 +199,11 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
ADVANCE_AND_MOVE(integer_start); ADVANCE_AND_MOVE(integer_start);
case '+': case '+':
cur->type = REDIS_STATUS_T; cur->type = REDIS_STATUS_T;
cur->cursor = 0;
ADVANCE_AND_MOVE(line); ADVANCE_AND_MOVE(line);
case '-': case '-':
cur->type = REDIS_ERROR_T; cur->type = REDIS_ERROR_T;
cur->cursor = 0;
ADVANCE_AND_MOVE(line); ADVANCE_AND_MOVE(line);
} }
...@@ -341,8 +343,9 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -341,8 +343,9 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
cur->clen = (unsigned)i64.i64; cur->clen = (unsigned)i64.i64;
cur->plen += cur->clen + 2; /* include \r\n */ cur->plen += cur->clen + 2; /* include \r\n */
/* Store remaining bytes for a complete bulk */ /* Store size of complete bulk */
cur->remaining = (unsigned)i64.i64; cur->size = (unsigned)i64.i64;
cur->cursor = 0;
ADVANCE_AND_MOVE(bulk); ADVANCE_AND_MOVE(bulk);
} }
...@@ -353,10 +356,10 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -353,10 +356,10 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
goto done; goto done;
} }
/* Store remaining objects for a complete multi bulk */ /* Store size of complete multi bulk */
cur->remaining = (unsigned)i64.i64; cur->size = (unsigned)i64.i64;
cur->cursor = -1; /* Is incremented in "done" */ cur->cursor = 0;
CALLBACK(array, cur, cur->remaining); CALLBACK(array, cur, cur->size);
goto done; goto done;
} }
...@@ -372,19 +375,17 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -372,19 +375,17 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
} }
STATE(bulk) { STATE(bulk) {
size_t remaining = cur->remaining; size_t remaining = cur->size - cur->cursor;
size_t available = (end-pos); size_t available = (end-pos);
/* Everything can be read */ /* Everything can be read */
if (remaining <= available) { if (remaining <= available) {
cur->remaining = 0;
CALLBACK(string, cur, pos, remaining); CALLBACK(string, cur, pos, remaining);
ADVANCE(remaining); ADVANCE(remaining);
MOVE(bulk_cr); MOVE(bulk_cr);
} }
/* Not everything can be read */ /* Not everything can be read */
cur->remaining -= available;
CALLBACK(string, cur, pos, available); CALLBACK(string, cur, pos, available);
ADVANCE(available); ADVANCE(available);
...@@ -453,10 +454,9 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -453,10 +454,9 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
/* Message is done when root object is done */ /* Message is done when root object is done */
do { do {
/* Move to nested object when we see an incomplete array */ /* Move to nested object when we see an incomplete array */
if (cur->type == REDIS_ARRAY_T && cur->remaining) { if (cur->type == REDIS_ARRAY_T && (cur->cursor < cur->size)) {
RESET_PROTOCOL_T(&stack[++stackidx]); RESET_PROTOCOL_T(&stack[++stackidx]);
cur->cursor++; cur->cursor++;
cur->remaining--;
break; break;
} }
......
...@@ -54,8 +54,8 @@ struct redis_protocol_s { ...@@ -54,8 +54,8 @@ struct redis_protocol_s {
unsigned char type; /* payload type */ unsigned char type; /* payload type */
void *data; /* payload data (to be populated by the callback functions) */ void *data; /* payload data (to be populated by the callback functions) */
const redis_protocol_t* parent; /* when nested, parent object */ const redis_protocol_t* parent; /* when nested, parent object */
int remaining; /* remaining bulk bytes/nested objects */ int size; /* size of complete bulk (bytes)/multi bulk (nested objects) */
int cursor; /* number of processed bulk bytes/nested objects */ int cursor; /* number of processed bytes/nested objects */
size_t poff; /* protocol offset */ size_t poff; /* protocol offset */
size_t plen; /* protocol length */ size_t plen; /* protocol length */
size_t coff; /* content offset */ size_t coff; /* content offset */
......
...@@ -47,6 +47,7 @@ struct log_entry_s { ...@@ -47,6 +47,7 @@ struct log_entry_s {
/* string_t specifics */ /* string_t specifics */
char string_buf[1024]; char string_buf[1024];
int string_size;
/* array_t specifics */ /* array_t specifics */
size_t array_len; size_t array_len;
...@@ -79,6 +80,7 @@ int on_string(redis_parser_t *parser, redis_protocol_t *p, const char *buf, size ...@@ -79,6 +80,7 @@ int on_string(redis_parser_t *parser, redis_protocol_t *p, const char *buf, size
log->obj = *p; log->obj = *p;
log->type = p->type; log->type = p->type;
log->string_buf[0] = '\0'; log->string_buf[0] = '\0';
log->string_size = p->size;
} }
/* Type should never change when called multiple times */ /* Type should never change when called multiple times */
...@@ -219,6 +221,7 @@ void test_string(redis_parser_t *p) { ...@@ -219,6 +221,7 @@ void test_string(redis_parser_t *p) {
/* Check callbacks */ /* Check callbacks */
assert(cb_log_idx == 1); assert(cb_log_idx == 1);
assert_equal_int(cb_log[0].string_size, 5);
assert(!strncmp(cb_log[0].string_buf, buf+4, 5)); assert(!strncmp(cb_log[0].string_buf, buf+4, 5));
/* Chunked check */ /* Chunked check */
...@@ -242,6 +245,7 @@ void test_empty_string(redis_parser_t *p) { ...@@ -242,6 +245,7 @@ void test_empty_string(redis_parser_t *p) {
/* Check callbacks */ /* Check callbacks */
assert(cb_log_idx == 1); assert(cb_log_idx == 1);
assert_equal_int(cb_log[0].string_size, 0);
assert(!strncmp(cb_log[0].string_buf, buf+4, 0)); assert(!strncmp(cb_log[0].string_buf, buf+4, 0));
/* Chunked check */ /* Chunked check */
...@@ -296,12 +300,14 @@ void test_array(redis_parser_t *p) { ...@@ -296,12 +300,14 @@ void test_array(redis_parser_t *p) {
assert_equal_size_t(cb_log[1].obj.plen, 4+5+2); assert_equal_size_t(cb_log[1].obj.plen, 4+5+2);
assert_equal_size_t(cb_log[1].obj.coff, 4+4); assert_equal_size_t(cb_log[1].obj.coff, 4+4);
assert_equal_size_t(cb_log[1].obj.clen, 5); assert_equal_size_t(cb_log[1].obj.clen, 5);
assert_equal_int(cb_log[1].string_size, 5);
assert(!strncmp(cb_log[1].string_buf, buf+4+4, 5)); assert(!strncmp(cb_log[1].string_buf, buf+4+4, 5));
assert_equal_size_t(cb_log[2].obj.poff, 4+11); assert_equal_size_t(cb_log[2].obj.poff, 4+11);
assert_equal_size_t(cb_log[2].obj.plen, 4+5+2); assert_equal_size_t(cb_log[2].obj.plen, 4+5+2);
assert_equal_size_t(cb_log[2].obj.coff, 4+11+4); assert_equal_size_t(cb_log[2].obj.coff, 4+11+4);
assert_equal_size_t(cb_log[2].obj.clen, 5); assert_equal_size_t(cb_log[2].obj.clen, 5);
assert_equal_int(cb_log[2].string_size, 5);
assert(!strncmp(cb_log[2].string_buf, buf+4+11+4, 5)); assert(!strncmp(cb_log[2].string_buf, buf+4+11+4, 5));
/* Chunked check */ /* Chunked check */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment