]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
update json lib in core and ESL and re-apply old patches
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 13 Sep 2012 17:54:25 +0000 (12:54 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 13 Sep 2012 17:54:31 +0000 (12:54 -0500)
libs/esl/src/esl_json.c
libs/esl/src/include/esl_json.h
src/include/switch_json.h
src/switch_json.c

index 2926a3230b97c09a7c40acf3e826d6f2c1819062..3de776b3a8103f7d24bf75ff90b17a711cfbf68a 100644 (file)
   THE SOFTWARE.
 */
 
-// cJSON
-// JSON parser in C.
+/* cJSON */
+/* JSON parser in C. */
 
-#include "esl.h"
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
 #include <float.h>
 #include <limits.h>
+#include <ctype.h>
+#include "esl_json.h"
+#include "esl.h"
+
+static const char *ep;
+
+ESL_DECLARE(const char *)cJSON_GetErrorPtr() {return ep;}
 
 static int cJSON_strcasecmp(const char *s1,const char *s2)
 {
@@ -51,14 +61,15 @@ static char* cJSON_strdup(const char* str)
 {
       size_t len;
       char* copy;
+      const char *s = str ? str : "";
 
-      len = strlen(str) + 1;
+      len = strlen(s) + 1;
       if (!(copy = (char*)cJSON_malloc(len))) return 0;
-      memcpy(copy,str,len);
+      memcpy(copy,s,len);
       return copy;
 }
 
-void cJSON_InitHooks(cJSON_Hooks* hooks)
+ESL_DECLARE(void)cJSON_InitHooks(cJSON_Hooks* hooks)
 {
     if (!hooks) { /* Reset hooks */
         cJSON_malloc = malloc;
@@ -70,16 +81,16 @@ void cJSON_InitHooks(cJSON_Hooks* hooks)
        cJSON_free       = (hooks->free_fn)?hooks->free_fn:free;
 }
 
-// Internal constructor.
-static cJSON *cJSON_New_Item(void)
+/* Internal constructor. */
+static cJSON *cJSON_New_Item()
 {
        cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
        if (node) memset(node,0,sizeof(cJSON));
        return node;
 }
 
-// Delete a cJSON structure.
-void cJSON_Delete(cJSON *c)
+/* Delete a cJSON structure. */
+ESL_DECLARE(void)cJSON_Delete(cJSON *c)
 {
        cJSON *next;
        while (c)
@@ -93,22 +104,22 @@ void cJSON_Delete(cJSON *c)
        }
 }
 
-// Parse the input text to generate a number, and populate the result into item.
+/* Parse the input text to generate a number, and populate the result into item. */
 static const char *parse_number(cJSON *item,const char *num)
 {
        double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
 
-       // Could use sscanf for this?
-       if (*num=='-') sign=-1,num++;   // Has sign?
-       if (*num=='0') num++;                   // is zero
-       if (*num>='1' && *num<='9')     do      n=(n*10.0)+(*num++ -'0');       while (*num>='0' && *num<='9'); // Number?
-       if (*num=='.') {num++;          do      n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}      // Fractional part?
-       if (*num=='e' || *num=='E')             // Exponent?
-       {       num++;if (*num=='+') num++;     else if (*num=='-') signsubscale=-1,num++;              // With sign?
-               while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');   // Number?
+       /* Could use sscanf for this? */
+       if (*num=='-') sign=-1,num++;   /* Has sign? */
+       if (*num=='0') num++;                   /* is zero */
+       if (*num>='1' && *num<='9')     do      n=(n*10.0)+(*num++ -'0');       while (*num>='0' && *num<='9'); /* Number? */
+       if (*num=='.' && num[1]>='0' && num[1]<='9') {num++;            do      n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}      /* Fractional part? */
+       if (*num=='e' || *num=='E')             /* Exponent? */
+       {       num++;if (*num=='+') num++;     else if (*num=='-') signsubscale=-1,num++;              /* With sign? */
+               while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');   /* Number? */
        }
 
-       n=sign*n*pow(10.0,(scale+subscale*signsubscale));       // number = +/- number.fraction * 10^+/- exponent
+       n=sign*n*pow(10.0,(scale+subscale*signsubscale));       /* number = +/- number.fraction * 10^+/- exponent */
        
        item->valuedouble=n;
        item->valueint=(int)n;
@@ -116,40 +127,43 @@ static const char *parse_number(cJSON *item,const char *num)
        return num;
 }
 
-// Render the number nicely from the given item into a string.
+/* Render the number nicely from the given item into a string. */
 static char *print_number(cJSON *item)
 {
        char *str;
        double d=item->valuedouble;
        if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
        {
-               str=(char*)cJSON_malloc(21);    // 2^64+1 can be represented in 21 chars.
-               sprintf(str,"%d",item->valueint);
+               str=(char*)cJSON_malloc(21);    /* 2^64+1 can be represented in 21 chars. */
+               if (str) sprintf(str,"%d",item->valueint);
        }
        else
        {
-               str=(char*)cJSON_malloc(64);    // This is a nice tradeoff.
-               if (fabs(floor(d)-d)<=DBL_EPSILON)                      sprintf(str,"%.0f",d);
-               else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)       sprintf(str,"%e",d);
-               else                                                                            sprintf(str,"%f",d);
+               str=(char*)cJSON_malloc(64);    /* This is a nice tradeoff. */
+               if (str)
+               {
+                       if (fabs(floor(d)-d)<=DBL_EPSILON)                      sprintf(str,"%.0f",d);
+                       else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)       sprintf(str,"%e",d);
+                       else                                                                            sprintf(str,"%f",d);
+               }
        }
        return str;
 }
 
-// Parse the input text into an unescaped cstring, and populate item.
+/* Parse the input text into an unescaped cstring, and populate item. */
 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
 static const char *parse_string(cJSON *item,const char *str)
 {
-       const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
-       if (*str!='\"') return 0;       // not a string!
+       const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
+       if (*str!='\"') {ep=str;return 0;}      /* not a string! */
        
-       while (*ptr!='\"' && (unsigned char)*ptr>31 && ++len) if (*ptr++ == '\\') ptr++;        // Skip escaped quotes.
+       while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;  /* Skip escaped quotes. */
        
-       out=(char*)cJSON_malloc(len+1); // This is how long we need for the string, roughly.
+       out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
        if (!out) return 0;
        
        ptr=str+1;ptr2=out;
-       while (*ptr!='\"' && (unsigned char)*ptr>31)
+       while (*ptr!='\"' && *ptr)
        {
                if (*ptr!='\\') *ptr2++=*ptr++;
                else
@@ -162,16 +176,31 @@ static const char *parse_string(cJSON *item,const char *str)
                                case 'n': *ptr2++='\n'; break;
                                case 'r': *ptr2++='\r'; break;
                                case 't': *ptr2++='\t'; break;
-                               case 'u':        // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
-                                       if (sscanf(ptr+1,"%4x",&uc) < 1) break; // get the unicode char.
-                                       len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
+                               case 'u':        /* transcode utf16 to utf8. */
+                                       if (sscanf(ptr+1,"%4x",&uc) < 1) break;
+
+                                       ptr+=4; /* get the unicode char. */
+
+                                       if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)        break;  // check for invalid.
+
+                                       if (uc>=0xD800 && uc<=0xDBFF)   // UTF16 surrogate pairs.
+                                       {
+                                               if (ptr[1]!='\\' || ptr[2]!='u')        break;  // missing second-half of surrogate.
+                                               if (sscanf(ptr+3,"%4x",&uc2) < 1) break;
+                                               ptr+=6;
+                                               if (uc2<0xDC00 || uc2>0xDFFF)           break;  // invalid second-half of surrogate.
+                                               uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
+                                       }
+
+                                       len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
                                        
                                        switch (len) {
+                                               case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                                                case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                                                case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                                                case 1: *--ptr2 =(char)(uc | firstByteMark[len]);
                                        }
-                                       ptr2+=len;ptr+=4;
+                                       ptr2+=len;
                                        break;
                                default:  *ptr2++=*ptr; break;
                        }
@@ -185,15 +214,17 @@ static const char *parse_string(cJSON *item,const char *str)
        return ptr;
 }
 
