3 Copyright (c) 2009 Dave Gamble
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 /* JSON parser in C. */
29 #include "komodo_cJSON.h"
33 #define DBL_EPSILON 2.2204460492503131E-16
36 static const char *ep;
38 long stripquotes(char *str)
44 if ( str[0] == '"' && str[len-1] == '"' )
45 str[len-1] = 0, offset = 1;
50 static int32_t cJSON_strcasecmp(const char *s1,const char *s2)
52 if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
53 for(; tolower((int32_t)(*s1)) == tolower((int32_t)(*s2)); ++s1, ++s2) if(*s1 == 0) return 0;
54 return tolower((int32_t)(*(const unsigned char *)s1)) - tolower((int32_t)(*(const unsigned char *)s2));
57 // the following written by jl777
58 /******************************************************************************
59 * Copyright © 2014-2017 The SuperNET Developers. *
61 * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
62 * the top-level directory of this distribution for the individual copyright *
63 * holder information and the developer policies on copyright and licensing. *
65 * Unless otherwise agreed in a custom licensing agreement, no part of the *
66 * SuperNET software, including this file may be copied, modified, propagated *
67 * or distributed except according to the terms contained in the LICENSE file *
69 * Removal or modification of this copyright notice is prohibited. *
71 ******************************************************************************/
73 void copy_cJSON(struct destbuf *dest,cJSON *obj)
81 str = cJSON_Print(obj);
84 offset = stripquotes(str);
85 //strcpy(dest,str+offset);
86 for (i=0; i<MAX_JSON_FIELD-1; i++)
87 if ( (dest->buf[i]= str[offset+i]) == 0 )
95 void copy_cJSON2(char *dest,int32_t maxlen,cJSON *obj)
100 if ( maxlen > sizeof(tmp.buf) )
101 maxlen = sizeof(tmp.buf);
102 copy_cJSON(&tmp,obj);
103 if ( strlen(tmp.buf) < maxlen )
104 strcpy(dest,tmp.buf);
108 int64_t _get_cJSON_int(cJSON *json)
113 copy_cJSON(&tmp,json);
114 if ( tmp.buf[0] != 0 )
115 return(calc_nxt64bits(tmp.buf));
120 int64_t get_cJSON_int(cJSON *json,char *field)
125 numjson = cJSON_GetObjectItem(json,field);
127 return(_get_cJSON_int(numjson));
132 int64_t conv_floatstr(char *numstr)
136 corr = (val < 0.) ? -0.50000000001 : 0.50000000001;
137 return((int64_t)(val * SATOSHIDEN + corr));
140 int64_t _conv_cJSON_float(cJSON *json)
142 int64_t conv_floatstr(char *);
146 copy_cJSON(&tmp,json);
147 return(conv_floatstr(tmp.buf));
152 int64_t conv_cJSON_float(cJSON *json,char *field)
155 return(_conv_cJSON_float(cJSON_GetObjectItem(json,field)));
159 int32_t extract_cJSON_str(char *dest,int32_t max,cJSON *json,char *field)
161 int32_t safecopy(char *dest,char *src,long len);
167 obj = cJSON_GetObjectItem(json,field);
170 str = cJSON_Print(obj);
171 offset = stripquotes(str);
172 len = safecopy(dest,str+offset,max);
179 cJSON *gen_list_json(char **list)
182 array = cJSON_CreateArray();
183 while ( list != 0 && *list != 0 && *list[0] != 0 )
185 item = cJSON_CreateString(*list++);
186 cJSON_AddItemToArray(array,item);
191 uint64_t get_API_nxt64bits(cJSON *obj)
193 uint64_t nxt64bits = 0;
197 if ( cJSON_IsNumber(obj) != 0 )
198 return((uint64_t)obj->valuedouble);
199 copy_cJSON(&tmp,obj);
200 nxt64bits = calc_nxt64bits(tmp.buf);
204 uint64_t j64bits(cJSON *json,char *field) { if ( field == 0 ) return(get_API_nxt64bits(json)); return(get_API_nxt64bits(cJSON_GetObjectItem(json,field))); }
205 uint64_t j64bitsi(cJSON *json,int32_t i) { return(get_API_nxt64bits(cJSON_GetArrayItem(json,i))); }
207 uint64_t get_satoshi_obj(cJSON *json,char *field)
210 uint64_t prev,satoshis,mult = 1;
211 struct destbuf numstr,checkstr;
213 numjson = cJSON_GetObjectItem(json,field);
214 copy_cJSON(&numstr,numjson);
215 satoshis = prev = 0; mult = 1; n = (int32_t)strlen(numstr.buf);
216 for (i=n-1; i>=0; i--,mult*=10)
218 satoshis += (mult * (numstr.buf[i] - '0'));
219 if ( satoshis < prev )
220 printf("get_satoshi_obj numstr.(%s) i.%d prev.%llu vs satoshis.%llu\n",numstr.buf,i,(unsigned long long)prev,(unsigned long long)satoshis);
223 sprintf(checkstr.buf,"%llu",(long long)satoshis);
224 if ( strcmp(checkstr.buf,numstr.buf) != 0 )
226 printf("SATOSHI GREMLIN?? numstr.(%s) -> %.8f -> (%s)\n",numstr.buf,dstr(satoshis),checkstr.buf);
231 void add_satoshis_json(cJSON *json,char *field,uint64_t satoshis)
235 sprintf(numstr,"%lld",(long long)satoshis);
236 obj = cJSON_CreateString(numstr);
237 cJSON_AddItemToObject(json,field,obj);
238 if ( satoshis != get_satoshi_obj(json,field) )
239 printf("error adding satoshi obj %ld -> %ld\n",(unsigned long)satoshis,(unsigned long)get_satoshi_obj(json,field));
242 char *cJSON_str(cJSON *json)
244 if ( json != 0 && cJSON_IsString(json) != 0 )
245 return(json->valuestring);
249 void jadd(cJSON *json,char *field,cJSON *item) { if ( json != 0 )cJSON_AddItemToObject(json,field,item); }
250 void jaddstr(cJSON *json,char *field,char *str) { if ( json != 0 && str != 0 ) cJSON_AddItemToObject(json,field,cJSON_CreateString(str)); }
251 void jaddnum(cJSON *json,char *field,double num) { if ( json != 0 )cJSON_AddItemToObject(json,field,cJSON_CreateNumber(num)); }
252 void jadd64bits(cJSON *json,char *field,uint64_t nxt64bits) { char numstr[64]; sprintf(numstr,"%llu",(long long)nxt64bits), jaddstr(json,field,numstr); }
253 void jaddi(cJSON *json,cJSON *item) { if ( json != 0 ) cJSON_AddItemToArray(json,item); }
254 void jaddistr(cJSON *json,char *str) { if ( json != 0 ) cJSON_AddItemToArray(json,cJSON_CreateString(str)); }
255 void jaddinum(cJSON *json,double num) { if ( json != 0 ) cJSON_AddItemToArray(json,cJSON_CreateNumber(num)); }
256 void jaddi64bits(cJSON *json,uint64_t nxt64bits) { char numstr[64]; sprintf(numstr,"%llu",(long long)nxt64bits), jaddistr(json,numstr); }
257 char *jstr(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == 0 ) return(cJSON_str(json)); return(cJSON_str(cJSON_GetObjectItem(json,field))); }
259 char *jstri(cJSON *json,int32_t i) { return(cJSON_str(cJSON_GetArrayItem(json,i))); }
260 char *jprint(cJSON *json,int32_t freeflag)
263 /*static portable_mutex_t mutex; static int32_t initflag;
266 portable_mutex_init(&mutex);
270 return(clonestr((char *)"{}"));
271 //portable_mutex_lock(&mutex);
273 str = cJSON_Print(json), _stripwhite(str,' ');
276 //portable_mutex_unlock(&mutex);
280 bits256 get_API_bits256(cJSON *obj)
282 bits256 hash; char *str;
283 memset(hash.bytes,0,sizeof(hash));
286 if ( cJSON_IsString(obj) != 0 && (str= obj->valuestring) != 0 && strlen(str) == 64 )
287 decode_hex(hash.bytes,sizeof(hash),str);
291 bits256 jbits256(cJSON *json,char *field) { if ( field == 0 ) return(get_API_bits256(json)); return(get_API_bits256(cJSON_GetObjectItem(json,field))); }
292 bits256 jbits256i(cJSON *json,int32_t i) { return(get_API_bits256(cJSON_GetArrayItem(json,i))); }
293 void jaddbits256(cJSON *json,char *field,bits256 hash) { char str[65]; bits256_str(str,hash), jaddstr(json,field,str); }
294 void jaddibits256(cJSON *json,bits256 hash) { char str[65]; bits256_str(str,hash), jaddistr(json,str); }
296 char *get_cJSON_fieldname(cJSON *obj)
300 if ( obj->child != 0 && obj->child->string != 0 )
301 return(obj->child->string);
302 else if ( obj->string != 0 )
305 return((char *)"<no cJSON string field>");
308 int32_t jnum(cJSON *obj,char *field)
310 char *str; int32_t polarity = 1;
312 obj = jobj(obj,field);
315 if ( cJSON_IsNumber(obj) != 0 )
316 return(obj->valuedouble);
317 else if ( cJSON_IsString(obj) != 0 && (str= jstr(obj,0)) != 0 )
320 polarity = -1, str++;
321 return(polarity * (int32_t)calc_nxt64bits(str));
327 void ensure_jsonitem(cJSON *json,char *field,char *value)
329 cJSON *obj = cJSON_GetObjectItem(json,field);
331 cJSON_AddItemToObject(json,field,cJSON_CreateString(value));
332 else cJSON_ReplaceItemInObject(json,field,cJSON_CreateString(value));
335 int32_t in_jsonarray(cJSON *array,char *value)
338 struct destbuf remote;
339 if ( array != 0 && cJSON_IsArray(array) != 0 )
341 n = cJSON_GetArraySize(array);
344 if ( array == 0 || n == 0 )
346 copy_cJSON(&remote,cJSON_GetArrayItem(array,i));
347 if ( strcmp(remote.buf,value) == 0 )
354 int32_t myatoi(char *str,int32_t range)
357 x = strtol(str,&ptr,10);
358 if ( range != 0 && x >= range )
363 int32_t get_API_int(cJSON *obj,int32_t val)
368 if ( cJSON_IsNumber(obj) != 0 )
369 return((int32_t)obj->valuedouble);
370 copy_cJSON(&buf,obj);
371 val = myatoi(buf.buf,0);
378 int32_t jint(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == 0 ) return(get_API_int(json,0)); return(get_API_int(cJSON_GetObjectItem(json,field),0)); }
379 int32_t jinti(cJSON *json,int32_t i) { if ( json == 0 ) return(0); return(get_API_int(cJSON_GetArrayItem(json,i),0)); }
381 uint32_t get_API_uint(cJSON *obj,uint32_t val)
386 if ( cJSON_IsNumber(obj) != 0 )
387 return((uint32_t)obj->valuedouble);
388 copy_cJSON(&buf,obj);
389 val = myatoi(buf.buf,0);
393 uint32_t juint(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == 0 ) return(get_API_uint(json,0)); return(get_API_uint(cJSON_GetObjectItem(json,field),0)); }
394 uint32_t juinti(cJSON *json,int32_t i) { if ( json == 0 ) return(0); return(get_API_uint(cJSON_GetArrayItem(json,i),0)); }
396 double get_API_float(cJSON *obj)
402 if ( cJSON_IsNumber(obj) != 0 )
403 return(obj->valuedouble);
404 copy_cJSON(&buf,obj);
410 double jdouble(cJSON *json,char *field)
415 return(get_API_float(json));
416 else return(get_API_float(cJSON_GetObjectItem(json,field)));
420 double jdoublei(cJSON *json,int32_t i)
423 return(get_API_float(cJSON_GetArrayItem(json,i)));
427 cJSON *jobj(cJSON *json,char *field) { if ( json != 0 ) return(cJSON_GetObjectItem(json,field)); return(0); }
429 void jdelete(cJSON *json,char *field)
431 if ( jobj(json,field) != 0 )
432 cJSON_DeleteItemFromObject(json,field);
435 cJSON *jduplicate(cJSON *json) { return(cJSON_Duplicate(json,1)); }
437 cJSON *jitem(cJSON *array,int32_t i) { if ( array != 0 && cJSON_IsArray(array) != 0 && cJSON_GetArraySize(array) > i ) return(cJSON_GetArrayItem(array,i)); return(0); }
438 cJSON *jarray(int32_t *nump,cJSON *json,char *field)
445 else array = cJSON_GetObjectItem(json,field);
446 if ( array != 0 && cJSON_IsArray(array) != 0 && (*nump= cJSON_GetArraySize(array)) > 0 )
453 int32_t expand_nxt64bits(char *NXTaddr,uint64_t nxt64bits)
458 for (i=0; nxt64bits!=0; i++)
460 modval = nxt64bits % 10;
461 rev[i] = (char)(modval + '0');
466 NXTaddr[i] = rev[n-1-i];
471 char *nxt64str(uint64_t nxt64bits)
473 static char NXTaddr[64];
474 expand_nxt64bits(NXTaddr,nxt64bits);
478 char *nxt64str2(uint64_t nxt64bits)
480 static char NXTaddr[64];
481 expand_nxt64bits(NXTaddr,nxt64bits);
485 int32_t cmp_nxt64bits(const char *str,uint64_t nxt64bits)
488 if ( str == 0 )//|| str[0] == 0 || nxt64bits == 0 )
490 if ( nxt64bits == 0 && str[0] == 0 )
492 expand_nxt64bits(expanded,nxt64bits);
493 return(strcmp(str,expanded));
496 uint64_t calc_nxt64bits(const char *NXTaddr)
499 int64_t n,i,polarity = 1;
500 uint64_t lastval,mult,nxt64bits = 0;
503 printf("calling calc_nxt64bits with null ptr!\n");
509 printf("calc_nxt64bits: illegal NXTaddr.(%s) too long\n",NXTaddr);
512 else if ( strcmp(NXTaddr,"0") == 0 || strcmp(NXTaddr,"false") == 0 )
514 // printf("zero address?\n"); getchar();
517 if ( NXTaddr[0] == '-' )
518 polarity = -1, NXTaddr++, n--;
521 for (i=n-1; i>=0; i--,mult*=10)
524 if ( c < '0' || c > '9' )
526 printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i);
531 printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i);
536 nxt64bits += mult * (c - '0');
537 if ( nxt64bits < lastval )
538 printf("calc_nxt64bits: warning: 64bit overflow %llx < %llx\n",(long long)nxt64bits,(long long)lastval);
541 while ( *NXTaddr == '0' && *NXTaddr != 0 )
543 if ( cmp_nxt64bits(NXTaddr,nxt64bits) != 0 )
544 printf("error calculating nxt64bits: %s -> %llx -> %s\n",NXTaddr,(long long)nxt64bits,nxt64str(nxt64bits));
546 return(-(int64_t)nxt64bits);
550 cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num)
552 int32_t j; cJSON *array;
553 array = cJSON_CreateArray();
554 for (j=0; j<num; j++)
555 jaddi64bits(array,addrs[j]);
559 void free_json(cJSON *json) { if ( json != 0 ) cJSON_Delete(json); }