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

Destroy hook for parser

parent 7540faf3
......@@ -497,6 +497,17 @@ error:
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) {
return &parser->stack[0];
}
......
......@@ -88,6 +88,7 @@ struct redis_parser_s {
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);
void redis_parser_destroy(redis_parser *parser);
redis_protocol *redis_parser_root(redis_parser *parser);
enum redis_parser_errno redis_parser_err(redis_parser *parser);
const char *redis_parser_strerror(enum redis_parser_errno err);
......
......@@ -111,11 +111,21 @@ int on_nil(redis_parser *parser, redis_protocol *p) {
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 = {
&on_string,
&on_array,
&on_integer,
&on_nil
&on_nil,
&destroy
};
#define RESET_PARSER(__parser) do { \
......@@ -530,6 +540,49 @@ void test_abort_after_error(redis_parser *p) {
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) {
redis_parser *parser = malloc(sizeof(redis_parser));
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