-// Render the cstring provided to an escaped version that can be printed.
+/* Render the cstring provided to an escaped version that can be printed. */
 static char *print_string_ptr(const char *str)
 {
-       const char *ptr;char *ptr2,*out;int len=0;
+       const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
        
        if (!str) return cJSON_strdup("");
-       ptr=str;while (*ptr && ++len) {if ((unsigned char)*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
+       ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
        
        out=(char*)cJSON_malloc(len+3);
+       if (!out) return 0;
+
        ptr2=out;ptr=str;
        *ptr2++='\"';
        while (*ptr)
@@ -202,7 +233,7 @@ static char *print_string_ptr(const char *str)
                else
                {
                        *ptr2++='\\';
-                       switch (*ptr++)
+                       switch (token=*ptr++)
                        {
                                case '\\':      *ptr2++='\\';   break;
                                case '\"':      *ptr2++='\"';   break;
@@ -211,17 +242,17 @@ static char *print_string_ptr(const char *str)
                                case '\n':      *ptr2++='n';    break;
                                case '\r':      *ptr2++='r';    break;
                                case '\t':      *ptr2++='t';    break;
-                               default: ptr2--;        break;  // eviscerate with prejudice.
+                               default: sprintf(ptr2,"u%04x",token);ptr2+=5;   break;  /* escape and print */
                        }
                }
        }
        *ptr2++='\"';*ptr2++=0;
        return out;
 }
-// Invote print_string_ptr (which is useful) on an item.
+/* Invote print_string_ptr (which is useful) on an item. */
 static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
 
-// Predeclare these prototypes.
+/* Predeclare these prototypes. */
 static const char *parse_value(cJSON *item,const char *value);
 static char *print_value(cJSON *item,int depth,int fmt);
 static const char *parse_array(cJSON *item,const char *value);
@@ -229,27 +260,28 @@ static char *print_array(cJSON *item,int depth,int fmt);
 static const char *parse_object(cJSON *item,const char *value);
 static char *print_object(cJSON *item,int depth,int fmt);
 
-// Utility to jump whitespace and cr/lf
-static const char *skip(const char *in) {while (in && (unsigned char)*in<=32) in++; return in;}
+/* Utility to jump whitespace and cr/lf */
+static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
 
-// Parse an object - create a new root, and populate.
-cJSON *cJSON_Parse(const char *value)
+/* Parse an object - create a new root, and populate. */
+ESL_DECLARE(cJSON *)cJSON_Parse(const char *value)
 {
        cJSON *c=cJSON_New_Item();
+       ep=0;
        if (!c) return 0;       /* memory fail */
 
        if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
        return c;
 }
 
-// Render a cJSON item/entity/structure to text.
+/* Render a cJSON item/entity/structure to text. */
 char *cJSON_Print(cJSON *item)                         {return print_value(item,0,1);}
 char *cJSON_PrintUnformatted(cJSON *item)      {return print_value(item,0,0);}
 
-// Parser core - when encountering text, process appropriately.
+/* Parser core - when encountering text, process appropriately. */
 static const char *parse_value(cJSON *item,const char *value)
 {
-       if (!value)                                             return 0;       // Fail on null.
+       if (!value)                                             return 0;       /* Fail on null. */
        if (!strncmp(value,"null",4))   { item->type=cJSON_NULL;  return value+4; }
        if (!strncmp(value,"false",5))  { item->type=cJSON_False; return value+5; }
        if (!strncmp(value,"true",4))   { item->type=cJSON_True; item->valueint=1;      return value+4; }
@@ -258,10 +290,10 @@ static const char *parse_value(cJSON *item,const char *value)
        if (*value=='[')                                { return parse_array(item,value); }
        if (*value=='{')                                { return parse_object(item,value); }
 
-       return 0;       // failure.
+       ep=value;return 0;      /* failure. */
 }
 
-// Render a value to text.
+/* Render a value to text. */
 static char *print_value(cJSON *item,int depth,int fmt)
 {
        char *out=0;
@@ -279,35 +311,35 @@ static char *print_value(cJSON *item,int depth,int fmt)
        return out;
 }
 
-// Build an array from input text.
+/* Build an array from input text. */
 static const char *parse_array(cJSON *item,const char *value)
 {
        cJSON *child;
-       if (*value!='[')        return 0;       // not an array!
+       if (*value!='[')        {ep=value;return 0;}    /* not an array! */
 
        item->type=cJSON_Array;
        value=skip(value+1);
-       if (*value==']') return value+1;        // empty array.
+       if (*value==']') return value+1;        /* empty array. */
 
        item->child=child=cJSON_New_Item();
-       if (!item->child) return 0;              // memory fail
-       value=skip(parse_value(child,skip(value)));     // skip any spacing, get the value.
+       if (!item->child) return 0;              /* memory fail */
+       value=skip(parse_value(child,skip(value)));     /* skip any spacing, get the value. */
        if (!value) return 0;
 
        while (*value==',')
        {
                cJSON *new_item;
-               if (!(new_item=cJSON_New_Item())) return 0;     // memory fail
+               if (!(new_item=cJSON_New_Item())) return 0;     /* memory fail */
                child->next=new_item;new_item->prev=child;child=new_item;
                value=skip(parse_value(child,skip(value+1)));
-               if (!value) return 0;   // memory fail
+               if (!value) return 0;   /* memory fail */
        }
 
-       if (*value==']') return value+1;        // end of array
-       return 0;       // malformed.
+       if (*value==']') return value+1;        /* end of array */
+       ep=value;return 0;      /* malformed. */
 }
 
-// Render an array to text
+/* Render an array to text */
 static char *print_array(cJSON *item,int depth,int fmt)
 {
        char **entries;
@@ -315,13 +347,13 @@ static char *print_array(cJSON *item,int depth,int fmt)
        cJSON *child=item->child;
        int numentries=0,i=0,fail=0;
        
-       // How many entries in the array?
+       /* How many entries in the array? */
        while (child) numentries++,child=child->next;
-       // Allocate an array to hold the values for each
+       /* Allocate an array to hold the values for each */
        entries=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!entries) return 0;
        memset(entries,0,numentries*sizeof(char*));
-       // Retrieve all the results:
+       /* Retrieve all the results: */
        child=item->child;
        while (child && !fail)
        {
@@ -331,12 +363,12 @@ static char *print_array(cJSON *item,int depth,int fmt)
                child=child->next;
        }
        
-       // If we didn't fail, try to malloc the output string
-       if (!fail) out=cJSON_malloc(len);
-       // If that fails, we fail.
+       /* If we didn't fail, try to malloc the output string */
+       if (!fail) out=(char*)cJSON_malloc(len);
+       /* If that fails, we fail. */
        if (!out) fail=1;
 
-       // Handle failure.
+       /* Handle failure. */
        if (fail)
        {
                for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
@@ -344,7 +376,7 @@ static char *print_array(cJSON *item,int depth,int fmt)
                return 0;
        }
        
-       // Compose the output array.
+       /* Compose the output array. */
        *out='[';
        ptr=out+1;*ptr=0;
        for (i=0;i<numentries;i++)
@@ -358,51 +390,52 @@ static char *print_array(cJSON *item,int depth,int fmt)
        return out;     
 }
 
