curl_json: fix the array access implemented in f1e1e37e
authorWilfried Goesgens <dothebart@citadel.org>
Thu, 30 Oct 2014 20:32:17 +0000 (21:32 +0100)
committerMarc Fournier <marc.fournier@camptocamp.com>
Fri, 31 Oct 2014 09:29:48 +0000 (10:29 +0100)
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
src/curl_json.c

index 3a8609a..1e0f78c 100644 (file)
 #</Plugin>
 
 #<Plugin curl_json>
+#  <URL "http://localhost:80/test.json">
+#    Instance "test_http_json"
+#    <Key "testArray/0">
+#      Type "gauge"
+#      # Expect: 1
+#    </Key>
+#    <Key "testArray/1">
+#      Type "gauge"
+#      # Expect: 2
+#    </Key>
+#    <Key "testArrayInbetween/0/blarg">
+#      Type "gauge"
+#      # Expect: 3
+#    </Key>
+#    <Key "testArrayInbetween/1/blub">
+#      Type "gauge"
+#      # Expect: 4
+#    </Key>
+#    <Key "testDirectHit">
+#      Type "gauge"
+#      # Expect: 5
+#    </Key>
+#    <Key "testSubLevelHit/oneMoreLevel">
+#      Type "gauge"
+#      # Expect: 6
+#    </Key>
+#  </URL>
+# 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
 #  <URL "http://localhost:5984/_stats">
 #    Instance "httpd"
index 9e0f672..6dec89e 100644 (file)
@@ -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;
   }