From 1e585c5d2b185194e76dd477e466a1fc5575798a Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Thu, 30 Oct 2014 21:32:17 +0100 Subject: [PATCH] curl_json: fix the array access implemented in f1e1e37e In the avl-tree we store two different structs, cj_key_t for the value we search, c_avl_tree_t for sub-nodes. The old version does assume when it will find a key, and when a tree, which doesn't have to be right in all cases. Therefore we utilize the magic to revalidate this cast. Being able to tell tree from key, we now can also implement array access on the right most node of the tree-path. --- src/collectd.conf.in | 35 +++++++++++++++++++++++++++++++++++ src/curl_json.c | 28 ++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 3a8609a1..1e0f78c1 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -298,6 +298,41 @@ # # +# +# Instance "test_http_json" +# +# Type "gauge" +# # Expect: 1 +# +# +# Type "gauge" +# # Expect: 2 +# +# +# Type "gauge" +# # Expect: 3 +# +# +# Type "gauge" +# # Expect: 4 +# +# +# Type "gauge" +# # Expect: 5 +# +# +# Type "gauge" +# # Expect: 6 +# +# +# put this as test.json on your webserver, the above config demonstraces +# how to match them. +# { +# "testArray":[1,2], +# "testArrayInbetween":[{"blarg":3},{"blub":4}], +# "testDirectHit":5, +# "testSubLevelHit":{"oneMoreLevel":6} +# } ## See: http://wiki.apache.org/couchdb/Runtime_Statistics # # Instance "httpd" diff --git a/src/curl_json.c b/src/curl_json.c index 9e0f6723..6dec89e5 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -232,9 +232,14 @@ static int cj_cb_number (void *ctx, if (key != NULL) NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects" " a map.", buffer); - cj_cb_inc_array_index (ctx, /* update_key = */ 0); - return (CJ_CB_CONTINUE); - } else { + cj_cb_inc_array_index (ctx, /* update_key = */ 1); + key = db->state[db->depth].key; + if (key == NULL) { + return (CJ_CB_CONTINUE); + } + } + else + { cj_cb_inc_array_index (ctx, /* update_key = */ 1); } @@ -274,10 +279,21 @@ static int cj_cb_map_key (void *ctx, memcpy (name, in_name, name_len); name[name_len] = 0; - if (c_avl_get (tree, name, (void *) &value) == 0) - db->state[db->depth].key = value; + if (c_avl_get (tree, name, (void *) &value) == 0) { + if (CJ_IS_KEY((cj_key_t*)value)) { + db->state[db->depth].key = value; + } + else { + db->state[db->depth].tree = (c_avl_tree_t*) value; + } + } else if (c_avl_get (tree, CJ_ANY, (void *) &value) == 0) - db->state[db->depth].key = value; + if (CJ_IS_KEY((cj_key_t*)value)) { + db->state[db->depth].key = value; + } + else { + db->state[db->depth].tree = (c_avl_tree_t*) value; + } else db->state[db->depth].key = NULL; } -- 2.11.0