-// Build an object from the text.
+/* Build an object from the text. */
 static const char *parse_object(cJSON *item,const char *value)
 {
        cJSON *child;
-       if (*value!='{')        return 0;       // not an object!
+       if (*value!='{')        {ep=value;return 0;}    /* not an object! */
        
        item->type=cJSON_Object;
        value=skip(value+1);
-       if (*value=='}') return value+1;        // empty array.
+       if (*value=='}') return value+1;        /* empty array. */
        
        item->child=child=cJSON_New_Item();
+       if (!item->child) return 0;
        value=skip(parse_string(child,skip(value)));
        if (!value) return 0;
        child->string=child->valuestring;child->valuestring=0;
-       if (*value!=':') return 0;      // fail!
-       value=skip(parse_value(child,skip(value+1)));   // skip any spacing, get the value.
+       if (*value!=':') {ep=value;return 0;}   /* fail! */
+       value=skip(parse_value(child,skip(value+1)));   /* skip any spacing, get the value. */
        if (!value) return 0;
        
        while (*value==',')
        {
                cJSON *new_item;
-               if (!(new_item=cJSON_New_Item()))       return 0; // memory fail
+               if (!(new_item=cJSON_New_Item()))       return 0; /* memory fail */
                child->next=new_item;new_item->prev=child;child=new_item;
                value=skip(parse_string(child,skip(value+1)));
                if (!value) return 0;
                child->string=child->valuestring;child->valuestring=0;
-               if (*value!=':') return 0;      // fail!
-               value=skip(parse_value(child,skip(value+1)));   // skip any spacing, get the value.             
+               if (*value!=':') {ep=value;return 0;}   /* fail! */
+               value=skip(parse_value(child,skip(value+1)));   /* skip any spacing, get the value. */
                if (!value) return 0;
        }
        
-       if (*value=='}') return value+1;        // end of array
-       return 0;       // malformed.   
+       if (*value=='}') return value+1;        /* end of array */
+       ep=value;return 0;      /* malformed. */
 }
 
-// Render an object to text.
+/* Render an object to text. */
 static char *print_object(cJSON *item,int depth,int fmt)
 {
        char **entries=0,**names=0;
        char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
        cJSON *child=item->child;
        int numentries=0,fail=0;
-       // Count the number of entries.
+       /* Count the number of entries. */
        while (child) numentries++,child=child->next;
-       // Allocate space for the names and the objects
+       /* Allocate space for the names and the objects */
        entries=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!entries) return 0;
        names=(char**)cJSON_malloc(numentries*sizeof(char*));
@@ -410,7 +443,7 @@ static char *print_object(cJSON *item,int depth,int fmt)
        memset(entries,0,sizeof(char*)*numentries);
        memset(names,0,sizeof(char*)*numentries);
 
-       // Collect all the results into our arrays:
+       /* Collect all the results into our arrays: */
        child=item->child;depth++;if (fmt) len+=depth;
        while (child)
        {
@@ -420,19 +453,19 @@ static char *print_object(cJSON *item,int depth,int fmt)
                child=child->next;
        }
        
-       // Try to allocate the output string
+       /* Try to allocate the output string */
        if (!fail) out=(char*)cJSON_malloc(len);
        if (!out) fail=1;
 
-       // Handle failure
+       /* Handle failure */
        if (fail)
        {
-               for (i=0;i<numentries;i++) {if (names[i]) free(names[i]);if (entries[i]) free(entries[i]);}
-               free(names);free(entries);
+               for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
+               cJSON_free(names);cJSON_free(entries);
                return 0;
        }
        
-       // Compose the output:
+       /* Compose the output: */
        *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
        for (i=0;i<numentries;i++)
        {
@@ -451,45 +484,46 @@ static char *print_object(cJSON *item,int depth,int fmt)
        return out;     
 }
 
