summaryrefslogtreecommitdiff
path: root/xs_json.h
diff options
context:
space:
mode:
authorGravatar default2024-03-25 08:55:30 +0100
committerGravatar default2024-03-25 08:55:30 +0100
commitabf4279000df446fb115b50d735d74475f0ec3f7 (patch)
treefc2721fb14e623a655daeb51a492630d55e19e33 /xs_json.h
parentUpdated documentation. (diff)
downloadsnac2-abf4279000df446fb115b50d735d74475f0ec3f7.tar.gz
snac2-abf4279000df446fb115b50d735d74475f0ec3f7.tar.xz
snac2-abf4279000df446fb115b50d735d74475f0ec3f7.zip
Backport from xs.
Diffstat (limited to 'xs_json.h')
-rw-r--r--xs_json.h107
1 files changed, 74 insertions, 33 deletions
diff --git a/xs_json.h b/xs_json.h
index d656b15..1494fe8 100644
--- a/xs_json.h
+++ b/xs_json.h
@@ -11,8 +11,10 @@ xs_val *xs_json_load(FILE *f);
11xs_val *xs_json_loads(const xs_str *json); 11xs_val *xs_json_loads(const xs_str *json);
12 12
13xstype xs_json_load_type(FILE *f); 13xstype xs_json_load_type(FILE *f);
14int xs_json_load_array_iter(FILE *f, xs_val **value, int *c); 14int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c);
15int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, int *c); 15int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c);
16xs_list *xs_json_load_array(FILE *f);
17xs_dict *xs_json_load_object(FILE *f);
16 18
17 19
18#ifdef XS_IMPLEMENTATION 20#ifdef XS_IMPLEMENTATION
@@ -324,10 +326,9 @@ static xs_val *_xs_json_load_lexer(FILE *f, js_type *t)
324} 326}
325 327
326 328
327static xs_list *_xs_json_load_array(FILE *f); 329int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c)
328static xs_dict *_xs_json_load_object(FILE *f); 330/* loads the next scalar value from the JSON stream */
329 331/* if the value ahead is complex, value is NULL and pt is filled */
330int xs_json_load_array_iter(FILE *f, xs_val **value, int *c)
331{ 332{
332 js_type t; 333 js_type t;
333 334
@@ -346,14 +347,16 @@ int xs_json_load_array_iter(FILE *f, xs_val **value, int *c)
346 return -1; 347 return -1;
347 } 348 }
348 349
349 if (t == JS_OBRACK) 350 if (*value == NULL) {
350 *value = _xs_json_load_array(f); 351 /* possible complex type ahead */
351 else 352 if (t == JS_OBRACK)
352 if (t == JS_OCURLY) 353 *pt = XSTYPE_LIST;
353 *value = _xs_json_load_object(f); 354 else
354 355 if (t == JS_OCURLY)
355 if (*value == NULL) 356 *pt = XSTYPE_DICT;
356 return -1; 357 else
358 return -1;
359 }
357 360
358 *c = *c + 1; 361 *c = *c + 1;
359 362
@@ -361,21 +364,38 @@ int xs_json_load_array_iter(FILE *f, xs_val **value, int *c)
361} 364}
362 365
363 366
364static xs_list *_xs_json_load_array(FILE *f) 367xs_list *xs_json_load_array(FILE *f)
365/* parses a JSON array */ 368/* loads a JSON array (after the initial OBRACK) */
366{ 369{
370 xstype t;
367 xs_list *l = xs_list_new(); 371 xs_list *l = xs_list_new();
368 int c = 0; 372 int c = 0;
369 373
370 for (;;) { 374 for (;;) {
371 xs *v = NULL; 375 xs *v = NULL;
372 int r = xs_json_load_array_iter(f, &v, &c); 376 int r = xs_json_load_array_iter(f, &v, &t, &c);
373 377
374 if (r == -1) 378 if (r == -1)
375 l = xs_free(l); 379 l = xs_free(l);
376 380
377 if (r == 1) 381 if (r == 1) {
382 /* partial load? */
383 if (v == NULL) {
384 if (t == XSTYPE_LIST)
385 v = xs_json_load_array(f);
386 else
387 if (t == XSTYPE_DICT)
388 v = xs_json_load_object(f);
389 }
390
391 /* still null? fail */
392 if (v == NULL) {
393 l = xs_free(l);
394 break;
395 }
396
378 l = xs_list_append(l, v); 397 l = xs_list_append(l, v);
398 }
379 else 399 else
380 break; 400 break;
381 } 401 }
@@ -384,7 +404,9 @@ static xs_list *_xs_json_load_array(FILE *f)
384} 404}
385 405
386 406
387int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, int *c) 407int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c)
408/* loads the next key and scalar value from the JSON stream */
409/* if the value ahead is complex, value is NULL and pt is filled */
388{ 410{
389 js_type t; 411 js_type t;
390 412
@@ -413,14 +435,16 @@ int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, int *c)
413 435
414 *value = _xs_json_load_lexer(f, &t); 436 *value = _xs_json_load_lexer(f, &t);
415 437
416 if (t == JS_OBRACK) 438 if (*value == NULL) {
417 *value = _xs_json_load_array(f); 439 /* possible complex type ahead */
418 else 440 if (t == JS_OBRACK)
419 if (t == JS_OCURLY) 441 *pt = XSTYPE_LIST;
420 *value = _xs_json_load_object(f); 442 else
421 443 if (t == JS_OCURLY)
422 if (*value == NULL) 444 *pt = XSTYPE_DICT;
423 return -1; 445 else
446 return -1;
447 }
424 448
425 *c = *c + 1; 449 *c = *c + 1;
426 450
@@ -428,22 +452,39 @@ int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, int *c)
428} 452}
429 453
430 454
431static xs_dict *_xs_json_load_object(FILE *f) 455xs_dict *xs_json_load_object(FILE *f)
432/* parses a JSON object */ 456/* loads a JSON object (after the initial OCURLY) */
433{ 457{
458 xstype t;
434 xs_dict *d = xs_dict_new(); 459 xs_dict *d = xs_dict_new();
435 int c = 0; 460 int c = 0;
436 461
437 for (;;) { 462 for (;;) {
438 xs *k = NULL; 463 xs *k = NULL;
439 xs *v = NULL; 464 xs *v = NULL;
440 int r = xs_json_load_object_iter(f, &k, &v, &c); 465 int r = xs_json_load_object_iter(f, &k, &v, &t, &c);
441 466
442 if (r == -1) 467 if (r == -1)
443 d = xs_free(d); 468 d = xs_free(d);
444 469
445 if (r == 1) 470 if (r == 1) {
471 /* partial load? */
472 if (v == NULL) {
473 if (t == XSTYPE_LIST)
474 v = xs_json_load_array(f);
475 else
476 if (t == XSTYPE_DICT)
477 v = xs_json_load_object(f);
478 }
479
480 /* still null? fail */
481 if (v == NULL) {
482 d = xs_free(d);
483 break;
484 }
485
446 d = xs_dict_append(d, k, v); 486 d = xs_dict_append(d, k, v);
487 }
447 else 488 else
448 break; 489 break;
449 } 490 }
@@ -492,10 +533,10 @@ xs_val *xs_json_load(FILE *f)
492 xstype t = xs_json_load_type(f); 533 xstype t = xs_json_load_type(f);
493 534
494 if (t == XSTYPE_LIST) 535 if (t == XSTYPE_LIST)
495 v = _xs_json_load_array(f); 536 v = xs_json_load_array(f);
496 else 537 else
497 if (t == XSTYPE_DICT) 538 if (t == XSTYPE_DICT)
498 v = _xs_json_load_object(f); 539 v = xs_json_load_object(f);
499 540
500 return v; 541 return v;
501} 542}