55
66#include <stdio.h>
77
8+ #include "py/binary.h"
9+ #include "py/objarray.h"
810#include "py/objlist.h"
911#include "py/objstringio.h"
1012#include "py/parsenum.h"
@@ -53,6 +55,8 @@ typedef struct _ujson_stream_t {
5355 mp_obj_t stream_obj ;
5456 mp_uint_t (* read )(mp_obj_t obj , void * buf , mp_uint_t size , int * errcode );
5557 int errcode ;
58+ mp_obj_t python_readinto [2 + 1 ];
59+ mp_obj_array_t bytearray_obj ;
5660 byte cur ;
5761} ujson_stream_t ;
5862
@@ -73,9 +77,39 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
7377 return s -> cur ;
7478}
7579
80+ STATIC mp_uint_t ujson_python_readinto (mp_obj_t obj , void * buf , mp_uint_t size , int * errcode ) {
81+ ujson_stream_t * s = obj ;
82+ s -> bytearray_obj .items = buf ;
83+ s -> bytearray_obj .len = size ;
84+ * errcode = 0 ;
85+ mp_obj_t ret = mp_call_method_n_kw (1 , 0 , s -> python_readinto );
86+ if (ret == mp_const_none ) {
87+ * errcode = MP_EAGAIN ;
88+ return MP_STREAM_ERROR ;
89+ }
90+ return mp_obj_get_int (ret );
91+ }
92+
7693STATIC mp_obj_t _mod_ujson_load (mp_obj_t stream_obj , bool return_first_json ) {
77- const mp_stream_p_t * stream_p = mp_get_stream_raise (stream_obj , MP_STREAM_OP_READ );
78- ujson_stream_t s = {stream_obj , stream_p -> read , 0 , 0 };
94+ const mp_stream_p_t * stream_p = mp_proto_get (MP_QSTR_protocol_stream , stream_obj );
95+ ujson_stream_t s ;
96+ if (stream_p == NULL ) {
97+ mp_load_method (stream_obj , MP_QSTR_readinto , s .python_readinto );
98+ s .bytearray_obj .base .type = & mp_type_bytearray ;
99+ s .bytearray_obj .typecode = BYTEARRAY_TYPECODE ;
100+ s .bytearray_obj .free = 0 ;
101+ // len and items are set at read time
102+ s .python_readinto [2 ] = MP_OBJ_FROM_PTR (& s .bytearray_obj );
103+ s .stream_obj = & s ;
104+ s .read = ujson_python_readinto ;
105+ } else {
106+ stream_p = mp_get_stream_raise (stream_obj , MP_STREAM_OP_READ );
107+ s .stream_obj = stream_obj ;
108+ s .read = stream_p -> read ;
109+ s .errcode = 0 ;
110+ s .cur = 0 ;
111+ }
112+
79113 JSON_DEBUG ("got JSON stream\n" );
80114 vstr_t vstr ;
81115 vstr_init (& vstr , 8 );
0 commit comments