-// Get Array size/item / object item.
-int    cJSON_GetArraySize(cJSON *array)                                                        {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
-cJSON *cJSON_GetArrayItem(cJSON *array,int item)                               {cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
-cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)   {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
+/* Get Array size/item / object item. */
+ESL_DECLARE(int)   cJSON_GetArraySize(cJSON *array)                                                    {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
+ESL_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item)                          {cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
+ESL_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string)      {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
 
-// Utility for array list handling.
+/* Utility for array list handling. */
 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
-// Utility for handling references.
-static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
+/* Utility for handling references. */
+static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
 
-// Add item to array/object.
-void   cJSON_AddItemToArray(cJSON *array, cJSON *item)                                         {cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
-void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)     {if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
-void   cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)                                                {cJSON_AddItemToArray(array,create_reference(item));}
-void   cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)    {cJSON_AddItemToObject(object,string,create_reference(item));}
+/* Add item to array/object. */
+ESL_DECLARE(void)  cJSON_AddItemToArray(cJSON *array, cJSON *item)                                             {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
+ESL_DECLARE(void)  cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
+ESL_DECLARE(void)      cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)                                                {cJSON_AddItemToArray(array,create_reference(item));}
+ESL_DECLARE(void)      cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)    {cJSON_AddItemToObject(object,string,create_reference(item));}
 
-cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)                       {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
+ESL_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which)                  {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
        if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
-void   cJSON_DeleteItemFromArray(cJSON *array,int which)                       {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
-cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
-void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
+ESL_DECLARE(void)  cJSON_DeleteItemFromArray(cJSON *array,int which)                   {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
+ESL_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
+ESL_DECLARE(void)  cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
 
-// Replace array/object items with new ones.
-void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)         {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
+/* Replace array/object items with new ones. */
+ESL_DECLARE(void)  cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)             {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
        newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
        if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
-void   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
-
-// Create basic types:
-cJSON *cJSON_CreateNull()                                              {cJSON *item=cJSON_New_Item();item->type=cJSON_NULL;return item;}
-cJSON *cJSON_CreateTrue()                                              {cJSON *item=cJSON_New_Item();item->type=cJSON_True;return item;}
-cJSON *cJSON_CreateFalse()                                             {cJSON *item=cJSON_New_Item();item->type=cJSON_False;return item;}
-cJSON *cJSON_CreateNumber(double num)                  {cJSON *item=cJSON_New_Item();item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;return item;}
-cJSON *cJSON_CreateString(const char *string)  {cJSON *item=cJSON_New_Item();item->type=cJSON_String;item->valuestring=cJSON_strdup(string);return item;}
-cJSON *cJSON_CreateArray()                                             {cJSON *item=cJSON_New_Item();item->type=cJSON_Array;return item;}
-cJSON *cJSON_CreateObject()                                            {cJSON *item=cJSON_New_Item();item->type=cJSON_Object;return item;}
-
-// Create Arrays:
-cJSON *cJSON_CreateIntArray(int *numbers,int count)                            {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
-cJSON *cJSON_CreateFloatArray(float *numbers,int count)                        {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
-cJSON *cJSON_CreateDoubleArray(double *numbers,int count)              {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
-cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+ESL_DECLARE(void)  cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
+
+/* Create basic types: */
+ESL_DECLARE(cJSON *)cJSON_CreateNull()                                         {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
+ESL_DECLARE(cJSON *)cJSON_CreateTrue()                                         {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
+ESL_DECLARE(cJSON *)cJSON_CreateFalse()                                                {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
+ESL_DECLARE(cJSON *)cJSON_CreateBool(int b)                                    {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
+ESL_DECLARE(cJSON *)cJSON_CreateNumber(double num)                     {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
+ESL_DECLARE(cJSON *)cJSON_CreateString(const char *string)     {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
+ESL_DECLARE(cJSON *)cJSON_CreateArray()                                                {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
+ESL_DECLARE(cJSON *)cJSON_CreateObject()                                               {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
+
+/* Create Arrays: */
+ESL_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count)                               {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+ESL_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count)                   {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+ESL_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count)         {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+ESL_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count)    {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
index 535498a06ce503dfee9faf164dd9a42bbef49bb9..615645597ac765dec5e14729ab90274346162479 100755 (executable)
@@ -19,9 +19,7 @@
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
 */
-
 #include "esl.h"
-
 #ifndef cJSON__h
 #define cJSON__h
 
@@ -30,7 +28,7 @@ extern "C"
 {
 #endif
 
-// cJSON Types:
+/* cJSON Types: */
 #define cJSON_False 0
 #define cJSON_True 1
 #define cJSON_NULL 2
@@ -41,18 +39,18 @@ extern "C"
        
 #define cJSON_IsReference 256
 
-// The cJSON structure:
+/* The cJSON structure: */
 typedef struct cJSON {
-       struct cJSON *next,*prev;       // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem
-       struct cJSON *child;            // An array or object item will have a child pointer pointing to a chain of the items in the array/object.
+       struct cJSON *next,*prev;       /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+       struct cJSON *child;            /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
 
-       int type;                                       // The type of the item, as above.
+       int type;                                       /* The type of the item, as above. */
 
-       char *valuestring;                      // The item's string, if type==cJSON_String
-       int valueint;                           // The item's number, if type==cJSON_Number
-       double valuedouble;                     // The item's number, if type==cJSON_Number
+       char *valuestring;                      /* The item's string, if type==cJSON_String */
+       int valueint;                           /* The item's number, if type==cJSON_Number */
+       double valuedouble;                     /* The item's number, if type==cJSON_Number */
 
-       char *string;                           // The item's name string, if this item is the child of, or is in the list of subitems of an object.
+       char *string;                           /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
 } cJSON;
 
 typedef struct cJSON_Hooks {
@@ -60,57 +58,61 @@ typedef struct cJSON_Hooks {
       void (*free_fn)(void *ptr);
 } cJSON_Hooks;
 
-// Supply malloc, realloc and free functions to cJSON
-extern void cJSON_InitHooks(cJSON_Hooks* hooks);
-
-
-// Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished.
-extern cJSON *cJSON_Parse(const char *value);
-// Render a cJSON entity to text for transfer/storage. Free the char* when finished.
-extern char  *cJSON_Print(cJSON *item);
-// Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished.
-extern char  *cJSON_PrintUnformatted(cJSON *item);
-// Delete a cJSON entity and all subentities.
-extern void   cJSON_Delete(cJSON *c);
-
-// Returns the number of items in an array (or object).
-extern int       cJSON_GetArraySize(cJSON *array);
-// Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
-extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
-// Get item "string" from object. Case insensitive.
-extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
+/* Supply malloc, realloc and free functions to cJSON */
+ESL_DECLARE(void) cJSON_InitHooks(cJSON_Hooks* hooks);
+
+
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
+ESL_DECLARE(cJSON *)cJSON_Parse(const char *value);
+/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
+ESL_DECLARE(char *)cJSON_Print(cJSON *item);
+/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
+ESL_DECLARE(char *)cJSON_PrintUnformatted(cJSON *item);
+/* Delete a cJSON entity and all subentities. */
+ESL_DECLARE(void)   cJSON_Delete(cJSON *c);
+
+/* Returns the number of items in an array (or object). */
+ESL_DECLARE(int)         cJSON_GetArraySize(cJSON *array);
+/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
+ESL_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item);
+/* Get item "string" from object. Case insensitive. */
+ESL_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string);
+
+/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+ESL_DECLARE(const char *)cJSON_GetErrorPtr();
        
-// These calls create a cJSON item of the appropriate type.
-extern cJSON *cJSON_CreateNull(void);
-extern cJSON *cJSON_CreateTrue(void);
-extern cJSON *cJSON_CreateFalse(void);
-extern cJSON *cJSON_CreateNumber(double num);
-extern cJSON *cJSON_CreateString(const char *string);
-extern cJSON *cJSON_CreateArray(void);
-extern cJSON *cJSON_CreateObject(void);
-
-// These utilities create an Array of count items.
-extern cJSON *cJSON_CreateIntArray(int *numbers,int count);
-extern cJSON *cJSON_CreateFloatArray(float *numbers,int count);
-extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count);
-extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
-
-// Append item to the specified array/object.
-extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
-extern void    cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
-// Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON.
-extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
-extern void    cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
-
-// Remove/Detatch items from Arrays/Objects.
-extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
-extern void   cJSON_DeleteItemFromArray(cJSON *array,int which);
-extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
-extern void   cJSON_DeleteItemFromObject(cJSON *object,const char *string);
+/* These calls create a cJSON item of the appropriate type. */
+ESL_DECLARE(cJSON *)cJSON_CreateNull();
+ESL_DECLARE(cJSON *)cJSON_CreateTrue();
+ESL_DECLARE(cJSON *)cJSON_CreateFalse();
+ESL_DECLARE(cJSON *)cJSON_CreateBool(int b);
+ESL_DECLARE(cJSON *)cJSON_CreateNumber(double num);
+ESL_DECLARE(cJSON *)cJSON_CreateString(const char *string);
+ESL_DECLARE(cJSON *)cJSON_CreateArray();
+ESL_DECLARE(cJSON *)cJSON_CreateObject();
+
+/* These utilities create an Array of count items. */
+ESL_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count);
+ESL_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count);
+ESL_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count);
+ESL_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count);
+
+/* Append item to the specified array/object. */
+ESL_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
+ESL_DECLARE(void)      cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
+/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
+ESL_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+ESL_DECLARE(void)      cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
+
+/* Remove/Detatch items from Arrays/Objects. */
+ESL_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which);
+ESL_DECLARE(void)   cJSON_DeleteItemFromArray(cJSON *array,int which);
+ESL_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string);
+ESL_DECLARE(void)   cJSON_DeleteItemFromObject(cJSON *object,const char *string);
        
-// Update array items.
-extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
-extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
+/* Update array items. */
+ESL_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
+ESL_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
 
 #define cJSON_AddNullToObject(object,name)     cJSON_AddItemToObject(object, name, cJSON_CreateNull())
 #define cJSON_AddTrueToObject(object,name)     cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
index 36f51be6dfd7bf1bb819822a2baf0b6b50a87f7b..c7baf9970d6cd35b42b6622f76ef4bed1727e32d 100755 (executable)
@@ -19,9 +19,7 @@
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
 */
-
 #include "switch.h"
-
 #ifndef cJSON__h
 #define cJSON__h
 
@@ -30,7 +28,7 @@ extern "C"
 {
 #endif
 
-// cJSON Types:
+/* cJSON Types: */
 #define cJSON_False 0
 #define cJSON_True 1
 #define cJSON_NULL 2
@@ -41,18 +39,18 @@ extern "C"
        
 #define cJSON_IsReference 256
 
-// The cJSON structure:
+/* The cJSON structure: */
 typedef struct cJSON {
-       struct cJSON *next,*prev;       // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem
-       struct cJSON *child;            // An array or object item will have a child pointer pointing to a chain of the items in the array/object.
+       struct cJSON *next,*prev;       /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+       struct cJSON *child;            /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
 
-       int type;                                       // The type of the item, as above.
+       int type;                                       /* The type of the item, as above. */
 
-       char *valuestring;                      // The item's string, if type==cJSON_String
-       int valueint;                           // The item's number, if type==cJSON_Number
-       double valuedouble;                     // The item's number, if type==cJSON_Number
+       char *valuestring;                      /* The item's string, if type==cJSON_String */
+       int valueint;                           /* The item's number, if type==cJSON_Number */
+       double valuedouble;                     /* The item's number, if type==cJSON_Number */
 
-       char *string;                           // The item's name string, if this item is the child of, or is in the list of subitems of an object.
+       char *string;                           /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
 } cJSON;
 
 typedef struct cJSON_Hooks {
@@ -60,55 +58,59 @@ typedef struct cJSON_Hooks {
       void (*free_fn)(void *ptr);
 } cJSON_Hooks;
 
-// Supply malloc, realloc and free functions to cJSON
+/* Supply malloc, realloc and free functions to cJSON */
 SWITCH_DECLARE(void) cJSON_InitHooks(cJSON_Hooks* hooks);
 
 
-// Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished.
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
 SWITCH_DECLARE(cJSON *)cJSON_Parse(const char *value);
-// Render a cJSON entity to text for transfer/storage. Free the char* when finished.
+/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
 SWITCH_DECLARE(char *)cJSON_Print(cJSON *item);
-// Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished.
+/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
 SWITCH_DECLARE(char *)cJSON_PrintUnformatted(cJSON *item);
-// Delete a cJSON entity and all subentities.
+/* Delete a cJSON entity and all subentities. */
 SWITCH_DECLARE(void)   cJSON_Delete(cJSON *c);
 
-// Returns the number of items in an array (or object).
+/* Returns the number of items in an array (or object). */
 SWITCH_DECLARE(int)      cJSON_GetArraySize(cJSON *array);
-// Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
+/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
 SWITCH_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item);
-// Get item "string" from object. Case insensitive.
+/* Get item "string" from object. Case insensitive. */
 SWITCH_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string);
+
+/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+SWITCH_DECLARE(const char *)cJSON_GetErrorPtr();
        
-// These calls create a cJSON item of the appropriate type.
-SWITCH_DECLARE(cJSON *)cJSON_CreateNull(void);
-SWITCH_DECLARE(cJSON *)cJSON_CreateTrue(void);
-SWITCH_DECLARE(cJSON *)cJSON_CreateFalse(void);
+/* These calls create a cJSON item of the appropriate type. */
+SWITCH_DECLARE(cJSON *)cJSON_CreateNull();
+SWITCH_DECLARE(cJSON *)cJSON_CreateTrue();
+SWITCH_DECLARE(cJSON *)cJSON_CreateFalse();
+SWITCH_DECLARE(cJSON *)cJSON_CreateBool(int b);
 SWITCH_DECLARE(cJSON *)cJSON_CreateNumber(double num);
 SWITCH_DECLARE(cJSON *)cJSON_CreateString(const char *string);
-SWITCH_DECLARE(cJSON *)cJSON_CreateArray(void);
-SWITCH_DECLARE(cJSON *)cJSON_CreateObject(void);
+SWITCH_DECLARE(cJSON *)cJSON_CreateArray();
+SWITCH_DECLARE(cJSON *)cJSON_CreateObject();
 
-// These utilities create an Array of count items.
+/* These utilities create an Array of count items. */
 SWITCH_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count);
 SWITCH_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count);
 SWITCH_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count);
 SWITCH_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count);
 
-// Append item to the specified array/object.
+/* Append item to the specified array/object. */
 SWITCH_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
 SWITCH_DECLARE(void)   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
-// Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON.
+/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
 SWITCH_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
 SWITCH_DECLARE(void)   cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
 
-// Remove/Detatch items from Arrays/Objects.
+/* Remove/Detatch items from Arrays/Objects. */
 SWITCH_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which);
 SWITCH_DECLARE(void)   cJSON_DeleteItemFromArray(cJSON *array,int which);
 SWITCH_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string);
 SWITCH_DECLARE(void)   cJSON_DeleteItemFromObject(cJSON *object,const char *string);
        
-// Update array items.
+/* Update array items. */
 SWITCH_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
 SWITCH_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
 
index 4bef601f8e4a3a3e9955b048c725acdf8f6a0287..005b32fd34fe4eab65fa5bee1ade49eab042da40 100644 (file)
   THE SOFTWARE.
 */
 
-// cJSON
-// JSON parser in C.
+/* cJSON */
+/* JSON parser in C. */
 
-#include "switch.h"
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
 #include <float.h>
+#include <limits.h>
+#include <ctype.h>
+#include "switch_json.h"
+#include "switch.h"
+
+static const char *ep;
+
+SWITCH_DECLARE(const char *)cJSON_GetErrorPtr() {return ep;}
 
 static int cJSON_strcasecmp(const char *s1,const char *s2)
 {
@@ -58,7 +69,7 @@ static char* cJSON_strdup(const char* str)
       return copy;
 }
 
-SWITCH_DECLARE(void) cJSON_InitHooks(cJSON_Hooks* hooks)
+SWITCH_DECLARE(void)cJSON_InitHooks(cJSON_Hooks* hooks)
 {
     if (!hooks) { /* Reset hooks */
         cJSON_malloc = malloc;
@@ -70,16 +81,16 @@ SWITCH_DECLARE(void) cJSON_InitHooks(cJSON_Hooks* hooks)
        cJSON_free       = (hooks->free_fn)?hooks->free_fn:free;
 }
 
-// Internal constructor.
-static cJSON *cJSON_New_Item(void)
+/* Internal constructor. */
+static cJSON *cJSON_New_Item()
 {
        cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
        if (node) memset(node,0,sizeof(cJSON));
        return node;
 }
 
-// Delete a cJSON structure.
-SWITCH_DECLARE(void) cJSON_Delete(cJSON *c)
+/* Delete a cJSON structure. */
+SWITCH_DECLARE(void)cJSON_Delete(cJSON *c)
 {
        cJSON *next;
        while (c)
@@ -93,22 +104,22 @@ SWITCH_DECLARE(void) cJSON_Delete(cJSON *c)
        }
 }
 
-// Parse the input text to generate a number, and populate the result into item.
+/* Parse the input text to generate a number, and populate the result into item. */
 static const char *parse_number(cJSON *item,const char *num)
 {
        double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
 
-       // Could use sscanf for this?
-       if (*num=='-') sign=-1,num++;   // Has sign?
-       if (*num=='0') num++;                   // is zero
-       if (*num>='1' && *num<='9')     do      n=(n*10.0)+(*num++ -'0');       while (*num>='0' && *num<='9'); // Number?
-       if (*num=='.') {num++;          do      n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}      // Fractional part?
-       if (*num=='e' || *num=='E')             // Exponent?
-       {       num++;if (*num=='+') num++;     else if (*num=='-') signsubscale=-1,num++;              // With sign?
-               while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');   // Number?
+       /* Could use sscanf for this? */
+       if (*num=='-') sign=-1,num++;   /* Has sign? */
+       if (*num=='0') num++;                   /* is zero */
+       if (*num>='1' && *num<='9')     do      n=(n*10.0)+(*num++ -'0');       while (*num>='0' && *num<='9'); /* Number? */
+       if (*num=='.' && num[1]>='0' && num[1]<='9') {num++;            do      n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}      /* Fractional part? */
+       if (*num=='e' || *num=='E')             /* Exponent? */
+       {       num++;if (*num=='+') num++;     else if (*num=='-') signsubscale=-1,num++;              /* With sign? */
+               while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');   /* Number? */
        }
 
-       n=sign*n*pow(10.0,(scale+subscale*signsubscale));       // number = +/- number.fraction * 10^+/- exponent
+       n=sign*n*pow(10.0,(scale+subscale*signsubscale));       /* number = +/- number.fraction * 10^+/- exponent */
        
        item->valuedouble=n;
        item->valueint=(int)n;
@@ -116,40 +127,43 @@ static const char *parse_number(cJSON *item,const char *num)
        return num;
 }
 
-// Render the number nicely from the given item into a string.
+/* Render the number nicely from the given item into a string. */
 static char *print_number(cJSON *item)
 {
        char *str;
        double d=item->valuedouble;
        if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
        {
-               str=(char*)cJSON_malloc(21);    // 2^64+1 can be represented in 21 chars.
-               sprintf(str,"%d",item->valueint);
+               str=(char*)cJSON_malloc(21);    /* 2^64+1 can be represented in 21 chars. */
+               if (str) sprintf(str,"%d",item->valueint);
        }
        else
        {
-               str=(char*)cJSON_malloc(64);    // This is a nice tradeoff.
-               if (fabs(floor(d)-d)<=DBL_EPSILON)                      sprintf(str,"%.0f",d);
-               else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)       sprintf(str,"%e",d);
-               else                                                                            sprintf(str,"%f",d);
+               str=(char*)cJSON_malloc(64);    /* This is a nice tradeoff. */
+               if (str)
+               {
+                       if (fabs(floor(d)-d)<=DBL_EPSILON)                      sprintf(str,"%.0f",d);
+                       else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)       sprintf(str,"%e",d);
+                       else                                                                            sprintf(str,"%f",d);
+               }
        }
        return str;
 }
 
