libjsonLinux

libjson is a lightweight C/C++ library, designed to provide support for parsing, building and accessing data stored in JSON format. It is still under development (currently the C++ interface doesn't exist), and I'm sure that there will be a few bugs to iron out, and features to add.

Links

Wishlist

  • C++ interface

Overview

To use libjson, you simply create a new json instance. It is then possible to provide data in plain-text JSON format, or to construct your object, adding data, arrays and sub-objects as you go. Once the data is in memory, accessing it is easy - you just provide the identifier, such as "results[1].resolution". You can even get a handle directly to the array or object, allowing you to add or access data from a given location. Getting the data out is also straight forward, just call a simple function that will provide you with a pointer and length of the plain-text JSON (don't forget to free the memory!).

Example

This sample code can be found in the repository.
  1. /*
  2.   libjson - a C library to parse and construct JSON data structures.
  3.  
  4.   Copyright (C) 2012 onwards  Attie Grande (attie@attie.co.uk)
  5.  
  6.   libjson is free software: you can redistribute it and/or modify it
  7.   under the terms of the GNU Lesser General Public License as published by
  8.   the Free Software Foundation, either version 3 of the License, or
  9.   (at your option) any later version.
  10.  
  11.   libjson is distributed in the hope that it will be useful,
  12.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.   GNU Lesser General Public License for more details.
  15.  
  16.   You should have received a copy of the GNU Lesser General Public License
  17.   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18. */
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <unistd.h>
  23. #include <fcntl.h>
  24. #include <errno.h>
  25. #include <string.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28.  
  29. #include <json.h>
  30.  
  31. int main(int argc, char *argv[]) {
  32.   json_err ret;
  33.  
  34.   struct json *json;
  35.   struct json_element *root;
  36.   struct json_element *target;
  37.   double value;
  38.  
  39.   int fd;
  40.   unsigned char inBuf[64];
  41.   int nBytes;
  42.  
  43.   unsigned char *out;
  44.   unsigned int outLen;
  45.  
  46.  
  47.   /* create a new json instance, and get a handle to the root object */
  48.   if ((ret = json_new(&json, &root)) != JSON_ENONE) {
  49.     fprintf(stderr, "json_new() failed: %d\n", ret);
  50.     return 1;
  51.   }
  52.  
  53.   /* open the file with test data in it */
  54.   if ((fd = open("./testdata.json", O_RDONLY)) < 0) {
  55.     fprintf(stderr, "open(): %d - '%s'\n", fd, strerror(errno));
  56.     return 1;
  57.   }
  58.  
  59.   /* push the data into the json instance, chunk by chunk */
  60.   while ((nBytes = read(fd, inBuf, sizeof(inBuf))) > 0) {
  61.     /* json_dataAdd() can return;
  62.           JSON_ECOMPLETE on success - at this point there shouldn't be any more data in the file...
  63.           JSON_EINCOMPLETE          - at this point there should be more data in the file...
  64.           or any other error value */
  65.     if ((ret = json_dataAdd(json, inBuf, nBytes)) != JSON_ENONE &&
  66.         ret != JSON_ECOMPLETE && ret != JSON_EINCOMPLETE) {
  67.       fprintf(stderr, "json_dataAdd() failed: %d\n", ret);
  68.       return 1;
  69.     }
  70.    
  71.     /* on JSON_ECOMPLETE, you should probably stop feeding it... */
  72.     if (ret == JSON_ECOMPLETE) break;
  73.   }
  74.  
  75.   /* close the file */
  76.   close(fd);
  77.  
  78.   /* check that we actually did comeplete reading in the json */
  79.   if (ret != JSON_ECOMPLETE) {
  80.     fprintf(stderr, "apparently there was some data missing... :-(\n");
  81.     return 1;
  82.   }
  83.  
  84.   /* print out the whole json object */
  85.   if ((ret = json_print(json, &out, &outLen)) != JSON_ENONE) {
  86.     fprintf(stderr, "json_print() failed: %d\n", ret);
  87.     return 1;
  88.   }
  89.   printf("out:>\n%s<\n", out);
  90.   printf("outLen:%d\n", outLen);
  91.   free(out);
  92.  
  93.   /* you can even add more data */
  94.   if ((ret = json_addString(root, "", "test", "Hello!", 6)) != JSON_ENONE) {
  95.     fprintf(stderr, "json_addString() failed: %d\n", ret);
  96.     return 1;
  97.   }
  98.   /* see... */
  99.   if ((ret = json_print(json, &out, &outLen)) != JSON_ENONE) {
  100.     fprintf(stderr, "json_print() failed: %d\n", ret);
  101.     return 1;
  102.   }
  103.   printf("out:>\n%s<\n", out);
  104.   printf("outLen:%d\n", outLen);
  105.   free(out);
  106.  
  107.   /* and how about querying for a sub-section of the object? */
  108.   if ((ret = json_getObject(root, "results[0].location", &target)) != JSON_ENONE) {
  109.     fprintf(stderr, "json_getObject() failed: %d\n", ret);
  110.     return 1;
  111.   }
  112.   /* see... */
  113.   if ((ret = json_printElement(target, &out, &outLen)) != JSON_ENONE) {
  114.     fprintf(stderr, "json_printElement() failed: %d\n", ret);
  115.     return 1;
  116.   }
  117.   printf("out:>\n%s<\n", out);
  118.   printf("outLen:%d\n", outLen);
  119.   free(out);
  120.  
  121.   /* or even querying for a specific element */
  122.   if ((ret = json_getFloat(root, "results[1].resolution", &value)) != JSON_ENONE) {
  123.     fprintf(stderr, "json_getFloat() failed: %d\n", ret);
  124.     return 1;
  125.   }
  126.   printf("results[1].resolution: %.12lf\n", value);
  127.  
  128.   /* or even querying for a specific element from the sub-section! */
  129.   if ((ret = json_getFloat(target, "lat", &value)) != JSON_ENONE) {
  130.     fprintf(stderr, "json_getFloat() failed: %d\n", ret);
  131.     return 1;
  132.   }
  133.   printf("target->lat: %.12lf\n", value);
  134.  
  135.   /* how about deleting an element */
  136.   if ((ret = json_deleteElement(root, "results[1].location")) != JSON_ENONE) {
  137.     fprintf(stderr, "json_deleteElement() failed: %d\n", ret);
  138.     return 1;
  139.   }
  140.   /* see... */
  141.   if ((ret = json_print(json, &out, &outLen)) != JSON_ENONE) {
  142.     fprintf(stderr, "json_print() failed: %d\n", ret);
  143.     return 1;
  144.   }
  145.   printf("out:>\n%s<\n", out);
  146.   printf("outLen:%d\n", outLen);
  147.   free(out);
  148.  
  149.   /* tidy up the json instance */
  150.   json_destroy(json);
  151.  
  152.   return 0;
  153. }