Skip to content

Commit

Permalink
for-each statement: Add support for $json iterators
Browse files Browse the repository at this point in the history
Example way of usage:
    for ($json(foo) in $(avp(bar)[*]))
        xlog("JSON fields: $json(foo/baz) $json(foo/qux)\n");
  • Loading branch information
liviuchircu committed Jul 16, 2015
1 parent 3607208 commit 2649a3a
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 14 deletions.
16 changes: 12 additions & 4 deletions action.c
Expand Up @@ -2069,12 +2069,14 @@ int do_action(struct action* a, struct sip_msg* msg)

static int for_each_handler(struct sip_msg *msg, struct action *a)
{
pv_spec_p spec;
pv_spec_p iter, spec;
pv_param_t pvp;
pv_value_t val;
int ret = 1;
int op = 0;

if (a->elem[2].type == ACTIONS_ST && a->elem[2].u.data) {
iter = a->elem[0].u.data;
spec = a->elem[1].u.data;

/*
Expand All @@ -2090,6 +2092,14 @@ static int for_each_handler(struct sip_msg *msg, struct action *a)
pvp.pvi.type = PV_IDX_INT;
pvp.pvn = spec->pvp.pvn;

/*
* for $json iterators, better to assume script writer
* wants data to be interpreted, rather than not
* (i.e. ":=" script operator, and not simply "=")
*/
if (iter->type == PVT_JSON)
op = COLONEQ_T;

for (;;) {
if (spec->getf(msg, &pvp, &val) != 0) {
LM_ERR("failed to get spec value\n");
Expand All @@ -2099,9 +2109,7 @@ static int for_each_handler(struct sip_msg *msg, struct action *a)
if (val.flags & PV_VAL_NULL)
break;

if (((pv_spec_p)a->elem[0].u.data)->
setf(msg, &((pv_spec_p)a->elem[0].u.data)->pvp,
0, &val) != 0) {
if (iter->setf(msg, &iter->pvp, op, &val) != 0) {
LM_ERR("failed to set scriptvar value\n");
return E_BUG;
}
Expand Down
7 changes: 4 additions & 3 deletions cfg.y
Expand Up @@ -1723,9 +1723,10 @@ while_cmd: WHILE exp stm { mk_action2( $$, WHILE_T,

foreach_cmd: FOR LPAREN script_var IN script_var RPAREN stm {
if ($3->type != PVT_SCRIPTVAR &&
$3->type != PVT_AVP) {
yyerror("\nfor-each statement: only \"var\" "
"and \"avp\" iterators are supported");
$3->type != PVT_AVP &&
$3->type != PVT_JSON) {
yyerror("\nfor-each statement: only \"var\", \"avp\" "
"and \"json\" iterators are supported!");
}

mk_action3( $$, FOR_EACH_T,
Expand Down
10 changes: 3 additions & 7 deletions modules/json/json.c
Expand Up @@ -49,10 +49,6 @@
#include <json_object_private.h>





#define PV_JSON_ID 8888
#define JSON_BUFF_SIZE 4096

enum
Expand Down Expand Up @@ -126,7 +122,7 @@ static cmd_export_t cmds[]={


static pv_export_t mod_items[] = {
{ {"json", sizeof("json")-1}, PV_JSON_ID, pv_get_json,
{ {"json", sizeof("json")-1}, PVT_JSON, pv_get_json,
pv_set_json, pv_parse_json_name, 0, 0, 0},
{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
};
Expand Down Expand Up @@ -212,7 +208,7 @@ int fixup_json_bind(void** param, int param_no)
return -1;
}

if( var->type != PV_JSON_ID )
if( var->type != PVT_JSON )
{
LM_ERR("Parameter no: %d must be a json variable\n",param_no);
return -1;
Expand Down Expand Up @@ -955,7 +951,7 @@ int pv_parse_json_name (pv_spec_p sp, str *in)


sp->pvp.pvn.u.dname = id ;
sp->type = PV_JSON_ID;
sp->type = PVT_JSON;
sp->getf = pv_get_json;
sp->setf = pv_set_json;

Expand Down
4 changes: 4 additions & 0 deletions pvar.h
Expand Up @@ -108,6 +108,10 @@ enum _pv_type {
PVT_HDRCNT, PVT_AUTH_NONCE_COUNT, PVT_AUTH_QOP,
PVT_AUTH_ALGORITHM, PVT_AUTH_OPAQUE, PVT_AUTH_CNONCE,
PVT_RU_Q, PVT_ROUTE_PARAM, PVT_ROUTE_TYPE,

/* registered by json module */
PVT_JSON,

PVT_EXTRA /* keep it last */
};

Expand Down

0 comments on commit 2649a3a

Please sign in to comment.