-// Parse the input text into an unescaped cstring, and populate item.
+/* Parse the input text into an unescaped cstring, and populate item. */
 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
 static const char *parse_string(cJSON *item,const char *str)
 {
-       const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
-       if (*str!='\"') return 0;       // not a string!
+       const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
+       if (*str!='\"') {ep=str;return 0;}      /* not a string! */
        
-       while (*ptr!='\"' && (unsigned char)*ptr>31 && ++len) if (*ptr++ == '\\') ptr++;        // Skip escaped quotes.
+       while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;  /* Skip escaped quotes. */
        
-       out=(char*)cJSON_malloc(len+1); // This is how long we need for the string, roughly.
+       out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
        if (!out) return 0;
        
        ptr=str+1;ptr2=out;
-       while (*ptr!='\"' && (unsigned char)*ptr>31)
+       while (*ptr!='\"' && *ptr)
        {
                if (*ptr!='\\') *ptr2++=*ptr++;
                else
@@ -162,16 +176,31 @@ static const char *parse_string(cJSON *item,const char *str)
                                case 'n': *ptr2++='\n'; break;
                                case 'r': *ptr2++='\r'; break;
                                case 't': *ptr2++='\t'; break;
-                               case 'u':        // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
-                                       if (sscanf(ptr+1,"%4x",&uc) < 1) break; // get the unicode char.
-                                       len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
+                               case 'u':        /* transcode utf16 to utf8. */
+                                       if (sscanf(ptr+1,"%4x",&uc) < 1) break;
+
+                                       ptr+=4; /* get the unicode char. */
+
+                                       if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)        break;  // check for invalid.
+
+                                       if (uc>=0xD800 && uc<=0xDBFF)   // UTF16 surrogate pairs.
+                                       {
+                                               if (ptr[1]!='\\' || ptr[2]!='u')        break;  // missing second-half of surrogate.
+                                               if (sscanf(ptr+3,"%4x",&uc2) < 1) break;
+                                               ptr+=6;
+                                               if (uc2<0xDC00 || uc2>0xDFFF)           break;  // invalid second-half of surrogate.
+                                               uc=0x10000 | ((uc&0x3FF)<<10) | (uc2&0x3FF);
+                                       }
+
+                                       len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
                                        
                                        switch (len) {
+                                               case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                                                case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                                                case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
                                                case 1: *--ptr2 =(char)(uc | firstByteMark[len]);
                                        }
-                                       ptr2+=len;ptr+=4;
+                                       ptr2+=len;
                                        break;
                                default:  *ptr2++=*ptr; break;
                        }
