C-based memory friendly JSON parser based on Serge Zaitsev's JSMN (https://bitbucket.org/zserge/jsmn/wiki/Home)

Dependents:   _library_jsmn _library_jsmn _library_jsmn

JSMN

jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C. It can be easily integrated into resource-limited or embedded projects.

You can find more information about JSON format at json.org

Library sources are available at https://bitbucket.org/zserge/jsmn

The web page with some information about jsmn can be found at http://zserge.com/jsmn.html

Revision:
1:70061827a9c8
Parent:
0:46575249ef23
Child:
2:5167da2fcc4e
--- a/jsmn.cpp	Tue May 06 09:33:30 2014 +0000
+++ b/jsmn.cpp	Mon Nov 17 15:54:28 2014 +0000
@@ -24,6 +24,7 @@
  */
 
 #include <stdlib.h>
+#include "mbed.h"
 
 #include "jsmn.h"
 
@@ -39,6 +40,7 @@
 )
 {
   jsmntok_t  *tok;
+
   if (parser->toknext >= num_tokens)
   {
     return NULL;
@@ -102,6 +104,7 @@
     if (js[parser->pos] < 32 || js[parser->pos] >= 127)
     {
       parser->pos = start;
+      printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
       return JSMN_ERR_INVAL;
     }
   }
@@ -171,8 +174,9 @@
     }
 
     /* Backslash: Quoted symbol expected */
-    if (c == '\\')
+    if (c == '\\' && parser->pos + 1 < len)
     {
+      int i;
       parser->pos++;
       switch (js[parser->pos])
       {
@@ -190,14 +194,16 @@
         /* Allows escaped symbol \uXXXX */
         case 'u':
           parser->pos++;
-          int i = 0;
-          for (; i < 4 && js[parser->pos] != '\0'; i++) 
+          for (i = 0; 
+               i < 4 && parser->pos < len && js[parser->pos] != '\0';
+               i++) 
           {
             /* If it isn't a hex character we have an ERR */
             if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */
                   (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
                   (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
               parser->pos = start;
+              printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
               return JSMN_ERR_INVAL;
             }
             parser->pos++;
@@ -208,6 +214,7 @@
         /* Unexpected symbol */
         default:
           parser->pos = start;
+          printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
           return JSMN_ERR_INVAL;
       }
     }
@@ -270,16 +277,20 @@
 
         type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
 
-        if (parser->toknext < 1)
+        if (parser->toknext < 1) {
+          printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
           return JSMN_ERR_INVAL;
+        }
 
         token = &tokens[parser->toknext - 1];
         for (;;)
         {
           if (token->start != -1 && token->end == -1) 
           {
-            if (token->type != type) 
+            if (token->type != type) {
+              printf("%s:%d: parser->pos=%d\r\n", __FILE__, __LINE__, parser->pos);
               return JSMN_ERR_INVAL;
+            }
 
             token->end = parser->pos + 1;
             parser->toksuper = token->parent;
@@ -306,9 +317,20 @@
       case '\t': 
       case '\r': 
       case '\n': 
+      case ' ' : 
+        break;
+        
       case ':' : 
+        parser->toksuper = parser->toknext - 1;
+        break;
+        
       case ',' : 
-      case ' ' : 
+        if (tokens != NULL &&
+            tokens[parser->toksuper].type != JSMN_ARRAY &&
+            tokens[parser->toksuper].type != JSMN_OBJECT) 
+        {
+          parser->toksuper = tokens[parser->toksuper].parent;   
+        }
         break;
       
       case '-' : 
@@ -325,6 +347,17 @@
       case 't' : 
       case 'f' : 
       case 'n' :
+        /* And they must not be keys of the object */
+        if (tokens != NULL)
+        {
+          jsmntok_t *t = &tokens[parser->toksuper];
+          if ( t->type == JSMN_OBJECT ||
+              (t->type == JSMN_STRING && t->size != 0))
+          {
+            printf("%s:%d: js[parser->pos]=%c\r\n", __FILE__, __LINE__, js[parser->pos]);
+            return JSMN_ERR_INVAL;
+          }
+        }
         r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens);
         if (r < 0)
           return r;
@@ -337,6 +370,7 @@
 
       /* Unexpected char in strict mode */
       default:
+        printf("%s:%d: js[parser->pos]=%c\r\n", __FILE__, __LINE__, js[parser->pos]);
         return JSMN_ERR_INVAL;
     }
   }
@@ -365,6 +399,3 @@
   parser->toknext = 0;
   parser->toksuper = -1;
 }
-
-
-