diff options
| -rw-r--r-- | xs_json.h | 124 | ||||
| -rw-r--r-- | xs_version.h | 2 |
2 files changed, 73 insertions, 53 deletions
| @@ -19,8 +19,8 @@ xs_val *xs_json_loads_full(const xs_str *json, int maxdepth); | |||
| 19 | xstype xs_json_load_type(FILE *f); | 19 | xstype xs_json_load_type(FILE *f); |
| 20 | int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c); | 20 | int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c); |
| 21 | int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c); | 21 | int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c); |
| 22 | xs_list *xs_json_load_array(FILE *f, int maxdepth); | 22 | int xs_json_load_array(FILE *f, int maxdepth, xs_list **l); |
| 23 | xs_dict *xs_json_load_object(FILE *f, int maxdepth); | 23 | int xs_json_load_object(FILE *f, int maxdepth, xs_dict **d); |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | #ifdef XS_IMPLEMENTATION | 26 | #ifdef XS_IMPLEMENTATION |
| @@ -377,43 +377,51 @@ int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c) | |||
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | 379 | ||
| 380 | xs_list *xs_json_load_array(FILE *f, int maxdepth) | 380 | int xs_json_load_array(FILE *f, int maxdepth, xs_list **l) |
| 381 | /* loads a full JSON array (after the initial OBRACK) */ | 381 | /* loads a full JSON array (after the initial OBRACK) */ |
| 382 | /* l can be NULL for the content to be dropped */ | ||
| 382 | { | 383 | { |
| 383 | xstype t; | 384 | xstype t; |
| 384 | xs_list *l = xs_list_new(); | 385 | int r = 0; |
| 385 | int c = 0; | 386 | int c = 0; |
| 386 | 387 | ||
| 387 | for (;;) { | 388 | for (;;) { |
| 388 | xs *v = NULL; | 389 | xs *v = NULL; |
| 389 | int r = xs_json_load_array_iter(f, &v, &t, &c); | 390 | r = xs_json_load_array_iter(f, &v, &t, &c); |
| 390 | |||
| 391 | if (r == -1) | ||
| 392 | l = xs_free(l); | ||
| 393 | 391 | ||
| 394 | if (r == 1) { | 392 | if (r == 1) { |
| 395 | /* partial load? */ | 393 | /* partial load? */ |
| 396 | if (v == NULL && maxdepth != 0) { | 394 | if (v == NULL && maxdepth != 0) { |
| 397 | if (t == XSTYPE_LIST) | 395 | if (t == XSTYPE_LIST) { |
| 398 | v = xs_json_load_array(f, maxdepth - 1); | 396 | if (l) |
| 397 | v = xs_list_new(); | ||
| 398 | |||
| 399 | r = xs_json_load_array(f, maxdepth - 1, &v); | ||
| 400 | } | ||
| 399 | else | 401 | else |
| 400 | if (t == XSTYPE_DICT) | 402 | if (t == XSTYPE_DICT) { |
| 401 | v = xs_json_load_object(f, maxdepth - 1); | 403 | if (l) |
| 404 | v = xs_dict_new(); | ||
| 405 | |||
| 406 | r = xs_json_load_object(f, maxdepth - 1, &v); | ||
| 407 | } | ||
| 402 | } | 408 | } |
| 403 | 409 | ||
| 404 | /* still null? fail */ | 410 | /* error? */ |
| 405 | if (v == NULL) { | 411 | if (r < 0) |
| 406 | l = xs_free(l); | ||
| 407 | break; | 412 | break; |
| 408 | } | ||
| 409 | 413 | ||
| 410 | l = xs_list_append(l, v); | 414 | if (l) |
| 415 | *l = xs_list_append(*l, v); | ||
| 411 | } | 416 | } |
| 412 | else | 417 | else |
| 413 | break; | 418 | break; |
| 414 | } | 419 | } |
| 415 | 420 | ||
| 416 | return l; | 421 | if (r < 0 && l) |
| 422 | *l = xs_free(*l); | ||
| 423 | |||
| 424 | return r; | ||
| 417 | } | 425 | } |
| 418 | 426 | ||
| 419 | 427 | ||
| @@ -465,59 +473,52 @@ int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, | |||
| 465 | } | 473 | } |
| 466 | 474 | ||
| 467 | 475 | ||
| 468 | xs_dict *xs_json_load_object(FILE *f, int maxdepth) | 476 | int xs_json_load_object(FILE *f, int maxdepth, xs_dict **d) |
| 469 | /* loads a full JSON object (after the initial OCURLY) */ | 477 | /* loads a full JSON object (after the initial OCURLY) */ |
| 478 | /* d can be NULL for the content to be dropped */ | ||
| 470 | { | 479 | { |
| 471 | xstype t; | 480 | xstype t; |
| 472 | xs_dict *d = xs_dict_new(); | 481 | int r = 0; |
| 473 | int c = 0; | 482 | int c = 0; |
| 474 | 483 | ||
| 475 | for (;;) { | 484 | for (;;) { |
| 476 | xs *k = NULL; | 485 | xs *k = NULL; |
| 477 | xs *v = NULL; | 486 | xs *v = NULL; |
| 478 | int r = xs_json_load_object_iter(f, &k, &v, &t, &c); | 487 | r = xs_json_load_object_iter(f, &k, &v, &t, &c); |
| 479 | |||
| 480 | if (r == -1) | ||
| 481 | d = xs_free(d); | ||
| 482 | 488 | ||
| 483 | if (r == 1) { | 489 | if (r == 1) { |
| 484 | /* partial load? */ | 490 | /* partial load? */ |
| 485 | if (v == NULL && maxdepth != 0) { | 491 | if (v == NULL && maxdepth != 0) { |
| 486 | if (t == XSTYPE_LIST) | 492 | if (t == XSTYPE_LIST) { |
| 487 | v = xs_json_load_array(f, maxdepth - 1); | 493 | if (d) |
| 494 | v = xs_list_new(); | ||
| 495 | |||
| 496 | r = xs_json_load_array(f, maxdepth - 1, &v); | ||
| 497 | } | ||
| 488 | else | 498 | else |
| 489 | if (t == XSTYPE_DICT) | 499 | if (t == XSTYPE_DICT) { |
| 490 | v = xs_json_load_object(f, maxdepth - 1); | 500 | if (d) |
| 501 | v = xs_dict_new(); | ||
| 502 | |||
| 503 | r = xs_json_load_object(f, maxdepth - 1, &v); | ||
| 504 | } | ||
| 491 | } | 505 | } |
| 492 | 506 | ||
| 493 | /* still null? fail */ | 507 | /* error? */ |
| 494 | if (v == NULL) { | 508 | if (r < 0) |
| 495 | d = xs_free(d); | ||
| 496 | break; | 509 | break; |
| 497 | } | ||
| 498 | 510 | ||
| 499 | d = xs_dict_append(d, k, v); | 511 | if (d) |
| 512 | *d = xs_dict_append(*d, k, v); | ||
| 500 | } | 513 | } |
| 501 | else | 514 | else |
| 502 | break; | 515 | break; |
| 503 | } | 516 | } |
| 504 | 517 | ||
| 505 | return d; | 518 | if (r < 0 && d) |
| 506 | } | 519 | *d = xs_free(*d); |
| 507 | |||
| 508 | |||
| 509 | xs_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 | 520 | ||
| 520 | return v; | 521 | return r; |
| 521 | } | 522 | } |
| 522 | 523 | ||
| 523 | 524 | ||
| @@ -545,11 +546,30 @@ xs_val *xs_json_load_full(FILE *f, int maxdepth) | |||
| 545 | xs_val *v = NULL; | 546 | xs_val *v = NULL; |
| 546 | xstype t = xs_json_load_type(f); | 547 | xstype t = xs_json_load_type(f); |
| 547 | 548 | ||
| 548 | if (t == XSTYPE_LIST) | 549 | if (t == XSTYPE_LIST) { |
| 549 | v = xs_json_load_array(f, maxdepth); | 550 | v = xs_list_new(); |
| 551 | xs_json_load_array(f, maxdepth, &v); | ||
| 552 | } | ||
| 550 | else | 553 | else |
| 551 | if (t == XSTYPE_DICT) | 554 | if (t == XSTYPE_DICT) { |
| 552 | v = xs_json_load_object(f, maxdepth); | 555 | v = xs_dict_new(); |
| 556 | xs_json_load_object(f, maxdepth, &v); | ||
| 557 | } | ||
| 558 | |||
| 559 | return v; | ||
| 560 | } | ||
| 561 | |||
| 562 | |||
| 563 | xs_val *xs_json_loads_full(const xs_str *json, int maxdepth) | ||
| 564 | /* loads a string in JSON format and converts to a multiple data */ | ||
| 565 | { | ||
| 566 | FILE *f; | ||
| 567 | xs_val *v = NULL; | ||
| 568 | |||
| 569 | if ((f = fmemopen((char *)json, strlen(json), "r")) != NULL) { | ||
| 570 | v = xs_json_load_full(f, maxdepth); | ||
| 571 | fclose(f); | ||
| 572 | } | ||
| 553 | 573 | ||
| 554 | return v; | 574 | return v; |
| 555 | } | 575 | } |
diff --git a/xs_version.h b/xs_version.h index c9418a7..74f453f 100644 --- a/xs_version.h +++ b/xs_version.h | |||
| @@ -1 +1 @@ | |||
| /* 963b6129fca4fb5c009533db0ed602ab8ed5424d 2025-06-12T11:33:02+02:00 */ | /* 851c21892c8df1d8f05ae95eaa4a5913e852653b 2025-06-21T17:58:11+02:00 */ | ||