@@ -185,15 +214,17 @@ static const char *parse_string(cJSON *item,const char *str)
        return ptr;
 }
 
-// Render the cstring provided to an escaped version that can be printed.
+/* Render the cstring provided to an escaped version that can be printed. */
 static char *print_string_ptr(const char *str)
 {
-       const char *ptr;char *ptr2,*out;int len=0;
+       const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
        
        if (!str) return cJSON_strdup("");
-       ptr=str;while (*ptr && ++len) {if ((unsigned char)*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
+       ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
        
        out=(char*)cJSON_malloc(len+3);
+       if (!out) return 0;
+
        ptr2=out;ptr=str;
        *ptr2++='\"';
        while (*ptr)
@@ -202,7 +233,7 @@ static char *print_string_ptr(const char *str)
                else
                {
                        *ptr2++='\\';
-                       switch (*ptr++)
+                       switch (token=*ptr++)
                        {
                                case '\\':      *ptr2++='\\';   break;
                                case '\"':      *ptr2++='\"';   break;
@@ -211,17 +242,17 @@ static char *print_string_ptr(const char *str)
                                case '\n':      *ptr2++='n';    break;
                                case '\r':      *ptr2++='r';    break;
                                case '\t':      *ptr2++='t';    break;
-                               default: ptr2--;        break;  // eviscerate with prejudice.
+                               default: sprintf(ptr2,"u%04x",token);ptr2+=5;   break;  /* escape and print */
                        }
                }
        }
        *ptr2++='\"';*ptr2++=0;
        return out;
 }
-// Invote print_string_ptr (which is useful) on an item.
+/* Invote print_string_ptr (which is useful) on an item. */
 static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
 
-// Predeclare these prototypes.
+/* Predeclare these prototypes. */
 static const char *parse_value(cJSON *item,const char *value);
 static char *print_value(cJSON *item,int depth,int fmt);
 static const char *parse_array(cJSON *item,const char *value);
@@ -229,27 +260,28 @@ static char *print_array(cJSON *item,int depth,int fmt);
 static const char *parse_object(cJSON *item,const char *value);
 static char *print_object(cJSON *item,int depth,int fmt);
 
-// Utility to jump whitespace and cr/lf
-static const char *skip(const char *in) {while (in && (unsigned char)*in<=32) in++; return in;}
+/* Utility to jump whitespace and cr/lf */
+static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
 
-// Parse an object - create a new root, and populate.
+/* Parse an object - create a new root, and populate. */
 SWITCH_DECLARE(cJSON *)cJSON_Parse(const char *value)
 {
        cJSON *c=cJSON_New_Item();
+       ep=0;
        if (!c) return 0;       /* memory fail */
 
        if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;}
        return c;
 }
 
