Skip to content

Latest commit

 

History

History
99 lines (78 loc) · 2.84 KB

parsing5.md

File metadata and controls

99 lines (78 loc) · 2.84 KB

Parsing a Json object - part 5: Iterators

We introduced the function json_object_object_foreach previously. However, json-c offers another iteration API more in a C++ iterator type style.

Consider our previous example:

#include <stdio.h>
#include <json-c/json.h>

int 
main(void)
{
   json_object *root = json_object_from_file("contact.json");
   json_object_object_foreach(root, key, val)
      printf("%s  -> %s\n", key, json_object_get_string(val));

   json_object_put(root);
   return 0;
}

If we refactor the above by replacing essentially implementing the macro json_object_object_foreach, we have:

#include <stdio.h>
#include <json-c/json.h>

int 
main(void)
{
   struct lh_entry *entry; // Struct needed here
   char *key;
   json_object *root = json_object_from_file("contact.json");
   entry = json_object_get_object(root)->head;
   while( entry )
   {
       key = (char *)entry->k;
       json_object* val = (json_object *) entry->v;
       printf("%s  -> %s\n", key, json_object_get_string(val));
       entry = entry->next;
   }
   json_object_put(root);
   return 0;
}

Examining the above code, we are violating the Object-Oriented principle of encapsulation and exposing the json-c internal representation of the json_object. This is not as apparent when using the macro json_object_object_foreach, yet even then the programmer has access to the internal struct lh_entry:

#include <stdio.h>
#include <json-c/json.h>

int 
main(void)
{
   json_object *root = json_object_from_file("contact.json");
   json_object_object_foreach(root, key, val)
      printf("Entry %p\n",entrykey);

   json_object_put(root);
   return 0;
}

The json-c libraries offers a way to avoid this "problem". To illustrate, consider json-parse08.c:

#include <stdio.h>
#include <json-c/json.h>

int 
main(void)
{
   struct json_object_iterator it;
   struct json_object_iterator itEnd;

   json_object *root = json_object_from_file("contact.json");
   it = json_object_iter_init_default();
   it = json_object_iter_begin(root);
   itEnd = json_object_iter_end(root);

   while (!json_object_iter_equal(&it, &itEnd))
   {
      const char* key = json_object_iter_peek_name(&it);
      json_object* val = json_object_iter_peek_value(&it);
      printf("%s  -> %s\n", key, json_object_get_string(val));
      json_object_iter_next(&it);
   }
   json_object_put(root);
   return 0;
}

The code should explain itself, but consult the documentation for more details if needed.

Note: The usage of struct in the declarations of it and itEnd are necessary for the data 'type' json_object_iterator.