Commit 54a39608 authored by Pieter Noordhuis's avatar Pieter Noordhuis
Browse files

Destroy hook for parser

parent 7540faf3
...@@ -497,6 +497,17 @@ error: ...@@ -497,6 +497,17 @@ error:
return pos-buf; return pos-buf;
} }
void redis_parser_destroy(redis_parser *parser) {
/* Only trigger destroy callback when the parser has unfinished
* redis_protocol instances. */
if (parser->stackidx >= 0 &&
parser->callbacks &&
parser->callbacks->destroy)
{
parser->callbacks->destroy(parser, redis_parser_root(parser));
}
}
redis_protocol *redis_parser_root(redis_parser *parser) { redis_protocol *redis_parser_root(redis_parser *parser) {
return &parser->stack[0]; return &parser->stack[0];
} }
......
...@@ -88,6 +88,7 @@ struct redis_parser_s { ...@@ -88,6 +88,7 @@ struct redis_parser_s {
void redis_parser_init(redis_parser *parser, const redis_parser_callbacks *callbacks); void redis_parser_init(redis_parser *parser, const redis_parser_callbacks *callbacks);
size_t redis_parser_execute(redis_parser *parser, redis_protocol **dst, const char *buf, size_t len); size_t redis_parser_execute(redis_parser *parser, redis_protocol **dst, const char *buf, size_t len);
void redis_parser_destroy(redis_parser *parser);
redis_protocol *redis_parser_root(redis_parser *parser); redis_protocol *redis_parser_root(redis_parser *parser);
enum redis_parser_errno redis_parser_err(redis_parser *parser); enum redis_parser_errno redis_parser_err(redis_parser *parser);
const char *redis_parser_strerror(enum redis_parser_errno err); const char *redis_parser_strerror(enum redis_parser_errno err);
......
...@@ -111,11 +111,21 @@ int on_nil(redis_parser *parser, redis_protocol *p) { ...@@ -111,11 +111,21 @@ int on_nil(redis_parser *parser, redis_protocol *p) {
return 0; return 0;
} }
static int destroy_called = 0;
void destroy(redis_parser *parser, redis_protocol *p) {
((void)parser);
((void)p);
destroy_called++;
}
static redis_parser_callbacks callbacks = { static redis_parser_callbacks callbacks = {
&on_string, &on_string,
&on_array, &on_array,
&on_integer, &on_integer,
&on_nil &on_nil,
&destroy
}; };
#define RESET_PARSER(__parser) do { \ #define RESET_PARSER(__parser) do { \
...@@ -530,6 +540,49 @@ void test_abort_after_error(redis_parser *p) { ...@@ -530,6 +540,49 @@ void test_abort_after_error(redis_parser *p) {
assert(res == NULL); assert(res == NULL);
} }
void test_destroy_callback_after_success(redis_parser *p) {
redis_protocol *res;
enum redis_parser_errno err;
RESET_PARSER(p);
assert_equal_size_t(redis_parser_execute(p, &res, "+ok\r\n", 5), 5);
assert(res != NULL);
assert(redis_parser_err(p) == RPE_OK);
/* Test that the destroy callback is NOT called when there are
* no errors or the parser is in-flight */
redis_parser_destroy(p);
assert_equal_int(destroy_called, 0);
}
void test_destroy_callback_after_error(redis_parser *p) {
redis_protocol *res;
enum redis_parser_errno err;
RESET_PARSER(p);
assert_equal_size_t(redis_parser_execute(p, &res, "+ok\r\r", 5), 4);
assert(res == NULL);
assert(redis_parser_err(p) != RPE_OK);
/* Test that the destroy callback is called after an error */
redis_parser_destroy(p);
assert_equal_int(destroy_called, 1);
}
void test_destroy_callback_in_flight(redis_parser *p) {
redis_protocol *res;
enum redis_parser_errno err;
RESET_PARSER(p);
assert_equal_size_t(redis_parser_execute(p, &res, "+ok\r", 4), 4);
assert(res == NULL);
assert(redis_parser_err(p) == RPE_OK);
/* Test that the destroy callback is called when the parser is in-flight */
redis_parser_destroy(p);
assert_equal_int(destroy_called, 1);
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
redis_parser *parser = malloc(sizeof(redis_parser)); redis_parser *parser = malloc(sizeof(redis_parser));
redis_parser_init(parser, &callbacks); redis_parser_init(parser, &callbacks);
......
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