@@ -53,6 +53,10 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) {
5353}
5454STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ujson_dumps_obj , mod_ujson_dumps );
5555
56+ #define JSON_DEBUG (...) (void)0
57+ // #define JSON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
58+
59+
5660// The function below implements a simple non-recursive JSON parser.
5761//
5862// The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt
@@ -80,6 +84,7 @@ typedef struct _ujson_stream_t {
8084
8185STATIC byte ujson_stream_next (ujson_stream_t * s ) {
8286 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 );
8388 if (s -> errcode != 0 ) {
8489 mp_raise_OSError (s -> errcode );
8590 }
@@ -89,9 +94,10 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
8994 return s -> cur ;
9095}
9196
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 ) {
9398 const mp_stream_p_t * stream_p = mp_get_stream_raise (stream_obj , MP_STREAM_OP_READ );
9499 ujson_stream_t s = {stream_obj , stream_p -> read , 0 , 0 };
100+ JSON_DEBUG ("got JSON stream\n" );
95101 vstr_t vstr ;
96102 vstr_init (& vstr , 8 );
97103 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) {
262268 }
263269 }
264270 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+ }
272283 }
273284 if (stack_top == MP_OBJ_NULL || stack .len != 0 ) {
274285 // not exactly 1 object
@@ -280,14 +291,18 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
280291 fail :
281292 mp_raise_ValueError (translate ("syntax error in JSON" ));
282293}
294+
295+ STATIC mp_obj_t mod_ujson_load (mp_obj_t stream_obj ) {
296+ return _mod_ujson_load (stream_obj , true);
297+ }
283298STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ujson_load_obj , mod_ujson_load );
284299
285300STATIC mp_obj_t mod_ujson_loads (mp_obj_t obj ) {
286301 size_t len ;
287302 const char * buf = mp_obj_str_get_data (obj , & len );
288303 vstr_t vstr = {len , len , (char * )buf , true};
289304 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 );
291306}
292307STATIC MP_DEFINE_CONST_FUN_OBJ_1 (mod_ujson_loads_obj , mod_ujson_loads );
293308
0 commit comments