diff options
| author | 2024-03-25 08:55:30 +0100 | |
|---|---|---|
| committer | 2024-03-25 08:55:30 +0100 | |
| commit | abf4279000df446fb115b50d735d74475f0ec3f7 (patch) | |
| tree | fc2721fb14e623a655daeb51a492630d55e19e33 /xs_json.h | |
| parent | Updated documentation. (diff) | |
| download | snac2-abf4279000df446fb115b50d735d74475f0ec3f7.tar.gz snac2-abf4279000df446fb115b50d735d74475f0ec3f7.tar.xz snac2-abf4279000df446fb115b50d735d74475f0ec3f7.zip | |
Backport from xs.
Diffstat (limited to 'xs_json.h')
| -rw-r--r-- | xs_json.h | 107 |
1 files changed, 74 insertions, 33 deletions
| @@ -11,8 +11,10 @@ xs_val *xs_json_load(FILE *f); | |||
| 11 | xs_val *xs_json_loads(const xs_str *json); | 11 | xs_val *xs_json_loads(const xs_str *json); |
| 12 | 12 | ||
| 13 | xstype xs_json_load_type(FILE *f); | 13 | xstype xs_json_load_type(FILE *f); |
| 14 | int xs_json_load_array_iter(FILE *f, xs_val **value, int *c); | 14 | int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c); |
| 15 | int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, int *c); | 15 | int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c); |
| 16 | xs_list *xs_json_load_array(FILE *f); | ||
| 17 | xs_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 | ||
| 327 | static xs_list *_xs_json_load_array(FILE *f); | 329 | int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c) |
| 328 | static 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 */ | |
| 330 | int 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 | ||
| 364 | static xs_list *_xs_json_load_array(FILE *f) | 367 | xs_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 | ||
| 387 | int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, int *c) | 407 | int 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 | ||
| 431 | static xs_dict *_xs_json_load_object(FILE *f) | 455 | xs_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 | } |