]> Git Repo - VerusCoin.git/blob - src/komodo_cJSON.c
Merge pull request #495 from jl777/dev
[VerusCoin.git] / src / komodo_cJSON.c
1
2 /*
3  Copyright (c) 2009 Dave Gamble
4  
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:
11  
12  The above copyright notice and this permission notice shall be included in
13  all copies or substantial portions of the Software.
14  
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
21  THE SOFTWARE.
22  */
23
24 /* cJSON */
25 /* JSON parser in C. */
26 #include <math.h>
27
28 #include "cJSON.h"
29 #include "komodo_cJSON.h"
30 #include "cJSON.c"
31
32 #ifndef DBL_EPSILON
33 #define DBL_EPSILON 2.2204460492503131E-16
34 #endif
35
36 static const char *ep;
37
38 long stripquotes(char *str)
39 {
40     long len,offset;
41     if ( str == 0 )
42         return(0);
43     len = strlen(str);
44     if ( str[0] == '"' && str[len-1] == '"' )
45         str[len-1] = 0, offset = 1;
46     else offset = 0;
47     return(offset);
48 }
49
50 static int32_t cJSON_strcasecmp(const char *s1,const char *s2)
51 {
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));
55 }
56
57 // the following written by jl777
58 /******************************************************************************
59  * Copyright © 2014-2017 The SuperNET Developers.                             *
60  *                                                                            *
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.  *
64  *                                                                            *
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 *
68  *                                                                            *
69  * Removal or modification of this copyright notice is prohibited.            *
70  *                                                                            *
71  ******************************************************************************/
72
73 void copy_cJSON(struct destbuf *dest,cJSON *obj)
74 {
75     char *str;
76     int i;
77     long offset;
78     dest->buf[0] = 0;
79     if ( obj != 0 )
80     {
81         str = cJSON_Print(obj);
82         if ( str != 0 )
83         {
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 )
88                     break;
89             dest->buf[i] = 0;
90             free(str);
91         }
92     }
93 }
94
95 void copy_cJSON2(char *dest,int32_t maxlen,cJSON *obj)
96 {
97     struct destbuf tmp;
98     maxlen--;
99     dest[0] = 0;
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);
105     else dest[0] = 0;
106 }
107
108 int64_t _get_cJSON_int(cJSON *json)
109 {
110     struct destbuf tmp;
111     if ( json != 0 )
112     {
113         copy_cJSON(&tmp,json);
114         if ( tmp.buf[0] != 0 )
115             return(calc_nxt64bits(tmp.buf));
116     }
117     return(0);
118 }
119
120 int64_t get_cJSON_int(cJSON *json,char *field)
121 {
122     cJSON *numjson;
123     if ( json != 0 )
124     {
125         numjson = cJSON_GetObjectItem(json,field);
126         if ( numjson != 0 )
127             return(_get_cJSON_int(numjson));
128     }
129     return(0);
130 }
131
132 int64_t conv_floatstr(char *numstr)
133 {
134     double val,corr;
135     val = atof(numstr);
136     corr = (val < 0.) ? -0.50000000001 : 0.50000000001;
137     return((int64_t)(val * SATOSHIDEN + corr));
138 }
139
140 int64_t _conv_cJSON_float(cJSON *json)
141 {
142     int64_t conv_floatstr(char *);
143     struct destbuf tmp;
144     if ( json != 0 )
145     {
146         copy_cJSON(&tmp,json);
147         return(conv_floatstr(tmp.buf));
148     }
149     return(0);
150 }
151
152 int64_t conv_cJSON_float(cJSON *json,char *field)
153 {
154     if ( json != 0 )
155         return(_conv_cJSON_float(cJSON_GetObjectItem(json,field)));
156     return(0);
157 }
158
159 int32_t extract_cJSON_str(char *dest,int32_t max,cJSON *json,char *field)
160 {
161     int32_t safecopy(char *dest,char *src,long len);
162     char *str;
163     cJSON *obj;
164     int32_t len;
165     long offset;
166     dest[0] = 0;
167     obj = cJSON_GetObjectItem(json,field);
168     if ( obj != 0 )
169     {
170         str = cJSON_Print(obj);
171         offset = stripquotes(str);
172         len = safecopy(dest,str+offset,max);
173         free(str);
174         return(len);
175     }
176     return(0);
177 }
178
179 cJSON *gen_list_json(char **list)
180 {
181     cJSON *array,*item;
182     array = cJSON_CreateArray();
183     while ( list != 0 && *list != 0 && *list[0] != 0 )
184     {
185         item = cJSON_CreateString(*list++);
186         cJSON_AddItemToArray(array,item);
187     }
188     return(array);
189 }
190
191 uint64_t get_API_nxt64bits(cJSON *obj)
192 {
193     uint64_t nxt64bits = 0;
194     struct destbuf tmp;
195     if ( obj != 0 )
196     {
197         if ( cJSON_IsNumber(obj) != 0 )
198             return((uint64_t)obj->valuedouble);
199         copy_cJSON(&tmp,obj);
200         nxt64bits = calc_nxt64bits(tmp.buf);
201     }
202     return(nxt64bits);
203 }
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))); }
206
207 uint64_t get_satoshi_obj(cJSON *json,char *field)
208 {
209     int32_t i,n;
210     uint64_t prev,satoshis,mult = 1;
211     struct destbuf numstr,checkstr;
212     cJSON *numjson;
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)
217     {
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);
221         prev = satoshis;
222     }
223     sprintf(checkstr.buf,"%llu",(long long)satoshis);
224     if ( strcmp(checkstr.buf,numstr.buf) != 0 )
225     {
226         printf("SATOSHI GREMLIN?? numstr.(%s) -> %.8f -> (%s)\n",numstr.buf,dstr(satoshis),checkstr.buf);
227     }
228     return(satoshis);
229 }
230
231 void add_satoshis_json(cJSON *json,char *field,uint64_t satoshis)
232 {
233     cJSON *obj;
234     char numstr[64];
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));
240 }
241
242 char *cJSON_str(cJSON *json)
243 {
244     if ( json != 0 && cJSON_IsString(json) != 0 )
245         return(json->valuestring);
246     return(0);
247 }
248
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))); }
258
259 char *jstri(cJSON *json,int32_t i) { return(cJSON_str(cJSON_GetArrayItem(json,i))); }
260 char *jprint(cJSON *json,int32_t freeflag)
261 {
262     char *str;
263     /*static portable_mutex_t mutex; static int32_t initflag;
264     if ( initflag == 0 )
265     {
266         portable_mutex_init(&mutex);
267         initflag = 1;
268     }*/
269     if ( json == 0 )
270         return(clonestr((char *)"{}"));
271     //portable_mutex_lock(&mutex);
272     //usleep(5000);
273     str = cJSON_Print(json), _stripwhite(str,' ');
274     if ( freeflag != 0 )
275         free_json(json);
276     //portable_mutex_unlock(&mutex);
277     return(str);
278 }
279
280 bits256 get_API_bits256(cJSON *obj)
281 {
282     bits256 hash; char *str;
283     memset(hash.bytes,0,sizeof(hash));
284     if ( obj != 0 )
285     {
286         if ( cJSON_IsString(obj) != 0 && (str= obj->valuestring) != 0 && strlen(str) == 64 )
287             decode_hex(hash.bytes,sizeof(hash),str);
288     }
289     return(hash);
290 }
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); }
295
296 char *get_cJSON_fieldname(cJSON *obj)
297 {
298     if ( obj != 0 )
299     {
300         if ( obj->child != 0 && obj->child->string != 0 )
301             return(obj->child->string);
302         else if ( obj->string != 0 )
303             return(obj->string);
304     }
305     return((char *)"<no cJSON string field>");
306 }
307
308 int32_t jnum(cJSON *obj,char *field)
309 {
310     char *str; int32_t polarity = 1;
311     if ( field != 0 )
312         obj = jobj(obj,field);
313     if ( obj != 0 )
314     {
315         if ( cJSON_IsNumber(obj) != 0 )
316             return(obj->valuedouble);
317         else if ( cJSON_IsString(obj) != 0 && (str= jstr(obj,0)) != 0 )
318         {
319             if ( str[0] == '-' )
320                 polarity = -1, str++;
321             return(polarity * (int32_t)calc_nxt64bits(str));
322         }
323     }
324     return(0);
325 }
326
327 void ensure_jsonitem(cJSON *json,char *field,char *value)
328 {
329     cJSON *obj = cJSON_GetObjectItem(json,field);
330     if ( obj == 0 )
331         cJSON_AddItemToObject(json,field,cJSON_CreateString(value));
332     else cJSON_ReplaceItemInObject(json,field,cJSON_CreateString(value));
333 }
334
335 int32_t in_jsonarray(cJSON *array,char *value)
336 {
337     int32_t i,n;
338     struct destbuf remote;
339     if ( array != 0 && cJSON_IsArray(array) != 0 )
340     {
341         n = cJSON_GetArraySize(array);
342         for (i=0; i<n; i++)
343         {
344             if ( array == 0 || n == 0 )
345                 break;
346             copy_cJSON(&remote,cJSON_GetArrayItem(array,i));
347             if ( strcmp(remote.buf,value) == 0 )
348                 return(1);
349         }
350     }
351     return(0);
352 }
353
354 int32_t myatoi(char *str,int32_t range)
355 {
356     long x; char *ptr;
357     x = strtol(str,&ptr,10);
358     if ( range != 0 && x >= range )
359         x = (range - 1);
360     return((int32_t)x);
361 }
362
363 int32_t get_API_int(cJSON *obj,int32_t val)
364 {
365     struct destbuf buf;
366     if ( obj != 0 )
367     {
368         if ( cJSON_IsNumber(obj) != 0 )
369             return((int32_t)obj->valuedouble);
370         copy_cJSON(&buf,obj);
371         val = myatoi(buf.buf,0);
372         if ( val < 0 )
373             val = 0;
374     }
375     return(val);
376 }
377
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)); }
380
381 uint32_t get_API_uint(cJSON *obj,uint32_t val)
382 {
383     struct destbuf buf;
384     if ( obj != 0 )
385     {
386         if ( cJSON_IsNumber(obj) != 0 )
387             return((uint32_t)obj->valuedouble);
388         copy_cJSON(&buf,obj);
389         val = myatoi(buf.buf,0);
390     }
391     return(val);
392 }
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)); }
395
396 double get_API_float(cJSON *obj)
397 {
398     double val = 0.;
399     struct destbuf buf;
400     if ( obj != 0 )
401     {
402         if ( cJSON_IsNumber(obj) != 0 )
403             return(obj->valuedouble);
404         copy_cJSON(&buf,obj);
405         val = atof(buf.buf);
406     }
407     return(val);
408 }
409
410 double jdouble(cJSON *json,char *field)
411 {
412     if ( json != 0 )
413     {
414         if ( field == 0 )
415             return(get_API_float(json));
416         else return(get_API_float(cJSON_GetObjectItem(json,field)));
417     } else return(0.);
418 }
419
420 double jdoublei(cJSON *json,int32_t i)
421 {
422     if ( json != 0 )
423         return(get_API_float(cJSON_GetArrayItem(json,i)));
424     else return(0.);
425 }
426
427 cJSON *jobj(cJSON *json,char *field) { if ( json != 0 ) return(cJSON_GetObjectItem(json,field)); return(0); }
428
429 void jdelete(cJSON *json,char *field)
430 {
431     if ( jobj(json,field) != 0 )
432         cJSON_DeleteItemFromObject(json,field);
433 }
434
435 cJSON *jduplicate(cJSON *json) { return(cJSON_Duplicate(json,1)); }
436
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)
439 {
440     cJSON *array;
441     if ( json != 0 )
442     {
443         if ( field == 0 )
444             array = json;
445         else array = cJSON_GetObjectItem(json,field);
446         if ( array != 0 && cJSON_IsArray(array) != 0 && (*nump= cJSON_GetArraySize(array)) > 0 )
447             return(array);
448     }
449     *nump = 0;
450     return(0);
451 }
452
453 int32_t expand_nxt64bits(char *NXTaddr,uint64_t nxt64bits)
454 {
455     int32_t i,n;
456     uint64_t modval;
457     char rev[64];
458     for (i=0; nxt64bits!=0; i++)
459     {
460         modval = nxt64bits % 10;
461         rev[i] = (char)(modval + '0');
462         nxt64bits /= 10;
463     }
464     n = i;
465     for (i=0; i<n; i++)
466         NXTaddr[i] = rev[n-1-i];
467     NXTaddr[i] = 0;
468     return(n);
469 }
470
471 char *nxt64str(uint64_t nxt64bits)
472 {
473     static char NXTaddr[64];
474     expand_nxt64bits(NXTaddr,nxt64bits);
475     return(NXTaddr);
476 }
477
478 char *nxt64str2(uint64_t nxt64bits)
479 {
480     static char NXTaddr[64];
481     expand_nxt64bits(NXTaddr,nxt64bits);
482     return(NXTaddr);
483 }
484
485 int32_t cmp_nxt64bits(const char *str,uint64_t nxt64bits)
486 {
487     char expanded[64];
488     if ( str == 0 )//|| str[0] == 0 || nxt64bits == 0 )
489         return(-1);
490     if ( nxt64bits == 0 && str[0] == 0 )
491         return(0);
492     expand_nxt64bits(expanded,nxt64bits);
493     return(strcmp(str,expanded));
494 }
495
496 uint64_t calc_nxt64bits(const char *NXTaddr)
497 {
498     int32_t c;
499     int64_t n,i,polarity = 1;
500     uint64_t lastval,mult,nxt64bits = 0;
501     if ( NXTaddr == 0 )
502     {
503         printf("calling calc_nxt64bits with null ptr!\n");
504         return(0);
505     }
506     n = strlen(NXTaddr);
507     if ( n >= 22 )
508     {
509         printf("calc_nxt64bits: illegal NXTaddr.(%s) too long\n",NXTaddr);
510         return(0);
511     }
512     else if ( strcmp(NXTaddr,"0") == 0 || strcmp(NXTaddr,"false") == 0 )
513     {
514         // printf("zero address?\n"); getchar();
515         return(0);
516     }
517     if ( NXTaddr[0] == '-' )
518         polarity = -1, NXTaddr++, n--;
519     mult = 1;
520     lastval = 0;
521     for (i=n-1; i>=0; i--,mult*=10)
522     {
523         c = NXTaddr[i];
524         if ( c < '0' || c > '9' )
525         {
526             printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i);
527 #ifdef __APPLE__
528             //while ( 1 )
529             {
530                 //sleep(60);
531                 printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i);
532             }
533 #endif
534             return(0);
535         }
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);
539         lastval = nxt64bits;
540     }
541     while ( *NXTaddr == '0' && *NXTaddr != 0 )
542         NXTaddr++;
543     if ( cmp_nxt64bits(NXTaddr,nxt64bits) != 0 )
544         printf("error calculating nxt64bits: %s -> %llx -> %s\n",NXTaddr,(long long)nxt64bits,nxt64str(nxt64bits));
545     if ( polarity < 0 )
546         return(-(int64_t)nxt64bits);
547     return(nxt64bits);
548 }
549
550 cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num)
551 {
552     int32_t j; cJSON *array;
553     array = cJSON_CreateArray();
554     for (j=0; j<num; j++)
555         jaddi64bits(array,addrs[j]);
556     return(array);
557 }
558
559 void free_json(cJSON *json) { if ( json != 0 ) cJSON_Delete(json); }
This page took 0.056552 seconds and 4 git commands to generate.