diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 9aa33fe59..af2f678a0 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -690,17 +690,17 @@ INLINE void ng_sdp_attr_manipulations(ng_parser_ctx_t *ctx, bencode_item_t *valu switch (__csh_lookup(&command_type)) { case CSH_LOOKUP("substitute"): - call_ng_flags_list(NULL, command_value, call_ng_flags_str_pair_ht, call_ng_flags_item_pair_ht, + call_ng_flags_list(ctx, command_value, call_ng_flags_str_pair_ht, call_ng_flags_item_pair_ht, &sm->subst_commands); break; case CSH_LOOKUP("add"): - call_ng_flags_str_list(NULL, command_value, call_ng_flags_esc_str_list, &sm->add_commands); + call_ng_flags_str_list(ctx, command_value, call_ng_flags_esc_str_list, &sm->add_commands); break; /* CMD_REM commands */ case CSH_LOOKUP("remove"): - call_ng_flags_str_list(NULL, command_value, call_ng_flags_str_ht, &sm->rem_commands); + call_ng_flags_str_list(ctx, command_value, call_ng_flags_str_ht, &sm->rem_commands); break; default: @@ -795,9 +795,10 @@ static void call_ng_flags_list(ng_parser_ctx_t *ctx, bencode_item_t *list, void (*item_callback)(ng_parser_ctx_t *, bencode_item_t *, helper_arg), helper_arg arg) { + const ng_parser_t *parser = ctx->parser; str s; - if (list->type != BENCODE_LIST) { - if (bencode_get_str(list, &s)) { + if (!parser->is_list(list)) { + if (parser->get_str(list, &s)) { str token; while (str_token_sep(&token, &s, ',')) str_callback(ctx, &token, arg); @@ -806,14 +807,7 @@ static void call_ng_flags_list(ng_parser_ctx_t *ctx, bencode_item_t *list, ilog(LOG_DEBUG, "Ignoring non-list non-string value"); return; } - for (bencode_item_t *it = list->child; it; it = it->sibling) { - if (bencode_get_str(it, &s)) - str_callback(ctx, &s, arg); - else if (item_callback) - item_callback(ctx, it, arg); - else - ilog(LOG_DEBUG, "Ignoring non-string value in list"); - } + parser->list_iter(ctx, list, str_callback, item_callback, arg); } static void call_ng_flags_str_list(ng_parser_ctx_t *ctx, bencode_item_t *list, void (*callback)(ng_parser_ctx_t *ctx, str *, helper_arg), helper_arg arg) diff --git a/daemon/control_ng.c b/daemon/control_ng.c index 3ec160434..8ae15c2a1 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -98,16 +98,40 @@ static void bencode_dict_iter(ng_parser_ctx_t *ctx, bencode_item_t *input, callback(ctx, &k, value); } } +static bool bencode_is_list(bencode_item_t *arg) { + return arg->type == BENCODE_LIST; +} +static void bencode_list_iter(ng_parser_ctx_t *ctx, bencode_item_t *list, + void (*str_callback)(ng_parser_ctx_t *, str *key, helper_arg), + void (*item_callback)(ng_parser_ctx_t *, bencode_item_t *, helper_arg), + helper_arg arg) +{ + if (list->type != BENCODE_LIST) + return; + str s; + for (bencode_item_t *it = list->child; it; it = it->sibling) { + if (bencode_get_str(it, &s)) + str_callback(ctx, &s, arg); + else if (item_callback) + item_callback(ctx, it, arg); + else + ilog(LOG_DEBUG, "Ignoring non-string value in list"); + } +} const ng_parser_t ng_parser_native = { .collapse = bencode_collapse_str, .dict_iter = bencode_dict_iter, + .is_list = bencode_is_list, + .list_iter = bencode_list_iter, .get_str = bencode_get_str, .get_int_str = bencode_get_integer_str, }; const ng_parser_t ng_parser_json = { .collapse = bencode_collapse_str_json, .dict_iter = bencode_dict_iter, + .is_list = bencode_is_list, + .list_iter = bencode_list_iter, .get_str = bencode_get_str, .get_int_str = bencode_get_integer_str, }; diff --git a/daemon/statistics.c b/daemon/statistics.c index 809e7b412..e48d432c6 100644 --- a/daemon/statistics.c +++ b/daemon/statistics.c @@ -1007,7 +1007,7 @@ const char *statistics_ng(ng_parser_ctx_t *ctx) { assert(sub_label != NULL); bencode_dictionary_add(dict, bencode_strdup(buf, sub_label), sub); } - else if (dict->type == BENCODE_LIST) + else if (ctx->parser->is_list(dict)) bencode_list_add(dict, sub); else abort(); diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 4b132b9c5..c15c7854a 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -14,14 +14,6 @@ struct call_stats; struct streambuf_stream; struct sockaddr_in6; -typedef union { - const struct sdp_attr_helper *attr_helper; - str_q *q; - str_case_ht *sct; - str_case_value_ht *svt; - void **generic; -} helper_arg __attribute__ ((__transparent_union__)); - struct sdp_ng_flags { enum call_opmode opmode; enum message_type message_type; diff --git a/include/control_ng.h b/include/control_ng.h index 7a2078298..12f19401b 100644 --- a/include/control_ng.h +++ b/include/control_ng.h @@ -97,10 +97,23 @@ enum call_opmode { OP_OTHER, }; +typedef union { + const struct sdp_attr_helper *attr_helper; + str_q *q; + str_case_ht *sct; + str_case_value_ht *svt; + void *generic; +} helper_arg __attribute__ ((__transparent_union__)); + struct ng_parser { str *(*collapse)(bencode_item_t *root, str *out); void (*dict_iter)(ng_parser_ctx_t *, bencode_item_t *, void (*callback)(ng_parser_ctx_t *, str *, bencode_item_t *)); + bool (*is_list)(bencode_item_t *); + void (*list_iter)(ng_parser_ctx_t *, bencode_item_t *input, + void (*str_callback)(ng_parser_ctx_t *, str *key, helper_arg), + void (*item_callback)(ng_parser_ctx_t *, bencode_item_t *, helper_arg), + helper_arg); str *(*get_str)(bencode_item_t *, str *s); long long (*get_int_str)(bencode_item_t *, long long def); };