commit
91245297e8
@ -276,6 +276,10 @@ msgstr ""
|
||||
msgid "3-arg pow() not supported"
|
||||
msgstr ""
|
||||
|
||||
#: shared-module/msgpack/__init__.c
|
||||
msgid "64 bit types"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/countio/Counter.c
|
||||
#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c
|
||||
msgid "A hardware interrupt channel is already in use"
|
||||
@ -2426,6 +2430,10 @@ msgstr ""
|
||||
msgid "circle can only be registered in one parent"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/msgpack/ExtType.c
|
||||
msgid "code outside range 0~127"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/displayio/Palette.c
|
||||
msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)"
|
||||
msgstr ""
|
||||
@ -2510,6 +2518,10 @@ msgstr ""
|
||||
msgid "default 'except' must be last"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/msgpack/__init__.c
|
||||
msgid "default is not a function"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/audiobusio/PDMIn.c
|
||||
msgid ""
|
||||
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
|
||||
@ -2609,6 +2621,10 @@ msgstr ""
|
||||
msgid "expecting key:value for dict"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/msgpack/__init__.c
|
||||
msgid "ext_hook is not a function"
|
||||
msgstr ""
|
||||
|
||||
#: py/argcheck.c
|
||||
msgid "extra keyword arguments given"
|
||||
msgstr ""
|
||||
@ -3141,6 +3157,10 @@ msgstr ""
|
||||
msgid "no binding for nonlocal found"
|
||||
msgstr ""
|
||||
|
||||
#: shared-module/msgpack/__init__.c
|
||||
msgid "no default packer"
|
||||
msgstr ""
|
||||
|
||||
#: py/builtinimport.c
|
||||
msgid "no module named '%q'"
|
||||
msgstr ""
|
||||
@ -3474,6 +3494,10 @@ msgstr ""
|
||||
msgid "shape must be a tuple"
|
||||
msgstr ""
|
||||
|
||||
#: shared-module/msgpack/__init__.c
|
||||
msgid "short read"
|
||||
msgstr ""
|
||||
|
||||
#: py/objstr.c
|
||||
msgid "sign not allowed in string format specifier"
|
||||
msgstr ""
|
||||
|
@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
|
||||
|
@ -15,6 +15,7 @@ LONGINT_IMPL = MPZ
|
||||
CIRCUITPY_DISPLAYIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
MICROPY_PY_ASYNC_AWAIT = 0
|
||||
|
||||
SUPEROPT_GC = 0
|
||||
|
@ -16,6 +16,7 @@ CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_DISPLAYIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_PIXELBUF = 1
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_RTC = 0
|
||||
|
@ -16,6 +16,7 @@ CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_PIXELBUF = 0
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_RTC = 0
|
||||
|
@ -15,6 +15,7 @@ CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
|
||||
|
@ -18,6 +18,7 @@ CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_GAMEPAD = 0
|
||||
CFLAGS_INLINE_LIMIT = 50
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
|
||||
# Include these Python libraries in firmware.
|
||||
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice
|
||||
|
@ -15,6 +15,7 @@ CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
# supersized, not ultra-supersized
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
|
@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
|
||||
|
@ -17,6 +17,7 @@ CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
|
||||
SUPEROPT_GC = 0
|
||||
|
||||
|
@ -14,6 +14,7 @@ LONGINT_IMPL = MPZ
|
||||
CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_GAMEPAD = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
|
||||
|
@ -15,6 +15,7 @@ CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_GAMEPAD = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
|
||||
|
@ -16,6 +16,7 @@ CIRCUITPY_BITBANGIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_VECTORIO = 0
|
||||
CIRCUITPY_BUSDEVICE = 0
|
||||
|
||||
|
@ -4,3 +4,5 @@ USB_PRODUCT = "Spresense"
|
||||
USB_MANUFACTURER = "Sony"
|
||||
|
||||
INTERNAL_FLASH_FILESYSTEM = 1
|
||||
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
|
@ -15,6 +15,7 @@ CIRCUITPY_DISPLAYIO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
CIRCUITPY_I2CPERIPHERAL = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_NEOPIXEL_WRITE = 0
|
||||
CIRCUITPY_NVM = 0
|
||||
CIRCUITPY_PIXELBUF = 0
|
||||
|
@ -16,6 +16,7 @@ CIRCUITPY_AUDIOMP3 = 0
|
||||
CIRCUITPY_BUSIO = 1
|
||||
CIRCUITPY_DISPLAYIO = 0
|
||||
CIRCUITPY_FRAMEBUFFERIO = 0
|
||||
CIRCUITPY_MSGPACK = 0
|
||||
CIRCUITPY_GAMEPAD = 0
|
||||
CIRCUITPY_NEOPIXEL_WRITE = 0
|
||||
CIRCUITPY_NVM = 0
|
||||
|
@ -292,6 +292,9 @@ endif
|
||||
ifeq ($(CIRCUITPY_PEW),1)
|
||||
SRC_PATTERNS += _pew/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_MSGPACK),1)
|
||||
SRC_PATTERNS += msgpack/%
|
||||
endif
|
||||
|
||||
# All possible sources are listed here, and are filtered by SRC_PATTERNS in SRC_COMMON_HAL
|
||||
SRC_COMMON_HAL_ALL = \
|
||||
@ -412,6 +415,8 @@ $(filter $(SRC_PATTERNS), \
|
||||
math/__init__.c \
|
||||
microcontroller/ResetReason.c \
|
||||
microcontroller/RunMode.c \
|
||||
msgpack/__init__.c \
|
||||
msgpack/ExtType.c \
|
||||
supervisor/RunReason.c \
|
||||
)
|
||||
|
||||
@ -481,6 +486,7 @@ SRC_SHARED_MODULE_ALL = \
|
||||
memorymonitor/AllocationAlarm.c \
|
||||
memorymonitor/AllocationSize.c \
|
||||
network/__init__.c \
|
||||
msgpack/__init__.c \
|
||||
os/__init__.c \
|
||||
random/__init__.c \
|
||||
rgbmatrix/RGBMatrix.c \
|
||||
|
@ -774,6 +774,13 @@ extern const struct _mp_obj_module_t wifi_module;
|
||||
#define WIFI_MODULE
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_MSGPACK
|
||||
extern const struct _mp_obj_module_t msgpack_module;
|
||||
#define MSGPACK_MODULE { MP_ROM_QSTR(MP_QSTR_msgpack), MP_ROM_PTR(&msgpack_module) },
|
||||
#else
|
||||
#define MSGPACK_MODULE
|
||||
#endif
|
||||
|
||||
// Define certain native modules with weak links so they can be replaced with Python
|
||||
// implementations. This list may grow over time.
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
@ -830,6 +837,7 @@ extern const struct _mp_obj_module_t wifi_module;
|
||||
_EVE_MODULE \
|
||||
MEMORYMONITOR_MODULE \
|
||||
MICROCONTROLLER_MODULE \
|
||||
MSGPACK_MODULE \
|
||||
NEOPIXEL_WRITE_MODULE \
|
||||
NETWORK_MODULE \
|
||||
SOCKET_MODULE \
|
||||
|
@ -308,3 +308,6 @@ CFLAGS += -DCIRCUITPY_WIFI=$(CIRCUITPY_WIFI)
|
||||
# Enabled micropython.native decorator (experimental)
|
||||
CIRCUITPY_ENABLE_MPY_NATIVE ?= 0
|
||||
CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE)
|
||||
|
||||
CIRCUITPY_MSGPACK ?= $(CIRCUITPY_FULL_BUILD)
|
||||
CFLAGS += -DCIRCUITPY_MSGPACK=$(CIRCUITPY_MSGPACK)
|
||||
|
126
shared-bindings/msgpack/ExtType.c
Normal file
126
shared-bindings/msgpack/ExtType.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Bernhard Boser
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "shared-bindings/msgpack/ExtType.h"
|
||||
|
||||
//| class ExtType:
|
||||
//| """ExtType represents ext type in msgpack."""
|
||||
//| def __init__(self, code: int, data: bytes) -> None:
|
||||
//| """Constructor
|
||||
//| :param int code: type code in range 0~127.
|
||||
//| :param bytes data: representation."""
|
||||
//|
|
||||
STATIC mp_obj_t mod_msgpack_exttype_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mod_msgpack_extype_obj_t *self = m_new_obj(mod_msgpack_extype_obj_t);
|
||||
self->base.type = &mod_msgpack_exttype_type;
|
||||
enum { ARG_code, ARG_data };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_code, MP_ARG_INT | MP_ARG_REQUIRED },
|
||||
{ MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
int code = args[ARG_code].u_int;
|
||||
if (code < 0 || code > 127) {
|
||||
mp_raise_AttributeError(translate("code outside range 0~127"));
|
||||
}
|
||||
self->code = code;
|
||||
|
||||
mp_obj_t data = args[ARG_data].u_obj;
|
||||
self->data = data;
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
|
||||
//| code: int
|
||||
//| """The type code, in range 0~127."""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t mod_msgpack_exttype_get_code(mp_obj_t self_in) {
|
||||
mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return MP_OBJ_NEW_SMALL_INT(self->code);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mod_msgpack_exttype_get_code_obj, mod_msgpack_exttype_get_code);
|
||||
|
||||
STATIC mp_obj_t mod_msgpack_exttype_set_code(mp_obj_t self_in, mp_obj_t code_in) {
|
||||
mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
int code = mp_obj_get_int(code_in);
|
||||
if (code < 0 || code > 127) {
|
||||
mp_raise_AttributeError(translate("code outside range 0~127"));
|
||||
}
|
||||
self->code = code;
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(mod_msgpack_exttype_set_code_obj, mod_msgpack_exttype_set_code);
|
||||
|
||||
const mp_obj_property_t mod_msgpack_exttype_code_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&mod_msgpack_exttype_get_code_obj,
|
||||
(mp_obj_t)&mod_msgpack_exttype_set_code_obj,
|
||||
(mp_obj_t)&mp_const_none_obj},
|
||||
};
|
||||
|
||||
//| data: bytes
|
||||
//| """Data."""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t mod_msgpack_exttype_get_data(mp_obj_t self_in) {
|
||||
mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return self->data;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mod_msgpack_exttype_get_data_obj, mod_msgpack_exttype_get_data);
|
||||
|
||||
STATIC mp_obj_t mod_msgpack_exttype_set_data(mp_obj_t self_in, mp_obj_t data_in) {
|
||||
mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
self->data = data_in;
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(mod_msgpack_exttype_set_data_obj, mod_msgpack_exttype_set_data);
|
||||
|
||||
const mp_obj_property_t mod_msgpack_exttype_data_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&mod_msgpack_exttype_get_data_obj,
|
||||
(mp_obj_t)&mod_msgpack_exttype_set_data_obj,
|
||||
(mp_obj_t)&mp_const_none_obj},
|
||||
};
|
||||
|
||||
STATIC mp_rom_map_elem_t mod_msgpack_exttype_locals_dict_table[] = {
|
||||
// Properties
|
||||
{ MP_ROM_QSTR(MP_QSTR_code), MP_ROM_PTR(&mod_msgpack_exttype_code_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_data), MP_ROM_PTR(&mod_msgpack_exttype_data_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mod_msgpack_exttype_locals_dict, mod_msgpack_exttype_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t mod_msgpack_exttype_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ExtType,
|
||||
.make_new = mod_msgpack_exttype_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&mod_msgpack_exttype_locals_dict,
|
||||
};
|
40
shared-bindings/msgpack/ExtType.h
Normal file
40
shared-bindings/msgpack/ExtType.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Bernhard Boser
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK_EXTTYPE___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK_EXTTYPE___INIT___H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
int32_t code;
|
||||
mp_obj_t data;
|
||||
} mod_msgpack_extype_obj_t;
|
||||
|
||||
extern const mp_obj_type_t mod_msgpack_exttype_type;
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK_EXTTYPE___INIT___H
|
162
shared-bindings/msgpack/__init__.c
Normal file
162
shared-bindings/msgpack/__init__.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Bernhard Boser
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/msgpack/__init__.h"
|
||||
#include "shared-module/msgpack/__init__.h"
|
||||
#include "shared-bindings/msgpack/ExtType.h"
|
||||
|
||||
#define MP_OBJ_IS_METH(o) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_bound_method))
|
||||
|
||||
//| """Pack object in msgpack format
|
||||
//|
|
||||
//| The msgpack format is similar to json, except that the encoded data is binary.
|
||||
//| See https://msgpack.org for details. The module implements a subset of the cpython
|
||||
//| module msgpack-python.
|
||||
//|
|
||||
//| Not implemented: 64-bit int, uint, float.
|
||||
//|
|
||||
//| Example 1::
|
||||
//|
|
||||
//| import msgpack
|
||||
//| from io import BytesIO
|
||||
//|
|
||||
//| b = BytesIO()
|
||||
//| msgpack.pack({'list': [True, False, None, 1, 3.14], 'str': 'blah'}, b)
|
||||
//| b.seek(0)
|
||||
//| print(msgpack.unpack(b))
|
||||
//|
|
||||
//| Example 2: handling objects::
|
||||
//|
|
||||
//| from msgpack import pack, unpack, ExtType
|
||||
//| from io import BytesIO
|
||||
//|
|
||||
//| class MyClass:
|
||||
//| def __init__(self, val):
|
||||
//| self.value = val
|
||||
//| def __str__(self):
|
||||
//| return str(self.value)
|
||||
//|
|
||||
//| data = MyClass(b'my_value')
|
||||
//|
|
||||
//| def encoder(obj):
|
||||
//| if isinstance(obj, MyClass):
|
||||
//| return ExtType(1, obj.value)
|
||||
//| return f"no encoder for {obj}"
|
||||
//|
|
||||
//| def decoder(code, data):
|
||||
//| if code == 1:
|
||||
//| return MyClass(data)
|
||||
//| return f"no decoder for type {code}"
|
||||
//|
|
||||
//| buffer = BytesIO()
|
||||
//| pack(data, buffer, default=encoder)
|
||||
//| buffer.seek(0)
|
||||
//| decoded = unpack(buffer, ext_hook=decoder)
|
||||
//| print(f"{data} -> {buffer.getvalue()} -> {decoded}")
|
||||
//|
|
||||
//| """
|
||||
//|
|
||||
|
||||
//| def pack(obj: object, buffer: WriteableBuffer, *, default: Union[Callable[[object], None], None] = None) -> None:
|
||||
//| """Ouput object to buffer in msgpack format.
|
||||
//|
|
||||
//| :param object obj: Object to convert to msgpack format.
|
||||
//| :param ~_typing.WriteableBuffer buffer: buffer to write into
|
||||
//| :param Optional[~_typing.Callable[[object], None]] default:
|
||||
//| function called for python objects that do not have
|
||||
//| a representation in msgpack format.
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t mod_msgpack_pack(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_obj, ARG_buffer, ARG_default };
|
||||
STATIC const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_obj, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_default, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
mp_obj_t handler = args[ARG_default].u_obj;
|
||||
if (handler != mp_const_none && !MP_OBJ_IS_FUN(handler) && !MP_OBJ_IS_METH(handler)) {
|
||||
mp_raise_ValueError(translate("default is not a function"));
|
||||
}
|
||||
|
||||
common_hal_msgpack_pack(args[ARG_obj].u_obj, args[ARG_buffer].u_obj, handler);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mod_msgpack_pack_obj, 1, mod_msgpack_pack);
|
||||
|
||||
|
||||
//| def unpack(buffer: ReadableBuffer, *, ext_hook: Union[Callable[[int, bytes], object], None] = None, use_list: bool=True) -> object:
|
||||
//| """Unpack and return one object from buffer.
|
||||
//|
|
||||
//| :param ~_typing.ReadableBuffer buffer: buffer to read from
|
||||
//| :param Optional[~_typing.Callable[[int, bytes], object]] ext_hook: function called for objects in
|
||||
//| msgpack ext format.
|
||||
//| :param Optional[bool] use_list: return array as list or tuple (use_list=False).
|
||||
//|
|
||||
//| :return object: object read from buffer.
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t mod_msgpack_unpack(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_buffer, ARG_ext_hook, ARG_use_list };
|
||||
STATIC const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_ext_hook, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
|
||||
{ MP_QSTR_use_list, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = true } },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
mp_obj_t hook = args[ARG_ext_hook].u_obj;
|
||||
if (hook != mp_const_none && !MP_OBJ_IS_FUN(hook) && !MP_OBJ_IS_METH(hook)) {
|
||||
mp_raise_ValueError(translate("ext_hook is not a function"));
|
||||
}
|
||||
|
||||
return common_hal_msgpack_unpack(args[ARG_buffer].u_obj, hook, args[ARG_use_list].u_bool);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mod_msgpack_unpack_obj, 1, mod_msgpack_unpack);
|
||||
|
||||
|
||||
STATIC const mp_rom_map_elem_t msgpack_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_msgpack) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ExtType), MP_ROM_PTR(&mod_msgpack_exttype_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_pack), MP_ROM_PTR(&mod_msgpack_pack_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&mod_msgpack_unpack_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(msgpack_module_globals, msgpack_module_globals_table);
|
||||
|
||||
const mp_obj_module_t msgpack_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&msgpack_module_globals,
|
||||
};
|
34
shared-bindings/msgpack/__init__.h
Normal file
34
shared-bindings/msgpack/__init__.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK___INIT___H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
// nothing for now
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MSGPACK___INIT___H
|
464
shared-module/msgpack/__init__.c
Normal file
464
shared-module/msgpack/__init__.c
Normal file
@ -0,0 +1,464 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Bernhard Boser
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/objarray.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/objstringio.h"
|
||||
#include "py/parsenum.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "shared-bindings/msgpack/ExtType.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// stream management
|
||||
|
||||
typedef struct _msgpack_stream_t {
|
||||
mp_obj_t stream_obj;
|
||||
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
|
||||
mp_uint_t (*write)(mp_obj_t obj, const void *buf, mp_uint_t size, int *errcode);
|
||||
int errcode;
|
||||
} msgpack_stream_t;
|
||||
|
||||
STATIC msgpack_stream_t get_stream(mp_obj_t stream_obj, int flags) {
|
||||
const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, flags);
|
||||
msgpack_stream_t s = {stream_obj, stream_p->read, stream_p->write, 0};
|
||||
return s;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// readers
|
||||
|
||||
STATIC void read(msgpack_stream_t *s, void *buf, mp_uint_t size) {
|
||||
if (size == 0) return;
|
||||
mp_uint_t ret = s->read(s->stream_obj, buf, size, &s->errcode);
|
||||
if (s->errcode != 0) {
|
||||
mp_raise_OSError(s->errcode);
|
||||
}
|
||||
if (ret == 0) {
|
||||
mp_raise_msg(&mp_type_EOFError, NULL);
|
||||
}
|
||||
if (ret < size) {
|
||||
mp_raise_ValueError(translate("short read"));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC uint8_t read1(msgpack_stream_t *s) {
|
||||
uint8_t res = 0;
|
||||
read(s, &res, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
STATIC uint16_t read2(msgpack_stream_t *s) {
|
||||
uint16_t res = 0;
|
||||
read(s, &res, 2);
|
||||
int n = 1;
|
||||
if (*(char *)&n == 1) res = __builtin_bswap16(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
STATIC uint32_t read4(msgpack_stream_t *s) {
|
||||
uint32_t res = 0;
|
||||
read(s, &res, 4);
|
||||
int n = 1;
|
||||
if (*(char *)&n == 1) res = __builtin_bswap32(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
STATIC size_t read_size(msgpack_stream_t *s, uint8_t len_index) {
|
||||
size_t res = 0;
|
||||
switch (len_index) {
|
||||
case 0: res = (size_t)read1(s); break;
|
||||
case 1: res = (size_t)read2(s); break;
|
||||
case 2: res = (size_t)read4(s); break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// writers
|
||||
|
||||
STATIC void write(msgpack_stream_t *s, const void *buf, mp_uint_t size) {
|
||||
mp_uint_t ret = s->write(s->stream_obj, buf, size, &s->errcode);
|
||||
if (s->errcode != 0) {
|
||||
mp_raise_OSError(s->errcode);
|
||||
}
|
||||
if (ret == 0) {
|
||||
mp_raise_msg(&mp_type_EOFError, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void write1(msgpack_stream_t *s, uint8_t obj) {
|
||||
write(s, &obj, 1);
|
||||
}
|
||||
|
||||
STATIC void write2(msgpack_stream_t *s, uint16_t obj) {
|
||||
int n = 1;
|
||||
if (*(char *)&n == 1) obj = __builtin_bswap16(obj);
|
||||
write(s, &obj, 2);
|
||||
}
|
||||
|
||||
STATIC void write4(msgpack_stream_t *s, uint32_t obj) {
|
||||
int n = 1;
|
||||
if (*(char *)&n == 1) obj = __builtin_bswap32(obj);
|
||||
write(s, &obj, 4);
|
||||
}
|
||||
|
||||
// compute and write msgpack size code (array structures)
|
||||
STATIC void write_size(msgpack_stream_t *s, uint8_t code, size_t size) {
|
||||
if ((uint8_t)size == size) {
|
||||
write1(s, code);
|
||||
write1(s, size);
|
||||
} else if ((uint16_t)size == size) {
|
||||
write1(s, code+1);
|
||||
write2(s, size);
|
||||
} else {
|
||||
write1(s, code+2);
|
||||
write4(s, size);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// packers
|
||||
|
||||
// This is a helper function to iterate through a dictionary. The state of
|
||||
// the iteration is held in *cur and should be initialised with zero for the
|
||||
// first call. Will return NULL when no more elements are available.
|
||||
STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, size_t *cur) {
|
||||
size_t max = dict->map.alloc;
|
||||
mp_map_t *map = &dict->map;
|
||||
|
||||
for (size_t i = *cur; i < max; i++) {
|
||||
if (MP_MAP_SLOT_IS_FILLED(map, i)) {
|
||||
*cur = i + 1;
|
||||
return &(map->table[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC void pack_int(msgpack_stream_t *s, int32_t x) {
|
||||
if (x > -32 && x < 128) {
|
||||
write1(s, x);
|
||||
} else if ((int8_t)x == x) {
|
||||
write1(s, 0xd0);
|
||||
write1(s, x);
|
||||
} else if ((int16_t)x == x) {
|
||||
write1(s, 0xd1);
|
||||
write2(s, x);
|
||||
} else {
|
||||
write1(s, 0xd2);
|
||||
write4(s, x);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pack_bin(msgpack_stream_t *s, const uint8_t* data, size_t len) {
|
||||
write_size(s, 0xc4, len);
|
||||
if (len > 0) write(s, data, len);
|
||||
}
|
||||
|
||||
STATIC void pack_ext(msgpack_stream_t *s, int8_t code, const uint8_t* data, size_t len) {
|
||||
if (len == 1) {
|
||||
write1(s, 0xd4);
|
||||
} else if (len == 2) {
|
||||
write1(s, 0xd5);
|
||||
} else if (len == 4) {
|
||||
write1(s, 0xd6);
|
||||
} else if (len == 8) {
|
||||
write1(s, 0xd7);
|
||||
} else if (len == 16) {
|
||||
write1(s, 0xd8);
|
||||
} else {
|
||||
write_size(s, 0xc7, len);
|
||||
}
|
||||
write1(s, code); // type byte
|
||||
if (len > 0) write(s, data, len);
|
||||
}
|
||||
|
||||
STATIC void pack_str(msgpack_stream_t *s, const char* str, size_t len) {
|
||||
if (len < 32) {
|
||||
write1(s, 0b10100000 | (uint8_t)len);
|
||||
} else {
|
||||
write_size(s, 0xd9, len);
|
||||
}
|
||||
if (len > 0) write(s, str, len);
|
||||
}
|
||||
|
||||
STATIC void pack_array(msgpack_stream_t *s, size_t len) {
|
||||
// only writes the header, manually write the objects after calling pack_array!
|
||||
if (len < 16) {
|
||||
write1(s, 0b10010000 | (uint8_t)len);
|
||||
} else if (len < 0x10000) {
|
||||
write1(s, 0xdc);
|
||||
write2(s, len);
|
||||
} else {
|
||||
write1(s, 0xdd);
|
||||
write4(s, len);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pack_dict(msgpack_stream_t *s, size_t len) {
|
||||
// only writes the header, manually write the objects after calling pack_array!
|
||||
if (len < 16) {
|
||||
write1(s, 0b10000000 | (uint8_t)len);
|
||||
} else if (len < 0x10000) {
|
||||
write1(s, 0xde);
|
||||
write2(s, len);
|
||||
} else {
|
||||
write1(s, 0xdf);
|
||||
write4(s, len);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pack(mp_obj_t obj, msgpack_stream_t *s, mp_obj_t default_handler) {
|
||||
if (MP_OBJ_IS_SMALL_INT(obj)) {
|
||||
// int
|
||||
int32_t x = MP_OBJ_SMALL_INT_VALUE(obj);
|
||||
pack_int(s, x);
|
||||
} else if (MP_OBJ_IS_STR(obj)) {
|
||||
// string
|
||||
size_t len;
|
||||
const char *data = mp_obj_str_get_data(obj, &len);
|
||||
pack_str(s, data, len);
|
||||
} else if (MP_OBJ_IS_TYPE(obj, &mod_msgpack_exttype_type)) {
|
||||
mod_msgpack_extype_obj_t *ext = MP_OBJ_TO_PTR(obj);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(ext->data, &bufinfo, MP_BUFFER_READ);
|
||||
pack_ext(s, ext->code, bufinfo.buf, bufinfo.len);
|
||||
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_bytes)) {
|
||||
// bytes
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
|
||||
pack_bin(s, bufinfo.buf, bufinfo.len);
|
||||
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_tuple)) {
|
||||
// tuple
|
||||
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(obj);
|
||||
pack_array(s, self->len);
|
||||
for (size_t i=0; i<self->len; i++) {
|
||||
pack(self->items[i], s, default_handler);
|
||||
}
|
||||
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_list)) {
|
||||
// list (layout differs from tuple)
|
||||
mp_obj_list_t *self = MP_OBJ_TO_PTR(obj);
|
||||
pack_array(s, self->len);
|
||||
for (size_t i=0; i<self->len; i++) {
|
||||
pack(self->items[i], s, default_handler);
|
||||
}
|
||||
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_dict)) {
|
||||
// dict
|
||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(obj);
|
||||
pack_dict(s, self->map.used);
|
||||
size_t cur = 0;
|
||||
mp_map_elem_t *next = NULL;
|
||||
while ((next = dict_iter_next(self, &cur)) != NULL) {
|
||||
pack(next->key, s, default_handler);
|
||||
pack(next->value, s, default_handler);
|
||||
}
|
||||
} else if (mp_obj_is_float(obj)) {
|
||||
union Float { mp_float_t f; uint32_t u; };
|
||||
union Float data;
|
||||
data.f = mp_obj_float_get(obj);
|
||||
write1(s, 0xca);
|
||||
write4(s, data.u);
|
||||
} else if (obj == mp_const_none) {
|
||||
write1(s, 0xc0);
|
||||
} else if (obj == mp_const_false) {
|
||||
write1(s, 0xc2);
|
||||
} else if (obj == mp_const_true) {
|
||||
write1(s, 0xc3);
|
||||
} else {
|
||||
if (default_handler != mp_const_none) {
|
||||
// set default_handler to mp_const_none to avoid infinite recursion
|
||||
// this also precludes some valid outputs
|
||||
pack(mp_call_function_1(default_handler, obj), s, mp_const_none);
|
||||
} else {
|
||||
mp_raise_ValueError(translate("no default packer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// unpacker
|
||||
|
||||
STATIC mp_obj_t unpack(msgpack_stream_t *s, mp_obj_t ext_hook, bool use_list);
|
||||
|
||||
STATIC mp_obj_t unpack_array_elements(msgpack_stream_t *s, size_t size, mp_obj_t ext_hook, bool use_list) {
|
||||
if (use_list) {
|
||||
mp_obj_list_t *t = MP_OBJ_TO_PTR(mp_obj_new_list(size, NULL));
|
||||
for (size_t i=0; i<size; i++) {
|
||||
t->items[i] = unpack(s, ext_hook, use_list);
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(t);
|
||||
} else {
|
||||
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(size, NULL));
|
||||
for (size_t i=0; i<size; i++) {
|
||||
t->items[i] = unpack(s, ext_hook, use_list);
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(t);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t unpack_bytes(msgpack_stream_t *s, size_t size) {
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, size);
|
||||
byte *p = (byte*)vstr.buf;
|
||||
read(s, p, size);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t unpack_ext(msgpack_stream_t *s, size_t size, mp_obj_t ext_hook) {
|
||||
int8_t code = read1(s);
|
||||
mp_obj_t data = unpack_bytes(s, size);
|
||||
if (ext_hook != mp_const_none) {
|
||||
return mp_call_function_2(ext_hook, MP_OBJ_NEW_SMALL_INT(code), data);
|
||||
} else {
|
||||
mod_msgpack_extype_obj_t *o = m_new_obj(mod_msgpack_extype_obj_t);
|
||||
o->base.type = &mod_msgpack_exttype_type;
|
||||
o->code = code;
|
||||
o->data = data;
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t unpack(msgpack_stream_t *s, mp_obj_t ext_hook, bool use_list) {
|
||||
uint8_t code = read1(s);
|
||||
if (((code & 0b10000000) == 0) || ((code & 0b11100000) == 0b11100000)) {
|
||||
// int
|
||||
return MP_OBJ_NEW_SMALL_INT((int8_t)code);
|
||||
}
|
||||
if ((code & 0b11100000) == 0b10100000) {
|
||||
// str
|
||||
size_t len = code & 0b11111;
|
||||
// allocate on stack; len < 32
|
||||
char str[len];
|
||||
read(s, &str, len);
|
||||
return mp_obj_new_str(str, len);
|
||||
}
|
||||
if ((code & 0b11110000) == 0b10010000) {
|
||||
// array (list / tuple)
|
||||
return unpack_array_elements(s, code & 0b1111, ext_hook, use_list);
|
||||
}
|
||||
if ((code & 0b11110000) == 0b10000000) {
|
||||
// map (dict)
|
||||
size_t len = code & 0b1111;
|
||||
mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(len));
|
||||
for (size_t i=0; i<len; i++) {
|
||||
mp_obj_dict_store(d, unpack(s, ext_hook, use_list), unpack(s, ext_hook, use_list));
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(d);
|
||||
}
|
||||
switch (code) {
|
||||
case 0xc0: return mp_const_none;
|
||||
case 0xc2: return mp_const_false;
|
||||
case 0xc3: return mp_const_true;
|
||||
case 0xc4:
|
||||
case 0xc5:
|
||||
case 0xc6: {
|
||||
// bin 8, 16, 32
|
||||
return unpack_bytes(s, read_size(s, code-0xc4));
|
||||
}
|
||||
case 0xcc: // uint8
|
||||
case 0xd0: // int8
|
||||
return MP_OBJ_NEW_SMALL_INT((int8_t)read1(s));
|
||||
case 0xcd: // uint16
|
||||
case 0xd1: // int16
|
||||
return MP_OBJ_NEW_SMALL_INT((int16_t)read2(s));
|
||||
case 0xce: // uint32
|
||||
case 0xd2: // int32
|
||||
return MP_OBJ_NEW_SMALL_INT((int32_t)read4(s));
|
||||
case 0xca: {
|
||||
union Float { mp_float_t f; uint32_t u; };
|
||||
union Float data;
|
||||
data.u = read4(s);
|
||||
return mp_obj_new_float(data.f);
|
||||
}
|
||||
case 0xd9:
|
||||
case 0xda:
|
||||
case 0xdb: {
|
||||
// str 8, 16, 32
|
||||
size_t size = read_size(s, code-0xd9);
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, size);
|
||||
byte *p = (byte*)vstr.buf;
|
||||
read(s, p, size);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
|
||||
}
|
||||
case 0xde:
|
||||
case 0xdf: {
|
||||
// map 16 & 32
|
||||
size_t len = read_size(s, code - 0xde + 1);
|
||||
mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(len));
|
||||
for (size_t i=0; i<len; i++) {
|
||||
mp_obj_dict_store(d, unpack(s, ext_hook, use_list), unpack(s, ext_hook, use_list));
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(d);
|
||||
}
|
||||
case 0xdc:
|
||||
case 0xdd: {
|
||||
// array 16 & 32
|
||||
size_t size = read_size(s, code - 0xdc + 1);
|
||||
return unpack_array_elements(s, size, ext_hook, use_list);
|
||||
}
|
||||
case 0xd4: // fixenxt 1
|
||||
return unpack_ext(s, 1, ext_hook);
|
||||
case 0xd5: // fixenxt 2
|
||||
return unpack_ext(s, 2, ext_hook);
|
||||
case 0xd6: // fixenxt 4
|
||||
return unpack_ext(s, 4, ext_hook);
|
||||
case 0xd7: // fixenxt 8
|
||||
return unpack_ext(s, 8, ext_hook);
|
||||
case 0xd8: // fixenxt 16
|
||||
return unpack_ext(s, 16, ext_hook);
|
||||
case 0xc7: // ext 8
|
||||
case 0xc8: // ext 16
|
||||
case 0xc9:
|
||||
// ext 8, 16, 32
|
||||
return unpack_ext(s, read_size(s, code-0xc7), ext_hook);
|
||||
case 0xc1: // never used
|
||||
case 0xcb: // float 64
|
||||
case 0xcf: // uint 64
|
||||
case 0xd3: // int 64
|
||||
default:
|
||||
mp_raise_NotImplementedError(translate("64 bit types"));
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_msgpack_pack(mp_obj_t obj, mp_obj_t stream_obj, mp_obj_t default_handler) {
|
||||
msgpack_stream_t stream = get_stream(stream_obj, MP_STREAM_OP_WRITE);
|
||||
pack(obj, &stream, default_handler);
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_msgpack_unpack(mp_obj_t stream_obj, mp_obj_t ext_hook, bool use_list) {
|
||||
msgpack_stream_t stream = get_stream(stream_obj, MP_STREAM_OP_WRITE);
|
||||
return unpack(&stream, ext_hook, use_list);
|
||||
}
|
34
shared-module/msgpack/__init__.h
Normal file
34
shared-module/msgpack/__init__.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_SHARED_MODULE_MSGPACK___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_MODULE_MSGPACK___INIT___H
|
||||
|
||||
#include "py/stream.h"
|
||||
|
||||
void common_hal_msgpack_pack(mp_obj_t obj, mp_obj_t stream_obj, mp_obj_t default_handler);
|
||||
mp_obj_t common_hal_msgpack_unpack(mp_obj_t stream_obj, mp_obj_t ext_hook, bool use_list);
|
||||
|
||||
#endif
|
30
tests/extmod/umsgpack_pack.py
Normal file
30
tests/extmod/umsgpack_pack.py
Normal file
@ -0,0 +1,30 @@
|
||||
try:
|
||||
from uio import BytesIO
|
||||
import umsgpack as msgpack
|
||||
except:
|
||||
try:
|
||||
from io import BytesIO
|
||||
import msgpack
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
b = BytesIO()
|
||||
msgpack.pack(False, s)
|
||||
print(b.getvalue())
|
||||
|
||||
b = BytesIO()
|
||||
msgpack.pack({"a": (-1, 0, 2, [3, None], 128)}, b)
|
||||
print(b.getvalue())
|
||||
|
||||
# pack to a small-int not allowed
|
||||
try:
|
||||
msgpack.pack(123, 1)
|
||||
except (AttributeError, OSError): # CPython and uPy have different errors
|
||||
print('Exception')
|
||||
|
||||
# pack to an object not allowed
|
||||
try:
|
||||
msgpack.pack(123, {})
|
||||
except (AttributeError, OSError): # CPython and uPy have different errors
|
||||
print('Exception')
|
5
tests/extmod/umsgpack_pack.py.ext
Normal file
5
tests/extmod/umsgpack_pack.py.ext
Normal file
@ -0,0 +1,5 @@
|
||||
b'\xc2'
|
||||
b'\x82\xa1a\x96\xff\x00\x02\x92\x03\xc0\xd1\x00\x80\xc4\x07abcdefg\xa1b\xd4\x05x'
|
||||
Exception ExtType
|
||||
Exception to int
|
||||
Exception to object
|
Loading…
x
Reference in New Issue
Block a user