-// Render a cJSON item/entity/structure to text.
-SWITCH_DECLARE(char *)cJSON_Print(cJSON *item)                         {return print_value(item,0,1);}
-SWITCH_DECLARE(char *)cJSON_PrintUnformatted(cJSON *item)      {return print_value(item,0,0);}
+/* Render a cJSON item/entity/structure to text. */
+char *cJSON_Print(cJSON *item)                         {return print_value(item,0,1);}
+char *cJSON_PrintUnformatted(cJSON *item)      {return print_value(item,0,0);}
 
-// Parser core - when encountering text, process appropriately.
+/* Parser core - when encountering text, process appropriately. */
 static const char *parse_value(cJSON *item,const char *value)
 {
-       if (!value)                                             return 0;       // Fail on null.
+       if (!value)                                             return 0;       /* Fail on null. */
        if (!strncmp(value,"null",4))   { item->type=cJSON_NULL;  return value+4; }
        if (!strncmp(value,"false",5))  { item->type=cJSON_False; return value+5; }
        if (!strncmp(value,"true",4))   { item->type=cJSON_True; item->valueint=1;      return value+4; }
@@ -258,10 +290,10 @@ static const char *parse_value(cJSON *item,const char *value)
        if (*value=='[')                                { return parse_array(item,value); }
        if (*value=='{')                                { return parse_object(item,value); }
 
-       return 0;       // failure.
+       ep=value;return 0;      /* failure. */
 }
 
-// Render a value to text.
+/* Render a value to text. */
 static char *print_value(cJSON *item,int depth,int fmt)
 {
        char *out=0;
@@ -279,35 +311,35 @@ static char *print_value(cJSON *item,int depth,int fmt)
        return out;
 }
 
-// Build an array from input text.
+/* Build an array from input text. */
 static const char *parse_array(cJSON *item,const char *value)
 {
        cJSON *child;
-       if (*value!='[')        return 0;       // not an array!
+       if (*value!='[')        {ep=value;return 0;}    /* not an array! */
 
        item->type=cJSON_Array;
        value=skip(value+1);
-       if (*value==']') return value+1;        // empty array.
+       if (*value==']') return value+1;        /* empty array. */
 
        item->child=child=cJSON_New_Item();
-       if (!item->child) return 0;              // memory fail
-       value=skip(parse_value(child,skip(value)));     // skip any spacing, get the value.
+       if (!item->child) return 0;              /* memory fail */
+       value=skip(parse_value(child,skip(value)));     /* skip any spacing, get the value. */
        if (!value) return 0;
 
        while (*value==',')
        {
                cJSON *new_item;
-               if (!(new_item=cJSON_New_Item())) return 0;     // memory fail
+               if (!(new_item=cJSON_New_Item())) return 0;     /* memory fail */
                child->next=new_item;new_item->prev=child;child=new_item;
                value=skip(parse_value(child,skip(value+1)));
-               if (!value) return 0;   // memory fail
+               if (!value) return 0;   /* memory fail */
        }
 
-       if (*value==']') return value+1;        // end of array
-       return 0;       // malformed.
+       if (*value==']') return value+1;        /* end of array */
+       ep=value;return 0;      /* malformed. */
 }
 
-// Render an array to text
+/* Render an array to text */
 static char *print_array(cJSON *item,int depth,int fmt)
 {
        char **entries;
@@ -315,13 +347,13 @@ static char *print_array(cJSON *item,int depth,int fmt)
        cJSON *child=item->child;
        int numentries=0,i=0,fail=0;
        
-       // How many entries in the array?
+       /* How many entries in the array? */
        while (child) numentries++,child=child->next;
-       // Allocate an array to hold the values for each
+       /* Allocate an array to hold the values for each */
        entries=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!entries) return 0;
        memset(entries,0,numentries*sizeof(char*));
-       // Retrieve all the results:
+       /* Retrieve all the results: */
        child=item->child;
        while (child && !fail)
        {
@@ -331,12 +363,12 @@ static char *print_array(cJSON *item,int depth,int fmt)
                child=child->next;
        }
        
-       // If we didn't fail, try to malloc the output string
-       if (!fail) out=cJSON_malloc(len);
-       // If that fails, we fail.
+       /* If we didn't fail, try to malloc the output string */
+       if (!fail) out=(char*)cJSON_malloc(len);
+       /* If that fails, we fail. */
        if (!out) fail=1;
 
-       // Handle failure.
+       /* Handle failure. */
        if (fail)
        {
                for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
@@ -344,7 +376,7 @@ static char *print_array(cJSON *item,int depth,int fmt)
                return 0;
        }
        
-       // Compose the output array.
+       /* Compose the output array. */
        *out='[';
        ptr=out+1;*ptr=0;
        for (i=0;i<numentries;i++)
@@ -358,51 +390,52 @@ static char *print_array(cJSON *item,int depth,int fmt)
        return out;     
 }
 
