]> Git Repo - VerusCoin.git/blame - src/cJSON.c
test
[VerusCoin.git] / src / cJSON.c
CommitLineData
3a2b2b45 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
c23b9ce3 28#include "cJSON.h"
3a2b2b45 29
30#ifndef DBL_EPSILON
31#define DBL_EPSILON 2.2204460492503131E-16
32#endif
33
34static const char *ep;
35
36long stripquotes(char *str)
37{
38 long len,offset;
39 if ( str == 0 )
40 return(0);
41 len = strlen(str);
42 if ( str[0] == '"' && str[len-1] == '"' )
43 str[len-1] = 0, offset = 1;
44 else offset = 0;
45 return(offset);
46}
47
48const char *cJSON_GetErrorPtr(void) {return ep;}
49
50static 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
57static void *(*cJSON_malloc)(size_t sz) = malloc;
58static void (*cJSON_free)(void *ptr) = free;
59
60static char* cJSON_strdup(const char* str)
61{
62 size_t len;
63 char* copy;
64
65 len = strlen(str) + 1;
66 if (!(copy = (char*)cJSON_malloc(len+1))) return 0;
67 memcpy(copy,str,len);
68 return copy;
69}
70
71void cJSON_InitHooks(cJSON_Hooks* hooks)
72{
73 if (!hooks) { /* Reset hooks */
74 cJSON_malloc = malloc;
75 cJSON_free = free;
76 return;
77 }
78
79 cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
80 cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
81}
82
83/* Internal constructor. */
84static cJSON *cJSON_New_Item(void)
85{
86 cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
87 if (node) memset(node,0,sizeof(cJSON));
88 return node;
89}
90
91/* Delete a cJSON structure. */
92void cJSON_Delete(cJSON *c)
93{
94 cJSON *next;
95 while (c)
96 {
97 next=c->next;
98 if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
99 if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
100 if (c->string) cJSON_free(c->string);
101 cJSON_free(c);
102 c=next;
103 }
104}
105
106/* Parse the input text to generate a number, and populate the result into item. */
107static const char *parse_number(cJSON *item,const char *num)
108{
109 double n=0,sign=1,scale=0;int32_t subscale=0,signsubscale=1;
110
111 if (*num=='-') sign=-1,num++; /* Has sign? */
112 if (*num=='0') num++; /* is zero */
113 if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
114 if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
115 if (*num=='e' || *num=='E') /* Exponent? */
116 { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
117 while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
118 }
119
120 n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
121
122 item->valuedouble=n;
123 item->valueint=(int64_t)n;
124 item->type=cJSON_Number;
125 return num;
126}
127
128/* Render the number nicely from the given item into a string. */
129static char *print_number(cJSON *item)
130{
131 char *str;
132 double d = item->valuedouble;
133 if ( fabs(((double)item->valueint) - d) <= DBL_EPSILON && d >= (1. - DBL_EPSILON) && d < (1LL << 62) )//d <= INT_MAX && d >= INT_MIN )
134 {
135 str = (char *)cJSON_malloc(24); /* 2^64+1 can be represented in 21 chars + sign. */
136 if ( str != 0 )
137 sprintf(str,"%lld",(long long)item->valueint);
138 }
139 else
140 {
141 str = (char *)cJSON_malloc(66); /* This is a nice tradeoff. */
142 if ( str != 0 )
143 {
144 if ( fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60 )
145 sprintf(str,"%.0f",d);
146 //else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
147 else
148 sprintf(str,"%.8f",d);
149 }
150 }
151 return str;
152}
153
154static unsigned parse_hex4(const char *str)
155{
156 unsigned h=0;
157 if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
158 h=h<<4;str++;
159 if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
160 h=h<<4;str++;
161 if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
162 h=h<<4;str++;
163 if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
164 return h;
165}
166
167/* Parse the input text into an unescaped cstring, and populate item. */
168static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
169static const char *parse_string(cJSON *item,const char *str)
170{
171 const char *ptr=str+1;char *ptr2;char *out;int32_t len=0;unsigned uc,uc2;
172 if (*str!='\"') {ep=str;return 0;} /* not a string! */
173
174 while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; // Skip escaped quotes
175
176 out=(char*)cJSON_malloc(len+2); /* This is how long we need for the string, roughly. */
177 if (!out) return 0;
178
179 ptr=str+1;ptr2=out;
180 while (*ptr!='\"' && *ptr)
181 {
182 if (*ptr!='\\')
183 {
184 if ( *ptr == '%' && is_hexstr((char *)&ptr[1],2) && isprint(_decode_hex((char *)&ptr[1])) != 0 )
185 *ptr2++ = _decode_hex((char *)&ptr[1]), ptr += 3;
186 else *ptr2++ = *ptr++;
187 }
188 else
189 {
190 ptr++;
191 switch (*ptr)
192 {
193 case 'b': *ptr2++='\b'; break;
194 case 'f': *ptr2++='\f'; break;
195 case 'n': *ptr2++='\n'; break;
196 case 'r': *ptr2++='\r'; break;
197 case 't': *ptr2++='\t'; break;
198 case 'u': // transcode utf16 to utf8
199 uc=parse_hex4(ptr+1);ptr+=4; // get the unicode char
200
201 if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // check for invalid
202
203 if (uc>=0xD800 && uc<=0xDBFF) // UTF16 surrogate pairs
204 {
205 if (ptr[1]!='\\' || ptr[2]!='u') break; // missing second-half of surrogate.
206 uc2=parse_hex4(ptr+3);ptr+=6;
207 if (uc2<0xDC00 || uc2>0xDFFF) break; // invalid second-half of surrogate
208 uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
209 }
210
211 len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
212
213 switch (len) {
214 case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
215 case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
216 case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
217 case 1: *--ptr2 =(uc | firstByteMark[len]);
218 }
219 ptr2+=len;
220 break;
221 default: *ptr2++=*ptr; break;
222 }
223 ptr++;
224 }
225 }
226 *ptr2=0;
227 if (*ptr=='\"') ptr++;
228 item->valuestring=out;
229 item->type=cJSON_String;
230 return ptr;
231}
232
233/* Render the cstring provided to an escaped version that can be printed. */
234static char *print_string_ptr(const char *str)
235{
236 const char *ptr;char *ptr2,*out;int32_t len=0;unsigned char token;
237
238 if (!str) return cJSON_strdup("");
239 ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
240
241 out=(char*)cJSON_malloc(len+3+1);
242 if (!out) return 0;
243
244 ptr2=out;ptr=str;
245 *ptr2++='\"';
246 while (*ptr)
247 {
248 if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
249 else
250 {
251 *ptr2++='\\';
252 switch (token=*ptr++)
253 {
254 case '\\': *ptr2++='\\'; break;
255 case '\"': *ptr2++='\"'; break;
256 case '\b': *ptr2++='b'; break;
257 case '\f': *ptr2++='f'; break;
258 case '\n': *ptr2++='n'; break;
259 case '\r': *ptr2++='r'; break;
260 case '\t': *ptr2++='t'; break;
261 default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
262 }
263 }
264 }
265 *ptr2++='\"';*ptr2++=0;
266 return out;
267}
268/* Invote print_string_ptr (which is useful) on an item. */
269static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
270
271/* Predeclare these prototypes. */
272static const char *parse_value(cJSON *item,const char *value);
273static char *print_value(cJSON *item,int32_t depth,int32_t fmt);
274static const char *parse_array(cJSON *item,const char *value);
275static char *print_array(cJSON *item,int32_t depth,int32_t fmt);
276static const char *parse_object(cJSON *item,const char *value);
277static char *print_object(cJSON *item,int32_t depth,int32_t fmt);
278
279/* Utility to jump whitespace and cr/lf */
280static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
281
282/* Parse an object - create a new root, and populate. */
283cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int32_t require_null_terminated)
284{
285 const char *end=0;
286 cJSON *c=cJSON_New_Item();
287 ep=0;
288 if (!c) return 0; /* memory fail */
289
290 end=parse_value(c,skip(value));
291 if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
292
293 /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
294 if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
295 if (return_parse_end) *return_parse_end=end;
296 return c;
297}
298/* Default options for cJSON_Parse */
299cJSON *cJSON_Parse(const char *value)
300{
301 return(cJSON_ParseWithOpts(value,0,0));
302}
303
304/* Render a cJSON item/entity/structure to text. */
305char *cJSON_Print(cJSON *item)
306{
307 return(print_value(item,0,1));
308}
309char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
310
311/* Parser core - when encountering text, process appropriately. */
312static const char *parse_value(cJSON *item,const char *value)
313{
314 if (!value) return 0; /* Fail on null. */
315 if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
316 if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
317 if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
318 if (*value=='\"') { return parse_string(item,value); }
319 if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
320 if (*value=='[') { return parse_array(item,value); }
321 if (*value=='{') { return parse_object(item,value); }
322
323 ep=value;return 0; /* failure. */
324}
325
326/* Render a value to text. */
327static char *print_value(cJSON *item,int32_t depth,int32_t fmt)
328{
329 char *out=0;
330 if (!item) return 0;
331 switch ((item->type)&255)
332 {
333 case cJSON_NULL: out=cJSON_strdup("null"); break;
334 case cJSON_False: out=cJSON_strdup("false");break;
335 case cJSON_True: out=cJSON_strdup("true"); break;
336 case cJSON_Number: out=print_number(item);break;
337 case cJSON_String: out=print_string(item);break;
338 case cJSON_Array: out=print_array(item,depth,fmt);break;
339 case cJSON_Object: out=print_object(item,depth,fmt);break;
340 }
341 return out;
342}
343
344/* Build an array from input text. */
345static const char *parse_array(cJSON *item,const char *value)
346{
347 cJSON *child;
348 if (*value!='[') {ep=value;return 0;} /* not an array! */
349
350 item->type=cJSON_Array;
351 value=skip(value+1);
352 if (*value==']') return value+1; /* empty array. */
353
354 item->child=child=cJSON_New_Item();
355 if (!item->child) return 0; /* memory fail */
356 value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
357 if (!value) return 0;
358
359 while (*value==',')
360 {
361 cJSON *new_item;
362 if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
363 child->next=new_item;new_item->prev=child;child=new_item;
364 value=skip(parse_value(child,skip(value+1)));
365 if (!value) return 0; /* memory fail */
366 }
367
368 if (*value==']') return value+1; /* end of array */
369 ep=value;return 0; /* malformed. */
370}
371
372/* Render an array to text */
373static char *print_array(cJSON *item,int32_t depth,int32_t fmt)
374{
375 char **entries;
376 char *out=0,*ptr,*ret;int32_t len=5;
377 cJSON *child=item->child;
378 int32_t numentries=0,i=0,fail=0;
379
380 /* How many entries in the array? */
381 while (child) numentries++,child=child->next;
382 /* Explicitly handle numentries==0 */
383 if (!numentries)
384 {
385 out=(char*)cJSON_malloc(3+1);
386 if (out) strcpy(out,"[]");
387 return out;
388 }
389 /* Allocate an array to hold the values for each */
390 entries=(char**)cJSON_malloc((1+numentries)*sizeof(char*));
391 if (!entries) return 0;
392 memset(entries,0,numentries*sizeof(char*));
393 /* Retrieve all the results: */
394 child=item->child;
395 while (child && !fail)
396 {
397 ret=print_value(child,depth+1,fmt);
398 entries[i++]=ret;
399 if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
400 child=child->next;
401 }
402
403 /* If we didn't fail, try to malloc the output string */
404 if (!fail) out=(char*)cJSON_malloc(len+1);
405 /* If that fails, we fail. */
406 if (!out) fail=1;
407
408 /* Handle failure. */
409 if (fail)
410 {
411 for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
412 cJSON_free(entries);
413 return 0;
414 }
415
416 /* Compose the output array. */
417 *out='[';
418 ptr=out+1;*ptr=0;
419 for (i=0;i<numentries;i++)
420 {
421 strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
422 if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
423 cJSON_free(entries[i]);
424 }
425 cJSON_free(entries);
426 *ptr++=']';*ptr++=0;
427 return out;
428}
429
430/* Build an object from the text. */
431static const char *parse_object(cJSON *item,const char *value)
432{
433 cJSON *child;
434 if (*value!='{') {ep=value;return 0;} /* not an object! */
435
436 item->type=cJSON_Object;
437 value=skip(value+1);
438 if (*value=='}') return value+1; /* empty array. */
439
440 item->child=child=cJSON_New_Item();
441 if (!item->child) return 0;
442 value=skip(parse_string(child,skip(value)));
443 if (!value) return 0;
444 child->string=child->valuestring;child->valuestring=0;
445 if (*value!=':') {ep=value;return 0;} /* fail! */
446 value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
447 if (!value) return 0;
448
449 while (*value==',')
450 {
451 cJSON *new_item;
452 if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
453 child->next=new_item;new_item->prev=child;child=new_item;
454 value=skip(parse_string(child,skip(value+1)));
455 if (!value) return 0;
456 child->string=child->valuestring;child->valuestring=0;
457 if (*value!=':') {ep=value;return 0;} /* fail! */
458 value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
459 if (!value) return 0;
460 }
461
462 if (*value=='}') return value+1; /* end of array */
463 ep=value;return 0; /* malformed. */
464}
465
466/* Render an object to text. */
467static char *print_object(cJSON *item,int32_t depth,int32_t fmt)
468{
469 char **entries=0,**names=0;
470 char *out=0,*ptr,*ret,*str;int32_t len=7,i=0,j;
471 cJSON *child=item->child,*firstchild;
472 int32_t numentries=0,fail=0;
473 // Count the number of entries
474 firstchild = child;
475 while ( child )
476 {
477 numentries++;
478 child = child->next;
479 if ( child == firstchild )
480 {
481 printf("cJSON infinite loop detected\n");
482 break;
483 }
484 }
485 /* Explicitly handle empty object case */
486 if (!numentries)
487 {
488 out=(char*)cJSON_malloc(fmt?depth+4+1:3+1);
489 if (!out) return 0;
490 ptr=out;*ptr++='{';
491 if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
492 *ptr++='}';*ptr++=0;
493 return out;
494 }
495 /* Allocate space for the names and the objects */
496 entries=(char**)cJSON_malloc(numentries*sizeof(char*));
497 if (!entries) return 0;
498 names=(char**)cJSON_malloc(numentries*sizeof(char*));
499 if (!names) {cJSON_free(entries);return 0;}
500 memset(entries,0,sizeof(char*)*numentries);
501 memset(names,0,sizeof(char*)*numentries);
502
503 /* Collect all the results into our arrays: */
504 child=item->child;depth++;if (fmt) len+=depth;
505 while ( child )
506 {
507 names[i]=str=print_string_ptr(child->string);
508 entries[i++]=ret=print_value(child,depth,fmt);
509 if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
510 child=child->next;
511 if ( child == firstchild )
512 break;
513 }
514
515 /* Try to allocate the output string */
516 if (!fail) out=(char*)cJSON_malloc(len+1);
517 if (!out) fail=1;
518
519 /* Handle failure */
520 if (fail)
521 {
522 for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
523 cJSON_free(names);cJSON_free(entries);
524 return 0;
525 }
526
527 /* Compose the output: */
528 *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
529 for (i=0;i<numentries;i++)
530 {
531 if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
532 strcpy(ptr,names[i]);ptr+=strlen(names[i]);
533 *ptr++=':';if (fmt) *ptr++='\t';
534 strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
535 if (i!=numentries-1) *ptr++=',';
536 if (fmt) *ptr++='\n';*ptr=0;
537 cJSON_free(names[i]);cJSON_free(entries[i]);
538 }
539
540 cJSON_free(names);cJSON_free(entries);
541 if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
542 *ptr++='}';*ptr++=0;
543 return out;
544}
545
546/* Get Array size/item / object item. */
547int32_t cJSON_GetArraySize(cJSON *array) {cJSON *c; if ( array == 0 ) return(0); c=array->child;int32_t i=0;while(c)i++,c=c->next;return i;}
548cJSON *cJSON_GetArrayItem(cJSON *array,int32_t item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
549cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
550
551/* Utility for array list handling. */
552static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
553/* Utility for handling references. */
554static 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;}
555
556/* Add item to array/object. */
557void 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);}}
558void 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);}
559void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
560void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
561
562cJSON *cJSON_DetachItemFromArray(cJSON *array,int32_t which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
563 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;}
564void cJSON_DeleteItemFromArray(cJSON *array,int32_t which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
565cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int32_t 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;}
566void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
567
568/* Replace array/object items with new ones. */
569void cJSON_ReplaceItemInArray(cJSON *array,int32_t which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
570 newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
571 if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
572void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int32_t 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);}}
573
574/* Create basic types: */
575cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
576cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
577cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
578cJSON *cJSON_CreateBool(int32_t b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
579cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int64_t)num;}return item;}
580cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
581cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
582cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
583
584/* Create Arrays: */
585cJSON *cJSON_CreateIntArray(int64_t *numbers,int32_t count) {int32_t i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber((double)numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
586cJSON *cJSON_CreateFloatArray(float *numbers,int32_t count) {int32_t 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;}
587cJSON *cJSON_CreateDoubleArray(double *numbers,int32_t count) {int32_t 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;}
588cJSON *cJSON_CreateStringArray(char **strings,int32_t count) {int32_t 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;}
589
590/* Duplication */
591cJSON *cJSON_Duplicate(cJSON *item,int32_t recurse)
592{
593 cJSON *newitem,*cptr,*nptr=0,*newchild;
594 /* Bail on bad ptr */
595 if (!item) return 0;
596 /* Create new item */
597 newitem=cJSON_New_Item();
598 if (!newitem) return 0;
599 /* Copy over all vars */
600 newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
601 if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
602 if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
603 /* If non-recursive, then we're done! */
604 if (!recurse) return newitem;
605 /* Walk the ->next chain for the child. */
606 cptr=item->child;
607 while (cptr)
608 {
609 newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
610 if (!newchild) {cJSON_Delete(newitem);return 0;}
611 if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
612 else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
613 cptr=cptr->next;
614 }
615 return newitem;
616}
617
618void cJSON_Minify(char *json)
619{
620 char *into=json;
621 while (*json)
622 {
623 if (*json==' ') json++;
624 else if (*json=='\t') json++; // Whitespace characters.
625 else if (*json=='\r') json++;
626 else if (*json=='\n') json++;
627 else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
628 else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
629 else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
630 else *into++=*json++; // All other characters.
631 }
632 *into=0; // and null-terminate.
633}
634
635// the following written by jl777
636/******************************************************************************
637 * Copyright © 2014-2016 The SuperNET Developers. *
638 * *
639 * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
640 * the top-level directory of this distribution for the individual copyright *
641 * holder information and the developer policies on copyright and licensing. *
642 * *
643 * Unless otherwise agreed in a custom licensing agreement, no part of the *
644 * SuperNET software, including this file may be copied, modified, propagated *
645 * or distributed except according to the terms contained in the LICENSE file *
646 * *
647 * Removal or modification of this copyright notice is prohibited. *
648 * *
649 ******************************************************************************/
650
651void copy_cJSON(struct destbuf *dest,cJSON *obj)
652{
653 char *str;
654 int i;
655 long offset;
656 dest->buf[0] = 0;
657 if ( obj != 0 )
658 {
659 str = cJSON_Print(obj);
660 if ( str != 0 )
661 {
662 offset = stripquotes(str);
663 //strcpy(dest,str+offset);
664 for (i=0; i<MAX_JSON_FIELD-1; i++)
665 if ( (dest->buf[i]= str[offset+i]) == 0 )
666 break;
667 dest->buf[i] = 0;
668 free(str);
669 }
670 }
671}
672
673void copy_cJSON2(char *dest,int32_t maxlen,cJSON *obj)
674{
675 struct destbuf tmp;
676 maxlen--;
677 dest[0] = 0;
678 if ( maxlen > sizeof(tmp.buf) )
679 maxlen = sizeof(tmp.buf);
680 copy_cJSON(&tmp,obj);
681 if ( strlen(tmp.buf) < maxlen )
682 strcpy(dest,tmp.buf);
683 else dest[0] = 0;
684}
685
686int64_t _get_cJSON_int(cJSON *json)
687{
688 struct destbuf tmp;
689 if ( json != 0 )
690 {
691 copy_cJSON(&tmp,json);
692 if ( tmp.buf[0] != 0 )
693 return(calc_nxt64bits(tmp.buf));
694 }
695 return(0);
696}
697
698int64_t get_cJSON_int(cJSON *json,char *field)
699{
700 cJSON *numjson;
701 if ( json != 0 )
702 {
703 numjson = cJSON_GetObjectItem(json,field);
704 if ( numjson != 0 )
705 return(_get_cJSON_int(numjson));
706 }
707 return(0);
708}
709
f3d5295c 710int64_t conv_floatstr(char *numstr)
711{
712 double val,corr;
713 val = atof(numstr);
714 corr = (val < 0.) ? -0.50000000001 : 0.50000000001;
715 return((int64_t)(val * SATOSHIDEN + corr));
716}
717
3a2b2b45 718int64_t _conv_cJSON_float(cJSON *json)
719{
720 int64_t conv_floatstr(char *);
721 struct destbuf tmp;
722 if ( json != 0 )
723 {
724 copy_cJSON(&tmp,json);
725 return(conv_floatstr(tmp.buf));
726 }
727 return(0);
728}
729
730int64_t conv_cJSON_float(cJSON *json,char *field)
731{
732 if ( json != 0 )
733 return(_conv_cJSON_float(cJSON_GetObjectItem(json,field)));
734 return(0);
735}
736
737int32_t extract_cJSON_str(char *dest,int32_t max,cJSON *json,char *field)
738{
739 int32_t safecopy(char *dest,char *src,long len);
740 char *str;
741 cJSON *obj;
742 int32_t len;
743 long offset;
744 dest[0] = 0;
745 obj = cJSON_GetObjectItem(json,field);
746 if ( obj != 0 )
747 {
748 str = cJSON_Print(obj);
749 offset = stripquotes(str);
750 len = safecopy(dest,str+offset,max);
751 free(str);
752 return(len);
753 }
754 return(0);
755}
756
757cJSON *gen_list_json(char **list)
758{
759 cJSON *array,*item;
760 array = cJSON_CreateArray();
761 while ( list != 0 && *list != 0 && *list[0] != 0 )
762 {
763 item = cJSON_CreateString(*list++);
764 cJSON_AddItemToArray(array,item);
765 }
766 return(array);
767}
768
769uint64_t get_API_nxt64bits(cJSON *obj)
770{
771 uint64_t nxt64bits = 0;
772 struct destbuf tmp;
773 if ( obj != 0 )
774 {
775 if ( is_cJSON_Number(obj) != 0 )
776 return((uint64_t)obj->valuedouble);
777 copy_cJSON(&tmp,obj);
778 nxt64bits = calc_nxt64bits(tmp.buf);
779 }
780 return(nxt64bits);
781}
782uint64_t j64bits(cJSON *json,char *field) { if ( field == 0 ) return(get_API_nxt64bits(json)); return(get_API_nxt64bits(cJSON_GetObjectItem(json,field))); }
783uint64_t j64bitsi(cJSON *json,int32_t i) { return(get_API_nxt64bits(cJSON_GetArrayItem(json,i))); }
784
785uint64_t get_satoshi_obj(cJSON *json,char *field)
786{
787 int32_t i,n;
788 uint64_t prev,satoshis,mult = 1;
789 struct destbuf numstr,checkstr;
790 cJSON *numjson;
791 numjson = cJSON_GetObjectItem(json,field);
792 copy_cJSON(&numstr,numjson);
793 satoshis = prev = 0; mult = 1; n = (int32_t)strlen(numstr.buf);
794 for (i=n-1; i>=0; i--,mult*=10)
795 {
796 satoshis += (mult * (numstr.buf[i] - '0'));
797 if ( satoshis < prev )
798 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);
799 prev = satoshis;
800 }
801 sprintf(checkstr.buf,"%llu",(long long)satoshis);
802 if ( strcmp(checkstr.buf,numstr.buf) != 0 )
803 {
804 printf("SATOSHI GREMLIN?? numstr.(%s) -> %.8f -> (%s)\n",numstr.buf,dstr(satoshis),checkstr.buf);
805 }
806 return(satoshis);
807}
808
809void add_satoshis_json(cJSON *json,char *field,uint64_t satoshis)
810{
811 cJSON *obj;
812 char numstr[64];
813 sprintf(numstr,"%lld",(long long)satoshis);
814 obj = cJSON_CreateString(numstr);
815 cJSON_AddItemToObject(json,field,obj);
816 if ( satoshis != get_satoshi_obj(json,field) )
817 printf("error adding satoshi obj %ld -> %ld\n",(unsigned long)satoshis,(unsigned long)get_satoshi_obj(json,field));
818}
819
820char *cJSON_str(cJSON *json)
821{
822 if ( json != 0 && is_cJSON_String(json) != 0 )
823 return(json->valuestring);
824 return(0);
825}
826
827void jadd(cJSON *json,char *field,cJSON *item) { if ( json != 0 )cJSON_AddItemToObject(json,field,item); }
828void jaddstr(cJSON *json,char *field,char *str) { if ( json != 0 && str != 0 ) cJSON_AddItemToObject(json,field,cJSON_CreateString(str)); }
829void jaddnum(cJSON *json,char *field,double num) { if ( json != 0 )cJSON_AddItemToObject(json,field,cJSON_CreateNumber(num)); }
830void jadd64bits(cJSON *json,char *field,uint64_t nxt64bits) { char numstr[64]; sprintf(numstr,"%llu",(long long)nxt64bits), jaddstr(json,field,numstr); }
831void jaddi(cJSON *json,cJSON *item) { if ( json != 0 ) cJSON_AddItemToArray(json,item); }
832void jaddistr(cJSON *json,char *str) { if ( json != 0 ) cJSON_AddItemToArray(json,cJSON_CreateString(str)); }
833void jaddinum(cJSON *json,double num) { if ( json != 0 ) cJSON_AddItemToArray(json,cJSON_CreateNumber(num)); }
834void jaddi64bits(cJSON *json,uint64_t nxt64bits) { char numstr[64]; sprintf(numstr,"%llu",(long long)nxt64bits), jaddistr(json,numstr); }
835char *jstr(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == 0 ) return(cJSON_str(json)); return(cJSON_str(cJSON_GetObjectItem(json,field))); }
836
837char *jstri(cJSON *json,int32_t i) { return(cJSON_str(cJSON_GetArrayItem(json,i))); }
838char *jprint(cJSON *json,int32_t freeflag)
839{
840 char *str;
841 /*static portable_mutex_t mutex; static int32_t initflag;
842 if ( initflag == 0 )
843 {
844 portable_mutex_init(&mutex);
845 initflag = 1;
846 }*/
847 if ( json == 0 )
34c42c40 848 return(clonestr((char *)"{}"));
3a2b2b45 849 //portable_mutex_lock(&mutex);
850 //usleep(5000);
851 str = cJSON_Print(json), _stripwhite(str,' ');
852 if ( freeflag != 0 )
853 free_json(json);
854 //portable_mutex_unlock(&mutex);
855 return(str);
856}
857
858bits256 get_API_bits256(cJSON *obj)
859{
860 bits256 hash; char *str;
861 memset(hash.bytes,0,sizeof(hash));
862 if ( obj != 0 )
863 {
864 if ( is_cJSON_String(obj) != 0 && (str= obj->valuestring) != 0 && strlen(str) == 64 )
865 decode_hex(hash.bytes,sizeof(hash),str);
866 }
867 return(hash);
868}
869bits256 jbits256(cJSON *json,char *field) { if ( field == 0 ) return(get_API_bits256(json)); return(get_API_bits256(cJSON_GetObjectItem(json,field))); }
870bits256 jbits256i(cJSON *json,int32_t i) { return(get_API_bits256(cJSON_GetArrayItem(json,i))); }
871void jaddbits256(cJSON *json,char *field,bits256 hash) { char str[65]; bits256_str(str,hash), jaddstr(json,field,str); }
872void jaddibits256(cJSON *json,bits256 hash) { char str[65]; bits256_str(str,hash), jaddistr(json,str); }
873
874char *get_cJSON_fieldname(cJSON *obj)
875{
876 if ( obj != 0 )
877 {
878 if ( obj->child != 0 && obj->child->string != 0 )
879 return(obj->child->string);
880 else if ( obj->string != 0 )
881 return(obj->string);
882 }
883 return((char *)"<no cJSON string field>");
884}
885
886int32_t jnum(cJSON *obj,char *field)
887{
888 char *str; int32_t polarity = 1;
889 if ( field != 0 )
890 obj = jobj(obj,field);
891 if ( obj != 0 )
892 {
893 if ( is_cJSON_Number(obj) != 0 )
894 return(obj->valuedouble);
895 else if ( is_cJSON_String(obj) != 0 && (str= jstr(obj,0)) != 0 )
896 {
897 if ( str[0] == '-' )
898 polarity = -1, str++;
899 return(polarity * (int32_t)calc_nxt64bits(str));
900 }
901 }
902 return(0);
903}
904
905void ensure_jsonitem(cJSON *json,char *field,char *value)
906{
907 cJSON *obj = cJSON_GetObjectItem(json,field);
908 if ( obj == 0 )
909 cJSON_AddItemToObject(json,field,cJSON_CreateString(value));
910 else cJSON_ReplaceItemInObject(json,field,cJSON_CreateString(value));
911}
912
913int32_t in_jsonarray(cJSON *array,char *value)
914{
915 int32_t i,n;
916 struct destbuf remote;
917 if ( array != 0 && is_cJSON_Array(array) != 0 )
918 {
919 n = cJSON_GetArraySize(array);
920 for (i=0; i<n; i++)
921 {
922 if ( array == 0 || n == 0 )
923 break;
924 copy_cJSON(&remote,cJSON_GetArrayItem(array,i));
925 if ( strcmp(remote.buf,value) == 0 )
926 return(1);
927 }
928 }
929 return(0);
930}
931
932int32_t myatoi(char *str,int32_t range)
933{
934 long x; char *ptr;
935 x = strtol(str,&ptr,10);
936 if ( range != 0 && x >= range )
937 x = (range - 1);
938 return((int32_t)x);
939}
940
941int32_t get_API_int(cJSON *obj,int32_t val)
942{
943 struct destbuf buf;
944 if ( obj != 0 )
945 {
946 if ( is_cJSON_Number(obj) != 0 )
947 return((int32_t)obj->valuedouble);
948 copy_cJSON(&buf,obj);
949 val = myatoi(buf.buf,0);
950 if ( val < 0 )
951 val = 0;
952 }
953 return(val);
954}
955int32_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)); }
956int32_t jinti(cJSON *json,int32_t i) { if ( json == 0 ) return(0); return(get_API_int(cJSON_GetArrayItem(json,i),0)); }
957
958uint32_t get_API_uint(cJSON *obj,uint32_t val)
959{
960 struct destbuf buf;
961 if ( obj != 0 )
962 {
963 if ( is_cJSON_Number(obj) != 0 )
964 return((uint32_t)obj->valuedouble);
965 copy_cJSON(&buf,obj);
966 val = myatoi(buf.buf,0);
967 }
968 return(val);
969}
970uint32_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)); }
971uint32_t juinti(cJSON *json,int32_t i) { if ( json == 0 ) return(0); return(get_API_uint(cJSON_GetArrayItem(json,i),0)); }
972
973double get_API_float(cJSON *obj)
974{
975 double val = 0.;
976 struct destbuf buf;
977 if ( obj != 0 )
978 {
979 if ( is_cJSON_Number(obj) != 0 )
980 return(obj->valuedouble);
981 copy_cJSON(&buf,obj);
982 val = atof(buf.buf);
983 }
984 return(val);
985}
986
987double jdouble(cJSON *json,char *field)
988{
989 if ( json != 0 )
990 {
991 if ( field == 0 )
992 return(get_API_float(json));
993 else return(get_API_float(cJSON_GetObjectItem(json,field)));
994 } else return(0.);
995}
996
997double jdoublei(cJSON *json,int32_t i)
998{
999 if ( json != 0 )
1000 return(get_API_float(cJSON_GetArrayItem(json,i)));
1001 else return(0.);
1002}
1003
1004cJSON *jobj(cJSON *json,char *field) { if ( json != 0 ) return(cJSON_GetObjectItem(json,field)); return(0); }
1005
1006void jdelete(cJSON *json,char *field)
1007{
1008 if ( jobj(json,field) != 0 )
1009 cJSON_DeleteItemFromObject(json,field);
1010}
1011
1012cJSON *jduplicate(cJSON *json) { return(cJSON_Duplicate(json,1)); }
1013
1014cJSON *jitem(cJSON *array,int32_t i) { if ( array != 0 && is_cJSON_Array(array) != 0 && cJSON_GetArraySize(array) > i ) return(cJSON_GetArrayItem(array,i)); return(0); }
1015cJSON *jarray(int32_t *nump,cJSON *json,char *field)
1016{
1017 cJSON *array;
1018 if ( json != 0 )
1019 {
1020 if ( field == 0 )
1021 array = json;
1022 else array = cJSON_GetObjectItem(json,field);
1023 if ( array != 0 && is_cJSON_Array(array) != 0 && (*nump= cJSON_GetArraySize(array)) > 0 )
1024 return(array);
1025 }
1026 *nump = 0;
1027 return(0);
1028}
1029
1030int32_t expand_nxt64bits(char *NXTaddr,uint64_t nxt64bits)
1031{
1032 int32_t i,n;
1033 uint64_t modval;
1034 char rev[64];
1035 for (i=0; nxt64bits!=0; i++)
1036 {
1037 modval = nxt64bits % 10;
1038 rev[i] = (char)(modval + '0');
1039 nxt64bits /= 10;
1040 }
1041 n = i;
1042 for (i=0; i<n; i++)
1043 NXTaddr[i] = rev[n-1-i];
1044 NXTaddr[i] = 0;
1045 return(n);
1046}
1047
1048char *nxt64str(uint64_t nxt64bits)
1049{
1050 static char NXTaddr[64];
1051 expand_nxt64bits(NXTaddr,nxt64bits);
1052 return(NXTaddr);
1053}
1054
1055char *nxt64str2(uint64_t nxt64bits)
1056{
1057 static char NXTaddr[64];
1058 expand_nxt64bits(NXTaddr,nxt64bits);
1059 return(NXTaddr);
1060}
1061
1062int32_t cmp_nxt64bits(const char *str,uint64_t nxt64bits)
1063{
1064 char expanded[64];
1065 if ( str == 0 )//|| str[0] == 0 || nxt64bits == 0 )
1066 return(-1);
1067 if ( nxt64bits == 0 && str[0] == 0 )
1068 return(0);
1069 expand_nxt64bits(expanded,nxt64bits);
1070 return(strcmp(str,expanded));
1071}
1072
1073uint64_t calc_nxt64bits(const char *NXTaddr)
1074{
1075 int32_t c;
1076 int64_t n,i,polarity = 1;
1077 uint64_t lastval,mult,nxt64bits = 0;
1078 if ( NXTaddr == 0 )
1079 {
1080 printf("calling calc_nxt64bits with null ptr!\n");
1081 return(0);
1082 }
1083 n = strlen(NXTaddr);
1084 if ( n >= 22 )
1085 {
1086 printf("calc_nxt64bits: illegal NXTaddr.(%s) too long\n",NXTaddr);
1087 return(0);
1088 }
1089 else if ( strcmp(NXTaddr,"0") == 0 || strcmp(NXTaddr,"false") == 0 )
1090 {
1091 // printf("zero address?\n"); getchar();
1092 return(0);
1093 }
1094 if ( NXTaddr[0] == '-' )
1095 polarity = -1, NXTaddr++, n--;
1096 mult = 1;
1097 lastval = 0;
1098 for (i=n-1; i>=0; i--,mult*=10)
1099 {
1100 c = NXTaddr[i];
1101 if ( c < '0' || c > '9' )
1102 {
1103 printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i);
1104#ifdef __APPLE__
1105 //while ( 1 )
1106 {
1107 //sleep(60);
1108 printf("calc_nxt64bits: illegal char.(%c %d) in (%s).%d\n",c,c,NXTaddr,(int32_t)i);
1109 }
1110#endif
1111 return(0);
1112 }
1113 nxt64bits += mult * (c - '0');
1114 if ( nxt64bits < lastval )
1115 printf("calc_nxt64bits: warning: 64bit overflow %llx < %llx\n",(long long)nxt64bits,(long long)lastval);
1116 lastval = nxt64bits;
1117 }
1118 while ( *NXTaddr == '0' && *NXTaddr != 0 )
1119 NXTaddr++;
1120 if ( cmp_nxt64bits(NXTaddr,nxt64bits) != 0 )
1121 printf("error calculating nxt64bits: %s -> %llx -> %s\n",NXTaddr,(long long)nxt64bits,nxt64str(nxt64bits));
1122 if ( polarity < 0 )
1123 return(-(int64_t)nxt64bits);
1124 return(nxt64bits);
1125}
1126
1127cJSON *addrs_jsonarray(uint64_t *addrs,int32_t num)
1128{
1129 int32_t j; cJSON *array;
1130 array = cJSON_CreateArray();
1131 for (j=0; j<num; j++)
1132 jaddi64bits(array,addrs[j]);
1133 return(array);
1134}
1135
1136void free_json(cJSON *json) { if ( json != 0 ) cJSON_Delete(json); }
This page took 0.149567 seconds and 4 git commands to generate.