@@ -94,7 +94,7 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
94
94
return s -> cur ;
95
95
}
96
96
97
- 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 ) {
98
98
const mp_stream_p_t * stream_p = mp_get_stream_raise (stream_obj , MP_STREAM_OP_READ );
99
99
ujson_stream_t s = {stream_obj , stream_p -> read , 0 , 0 };
100
100
JSON_DEBUG ("got JSON stream\n" );
@@ -107,15 +107,6 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
107
107
mp_obj_type_t * stack_top_type = NULL ;
108
108
mp_obj_t stack_key = MP_OBJ_NULL ;
109
109
S_NEXT (s );
110
- // Eat _leading_ whitespace.
111
- // If we eat trailing whitespace we will block for timeout on streams like UART that
112
- // wait for requested data. Furthermore, it is an OSError to read(1) and incur
113
- // a timeout on those APIs.
114
- // For these reasons, we must only eat _leading_ whitespace.
115
- while (unichar_isspace (S_CUR (s ))) {
116
- JSON_DEBUG ("Eating leading whitespace" );
117
- S_NEXT (s );
118
- }
119
110
for (;;) {
120
111
cont :
121
112
if (S_END (s )) {
@@ -277,9 +268,19 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
277
268
}
278
269
}
279
270
success :
280
- // It is legal for a stream to have contents before and after JSON.
281
- // If this parser has consumed a full successful JSON and its parse
282
- // stack is empty, the parse has succeeded.
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
+ }
283
+ }
283
284
if (stack_top == MP_OBJ_NULL || stack .len != 0 ) {
284
285
// not exactly 1 object
285
286
goto fail ;
@@ -290,14 +291,18 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
290
291
fail :
291
292
mp_raise_ValueError (translate ("syntax error in JSON" ));
292
293
}
294
+
295
+ STATIC mp_obj_t mod_ujson_load (mp_obj_t stream_obj ) {
296
+ return _mod_ujson_load (stream_obj , true);
297
+ }
293
298
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ujson_load_obj , mod_ujson_load );
294
299
295
300
STATIC mp_obj_t mod_ujson_loads (mp_obj_t obj ) {
296
301
size_t len ;
297
302
const char * buf = mp_obj_str_get_data (obj , & len );
298
303
vstr_t vstr = {len , len , (char * )buf , true};
299
304
mp_obj_stringio_t sio = {{& mp_type_stringio }, & vstr , 0 , MP_OBJ_NULL };
300
- return mod_ujson_load (MP_OBJ_FROM_PTR (& sio ));
305
+ return _mod_ujson_load (MP_OBJ_FROM_PTR (& sio ), false );
301
306
}
302
307
STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ujson_loads_obj , mod_ujson_loads );
303
308
0 commit comments