Commit 37c16d6d authored by Pieter Noordhuis's avatar Pieter Noordhuis
Browse files

Extract separate state for the CR after a bulk

parent 9b466678
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
X(integer_body) \ X(integer_body) \
X(integer_lf) \ X(integer_lf) \
X(bulk) \ X(bulk) \
X(bulk_cr) \
X(bulk_lf) \ X(bulk_lf) \
X(line) \ X(line) \
X(line_lf) \ X(line_lf) \
...@@ -48,16 +49,20 @@ static const char * strstate[] = { ...@@ -48,16 +49,20 @@ static const char * strstate[] = {
}; };
#undef _ENUM_GEN #undef _ENUM_GEN
#define TRANSITION(st) do { \ #define TRANSITION(st) do { \
state = s_##st; \ pos++; nread++; \
pos++; nread++; \ TRANSITION_WITHOUT_POS_INCR(st); \
if (pos < end) { \ } while(0)
ch = *pos; \
goto l_##st; \ #define TRANSITION_WITHOUT_POS_INCR(st) do { \
} \ state = s_##st; \
\ if (pos < end) { \
/* No more data */ \ ch = *pos; \
goto finalize; \ goto l_##st; \
} \
\
/* No more data */ \
goto finalize; \
} while(0) } while(0)
#ifdef DEBUG #ifdef DEBUG
...@@ -153,6 +158,7 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -153,6 +158,7 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
switch (state) { switch (state) {
case s_type_char: case s_type_char:
l_type_char:
{ {
cur->poff = nread; cur->poff = nread;
...@@ -172,10 +178,9 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -172,10 +178,9 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
case '-': case '-':
cur->type = REDIS_ERROR_T; cur->type = REDIS_ERROR_T;
assert(NULL); assert(NULL);
default:
goto error;
} }
break;
goto error;
} }
case s_integer_sign: case s_integer_sign:
...@@ -290,37 +295,48 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -290,37 +295,48 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
{ {
size_t len = cur->remaining; size_t len = cur->remaining;
if (len) { /* Everything can be read */
if ((end-pos) < len) len = (end-pos); if (len <= (end-pos)) {
CALLBACK(string, pos, len);
cur->remaining -= len; cur->remaining -= len;
pos += len - 1; nread += len - 1; CALLBACK(string, pos, len);
break; pos += len; nread += len;
TRANSITION_WITHOUT_POS_INCR(bulk_cr);
} }
/* No remaining bytes for this bulk */ /* Not everything can be read */
if (ch != '\r') { len = (end-pos);
goto error; cur->remaining -= len;
CALLBACK(string, pos, len);
pos += len; nread += len;
goto finalize;
}
case s_bulk_cr:
l_bulk_cr:
{
if (ch == '\r') {
TRANSITION(bulk_lf);
} }
TRANSITION(bulk_lf); goto error;
} }
case s_bulk_lf: case s_bulk_lf:
l_bulk_lf: l_bulk_lf:
{ {
if (ch != '\n') { if (ch == '\n') {
goto error; goto done;
} }
goto done;
goto error;
} }
default: default:
assert(NULL); assert(NULL);
} }
pos++; nread++; /* Transitions should be made from within the switch */
continue; assert(NULL && "invalid code path");
done: done:
/* Message is done when root object is done */ /* Message is done when root object is done */
......
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