Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/compat/jansson/load.c
1201 views
1
/*
2
* Copyright (c) 2009-2013 Petri Lehtinen <[email protected]>
3
*
4
* Jansson is free software; you can redistribute it and/or modify
5
* it under the terms of the MIT license. See LICENSE for details.
6
*/
7
8
#ifndef _GNU_SOURCE
9
#define _GNU_SOURCE
10
#endif
11
12
#include <errno.h>
13
#include <limits.h>
14
#include <stdio.h>
15
#include <stdlib.h>
16
#include <string.h>
17
#include <assert.h>
18
19
#include "jansson.h"
20
#include "jansson_private.h"
21
#include "strbuffer.h"
22
#include "utf.h"
23
24
#define STREAM_STATE_OK 0
25
#define STREAM_STATE_EOF -1
26
#define STREAM_STATE_ERROR -2
27
28
#define TOKEN_INVALID -1
29
#define TOKEN_EOF 0
30
#define TOKEN_STRING 256
31
#define TOKEN_INTEGER 257
32
#define TOKEN_REAL 258
33
#define TOKEN_TRUE 259
34
#define TOKEN_FALSE 260
35
#define TOKEN_NULL 261
36
37
/* Locale independent versions of isxxx() functions */
38
#define l_isupper(c) ('A' <= (c) && (c) <= 'Z')
39
#define l_islower(c) ('a' <= (c) && (c) <= 'z')
40
#define l_isalpha(c) (l_isupper(c) || l_islower(c))
41
#define l_isdigit(c) ('0' <= (c) && (c) <= '9')
42
#define l_isxdigit(c) \
43
(l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f'))
44
45
/* Read one byte from stream, convert to unsigned char, then int, and
46
return. return EOF on end of file. This corresponds to the
47
behaviour of fgetc(). */
48
typedef int (*get_func)(void *data);
49
50
typedef struct {
51
get_func get;
52
void *data;
53
char buffer[5];
54
size_t buffer_pos;
55
int state;
56
int line;
57
int column, last_column;
58
size_t position;
59
} stream_t;
60
61
typedef struct {
62
stream_t stream;
63
strbuffer_t saved_text;
64
int token;
65
union {
66
char *string;
67
json_int_t integer;
68
double real;
69
} value;
70
} lex_t;
71
72
#define stream_to_lex(stream) container_of(stream, lex_t, stream)
73
74
75
/*** error reporting ***/
76
77
static void error_set(json_error_t *error, const lex_t *lex,
78
const char *msg, ...)
79
{
80
va_list ap;
81
char msg_text[JSON_ERROR_TEXT_LENGTH];
82
char msg_with_context[JSON_ERROR_TEXT_LENGTH];
83
84
int line = -1, col = -1;
85
size_t pos = 0;
86
const char *result = msg_text;
87
88
if(!error)
89
return;
90
91
va_start(ap, msg);
92
vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap);
93
msg_text[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
94
va_end(ap);
95
96
if(lex)
97
{
98
const char *saved_text = strbuffer_value(&lex->saved_text);
99
100
line = lex->stream.line;
101
col = lex->stream.column;
102
pos = lex->stream.position;
103
104
if(saved_text && saved_text[0])
105
{
106
if(lex->saved_text.length <= 20) {
107
snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
108
"%s near '%s'", msg_text, saved_text);
109
msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
110
result = msg_with_context;
111
}
112
}
113
else
114
{
115
if(lex->stream.state == STREAM_STATE_ERROR) {
116
/* No context for UTF-8 decoding errors */
117
result = msg_text;
118
}
119
else {
120
snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
121
"%s near end of file", msg_text);
122
msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
123
result = msg_with_context;
124
}
125
}
126
}
127
128
jsonp_error_set(error, line, col, pos, "%s", result);
129
}
130
131
132
/*** lexical analyzer ***/
133
134
static void
135
stream_init(stream_t *stream, get_func get, void *data)
136
{
137
stream->get = get;
138
stream->data = data;
139
stream->buffer[0] = '\0';
140
stream->buffer_pos = 0;
141
142
stream->state = STREAM_STATE_OK;
143
stream->line = 1;
144
stream->column = 0;
145
stream->position = 0;
146
}
147
148
static int stream_get(stream_t *stream, json_error_t *error)
149
{
150
int c;
151
152
if(stream->state != STREAM_STATE_OK)
153
return stream->state;
154
155
if(!stream->buffer[stream->buffer_pos])
156
{
157
c = stream->get(stream->data);
158
if(c == EOF) {
159
stream->state = STREAM_STATE_EOF;
160
return STREAM_STATE_EOF;
161
}
162
163
stream->buffer[0] = c;
164
stream->buffer_pos = 0;
165
166
if(0x80 <= c && c <= 0xFF)
167
{
168
/* multi-byte UTF-8 sequence */
169
int i, count;
170
171
count = utf8_check_first(c);
172
if(!count)
173
goto out;
174
175
assert(count >= 2);
176
177
for(i = 1; i < count; i++)
178
stream->buffer[i] = stream->get(stream->data);
179
180
if(!utf8_check_full(stream->buffer, count, NULL))
181
goto out;
182
183
stream->buffer[count] = '\0';
184
}
185
else
186
stream->buffer[1] = '\0';
187
}
188
189
c = stream->buffer[stream->buffer_pos++];
190
191
stream->position++;
192
if(c == '\n') {
193
stream->line++;
194
stream->last_column = stream->column;
195
stream->column = 0;
196
}
197
else if(utf8_check_first(c)) {
198
/* track the Unicode character column, so increment only if
199
this is the first character of a UTF-8 sequence */
200
stream->column++;
201
}
202
203
return c;
204
205
out:
206
stream->state = STREAM_STATE_ERROR;
207
error_set(error, stream_to_lex(stream), "unable to decode byte 0x%x", c);
208
return STREAM_STATE_ERROR;
209
}
210
211
static void stream_unget(stream_t *stream, int c)
212
{
213
if(c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR)
214
return;
215
216
stream->position--;
217
if(c == '\n') {
218
stream->line--;
219
stream->column = stream->last_column;
220
}
221
else if(utf8_check_first(c))
222
stream->column--;
223
224
assert(stream->buffer_pos > 0);
225
stream->buffer_pos--;
226
assert(stream->buffer[stream->buffer_pos] == c);
227
}
228
229
230
static int lex_get(lex_t *lex, json_error_t *error)
231
{
232
return stream_get(&lex->stream, error);
233
}
234
235
static void lex_save(lex_t *lex, int c)
236
{
237
strbuffer_append_byte(&lex->saved_text, c);
238
}
239
240
static int lex_get_save(lex_t *lex, json_error_t *error)
241
{
242
int c = stream_get(&lex->stream, error);
243
if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR)
244
lex_save(lex, c);
245
return c;
246
}
247
248
static void lex_unget(lex_t *lex, int c)
249
{
250
stream_unget(&lex->stream, c);
251
}
252
253
static void lex_unget_unsave(lex_t *lex, int c)
254
{
255
if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {
256
/* Since we treat warnings as errors, when assertions are turned
257
* off the "d" variable would be set but never used. Which is
258
* treated as an error by GCC.
259
*/
260
#ifndef NDEBUG
261
char d;
262
#endif
263
stream_unget(&lex->stream, c);
264
#ifndef NDEBUG
265
d =
266
#endif
267
strbuffer_pop(&lex->saved_text);
268
assert(c == d);
269
}
270
}
271
272
static void lex_save_cached(lex_t *lex)
273
{
274
while(lex->stream.buffer[lex->stream.buffer_pos] != '\0')
275
{
276
lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]);
277
lex->stream.buffer_pos++;
278
lex->stream.position++;
279
}
280
}
281
282
/* assumes that str points to 'u' plus at least 4 valid hex digits */
283
static int32_t decode_unicode_escape(const char *str)
284
{
285
int i;
286
int32_t value = 0;
287
288
assert(str[0] == 'u');
289
290
for(i = 1; i <= 4; i++) {
291
char c = str[i];
292
value <<= 4;
293
if(l_isdigit(c))
294
value += c - '0';
295
else if(l_islower(c))
296
value += c - 'a' + 10;
297
else if(l_isupper(c))
298
value += c - 'A' + 10;
299
else
300
assert(0);
301
}
302
303
return value;
304
}
305
306
static void lex_scan_string(lex_t *lex, json_error_t *error)
307
{
308
int c;
309
const char *p;
310
char *t;
311
int i;
312
313
lex->value.string = NULL;
314
lex->token = TOKEN_INVALID;
315
316
c = lex_get_save(lex, error);
317
318
while(c != '"') {
319
if(c == STREAM_STATE_ERROR)
320
goto out;
321
322
else if(c == STREAM_STATE_EOF) {
323
error_set(error, lex, "premature end of input");
324
goto out;
325
}
326
327
else if(0 <= c && c <= 0x1F) {
328
/* control character */
329
lex_unget_unsave(lex, c);
330
if(c == '\n')
331
error_set(error, lex, "unexpected newline", c);
332
else
333
error_set(error, lex, "control character 0x%x", c);
334
goto out;
335
}
336
337
else if(c == '\\') {
338
c = lex_get_save(lex, error);
339
if(c == 'u') {
340
c = lex_get_save(lex, error);
341
for(i = 0; i < 4; i++) {
342
if(!l_isxdigit(c)) {
343
error_set(error, lex, "invalid escape");
344
goto out;
345
}
346
c = lex_get_save(lex, error);
347
}
348
}
349
else if(c == '"' || c == '\\' || c == '/' || c == 'b' ||
350
c == 'f' || c == 'n' || c == 'r' || c == 't')
351
c = lex_get_save(lex, error);
352
else {
353
error_set(error, lex, "invalid escape");
354
goto out;
355
}
356
}
357
else
358
c = lex_get_save(lex, error);
359
}
360
361
/* the actual value is at most of the same length as the source
362
string, because:
363
- shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte
364
- a single \uXXXX escape (length 6) is converted to at most 3 bytes
365
- two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair
366
are converted to 4 bytes
367
*/
368
lex->value.string = jsonp_malloc(lex->saved_text.length + 1);
369
if(!lex->value.string) {
370
/* this is not very nice, since TOKEN_INVALID is returned */
371
goto out;
372
}
373
374
/* the target */
375
t = lex->value.string;
376
377
/* + 1 to skip the " */
378
p = strbuffer_value(&lex->saved_text) + 1;
379
380
while(*p != '"') {
381
if(*p == '\\') {
382
p++;
383
if(*p == 'u') {
384
char buffer[4];
385
int length;
386
int32_t value;
387
388
value = decode_unicode_escape(p);
389
p += 5;
390
391
if(0xD800 <= value && value <= 0xDBFF) {
392
/* surrogate pair */
393
if(*p == '\\' && *(p + 1) == 'u') {
394
int32_t value2 = decode_unicode_escape(++p);
395
p += 5;
396
397
if(0xDC00 <= value2 && value2 <= 0xDFFF) {
398
/* valid second surrogate */
399
value =
400
((value - 0xD800) << 10) +
401
(value2 - 0xDC00) +
402
0x10000;
403
}
404
else {
405
/* invalid second surrogate */
406
error_set(error, lex,
407
"invalid Unicode '\\u%04X\\u%04X'",
408
value, value2);
409
goto out;
410
}
411
}
412
else {
413
/* no second surrogate */
414
error_set(error, lex, "invalid Unicode '\\u%04X'",
415
value);
416
goto out;
417
}
418
}
419
else if(0xDC00 <= value && value <= 0xDFFF) {
420
error_set(error, lex, "invalid Unicode '\\u%04X'", value);
421
goto out;
422
}
423
else if(value == 0)
424
{
425
error_set(error, lex, "\\u0000 is not allowed");
426
goto out;
427
}
428
429
if(utf8_encode(value, buffer, &length))
430
assert(0);
431
432
memcpy(t, buffer, length);
433
t += length;
434
}
435
else {
436
switch(*p) {
437
case '"': case '\\': case '/':
438
*t = *p; break;
439
case 'b': *t = '\b'; break;
440
case 'f': *t = '\f'; break;
441
case 'n': *t = '\n'; break;
442
case 'r': *t = '\r'; break;
443
case 't': *t = '\t'; break;
444
default: assert(0);
445
}
446
t++;
447
p++;
448
}
449
}
450
else
451
*(t++) = *(p++);
452
}
453
*t = '\0';
454
lex->token = TOKEN_STRING;
455
return;
456
457
out:
458
jsonp_free(lex->value.string);
459
}
460
461
#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
462
#if JSON_INTEGER_IS_LONG_LONG
463
#ifdef _MSC_VER /* Microsoft Visual Studio */
464
#define json_strtoint _strtoi64
465
#else
466
#define json_strtoint strtoll
467
#endif
468
#else
469
#define json_strtoint strtol
470
#endif
471
#endif
472
473
static int lex_scan_number(lex_t *lex, int c, json_error_t *error)
474
{
475
const char *saved_text;
476
char *end;
477
double value;
478
479
lex->token = TOKEN_INVALID;
480
481
if(c == '-')
482
c = lex_get_save(lex, error);
483
484
if(c == '0') {
485
c = lex_get_save(lex, error);
486
if(l_isdigit(c)) {
487
lex_unget_unsave(lex, c);
488
goto out;
489
}
490
}
491
else if(l_isdigit(c)) {
492
c = lex_get_save(lex, error);
493
while(l_isdigit(c))
494
c = lex_get_save(lex, error);
495
}
496
else {
497
lex_unget_unsave(lex, c);
498
goto out;
499
}
500
501
if(c != '.' && c != 'E' && c != 'e') {
502
json_int_t value;
503
504
lex_unget_unsave(lex, c);
505
506
saved_text = strbuffer_value(&lex->saved_text);
507
508
errno = 0;
509
value = json_strtoint(saved_text, &end, 10);
510
if(errno == ERANGE) {
511
if(value < 0)
512
error_set(error, lex, "too big negative integer");
513
else
514
error_set(error, lex, "too big integer");
515
goto out;
516
}
517
518
assert(end == saved_text + lex->saved_text.length);
519
520
lex->token = TOKEN_INTEGER;
521
lex->value.integer = value;
522
return 0;
523
}
524
525
if(c == '.') {
526
c = lex_get(lex, error);
527
if(!l_isdigit(c)) {
528
lex_unget(lex, c);
529
goto out;
530
}
531
lex_save(lex, c);
532
533
c = lex_get_save(lex, error);
534
while(l_isdigit(c))
535
c = lex_get_save(lex, error);
536
}
537
538
if(c == 'E' || c == 'e') {
539
c = lex_get_save(lex, error);
540
if(c == '+' || c == '-')
541
c = lex_get_save(lex, error);
542
543
if(!l_isdigit(c)) {
544
lex_unget_unsave(lex, c);
545
goto out;
546
}
547
548
c = lex_get_save(lex, error);
549
while(l_isdigit(c))
550
c = lex_get_save(lex, error);
551
}
552
553
lex_unget_unsave(lex, c);
554
555
if(jsonp_strtod(&lex->saved_text, &value)) {
556
error_set(error, lex, "real number overflow");
557
goto out;
558
}
559
560
lex->token = TOKEN_REAL;
561
lex->value.real = value;
562
return 0;
563
564
out:
565
return -1;
566
}
567
568
static int lex_scan(lex_t *lex, json_error_t *error)
569
{
570
int c;
571
572
strbuffer_clear(&lex->saved_text);
573
574
if(lex->token == TOKEN_STRING) {
575
jsonp_free(lex->value.string);
576
lex->value.string = NULL;
577
}
578
579
c = lex_get(lex, error);
580
while(c == ' ' || c == '\t' || c == '\n' || c == '\r')
581
c = lex_get(lex, error);
582
583
if(c == STREAM_STATE_EOF) {
584
lex->token = TOKEN_EOF;
585
goto out;
586
}
587
588
if(c == STREAM_STATE_ERROR) {
589
lex->token = TOKEN_INVALID;
590
goto out;
591
}
592
593
lex_save(lex, c);
594
595
if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',')
596
lex->token = c;
597
598
else if(c == '"')
599
lex_scan_string(lex, error);
600
601
else if(l_isdigit(c) || c == '-') {
602
if(lex_scan_number(lex, c, error))
603
goto out;
604
}
605
606
else if(l_isalpha(c)) {
607
/* eat up the whole identifier for clearer error messages */
608
const char *saved_text;
609
610
c = lex_get_save(lex, error);
611
while(l_isalpha(c))
612
c = lex_get_save(lex, error);
613
lex_unget_unsave(lex, c);
614
615
saved_text = strbuffer_value(&lex->saved_text);
616
617
if(strcmp(saved_text, "true") == 0)
618
lex->token = TOKEN_TRUE;
619
else if(strcmp(saved_text, "false") == 0)
620
lex->token = TOKEN_FALSE;
621
else if(strcmp(saved_text, "null") == 0)
622
lex->token = TOKEN_NULL;
623
else
624
lex->token = TOKEN_INVALID;
625
}
626
627
else {
628
/* save the rest of the input UTF-8 sequence to get an error
629
message of valid UTF-8 */
630
lex_save_cached(lex);
631
lex->token = TOKEN_INVALID;
632
}
633
634
out:
635
return lex->token;
636
}
637
638
static char *lex_steal_string(lex_t *lex)
639
{
640
char *result = NULL;
641
if(lex->token == TOKEN_STRING)
642
{
643
result = lex->value.string;
644
lex->value.string = NULL;
645
}
646
return result;
647
}
648
649
static int lex_init(lex_t *lex, get_func get, void *data)
650
{
651
stream_init(&lex->stream, get, data);
652
if(strbuffer_init(&lex->saved_text))
653
return -1;
654
655
lex->token = TOKEN_INVALID;
656
return 0;
657
}
658
659
static void lex_close(lex_t *lex)
660
{
661
if(lex->token == TOKEN_STRING)
662
jsonp_free(lex->value.string);
663
strbuffer_close(&lex->saved_text);
664
}
665
666
667
/*** parser ***/
668
669
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error);
670
671
static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error)
672
{
673
json_t *object = json_object();
674
if(!object)
675
return NULL;
676
677
lex_scan(lex, error);
678
if(lex->token == '}')
679
return object;
680
681
while(1) {
682
char *key;
683
json_t *value;
684
685
if(lex->token != TOKEN_STRING) {
686
error_set(error, lex, "string or '}' expected");
687
goto error;
688
}
689
690
key = lex_steal_string(lex);
691
if(!key)
692
return NULL;
693
694
if(flags & JSON_REJECT_DUPLICATES) {
695
if(json_object_get(object, key)) {
696
jsonp_free(key);
697
error_set(error, lex, "duplicate object key");
698
goto error;
699
}
700
}
701
702
lex_scan(lex, error);
703
if(lex->token != ':') {
704
jsonp_free(key);
705
error_set(error, lex, "':' expected");
706
goto error;
707
}
708
709
lex_scan(lex, error);
710
value = parse_value(lex, flags, error);
711
if(!value) {
712
jsonp_free(key);
713
goto error;
714
}
715
716
if(json_object_set_nocheck(object, key, value)) {
717
jsonp_free(key);
718
json_decref(value);
719
goto error;
720
}
721
722
json_decref(value);
723
jsonp_free(key);
724
725
lex_scan(lex, error);
726
if(lex->token != ',')
727
break;
728
729
lex_scan(lex, error);
730
}
731
732
if(lex->token != '}') {
733
error_set(error, lex, "'}' expected");
734
goto error;
735
}
736
737
return object;
738
739
error:
740
json_decref(object);
741
return NULL;
742
}
743
744
static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error)
745
{
746
json_t *array = json_array();
747
if(!array)
748
return NULL;
749
750
lex_scan(lex, error);
751
if(lex->token == ']')
752
return array;
753
754
while(lex->token) {
755
json_t *elem = parse_value(lex, flags, error);
756
if(!elem)
757
goto error;
758
759
if(json_array_append(array, elem)) {
760
json_decref(elem);
761
goto error;
762
}
763
json_decref(elem);
764
765
lex_scan(lex, error);
766
if(lex->token != ',')
767
break;
768
769
lex_scan(lex, error);
770
}
771
772
if(lex->token != ']') {
773
error_set(error, lex, "']' expected");
774
goto error;
775
}
776
777
return array;
778
779
error:
780
json_decref(array);
781
return NULL;
782
}
783
784
static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
785
{
786
json_t *json;
787
double value;
788
789
switch(lex->token) {
790
case TOKEN_STRING: {
791
json = json_string_nocheck(lex->value.string);
792
break;
793
}
794
795
case TOKEN_INTEGER: {
796
if (flags & JSON_DECODE_INT_AS_REAL) {
797
if(jsonp_strtod(&lex->saved_text, &value)) {
798
error_set(error, lex, "real number overflow");
799
return NULL;
800
}
801
json = json_real(value);
802
} else {
803
json = json_integer(lex->value.integer);
804
}
805
break;
806
}
807
808
case TOKEN_REAL: {
809
json = json_real(lex->value.real);
810
break;
811
}
812
813
case TOKEN_TRUE:
814
json = json_true();
815
break;
816
817
case TOKEN_FALSE:
818
json = json_false();
819
break;
820
821
case TOKEN_NULL:
822
json = json_null();
823
break;
824
825
case '{':
826
json = parse_object(lex, flags, error);
827
break;
828
829
case '[':
830
json = parse_array(lex, flags, error);
831
break;
832
833
case TOKEN_INVALID:
834
error_set(error, lex, "invalid token");
835
return NULL;
836
837
default:
838
error_set(error, lex, "unexpected token");
839
return NULL;
840
}
841
842
if(!json)
843
return NULL;
844
845
return json;
846
}
847
848
static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error)
849
{
850
json_t *result;
851
852
lex_scan(lex, error);
853
if(!(flags & JSON_DECODE_ANY)) {
854
if(lex->token != '[' && lex->token != '{') {
855
error_set(error, lex, "'[' or '{' expected");
856
return NULL;
857
}
858
}
859
860
result = parse_value(lex, flags, error);
861
if(!result)
862
return NULL;
863
864
if(!(flags & JSON_DISABLE_EOF_CHECK)) {
865
lex_scan(lex, error);
866
if(lex->token != TOKEN_EOF) {
867
error_set(error, lex, "end of file expected");
868
json_decref(result);
869
return NULL;
870
}
871
}
872
873
if(error) {
874
/* Save the position even though there was no error */
875
error->position = lex->stream.position;
876
}
877
878
return result;
879
}
880
881
typedef struct
882
{
883
const char *data;
884
int pos;
885
} string_data_t;
886
887
static int string_get(void *data)
888
{
889
char c;
890
string_data_t *stream = (string_data_t *)data;
891
c = stream->data[stream->pos];
892
if(c == '\0')
893
return EOF;
894
else
895
{
896
stream->pos++;
897
return (unsigned char)c;
898
}
899
}
900
901
json_t *json_loads(const char *string, size_t flags, json_error_t *error)
902
{
903
lex_t lex;
904
json_t *result;
905
string_data_t stream_data;
906
907
jsonp_error_init(error, "<string>");
908
909
if (string == NULL) {
910
error_set(error, NULL, "wrong arguments");
911
return NULL;
912
}
913
914
stream_data.data = string;
915
stream_data.pos = 0;
916
917
if(lex_init(&lex, string_get, (void *)&stream_data))
918
return NULL;
919
920
result = parse_json(&lex, flags, error);
921
922
lex_close(&lex);
923
return result;
924
}
925
926
typedef struct
927
{
928
const char *data;
929
size_t len;
930
size_t pos;
931
} buffer_data_t;
932
933
static int buffer_get(void *data)
934
{
935
char c;
936
buffer_data_t *stream = data;
937
if(stream->pos >= stream->len)
938
return EOF;
939
940
c = stream->data[stream->pos];
941
stream->pos++;
942
return (unsigned char)c;
943
}
944
945
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error)
946
{
947
lex_t lex;
948
json_t *result;
949
buffer_data_t stream_data;
950
951
jsonp_error_init(error, "<buffer>");
952
953
if (buffer == NULL) {
954
error_set(error, NULL, "wrong arguments");
955
return NULL;
956
}
957
958
stream_data.data = buffer;
959
stream_data.pos = 0;
960
stream_data.len = buflen;
961
962
if(lex_init(&lex, buffer_get, (void *)&stream_data))
963
return NULL;
964
965
result = parse_json(&lex, flags, error);
966
967
lex_close(&lex);
968
return result;
969
}
970
971
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
972
{
973
lex_t lex;
974
const char *source;
975
json_t *result;
976
977
if(input == stdin)
978
source = "<stdin>";
979
else
980
source = "<stream>";
981
982
jsonp_error_init(error, source);
983
984
if (input == NULL) {
985
error_set(error, NULL, "wrong arguments");
986
return NULL;
987
}
988
989
if(lex_init(&lex, (get_func)fgetc, input))
990
return NULL;
991
992
result = parse_json(&lex, flags, error);
993
994
lex_close(&lex);
995
return result;
996
}
997
998
json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
999
{
1000
json_t *result;
1001
FILE *fp;
1002
1003
jsonp_error_init(error, path);
1004
1005
if (path == NULL) {
1006
error_set(error, NULL, "wrong arguments");
1007
return NULL;
1008
}
1009
1010
fp = fopen(path, "rb");
1011
if(!fp)
1012
{
1013
error_set(error, NULL, "unable to open %s: %s",
1014
path, strerror(errno));
1015
return NULL;
1016
}
1017
1018
result = json_loadf(fp, flags, error);
1019
1020
fclose(fp);
1021
return result;
1022
}
1023
1024
#define MAX_BUF_LEN 1024
1025
1026
typedef struct
1027
{
1028
char data[MAX_BUF_LEN];
1029
size_t len;
1030
size_t pos;
1031
json_load_callback_t callback;
1032
void *arg;
1033
} callback_data_t;
1034
1035
static int callback_get(void *data)
1036
{
1037
char c;
1038
callback_data_t *stream = data;
1039
1040
if(stream->pos >= stream->len) {
1041
stream->pos = 0;
1042
stream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg);
1043
if(stream->len == 0 || stream->len == (size_t)-1)
1044
return EOF;
1045
}
1046
1047
c = stream->data[stream->pos];
1048
stream->pos++;
1049
return (unsigned char)c;
1050
}
1051
1052
json_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags, json_error_t *error)
1053
{
1054
lex_t lex;
1055
json_t *result;
1056
1057
callback_data_t stream_data;
1058
1059
memset(&stream_data, 0, sizeof(stream_data));
1060
stream_data.callback = callback;
1061
stream_data.arg = arg;
1062
1063
jsonp_error_init(error, "<callback>");
1064
1065
if (callback == NULL) {
1066
error_set(error, NULL, "wrong arguments");
1067
return NULL;
1068
}
1069
1070
if(lex_init(&lex, (get_func)callback_get, &stream_data))
1071
return NULL;
1072
1073
result = parse_json(&lex, flags, error);
1074
1075
lex_close(&lex);
1076
return result;
1077
}
1078
1079