@@ -53,6 +53,10 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) {
53
53
}
54
54
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ujson_dumps_obj , mod_ujson_dumps );
55
55
56
+ #define JSON_DEBUG (...) (void)0
57
+ // #define JSON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
58
+
59
+
56
60
// The function below implements a simple non-recursive JSON parser.
57
61
//
58
62
// The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt
@@ -80,6 +84,7 @@ typedef struct _ujson_stream_t {
80
84
81
85
STATIC byte ujson_stream_next (ujson_stream_t * s ) {
82
86
mp_uint_t ret = s -> read (s -> stream_obj , & s -> cur , 1 , & s -> errcode );
87
+ JSON_DEBUG (" usjon_stream_next err:%2d cur: %c \n" , s -> errcode , s -> cur );
83
88
if (s -> errcode != 0 ) {
84
89
mp_raise_OSError (s -> errcode );
85
90
}
@@ -89,9 +94,10 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
89
94
return s -> cur ;
90
95
}
91
96
92
- STATIC mp_obj_t mod_ujson_load (mp_obj_t stream_obj ) {
97
+ STATIC mp_obj_t _mod_ujson_load (mp_obj_t stream_obj , bool return_first_json ) {
93
98
const mp_stream_p_t * stream_p = mp_get_stream_raise (stream_obj , MP_STREAM_OP_READ );
94
99
ujson_stream_t s = {stream_obj , stream_p -> read , 0 , 0 };
100
+ JSON_DEBUG ("got JSON stream\n" );
95
101
vstr_t vstr ;
96
102
vstr_init (& vstr , 8 );
97
103
mp_obj_list_t stack ; // we use a list as a simple stack for nested JSON
@@ -262,13 +268,18 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
262
268
}
263
269
}
264
270
success :
265
- // eat trailing whitespace
266
- while (unichar_isspace (S_CUR (s ))) {
267
- S_NEXT (s );
268
- }
269
- if (!S_END (s )) {
270
- // unexpected chars
271
- goto fail ;
271
+ // It is legal for a stream to have contents after JSON.
272
+ // E.g., A UART is not closed after receiving an object; in load() we will
273
+ // return the first complete JSON object, while in loads() we will retain
274
+ // strict adherence to the buffer's complete semantic.
275
+ if (!return_first_json ) {
276
+ while (unichar_isspace (S_CUR (s ))) {
277
+ S_NEXT (s );
278
+ }
279
+ if (!S_END (s )) {
280
+ // unexpected chars
281
+ goto fail ;
282
+ }
272
283
}
273
284
if (stack_top == MP_OBJ_NULL || stack .len != 0 ) {
274
285
// not exactly 1 object
@@ -280,14 +291,18 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
280
291
fail :
281
292
mp_raise_ValueError (translate ("syntax error in JSON" ));
282
293
}
294
+
295
+ STATIC mp_obj_t mod_ujson_load (mp_obj_t stream_obj ) {
296
+ return _mod_ujson_load (stream_obj , true);
297
+ }
283
298
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ujson_load_obj , mod_ujson_load );
284
299
285
300
STATIC mp_obj_t mod_ujson_loads (mp_obj_t obj ) {
286
301
size_t len ;
287
302
const char * buf = mp_obj_str_get_data (obj , & len );
288
303
vstr_t vstr = {len , len , (char * )buf , true};
289
304
mp_obj_stringio_t sio = {{& mp_type_stringio }, & vstr , 0 , MP_OBJ_NULL };
290
- return mod_ujson_load (MP_OBJ_FROM_PTR (& sio ));
305
+ return _mod_ujson_load (MP_OBJ_FROM_PTR (& sio ), false );
291
306
}
292
307
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ujson_loads_obj , mod_ujson_loads );
293
308
0 commit comments