-// Build an object from the text.
+/* Build an object from the text. */
 static const char *parse_object(cJSON *item,const char *value)
 {
        cJSON *child;
-       if (*value!='{')        return 0;       // not an object!
+       if (*value!='{')        {ep=value;return 0;}    /* not an object! */
        
        item->type=cJSON_Object;
        value=skip(value+1);
-       if (*value=='}') return value+1;        // empty array.
+       if (*value=='}') return value+1;        /* empty array. */
        
        item->child=child=cJSON_New_Item();
+       if (!item->child) return 0;
        value=skip(parse_string(child,skip(value)));
        if (!value) return 0;
        child->string=child->valuestring;child->valuestring=0;
-       if (*value!=':') return 0;      // fail!
-       value=skip(parse_value(child,skip(value+1)));   // skip any spacing, get the value.
+       if (*value!=':') {ep=value;return 0;}   /* fail! */
+       value=skip(parse_value(child,skip(value+1)));   /* skip any spacing, get the value. */
        if (!value) return 0;
        
        while (*value==',')
        {
                cJSON *new_item;
-               if (!(new_item=cJSON_New_Item()))       return 0; // memory fail
+               if (!(new_item=cJSON_New_Item()))       return 0; /* memory fail */
                child->next=new_item;new_item->prev=child;child=new_item;
                value=skip(parse_string(child,skip(value+1)));
                if (!value) return 0;
                child->string=child->valuestring;child->valuestring=0;
-               if (*value!=':') return 0;      // fail!
-               value=skip(parse_value(child,skip(value+1)));   // skip any spacing, get the value.             
+               if (*value!=':') {ep=value;return 0;}   /* fail! */
+               value=skip(parse_value(child,skip(value+1)));   /* skip any spacing, get the value. */
                if (!value) return 0;
        }
        
-       if (*value=='}') return value+1;        // end of array
-       return 0;       // malformed.   
+       if (*value=='}') return value+1;        /* end of array */
+       ep=value;return 0;      /* malformed. */
 }
 
-// Render an object to text.
+/* Render an object to text. */
 static char *print_object(cJSON *item,int depth,int fmt)
 {
        char **entries=0,**names=0;
        char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
        cJSON *child=item->child;
        int numentries=0,fail=0;
-       // Count the number of entries.
+       /* Count the number of entries. */
        while (child) numentries++,child=child->next;
-       // Allocate space for the names and the objects
+       /* Allocate space for the names and the objects */
        entries=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!entries) return 0;
        names=(char**)cJSON_malloc(numentries*sizeof(char*));
@@ -410,7 +443,7 @@ static char *print_object(cJSON *item,int depth,int fmt)
        memset(entries,0,sizeof(char*)*numentries);
        memset(names,0,sizeof(char*)*numentries);
 
-       // Collect all the results into our arrays:
+       /* Collect all the results into our arrays: */
        child=item->child;depth++;if (fmt) len+=depth;
        while (child)
        {
@@ -420,19 +453,19 @@ static char *print_object(cJSON *item,int depth,int fmt)
                child=child->next;
        }
        
-       // Try to allocate the output string
+       /* Try to allocate the output string */
        if (!fail) out=(char*)cJSON_malloc(len);
        if (!out) fail=1;
 
-       // Handle failure
+       /* Handle failure */
        if (fail)
        {
-               for (i=0;i<numentries;i++) {if (names[i]) free(names[i]);if (entries[i]) free(entries[i]);}
-               free(names);free(entries);
+               for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
+               cJSON_free(names);cJSON_free(entries);
                return 0;
        }
        
-       // Compose the output:
+       /* Compose the output: */
        *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
        for (i=0;i<numentries;i++)
        {
@@ -451,45 +484,46 @@ static char *print_object(cJSON *item,int depth,int fmt)
        return out;     
 }
 
-// Get Array size/item / object item.
-SWITCH_DECLARE(int)    cJSON_GetArraySize(cJSON *array)                                                        {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
+/* Get Array size/item / object item. */
+SWITCH_DECLARE(int)   cJSON_GetArraySize(cJSON *array)                                                 {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
 SWITCH_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item)                               {cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
 SWITCH_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string)   {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
 
-// Utility for array list handling.
+/* Utility for array list handling. */
 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
-// Utility for handling references.
-static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
+/* Utility for handling references. */
+static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
 
-// Add item to array/object.
-SWITCH_DECLARE(void)   cJSON_AddItemToArray(cJSON *array, cJSON *item)                                         {cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
-SWITCH_DECLARE(void)   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)     {if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
+/* Add item to array/object. */
+SWITCH_DECLARE(void)  cJSON_AddItemToArray(cJSON *array, cJSON *item)                                          {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
+SWITCH_DECLARE(void)  cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)      {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
 SWITCH_DECLARE(void)   cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)                                                {cJSON_AddItemToArray(array,create_reference(item));}
 SWITCH_DECLARE(void)   cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)    {cJSON_AddItemToObject(object,string,create_reference(item));}
 
 SWITCH_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which)                       {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
        if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
-SWITCH_DECLARE(void)   cJSON_DeleteItemFromArray(cJSON *array,int which)                       {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
+SWITCH_DECLARE(void)  cJSON_DeleteItemFromArray(cJSON *array,int which)                        {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
 SWITCH_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
-SWITCH_DECLARE(void)   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
+SWITCH_DECLARE(void)  cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
 
-// Replace array/object items with new ones.
-SWITCH_DECLARE(void)   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)         {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
+/* Replace array/object items with new ones. */
+SWITCH_DECLARE(void)  cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)          {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
        newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
        if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
-SWITCH_DECLARE(void)   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
-
-// Create basic types:
-SWITCH_DECLARE(cJSON *)cJSON_CreateNull()                                              {cJSON *item=cJSON_New_Item();item->type=cJSON_NULL;return item;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateTrue()                                              {cJSON *item=cJSON_New_Item();item->type=cJSON_True;return item;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateFalse()                                             {cJSON *item=cJSON_New_Item();item->type=cJSON_False;return item;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateNumber(double num)                  {cJSON *item=cJSON_New_Item();item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;return item;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateString(const char *string)  {cJSON *item=cJSON_New_Item();item->type=cJSON_String;item->valuestring=cJSON_strdup(string);return item;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateArray()                                             {cJSON *item=cJSON_New_Item();item->type=cJSON_Array;return item;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateObject()                                            {cJSON *item=cJSON_New_Item();item->type=cJSON_Object;return item;}
-
-// Create Arrays:
-SWITCH_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count)                            {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count)                        {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count)              {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
-SWITCH_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+SWITCH_DECLARE(void)  cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
+
+/* Create basic types: */
+SWITCH_DECLARE(cJSON *)cJSON_CreateNull()                                              {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateTrue()                                              {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateFalse()                                             {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateBool(int b)                                 {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateNumber(double num)                  {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateString(const char *string)  {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateArray()                                             {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateObject()                                            {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
+
+/* Create Arrays: */
+SWITCH_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count)                            {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count)                        {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count)              {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+SWITCH_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}