diff options
| author | Dan Halbert <halbert@adafruit.com> | 2020-07-16 14:33:33 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-16 14:33:33 -0400 |
| commit | 88d89563783771daba2973eb8dc3faa237ba4b62 (patch) | |
| tree | a5403791e9126eb2ec6c654b36f8c4b4ca705085 /extmod | |
| parent | 72f6d7ee21bd442b87def2751d9c65dd887fe3ba (diff) | |
| parent | 372bcf8a956c8b20c423333114d7aa061dd54751 (diff) | |
Merge pull request #3143 from tannewt/improve_json
Add support to json.load for any object with readinto
Diffstat (limited to 'extmod')
| -rw-r--r-- | extmod/modujson.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/extmod/modujson.c b/extmod/modujson.c index 5e9083958..431b5e0cf 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -5,6 +5,8 @@ #include <stdio.h> +#include "py/binary.h" +#include "py/objarray.h" #include "py/objlist.h" #include "py/objstringio.h" #include "py/parsenum.h" @@ -53,6 +55,8 @@ typedef struct _ujson_stream_t { mp_obj_t stream_obj; mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode); int errcode; + mp_obj_t python_readinto[2 + 1]; + mp_obj_array_t bytearray_obj; byte cur; } ujson_stream_t; @@ -73,9 +77,39 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) { return s->cur; } +STATIC mp_uint_t ujson_python_readinto(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode) { + ujson_stream_t* s = obj; + s->bytearray_obj.items = buf; + s->bytearray_obj.len = size; + *errcode = 0; + mp_obj_t ret = mp_call_method_n_kw(1, 0, s->python_readinto); + if (ret == mp_const_none) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } + return mp_obj_get_int(ret); +} + STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) { - const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ); - ujson_stream_t s = {stream_obj, stream_p->read, 0, 0}; + const mp_stream_p_t *stream_p = mp_proto_get(MP_QSTR_protocol_stream, stream_obj); + ujson_stream_t s; + if (stream_p == NULL) { + mp_load_method(stream_obj, MP_QSTR_readinto, s.python_readinto); + s.bytearray_obj.base.type = &mp_type_bytearray; + s.bytearray_obj.typecode = BYTEARRAY_TYPECODE; + s.bytearray_obj.free = 0; + // len and items are set at read time + s.python_readinto[2] = MP_OBJ_FROM_PTR(&s.bytearray_obj); + s.stream_obj = &s; + s.read = ujson_python_readinto; + } else { + stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ); + s.stream_obj = stream_obj; + s.read = stream_p->read; + s.errcode = 0; + s.cur = 0; + } + JSON_DEBUG("got JSON stream\n"); vstr_t vstr; vstr_init(&vstr, 8); |
