summaryrefslogtreecommitdiff
path: root/xs_json.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs_json.h')
-rw-r--r--xs_json.h163
1 files changed, 94 insertions, 69 deletions
diff --git a/xs_json.h b/xs_json.h
index 8b449a9..07800fa 100644
--- a/xs_json.h
+++ b/xs_json.h
@@ -8,6 +8,7 @@
8#define MAX_JSON_DEPTH 32 8#define MAX_JSON_DEPTH 32
9#endif 9#endif
10 10
11void xs_json_dump_value(const xs_val *data, int level, int indent, FILE *f);
11int xs_json_dump(const xs_val *data, int indent, FILE *f); 12int xs_json_dump(const xs_val *data, int indent, FILE *f);
12xs_str *xs_json_dumps(const xs_val *data, int indent); 13xs_str *xs_json_dumps(const xs_val *data, int indent);
13 14
@@ -19,8 +20,8 @@ xs_val *xs_json_loads_full(const xs_str *json, int maxdepth);
19xstype xs_json_load_type(FILE *f); 20xstype xs_json_load_type(FILE *f);
20int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c); 21int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c);
21int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c); 22int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c);
22xs_list *xs_json_load_array(FILE *f, int maxdepth); 23int xs_json_load_array(FILE *f, int maxdepth, xs_list **l);
23xs_dict *xs_json_load_object(FILE *f, int maxdepth); 24int xs_json_load_object(FILE *f, int maxdepth, xs_dict **d);
24 25
25 26
26#ifdef XS_IMPLEMENTATION 27#ifdef XS_IMPLEMENTATION
@@ -77,7 +78,7 @@ static void _xs_json_indent(int level, int indent, FILE *f)
77} 78}
78 79
79 80
80static void _xs_json_dump(const xs_val *data, int level, int indent, FILE *f) 81void xs_json_dump_value(const xs_val *data, int level, int indent, FILE *f)
81/* dumps partial data as JSON */ 82/* dumps partial data as JSON */
82{ 83{
83 int c = 0; 84 int c = 0;
@@ -108,7 +109,7 @@ static void _xs_json_dump(const xs_val *data, int level, int indent, FILE *f)
108 fputc(',', f); 109 fputc(',', f);
109 110
110 _xs_json_indent(level + 1, indent, f); 111 _xs_json_indent(level + 1, indent, f);
111 _xs_json_dump(v, level + 1, indent, f); 112 xs_json_dump_value(v, level + 1, indent, f);
112 113
113 c++; 114 c++;
114 } 115 }
@@ -135,7 +136,7 @@ static void _xs_json_dump(const xs_val *data, int level, int indent, FILE *f)
135 if (indent) 136 if (indent)
136 fputc(' ', f); 137 fputc(' ', f);
137 138
138 _xs_json_dump(v, level + 1, indent, f); 139 xs_json_dump_value(v, level + 1, indent, f);
139 140
140 c++; 141 c++;
141 } 142 }
@@ -154,6 +155,20 @@ static void _xs_json_dump(const xs_val *data, int level, int indent, FILE *f)
154} 155}
155 156
156 157
158int xs_json_dump(const xs_val *data, int indent, FILE *f)
159/* dumps data into a file as JSON */
160{
161 xstype t = xs_type(data);
162
163 if (t == XSTYPE_LIST || t == XSTYPE_DICT) {
164 xs_json_dump_value(data, 0, indent, f);
165 return 1;
166 }
167
168 return 0;
169}
170
171
157xs_str *xs_json_dumps(const xs_val *data, int indent) 172xs_str *xs_json_dumps(const xs_val *data, int indent)
158/* dumps data as a JSON string */ 173/* dumps data as a JSON string */
159{ 174{
@@ -173,20 +188,6 @@ xs_str *xs_json_dumps(const xs_val *data, int indent)
173} 188}
174 189
175 190
176int xs_json_dump(const xs_val *data, int indent, FILE *f)
177/* dumps data into a file as JSON */
178{
179 xstype t = xs_type(data);
180
181 if (t == XSTYPE_LIST || t == XSTYPE_DICT) {
182 _xs_json_dump(data, 0, indent, f);
183 return 1;
184 }
185
186 return 0;
187}
188
189
190/** JSON loads **/ 191/** JSON loads **/
191 192
192typedef enum { 193typedef enum {
@@ -370,6 +371,8 @@ int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c)
370 else 371 else
371 return -1; 372 return -1;
372 } 373 }
374 else
375 *pt = xs_type(*value);
373 376
374 *c = *c + 1; 377 *c = *c + 1;
375 378
@@ -377,43 +380,51 @@ int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c)
377} 380}
378 381
379 382
380xs_list *xs_json_load_array(FILE *f, int maxdepth) 383int xs_json_load_array(FILE *f, int maxdepth, xs_list **l)
381/* loads a full JSON array (after the initial OBRACK) */ 384/* loads a full JSON array (after the initial OBRACK) */
385/* l can be NULL for the content to be dropped */
382{ 386{
383 xstype t; 387 xstype t;
384 xs_list *l = xs_list_new(); 388 int r = 0;
385 int c = 0; 389 int c = 0;
386 390
387 for (;;) { 391 for (;;) {
388 xs *v = NULL; 392 xs *v = NULL;
389 int r = xs_json_load_array_iter(f, &v, &t, &c); 393 r = xs_json_load_array_iter(f, &v, &t, &c);
390
391 if (r == -1)
392 l = xs_free(l);
393 394
394 if (r == 1) { 395 if (r == 1) {
395 /* partial load? */ 396 /* partial load? */
396 if (v == NULL && maxdepth != 0) { 397 if (v == NULL && maxdepth != 0) {
397 if (t == XSTYPE_LIST) 398 if (t == XSTYPE_LIST) {
398 v = xs_json_load_array(f, maxdepth - 1); 399 if (l)
400 v = xs_list_new();
401
402 r = xs_json_load_array(f, maxdepth - 1, &v);
403 }
399 else 404 else
400 if (t == XSTYPE_DICT) 405 if (t == XSTYPE_DICT) {
401 v = xs_json_load_object(f, maxdepth - 1); 406 if (l)
407 v = xs_dict_new();
408
409 r = xs_json_load_object(f, maxdepth - 1, &v);
410 }
402 } 411 }
403 412
404 /* still null? fail */ 413 /* error? */
405 if (v == NULL) { 414 if (r < 0)
406 l = xs_free(l);
407 break; 415 break;
408 }
409 416
410 l = xs_list_append(l, v); 417 if (l)
418 *l = xs_list_append(*l, v);
411 } 419 }
412 else 420 else
413 break; 421 break;
414 } 422 }
415 423
416 return l; 424 if (r < 0 && l)
425 *l = xs_free(*l);
426
427 return r;
417} 428}
418 429
419 430
@@ -458,6 +469,8 @@ int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt,
458 else 469 else
459 return -1; 470 return -1;
460 } 471 }
472 else
473 *pt = xs_type(*value);
461 474
462 *c = *c + 1; 475 *c = *c + 1;
463 476
@@ -465,59 +478,52 @@ int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt,
465} 478}
466 479
467 480
468xs_dict *xs_json_load_object(FILE *f, int maxdepth) 481int xs_json_load_object(FILE *f, int maxdepth, xs_dict **d)
469/* loads a full JSON object (after the initial OCURLY) */ 482/* loads a full JSON object (after the initial OCURLY) */
483/* d can be NULL for the content to be dropped */
470{ 484{
471 xstype t; 485 xstype t;
472 xs_dict *d = xs_dict_new(); 486 int r = 0;
473 int c = 0; 487 int c = 0;
474 488
475 for (;;) { 489 for (;;) {
476 xs *k = NULL; 490 xs *k = NULL;
477 xs *v = NULL; 491 xs *v = NULL;
478 int r = xs_json_load_object_iter(f, &k, &v, &t, &c); 492 r = xs_json_load_object_iter(f, &k, &v, &t, &c);
479
480 if (r == -1)
481 d = xs_free(d);
482 493
483 if (r == 1) { 494 if (r == 1) {
484 /* partial load? */ 495 /* partial load? */
485 if (v == NULL && maxdepth != 0) { 496 if (v == NULL && maxdepth != 0) {
486 if (t == XSTYPE_LIST) 497 if (t == XSTYPE_LIST) {
487 v = xs_json_load_array(f, maxdepth - 1); 498 if (d)
499 v = xs_list_new();
500
501 r = xs_json_load_array(f, maxdepth - 1, &v);
502 }
488 else 503 else
489 if (t == XSTYPE_DICT) 504 if (t == XSTYPE_DICT) {
490 v = xs_json_load_object(f, maxdepth - 1); 505 if (d)
506 v = xs_dict_new();
507
508 r = xs_json_load_object(f, maxdepth - 1, &v);
509 }
491 } 510 }
492 511
493 /* still null? fail */ 512 /* error? */
494 if (v == NULL) { 513 if (r < 0)
495 d = xs_free(d);
496 break; 514 break;
497 }
498 515
499 d = xs_dict_append(d, k, v); 516 if (d)
517 *d = xs_dict_append(*d, k, v);
500 } 518 }
501 else 519 else
502 break; 520 break;
503 } 521 }
504 522
505 return d; 523 if (r < 0 && d)
506} 524 *d = xs_free(*d);
507
508
509xs_val *xs_json_loads_full(const xs_str *json, int maxdepth)
510/* loads a string in JSON format and converts to a multiple data */
511{
512 FILE *f;
513 xs_val *v = NULL;
514
515 if ((f = fmemopen((char *)json, strlen(json), "r")) != NULL) {
516 v = xs_json_load_full(f, maxdepth);
517 fclose(f);
518 }
519 525
520 return v; 526 return r;
521} 527}
522 528
523 529
@@ -545,11 +551,30 @@ xs_val *xs_json_load_full(FILE *f, int maxdepth)
545 xs_val *v = NULL; 551 xs_val *v = NULL;
546 xstype t = xs_json_load_type(f); 552 xstype t = xs_json_load_type(f);
547 553
548 if (t == XSTYPE_LIST) 554 if (t == XSTYPE_LIST) {
549 v = xs_json_load_array(f, maxdepth); 555 v = xs_list_new();
556 xs_json_load_array(f, maxdepth, &v);
557 }
550 else 558 else
551 if (t == XSTYPE_DICT) 559 if (t == XSTYPE_DICT) {
552 v = xs_json_load_object(f, maxdepth); 560 v = xs_dict_new();
561 xs_json_load_object(f, maxdepth, &v);
562 }
563
564 return v;
565}
566
567
568xs_val *xs_json_loads_full(const xs_str *json, int maxdepth)
569/* loads a string in JSON format and converts to a multiple data */
570{
571 FILE *f;
572 xs_val *v = NULL;
573
574 if ((f = fmemopen((char *)json, strlen(json), "r")) != NULL) {
575 v = xs_json_load_full(f, maxdepth);
576 fclose(f);
577 }
553 578
554 return v; 579 return v;
555} 580}