summaryrefslogtreecommitdiff
path: root/xs_json.h
diff options
context:
space:
mode:
authorGravatar default2023-09-03 20:22:32 +0200
committerGravatar default2023-09-03 20:22:32 +0200
commit8535fc84c92e42ca379558b3c0a3a9a2d0faedaa (patch)
tree115bddc23890b45322a5088cb4308696f22820cf /xs_json.h
parentImproved heart <3 emoji. (diff)
downloadpenes-snac2-8535fc84c92e42ca379558b3c0a3a9a2d0faedaa.tar.gz
penes-snac2-8535fc84c92e42ca379558b3c0a3a9a2d0faedaa.tar.xz
penes-snac2-8535fc84c92e42ca379558b3c0a3a9a2d0faedaa.zip
Backport from xs.
Diffstat (limited to 'xs_json.h')
-rw-r--r--xs_json.h179
1 files changed, 116 insertions, 63 deletions
diff --git a/xs_json.h b/xs_json.h
index 3df5d53..639b52d 100644
--- a/xs_json.h
+++ b/xs_json.h
@@ -6,8 +6,13 @@
6 6
7int xs_json_dump(const xs_val *data, int indent, FILE *f); 7int xs_json_dump(const xs_val *data, int indent, FILE *f);
8xs_str *xs_json_dumps(const xs_val *data, int indent); 8xs_str *xs_json_dumps(const xs_val *data, int indent);
9xs_val *xs_json_loads(const xs_str *json); 9
10xs_val *xs_json_load(FILE *f); 10xs_val *xs_json_load(FILE *f);
11xs_val *xs_json_loads(const xs_str *json);
12
13xstype xs_json_load_type(FILE *f);
14int xs_json_load_array_iter(FILE *f, xs_val **value, int *c);
15int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, int *c);
11 16
12 17
13#ifdef XS_IMPLEMENTATION 18#ifdef XS_IMPLEMENTATION
@@ -176,8 +181,6 @@ int xs_json_dump(const xs_val *data, int indent, FILE *f)
176 181
177/** JSON loads **/ 182/** JSON loads **/
178 183
179/* this code comes mostly from the Minimum Profit Text Editor (MPDM) */
180
181typedef enum { 184typedef enum {
182 JS_ERROR = -1, 185 JS_ERROR = -1,
183 JS_INCOMPLETE, 186 JS_INCOMPLETE,
@@ -326,6 +329,40 @@ static xs_val *_xs_json_load_lexer(FILE *f, js_type *t)
326static xs_list *_xs_json_load_array(FILE *f); 329static xs_list *_xs_json_load_array(FILE *f);
327static xs_dict *_xs_json_load_object(FILE *f); 330static xs_dict *_xs_json_load_object(FILE *f);
328 331
332int xs_json_load_array_iter(FILE *f, xs_val **value, int *c)
333{
334 js_type t;
335
336 *value = _xs_json_load_lexer(f, &t);
337
338 if (t == JS_ERROR)
339 return -1;
340
341 if (t == JS_CBRACK)
342 return 0;
343
344 if (*c > 0) {
345 if (t == JS_COMMA)
346 *value = _xs_json_load_lexer(f, &t);
347 else
348 return -1;
349 }
350
351 if (t == JS_OBRACK)
352 *value = _xs_json_load_array(f);
353 else
354 if (t == JS_OCURLY)
355 *value = _xs_json_load_object(f);
356
357 if (*value == NULL)
358 return -1;
359
360 *c = *c + 1;
361
362 return 1;
363}
364
365
329static xs_list *_xs_json_load_array(FILE *f) 366static xs_list *_xs_json_load_array(FILE *f)
330/* parses a JSON array */ 367/* parses a JSON array */
331{ 368{
@@ -333,36 +370,63 @@ static xs_list *_xs_json_load_array(FILE *f)
333 int c = 0; 370 int c = 0;
334 371
335 for (;;) { 372 for (;;) {
336 js_type tt; 373 xs *v = NULL;
337 xs *v = _xs_json_load_lexer(f, &tt); 374 int r = xs_json_load_array_iter(f, &v, &c);
375
376 if (r == -1)
377 l = xs_free(l);
338 378
339 if (tt == JS_ERROR) 379 if (r == 1)
380 l = xs_list_append(l, v);
381 else
340 break; 382 break;
383 }
341 384
342 if (tt == JS_CBRACK) 385 return l;
343 return l; 386}
344 387
345 if (c > 0) {
346 if (tt == JS_COMMA)
347 v = _xs_json_load_lexer(f, &tt);
348 else
349 break;
350 }
351 388
352 if (tt == JS_OBRACK) 389int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, int *c)
353 v = _xs_json_load_array(f); 390{
354 else 391 js_type t;
355 if (tt == JS_OCURLY)
356 v = _xs_json_load_object(f);
357 392
358 if (v == NULL) 393 *key = _xs_json_load_lexer(f, &t);
359 break; 394
395 if (t == JS_ERROR)
396 return -1;
360 397
361 l = xs_list_append(l, v); 398 if (t == JS_CCURLY)
362 c++; 399 return 0;
400
401 if (*c > 0) {
402 if (t == JS_COMMA)
403 *key = _xs_json_load_lexer(f, &t);
404 else
405 return -1;
363 } 406 }
364 407
365 return xs_free(l); 408 if (t != JS_STRING)
409 return -1;
410
411 xs_free(_xs_json_load_lexer(f, &t));
412
413 if (t != JS_COLON)
414 return -1;
415
416 *value = _xs_json_load_lexer(f, &t);
417
418 if (t == JS_OBRACK)
419 *value = _xs_json_load_array(f);
420 else
421 if (t == JS_OCURLY)
422 *value = _xs_json_load_object(f);
423
424 if (*value == NULL)
425 return -1;
426
427 *c = *c + 1;
428
429 return 1;
366} 430}
367 431
368 432
@@ -375,47 +439,20 @@ static xs_dict *_xs_json_load_object(FILE *f)
375 d = xs_dict_new(); 439 d = xs_dict_new();
376 440
377 for (;;) { 441 for (;;) {
378 js_type tt; 442 xs *k = NULL;
379 xs *k = _xs_json_load_lexer(f, &tt);
380 xs *v = NULL; 443 xs *v = NULL;
444 int r = xs_json_load_object_iter(f, &k, &v, &c);
381 445
382 if (tt == JS_ERROR) 446 if (r == -1)
383 break; 447 d = xs_free(d);
384
385 if (tt == JS_CCURLY)
386 return d;
387
388 if (c > 0) {
389 if (tt == JS_COMMA)
390 k = _xs_json_load_lexer(f, &tt);
391 else
392 break;
393 }
394
395 if (tt != JS_STRING)
396 break;
397
398 xs_free(_xs_json_load_lexer(f, &tt));
399 448
400 if (tt != JS_COLON) 449 if (r == 1)
401 break; 450 d = xs_dict_append(d, k, v);
402
403 v = _xs_json_load_lexer(f, &tt);
404
405 if (tt == JS_OBRACK)
406 v = _xs_json_load_array(f);
407 else 451 else
408 if (tt == JS_OCURLY)
409 v = _xs_json_load_object(f);
410
411 if (v == NULL)
412 break; 452 break;
413
414 d = xs_dict_append(d, k, v);
415 c++;
416 } 453 }
417 454
418 return xs_free(d); 455 return d;
419} 456}
420 457
421 458
@@ -434,18 +471,34 @@ xs_val *xs_json_loads(const xs_str *json)
434} 471}
435 472
436 473
474xstype xs_json_load_type(FILE *f)
475/* identifies the type of a JSON stream */
476{
477 xstype t = XSTYPE_NULL;
478 js_type jt;
479
480 xs_free(_xs_json_load_lexer(f, &jt));
481
482 if (jt == JS_OBRACK)
483 t = XSTYPE_LIST;
484 else
485 if (jt == JS_OCURLY)
486 t = XSTYPE_DICT;
487
488 return t;
489}
490
491
437xs_val *xs_json_load(FILE *f) 492xs_val *xs_json_load(FILE *f)
438/* loads a JSON file */ 493/* loads a JSON file */
439{ 494{
440 xs_val *v = NULL; 495 xs_val *v = NULL;
441 js_type t; 496 xstype t = xs_json_load_type(f);
442 497
443 xs_free(_xs_json_load_lexer(f, &t)); 498 if (t == XSTYPE_LIST)
444
445 if (t == JS_OBRACK)
446 v = _xs_json_load_array(f); 499 v = _xs_json_load_array(f);
447 else 500 else
448 if (t == JS_OCURLY) 501 if (t == XSTYPE_DICT)
449 v = _xs_json_load_object(f); 502 v = _xs_json_load_object(f);
450 503
451 return v; 504 return v;