summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2019-12-09 14:50:16 -0800
committerGitHub <noreply@github.com>2019-12-09 14:50:16 -0800
commit19ac8aea8ca7656ecfdac597448feab493803669 (patch)
tree8f6aef1374c8c4f7366dcabe028b2325b7d50d85
parent2379cd9ef48ca0ff11bafaaf83d6234534665202 (diff)
parentd5eca87ca23e9288b31c51f3d841fd2bb37c631b (diff)
Merge pull request #2353 from jepler/audiosample-protocol
Convert audiosamples to use micropython "protocols" (safely)
-rw-r--r--extmod/machine_i2c.c21
-rw-r--r--extmod/machine_i2c.h2
-rw-r--r--extmod/machine_pinbase.c1
-rw-r--r--extmod/machine_signal.c8
-rw-r--r--extmod/machine_spi.c7
-rw-r--r--extmod/machine_spi.h2
-rw-r--r--extmod/modframebuf.c16
-rw-r--r--extmod/modlwip.c1
-rw-r--r--extmod/modussl_axtls.c1
-rw-r--r--extmod/modussl_mbedtls.c1
-rw-r--r--extmod/moduzlib.c1
-rw-r--r--extmod/modwebrepl.c1
-rw-r--r--extmod/modwebsocket.c1
-rw-r--r--extmod/vfs.c2
-rw-r--r--extmod/vfs.h2
-rw-r--r--extmod/vfs_fat.c1
-rw-r--r--extmod/vfs_fat_file.c2
-rw-r--r--extmod/vfs_posix.c1
-rw-r--r--extmod/vfs_posix_file.c2
-rw-r--r--extmod/virtpin.c5
-rw-r--r--extmod/virtpin.h2
-rw-r--r--lib/utils/sys_stdio_mphal.c2
-rw-r--r--locale/ID.po6
-rw-r--r--locale/circuitpython.pot6
-rw-r--r--locale/de_DE.po6
-rw-r--r--locale/en_US.po6
-rw-r--r--locale/en_x_pirate.po6
-rw-r--r--locale/es.po6
-rw-r--r--locale/fil.po6
-rw-r--r--locale/fr.po6
-rw-r--r--locale/it_IT.po6
-rw-r--r--locale/ko.po6
-rw-r--r--locale/pl.po6
-rw-r--r--locale/pt_BR.po6
-rw-r--r--locale/zh_Latn_pinyin.po6
-rw-r--r--ports/unix/coverage.c2
-rw-r--r--ports/unix/file.c2
-rw-r--r--ports/unix/modusocket.c1
-rw-r--r--py/modio.c2
-rw-r--r--py/objstringio.c2
-rw-r--r--py/proto.c50
-rw-r--r--py/proto.h43
-rw-r--r--py/py.mk1
-rw-r--r--py/stream.c11
-rw-r--r--py/stream.h4
-rw-r--r--shared-bindings/_bleio/CharacteristicBuffer.c1
-rw-r--r--shared-bindings/audiocore/RawSample.c11
-rw-r--r--shared-bindings/audiocore/RawSample.h2
-rw-r--r--shared-bindings/audiocore/WaveFile.c12
-rw-r--r--shared-bindings/audiomixer/Mixer.c11
-rw-r--r--shared-bindings/audiomixer/Mixer.h2
-rw-r--r--shared-bindings/busio/UART.c1
-rw-r--r--shared-bindings/socket/__init__.c1
-rw-r--r--shared-bindings/terminalio/Terminal.c1
-rw-r--r--shared-bindings/usb_midi/PortIn.c1
-rw-r--r--shared-bindings/usb_midi/PortOut.c1
-rw-r--r--shared-module/audiocore/RawSample.c6
-rw-r--r--shared-module/audiocore/__init__.c92
-rw-r--r--shared-module/audiocore/__init__.h23
-rw-r--r--shared-module/audiomixer/Mixer.c8
60 files changed, 323 insertions, 128 deletions
diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c
index 85b46a9f6..4129ace0a 100644
--- a/extmod/machine_i2c.c
+++ b/extmod/machine_i2c.c
@@ -318,7 +318,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_init_obj, 1, machine_i2c_obj_init);
STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
mp_obj_base_t *self = MP_OBJ_TO_PTR(self_in);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
mp_obj_t list = mp_obj_new_list(0, NULL);
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
for (int addr = 0x08; addr < 0x78; ++addr) {
@@ -333,7 +333,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_scan_obj, machine_i2c_scan);
STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
if (i2c_p->start == NULL) {
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
@@ -347,7 +347,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_start_obj, machine_i2c_start);
STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
if (i2c_p->stop == NULL) {
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
@@ -361,7 +361,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_stop_obj, machine_i2c_stop);
STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
if (i2c_p->read == NULL) {
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
@@ -385,7 +385,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readinto_obj, 2, 3, machine_i2c_
STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
if (i2c_p->write == NULL) {
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
@@ -407,7 +407,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(machine_i2c_write_obj, machine_i2c_write);
STATIC mp_obj_t machine_i2c_readfrom(size_t n_args, const mp_obj_t *args) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
mp_int_t addr = mp_obj_get_int(args[1]);
vstr_t vstr;
vstr_init_len(&vstr, mp_obj_get_int(args[2]));
@@ -422,7 +422,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_obj, 3, 4, machine_i2c_
STATIC mp_obj_t machine_i2c_readfrom_into(size_t n_args, const mp_obj_t *args) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
mp_int_t addr = mp_obj_get_int(args[1]);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE);
@@ -437,7 +437,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_into_obj, 3, 4, machine
STATIC mp_obj_t machine_i2c_writeto(size_t n_args, const mp_obj_t *args) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
mp_int_t addr = mp_obj_get_int(args[1]);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
@@ -453,7 +453,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_writeto_obj, 3, 4, machin
STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, uint8_t *buf, size_t len) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
uint8_t memaddr_buf[4];
size_t memaddr_len = 0;
for (int16_t i = addrsize - 8; i >= 0; i -= 8) {
@@ -473,7 +473,7 @@ STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t a
STATIC int write_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, const uint8_t *buf, size_t len) {
mp_obj_base_t *self = (mp_obj_base_t*)MP_OBJ_TO_PTR(self_in);
- mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)self->type->protocol;
+ mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t*)mp_proto_get(self, QSTR_protocol_i2c);
// need some memory to create the buffer to send; try to use stack if possible
uint8_t buf2_stack[MAX_MEMADDR_SIZE + BUF_STACK_SIZE];
@@ -621,6 +621,7 @@ int mp_machine_soft_i2c_write(mp_obj_base_t *self_in, const uint8_t *src, size_t
}
STATIC const mp_machine_i2c_p_t mp_machine_soft_i2c_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_i2c)
.start = (int(*)(mp_obj_base_t*))mp_hal_i2c_start,
.stop = (int(*)(mp_obj_base_t*))mp_hal_i2c_stop,
.read = mp_machine_soft_i2c_read,
diff --git a/extmod/machine_i2c.h b/extmod/machine_i2c.h
index f5af6656f..7f5ee568e 100644
--- a/extmod/machine_i2c.h
+++ b/extmod/machine_i2c.h
@@ -27,10 +27,12 @@
#define MICROPY_INCLUDED_EXTMOD_MACHINE_I2C_H
#include "py/obj.h"
+#include "py/proto.h"
// I2C protocol
// the first 4 methods can be NULL, meaning operation is not supported
typedef struct _mp_machine_i2c_p_t {
+ MP_PROTOCOL_HEAD
int (*start)(mp_obj_base_t *obj);
int (*stop)(mp_obj_base_t *obj);
int (*read)(mp_obj_base_t *obj, uint8_t *dest, size_t len, bool nack);
diff --git a/extmod/machine_pinbase.c b/extmod/machine_pinbase.c
index 997a6fd99..6cd14c187 100644
--- a/extmod/machine_pinbase.c
+++ b/extmod/machine_pinbase.c
@@ -74,6 +74,7 @@ mp_uint_t pinbase_ioctl(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *err
}
STATIC const mp_pin_p_t pinbase_pin_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_pin)
.ioctl = pinbase_ioctl,
};
diff --git a/extmod/machine_signal.c b/extmod/machine_signal.c
index 62658cbb1..50501e34f 100644
--- a/extmod/machine_signal.c
+++ b/extmod/machine_signal.c
@@ -47,12 +47,7 @@ STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, const
bool invert = false;
#if defined(MICROPY_PY_MACHINE_PIN_MAKE_NEW)
- mp_pin_p_t *pin_p = NULL;
-
- if (MP_OBJ_IS_OBJ(pin)) {
- mp_obj_base_t *pin_base = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
- pin_p = (mp_pin_p_t*)pin_base->type->protocol;
- }
+ mp_pin_p_t *pin_p = (mp_pin_t*)mp_proto_get(QSTR_pin_protocol, pin);
if (pin_p == NULL) {
// If first argument isn't a Pin-like object, we filter out "invert"
@@ -170,6 +165,7 @@ STATIC const mp_rom_map_elem_t signal_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(signal_locals_dict, signal_locals_dict_table);
STATIC const mp_pin_p_t signal_pin_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_pin)
.ioctl = signal_ioctl,
};
diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c
index c5707a3d0..4ead321d9 100644
--- a/extmod/machine_spi.c
+++ b/extmod/machine_spi.c
@@ -67,7 +67,7 @@ mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, const
STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(args[0]);
- mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
+ mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)mp_proto_get(QSTR_protocol_spi, s);
spi_p->init(s, n_args - 1, args + 1, kw_args);
return mp_const_none;
}
@@ -75,7 +75,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_spi_init_obj, 1, machine_spi_init);
STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) {
mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(self);
- mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
+ mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)mp_proto_get(QSTR_protocol_spi, s);
if (spi_p->deinit != NULL) {
spi_p->deinit(s);
}
@@ -85,7 +85,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_deinit);
STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) {
mp_obj_base_t *s = (mp_obj_base_t*)MP_OBJ_TO_PTR(self);
- mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)s->type->protocol;
+ mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t*)mp_proto_get(QSTR_protocol_spi, s);
spi_p->transfer(s, len, src, dest);
}
@@ -268,6 +268,7 @@ STATIC void mp_machine_soft_spi_transfer(mp_obj_base_t *self_in, size_t len, con
}
const mp_machine_spi_p_t mp_machine_soft_spi_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_spi)
.init = mp_machine_soft_spi_init,
.deinit = NULL,
.transfer = mp_machine_soft_spi_transfer,
diff --git a/extmod/machine_spi.h b/extmod/machine_spi.h
index db21e1cd3..365b44d6e 100644
--- a/extmod/machine_spi.h
+++ b/extmod/machine_spi.h
@@ -27,11 +27,13 @@
#define MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
#include "py/obj.h"
+#include "py/proto.h"
#include "py/mphal.h"
#include "drivers/bus/spi.h"
// SPI protocol
typedef struct _mp_machine_spi_p_t {
+ MP_PROTOCOL_HEAD
void (*init)(mp_obj_base_t *obj, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
void (*deinit)(mp_obj_base_t *obj); // can be NULL
void (*transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest);
diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c
index 561b842bc..a51d1c380 100644
--- a/extmod/modframebuf.c
+++ b/extmod/modframebuf.c
@@ -28,6 +28,7 @@
#include <string.h>
#include "py/runtime.h"
+#include "py/proto.h"
#if MICROPY_PY_FRAMEBUF
@@ -46,6 +47,7 @@ typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t*, int, int);
typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, int, int, int, int, uint32_t);
typedef struct _mp_framebuf_p_t {
+ MP_PROTOCOL_HEAD
setpixel_t setpixel;
getpixel_t getpixel;
fill_rect_t fill_rect;
@@ -227,13 +229,13 @@ STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int
}
STATIC mp_framebuf_p_t formats[] = {
- [FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
- [FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
- [FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
- [FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
- [FRAMEBUF_GS8] = {gs8_setpixel, gs8_getpixel, gs8_fill_rect},
- [FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
- [FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
+ [FRAMEBUF_MVLSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
+ [FRAMEBUF_RGB565] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
+ [FRAMEBUF_GS2_HMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
+ [FRAMEBUF_GS4_HMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
+ [FRAMEBUF_GS8] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs8_setpixel, gs8_getpixel, gs8_fill_rect},
+ [FRAMEBUF_MHLSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
+ [FRAMEBUF_MHMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
};
static inline void setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index e5e92c42b..776b81ee5 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -1261,6 +1261,7 @@ STATIC const mp_rom_map_elem_t lwip_socket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(lwip_socket_locals_dict, lwip_socket_locals_dict_table);
STATIC const mp_stream_p_t lwip_socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = lwip_socket_read,
.write = lwip_socket_write,
.ioctl = lwip_socket_ioctl,
diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c
index cfa652585..032dea09f 100644
--- a/extmod/modussl_axtls.c
+++ b/extmod/modussl_axtls.c
@@ -221,6 +221,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
STATIC const mp_stream_p_t ussl_socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = socket_read,
.write = socket_write,
.ioctl = socket_ioctl,
diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c
index 08807d20b..9abdeb966 100644
--- a/extmod/modussl_mbedtls.c
+++ b/extmod/modussl_mbedtls.c
@@ -305,6 +305,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
STATIC const mp_stream_p_t ussl_socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = socket_read,
.write = socket_write,
.ioctl = socket_ioctl,
diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c
index 7f15d02a8..3a081bc45 100644
--- a/extmod/moduzlib.c
+++ b/extmod/moduzlib.c
@@ -134,6 +134,7 @@ STATIC const mp_rom_map_elem_t decompio_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table);
STATIC const mp_stream_p_t decompio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = decompio_read,
};
diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c
index 06da210d1..fb4d97358 100644
--- a/extmod/modwebrepl.c
+++ b/extmod/modwebrepl.c
@@ -331,6 +331,7 @@ STATIC const mp_rom_map_elem_t webrepl_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(webrepl_locals_dict, webrepl_locals_dict_table);
STATIC const mp_stream_p_t webrepl_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = webrepl_read,
.write = webrepl_write,
.ioctl = webrepl_ioctl,
diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c
index 997c7e262..496e4b5bb 100644
--- a/extmod/modwebsocket.c
+++ b/extmod/modwebsocket.c
@@ -286,6 +286,7 @@ STATIC const mp_rom_map_elem_t websocket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(websocket_locals_dict, websocket_locals_dict_table);
STATIC const mp_stream_p_t websocket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = websocket_read,
.write = websocket_write,
.ioctl = websocket_ioctl,
diff --git a/extmod/vfs.c b/extmod/vfs.c
index 7d6e6999b..2bb4057e7 100644
--- a/extmod/vfs.c
+++ b/extmod/vfs.c
@@ -126,7 +126,7 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) {
}
// If the mounted object has the VFS protocol, call its import_stat helper
- const mp_vfs_proto_t *proto = mp_obj_get_type(vfs->obj)->protocol;
+ const mp_vfs_proto_t *proto = (mp_vfs_proto_t*)mp_proto_get(MP_QSTR_protocol_vfs, vfs->obj);
if (proto != NULL) {
return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
}
diff --git a/extmod/vfs.h b/extmod/vfs.h
index 38c77943c..6c0692365 100644
--- a/extmod/vfs.h
+++ b/extmod/vfs.h
@@ -28,6 +28,7 @@
#include "py/lexer.h"
#include "py/obj.h"
+#include "py/proto.h"
// return values of mp_vfs_lookup_path
// ROOT is 0 so that the default current directory is the root directory
@@ -47,6 +48,7 @@
// At the moment the VFS protocol just has import_stat, but could be extended to other methods
typedef struct _mp_vfs_proto_t {
+ MP_PROTOCOL_HEAD
mp_import_stat_t (*import_stat)(void *self, const char *path);
} mp_vfs_proto_t;
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index 20d3e3e5c..60f4393f4 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -488,6 +488,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
STATIC const mp_vfs_proto_t fat_vfs_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_vfs)
.import_stat = fat_vfs_import_stat,
};
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index 6aad1884c..3ea9cee52 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -254,6 +254,7 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
#if MICROPY_PY_IO_FILEIO
STATIC const mp_stream_p_t fileio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = file_obj_read,
.write = file_obj_write,
.ioctl = file_obj_ioctl,
@@ -272,6 +273,7 @@ const mp_obj_type_t mp_type_vfs_fat_fileio = {
#endif
STATIC const mp_stream_p_t textio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = file_obj_read,
.write = file_obj_write,
.ioctl = file_obj_ioctl,
diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c
index d28dfe451..56a5de303 100644
--- a/extmod/vfs_posix.c
+++ b/extmod/vfs_posix.c
@@ -350,6 +350,7 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
STATIC const mp_vfs_proto_t vfs_posix_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_vfs)
.import_stat = mp_vfs_posix_import_stat,
};
diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c
index b760b3847..be455fa28 100644
--- a/extmod/vfs_posix_file.c
+++ b/extmod/vfs_posix_file.c
@@ -220,6 +220,7 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
#if MICROPY_PY_IO_FILEIO
STATIC const mp_stream_p_t fileio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = vfs_posix_file_read,
.write = vfs_posix_file_write,
.ioctl = vfs_posix_file_ioctl,
@@ -238,6 +239,7 @@ const mp_obj_type_t mp_type_vfs_posix_fileio = {
#endif
STATIC const mp_stream_p_t textio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = vfs_posix_file_read,
.write = vfs_posix_file_write,
.ioctl = vfs_posix_file_ioctl,
diff --git a/extmod/virtpin.c b/extmod/virtpin.c
index dbfa21d66..559f99265 100644
--- a/extmod/virtpin.c
+++ b/extmod/virtpin.c
@@ -25,15 +25,16 @@
*/
#include "extmod/virtpin.h"
+#include "py/proto.h"
int mp_virtual_pin_read(mp_obj_t pin) {
mp_obj_base_t* s = (mp_obj_base_t*)MP_OBJ_TO_PTR(pin);
- mp_pin_p_t *pin_p = (mp_pin_p_t*)s->type->protocol;
+ const mp_pin_p_t *pin_p = mp_proto_get(MP_QSTR_protocol_pin, s);
return pin_p->ioctl(pin, MP_PIN_READ, 0, NULL);
}
void mp_virtual_pin_write(mp_obj_t pin, int value) {
mp_obj_base_t* s = (mp_obj_base_t*)MP_OBJ_TO_PTR(pin);
- mp_pin_p_t *pin_p = (mp_pin_p_t*)s->type->protocol;
+ const mp_pin_p_t *pin_p = mp_proto_get(MP_QSTR_protocol_pin, s);
pin_p->ioctl(pin, MP_PIN_WRITE, value, NULL);
}
diff --git a/extmod/virtpin.h b/extmod/virtpin.h
index 706affc19..591249e48 100644
--- a/extmod/virtpin.h
+++ b/extmod/virtpin.h
@@ -27,6 +27,7 @@
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
#include "py/obj.h"
+#include "py/proto.h"
#define MP_PIN_READ (1)
#define MP_PIN_WRITE (2)
@@ -35,6 +36,7 @@
// Pin protocol
typedef struct _mp_pin_p_t {
+ MP_PROTOCOL_HEAD
mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
} mp_pin_p_t;
diff --git a/lib/utils/sys_stdio_mphal.c b/lib/utils/sys_stdio_mphal.c
index 266783f37..c1607dfe8 100644
--- a/lib/utils/sys_stdio_mphal.c
+++ b/lib/utils/sys_stdio_mphal.c
@@ -123,6 +123,7 @@ STATIC const mp_rom_map_elem_t stdio_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(stdio_locals_dict, stdio_locals_dict_table);
STATIC const mp_stream_p_t stdio_obj_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = stdio_read,
.write = stdio_write,
.ioctl = stdio_ioctl,
@@ -158,6 +159,7 @@ STATIC mp_uint_t stdio_buffer_write(mp_obj_t self_in, const void *buf, mp_uint_t
}
STATIC const mp_stream_p_t stdio_buffer_obj_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = stdio_buffer_read,
.write = stdio_buffer_write,
.is_text = false,
diff --git a/locale/ID.po b/locale/ID.po
index 6a0b73b6f..472c042c6 100644
--- a/locale/ID.po
+++ b/locale/ID.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -120,6 +120,10 @@ msgstr ""
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr "'%s' integer 0x%x tidak cukup didalam mask 0x%x"
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index a24ab186a..1541b1f74 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -119,6 +119,10 @@ msgstr ""
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr ""
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 37937b94f..b34626ea1 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
@@ -121,6 +121,10 @@ msgstr "'%s' integer %d ist nicht im Bereich %d..%d"
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr "'%s' Integer 0x%x passt nicht in Maske 0x%x"
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/en_US.po b/locale/en_US.po
index e0e63e4fd..95884c7b2 100644
--- a/locale/en_US.po
+++ b/locale/en_US.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -119,6 +119,10 @@ msgstr ""
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr ""
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po
index b22687469..ed7d2cec7 100644
--- a/locale/en_x_pirate.po
+++ b/locale/en_x_pirate.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n"
@@ -121,6 +121,10 @@ msgstr ""
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr ""
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/es.po b/locale/es.po
index 4e8df4195..fac38c081 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -121,6 +121,10 @@ msgstr "'%s' entero %d no esta dentro del rango %d..%d"
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr "'%s' entero 0x%x no cabe en la máscara 0x%x"
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/fil.po b/locale/fil.po
index f3f2b7e3b..776002768 100644
--- a/locale/fil.po
+++ b/locale/fil.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@@ -122,6 +122,10 @@ msgstr "'%s' integer %d ay wala sa sakop ng %d..%d"
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr "'%s' integer 0x%x ay wala sa mask na sakop ng 0x%x"
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/fr.po b/locale/fr.po
index 098bd8d1f..78d079bf1 100644
--- a/locale/fr.po
+++ b/locale/fr.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n"
@@ -123,6 +123,10 @@ msgstr "'%s' l'entier %d n'est pas dans la gamme %d..%d"
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr "'%s' l'entier 0x%x ne correspond pas au masque 0x%x"
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/it_IT.po b/locale/it_IT.po
index 154dda932..67585fe2f 100644
--- a/locale/it_IT.po
+++ b/locale/it_IT.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@@ -121,6 +121,10 @@ msgstr "intero '%s' non è nell'intervallo %d..%d"
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr "intero '%s' non è nell'intervallo %d..%d"
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/ko.po b/locale/ko.po
index 5fc91553b..0cf674737 100644
--- a/locale/ko.po
+++ b/locale/ko.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2019-05-06 14:22-0700\n"
"Last-Translator: \n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -121,6 +121,10 @@ msgstr ""
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr ""
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/pl.po b/locale/pl.po
index edfce95c6..0e33f3022 100644
--- a/locale/pl.po
+++ b/locale/pl.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@@ -120,6 +120,10 @@ msgstr "'%s' liczba %d poza zakresem %d..%d"
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr "'%s' liczba 0x%x nie pasuje do maski 0x%x"
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index a2b259fc4..f1f707f63 100644
--- a/locale/pt_BR.po
+++ b/locale/pt_BR.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -121,6 +121,10 @@ msgstr ""
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr ""
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index de78d35b5..6e49774b5 100644
--- a/locale/zh_Latn_pinyin.po
+++ b/locale/zh_Latn_pinyin.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-11-27 14:54-0500\n"
+"POT-Creation-Date: 2019-12-06 13:25-0600\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@@ -121,6 +121,10 @@ msgstr "'%s' zhěngshù %d bùzài fànwéi nèi %d.%d"
msgid "'%s' integer 0x%x does not fit in mask 0x%x"
msgstr "'%s' zhěngshù 0x%x bù shìyòng yú yǎn mǎ 0x%x"
+#: py/proto.c
+msgid "'%s' object does not support '%q'"
+msgstr ""
+
#: py/obj.c
#, c-format
msgid "'%s' object does not support item assignment"
diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c
index 841924c58..849820fff 100644
--- a/ports/unix/coverage.c
+++ b/ports/unix/coverage.c
@@ -96,6 +96,7 @@ STATIC const mp_rom_map_elem_t rawfile_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
STATIC const mp_stream_p_t fileio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = stest_read,
.write = stest_write,
.ioctl = stest_ioctl,
@@ -123,6 +124,7 @@ STATIC const mp_rom_map_elem_t rawfile_locals_dict_table2[] = {
STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict2, rawfile_locals_dict_table2);
STATIC const mp_stream_p_t textio_stream_p2 = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = stest_read2,
.write = NULL,
.is_text = true,
diff --git a/ports/unix/file.c b/ports/unix/file.c
index c0cf6dcc4..e5c73d26c 100644
--- a/ports/unix/file.c
+++ b/ports/unix/file.c
@@ -230,6 +230,7 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
#if MICROPY_PY_IO_FILEIO
STATIC const mp_stream_p_t fileio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = fdfile_read,
.write = fdfile_write,
.ioctl = fdfile_ioctl,
@@ -248,6 +249,7 @@ const mp_obj_type_t mp_type_fileio = {
#endif
STATIC const mp_stream_p_t textio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = fdfile_read,
.write = fdfile_write,
.ioctl = fdfile_ioctl,
diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c
index 84e9298fd..95da276ed 100644
--- a/ports/unix/modusocket.c
+++ b/ports/unix/modusocket.c
@@ -374,6 +374,7 @@ STATIC const mp_rom_map_elem_t usocket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(usocket_locals_dict, usocket_locals_dict_table);
STATIC const mp_stream_p_t usocket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = socket_read,
.write = socket_write,
.ioctl = socket_ioctl,
diff --git a/py/modio.c b/py/modio.c
index d7c1a58a8..17840a6d8 100644
--- a/py/modio.c
+++ b/py/modio.c
@@ -90,6 +90,7 @@ STATIC mp_uint_t iobase_ioctl(mp_obj_t obj, mp_uint_t request, uintptr_t arg, in
}
STATIC const mp_stream_p_t iobase_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = iobase_read,
.write = iobase_write,
.ioctl = iobase_ioctl,
@@ -185,6 +186,7 @@ STATIC const mp_rom_map_elem_t bufwriter_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(bufwriter_locals_dict, bufwriter_locals_dict_table);
STATIC const mp_stream_p_t bufwriter_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.write = bufwriter_write,
};
diff --git a/py/objstringio.c b/py/objstringio.c
index d2ca6decd..178e6446c 100644
--- a/py/objstringio.c
+++ b/py/objstringio.c
@@ -240,6 +240,7 @@ STATIC const mp_rom_map_elem_t stringio_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(stringio_locals_dict, stringio_locals_dict_table);
STATIC const mp_stream_p_t stringio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = stringio_read,
.write = stringio_write,
.ioctl = stringio_ioctl,
@@ -247,6 +248,7 @@ STATIC const mp_stream_p_t stringio_stream_p = {
};
STATIC const mp_stream_p_t bytesio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = stringio_read,
.write = stringio_write,
.ioctl = stringio_ioctl,
diff --git a/py/proto.c b/py/proto.c
new file mode 100644
index 000000000..e5053130b
--- /dev/null
+++ b/py/proto.c
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Jeff Epler 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.
+ */
+
+#include "py/obj.h"
+#include "py/proto.h"
+#include "py/runtime.h"
+
+#ifndef MICROPY_UNSAFE_PROTO
+const void *mp_proto_get(uint16_t name, mp_const_obj_t obj) {
+ mp_obj_type_t *type = mp_obj_get_type(obj);
+ if (!type->protocol) return NULL;
+ uint16_t proto_name = *(const uint16_t*) type->protocol;
+ if (proto_name == name) {
+ return type->protocol;
+ }
+ return NULL;
+}
+#endif
+
+const void *mp_proto_get_or_throw(uint16_t name, mp_const_obj_t obj) {
+ const void *proto = mp_proto_get(name, obj);
+ if (proto) {
+ return proto;
+ }
+ mp_raise_TypeError_varg(translate("'%s' object does not support '%q'"),
+ mp_obj_get_type_str(obj), name);
+}
diff --git a/py/proto.h b/py/proto.h
new file mode 100644
index 000000000..2d4f80565
--- /dev/null
+++ b/py/proto.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Jeff Epler 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_PY_PROTO_H
+#define MICROPY_INCLUDED_PY_PROTO_H
+
+#ifdef MICROPY_UNSAFE_PROTO
+#define MP_PROTOCOL_HEAD /* NOTHING */
+#define MP_PROTO_IMPLEMENT(name) /* NOTHING */
+static inline void *mp_proto_get(uint16_t name, mp_const_obj_type_t obj) { return mp_obj_get_type(obj)->protocol; }
+#else
+#define MP_PROTOCOL_HEAD \
+ uint16_t name; // The name of this protocol, a qstr
+#define MP_PROTO_IMPLEMENT(n) .name = n,
+const void *mp_proto_get(uint16_t name, mp_const_obj_t obj);
+const void *mp_proto_get_or_throw(uint16_t name, mp_const_obj_t obj);
+#endif
+
+#endif
+
diff --git a/py/py.mk b/py/py.mk
index 17cb79264..ae9b005b6 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -214,6 +214,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\
objtype.o \
objzip.o \
opmethods.o \
+ proto.o \
reload.o \
sequence.o \
stream.o \
diff --git a/py/stream.c b/py/stream.c
index 1d25f6470..2ff2b76a6 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -86,8 +86,7 @@ mp_uint_t mp_stream_rw(mp_obj_t stream, void *buf_, mp_uint_t size, int *errcode
}
const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) {
- mp_obj_type_t *type = mp_obj_get_type(self_in);
- const mp_stream_p_t *stream_p = type->protocol;
+ const mp_stream_p_t *stream_p = mp_proto_get(MP_QSTR_protocol_stream, self_in);
if (stream_p == NULL
|| ((flags & MP_STREAM_OP_READ) && stream_p->read == NULL)
|| ((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL)
@@ -522,7 +521,7 @@ int mp_stream_errno;
ssize_t mp_stream_posix_write(mp_obj_t stream, const void *buf, size_t len) {
mp_obj_base_t* o = (mp_obj_base_t*)MP_OBJ_TO_PTR(stream);
- const mp_stream_p_t *stream_p = o->type->protocol;
+ const mp_stream_p_t *stream_p = mp_get_stream(o);
mp_uint_t out_sz = stream_p->write(stream, buf, len, &mp_stream_errno);
if (out_sz == MP_STREAM_ERROR) {
return -1;
@@ -533,7 +532,7 @@ ssize_t mp_stream_posix_write(mp_obj_t stream, const void *buf, size_t len) {
ssize_t mp_stream_posix_read(mp_obj_t stream, void *buf, size_t len) {
mp_obj_base_t* o = (mp_obj_base_t*)MP_OBJ_TO_PTR(stream);
- const mp_stream_p_t *stream_p = o->type->protocol;
+ const mp_stream_p_t *stream_p = mp_get_stream(o);
mp_uint_t out_sz = stream_p->read(stream, buf, len, &mp_stream_errno);
if (out_sz == MP_STREAM_ERROR) {
return -1;
@@ -544,7 +543,7 @@ ssize_t mp_stream_posix_read(mp_obj_t stream, void *buf, size_t len) {
off_t mp_stream_posix_lseek(mp_obj_t stream, off_t offset, int whence) {
const mp_obj_base_t* o = (mp_obj_base_t*)MP_OBJ_TO_PTR(stream);
- const mp_stream_p_t *stream_p = o->type->protocol;
+ const mp_stream_p_t *stream_p = mp_get_stream(o);
struct mp_stream_seek_t seek_s;
seek_s.offset = offset;
seek_s.whence = whence;
@@ -557,7 +556,7 @@ off_t mp_stream_posix_lseek(mp_obj_t stream, off_t offset, int whence) {
int mp_stream_posix_fsync(mp_obj_t stream) {
mp_obj_base_t* o = (mp_obj_base_t*)MP_OBJ_TO_PTR(stream);
- const mp_stream_p_t *stream_p = o->type->protocol;
+ const mp_stream_p_t *stream_p = mp_get_stream(o);
mp_uint_t res = stream_p->ioctl(stream, MP_STREAM_FLUSH, 0, &mp_stream_errno);
if (res == MP_STREAM_ERROR) {
return -1;
diff --git a/py/stream.h b/py/stream.h
index 03e24c746..543fe8c82 100644
--- a/py/stream.h
+++ b/py/stream.h
@@ -27,6 +27,7 @@
#define MICROPY_INCLUDED_PY_STREAM_H
#include "py/obj.h"
+#include "py/proto.h"
#include "py/mperrno.h"
#define MP_STREAM_ERROR ((mp_uint_t)-1)
@@ -64,6 +65,7 @@ struct mp_stream_seek_t {
// Stream protocol
typedef struct _mp_stream_p_t {
+ MP_PROTOCOL_HEAD
// On error, functions should return MP_STREAM_ERROR and fill in *errcode (values
// are implementation-dependent, but will be exposed to user, e.g. via exception).
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
@@ -93,7 +95,7 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_ioctl_obj);
// Object is assumed to have a non-NULL stream protocol with valid r/w/ioctl methods
static inline const mp_stream_p_t *mp_get_stream(mp_const_obj_t self) {
- return (const mp_stream_p_t*)((const mp_obj_base_t*)MP_OBJ_TO_PTR(self))->type->protocol;
+ return mp_proto_get(MP_QSTR_protocol_stream, self);
}
const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags);
diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c
index e7524da2d..fc95d0d50 100644
--- a/shared-bindings/_bleio/CharacteristicBuffer.c
+++ b/shared-bindings/_bleio/CharacteristicBuffer.c
@@ -230,6 +230,7 @@ STATIC const mp_rom_map_elem_t bleio_characteristic_buffer_locals_dict_table[] =
STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_buffer_locals_dict, bleio_characteristic_buffer_locals_dict_table);
STATIC const mp_stream_p_t characteristic_buffer_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = bleio_characteristic_buffer_read,
.write = bleio_characteristic_buffer_write,
.ioctl = bleio_characteristic_buffer_ioctl,
diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c
index 07f8c683f..87d410ea1 100644
--- a/shared-bindings/audiocore/RawSample.c
+++ b/shared-bindings/audiocore/RawSample.c
@@ -180,9 +180,20 @@ STATIC const mp_rom_map_elem_t audioio_rawsample_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(audioio_rawsample_locals_dict, audioio_rawsample_locals_dict_table);
+STATIC const audiosample_p_t audioio_rawsample_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
+ .sample_rate = (audiosample_sample_rate_fun)common_hal_audioio_rawsample_get_sample_rate,
+ .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audioio_rawsample_get_bits_per_sample,
+ .channel_count = (audiosample_channel_count_fun)common_hal_audioio_rawsample_get_channel_count,
+ .reset_buffer = (audiosample_reset_buffer_fun)audioio_rawsample_reset_buffer,
+ .get_buffer = (audiosample_get_buffer_fun)audioio_rawsample_get_buffer,
+ .get_buffer_structure = (audiosample_get_buffer_structure_fun)audioio_rawsample_get_buffer_structure,
+};
+
const mp_obj_type_t audioio_rawsample_type = {
{ &mp_type_type },
.name = MP_QSTR_RawSample,
.make_new = audioio_rawsample_make_new,
.locals_dict = (mp_obj_dict_t*)&audioio_rawsample_locals_dict,
+ .protocol = &audioio_rawsample_proto,
};
diff --git a/shared-bindings/audiocore/RawSample.h b/shared-bindings/audiocore/RawSample.h
index b02778cad..61f61a066 100644
--- a/shared-bindings/audiocore/RawSample.h
+++ b/shared-bindings/audiocore/RawSample.h
@@ -39,6 +39,8 @@ void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t* self,
void common_hal_audioio_rawsample_deinit(audioio_rawsample_obj_t* self);
bool common_hal_audioio_rawsample_deinited(audioio_rawsample_obj_t* self);
uint32_t common_hal_audioio_rawsample_get_sample_rate(audioio_rawsample_obj_t* self);
+uint8_t common_hal_audioio_rawsample_get_bits_per_sample(audioio_rawsample_obj_t* self);
+uint8_t common_hal_audioio_rawsample_get_channel_count(audioio_rawsample_obj_t* self);
void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t* self, uint32_t sample_rate);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H
diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c
index 1b3a94ff3..178d2a139 100644
--- a/shared-bindings/audiocore/WaveFile.c
+++ b/shared-bindings/audiocore/WaveFile.c
@@ -206,9 +206,21 @@ STATIC const mp_rom_map_elem_t audioio_wavefile_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(audioio_wavefile_locals_dict, audioio_wavefile_locals_dict_table);
+STATIC const audiosample_p_t audioio_wavefile_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
+ .sample_rate = (audiosample_sample_rate_fun)common_hal_audioio_wavefile_get_sample_rate,
+ .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audioio_wavefile_get_bits_per_sample,
+ .channel_count = (audiosample_channel_count_fun)common_hal_audioio_wavefile_get_channel_count,
+ .reset_buffer = (audiosample_reset_buffer_fun)audioio_wavefile_reset_buffer,
+ .get_buffer = (audiosample_get_buffer_fun)audioio_wavefile_get_buffer,
+ .get_buffer_structure = (audiosample_get_buffer_structure_fun)audioio_wavefile_get_buffer_structure,
+};
+
+
const mp_obj_type_t audioio_wavefile_type = {
{ &mp_type_type },
.name = MP_QSTR_WaveFile,
.make_new = audioio_wavefile_make_new,
.locals_dict = (mp_obj_dict_t*)&audioio_wavefile_locals_dict,
+ .protocol = &audioio_wavefile_proto,
};
diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c
index ed7b95d9e..03ffb9373 100644
--- a/shared-bindings/audiomixer/Mixer.c
+++ b/shared-bindings/audiomixer/Mixer.c
@@ -291,9 +291,20 @@ STATIC const mp_rom_map_elem_t audiomixer_mixer_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(audiomixer_mixer_locals_dict, audiomixer_mixer_locals_dict_table);
+STATIC const audiosample_p_t audiomixer_mixer_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
+ .sample_rate = (audiosample_sample_rate_fun)common_hal_audiomixer_mixer_get_sample_rate,
+ .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audiomixer_mixer_get_bits_per_sample,
+ .channel_count = (audiosample_channel_count_fun)common_hal_audiomixer_mixer_get_channel_count,
+ .reset_buffer = (audiosample_reset_buffer_fun)audiomixer_mixer_reset_buffer,
+ .get_buffer = (audiosample_get_buffer_fun)audiomixer_mixer_get_buffer,
+ .get_buffer_structure = (audiosample_get_buffer_structure_fun)audiomixer_mixer_get_buffer_structure,
+};
+
const mp_obj_type_t audiomixer_mixer_type = {
{ &mp_type_type },
.name = MP_QSTR_Mixer,
.make_new = audiomixer_mixer_make_new,
.locals_dict = (mp_obj_dict_t*)&audiomixer_mixer_locals_dict,
+ .protocol = &audiomixer_mixer_proto,
};
diff --git a/shared-bindings/audiomixer/Mixer.h b/shared-bindings/audiomixer/Mixer.h
index 9eabbf61d..a99e1bf62 100644
--- a/shared-bindings/audiomixer/Mixer.h
+++ b/shared-bindings/audiomixer/Mixer.h
@@ -47,5 +47,7 @@ bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t* self);
bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self);
uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* self);
+uint8_t common_hal_audiomixer_mixer_get_channel_count(audiomixer_mixer_obj_t* self);
+uint8_t common_hal_audiomixer_mixer_get_bits_per_sample(audiomixer_mixer_obj_t* self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H
diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c
index 7a3b48e89..1fc81e78e 100644
--- a/shared-bindings/busio/UART.c
+++ b/shared-bindings/busio/UART.c
@@ -398,6 +398,7 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(busio_uart_locals_dict, busio_uart_locals_dict_table);
STATIC const mp_stream_p_t uart_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = busio_uart_read,
.write = busio_uart_write,
.ioctl = busio_uart_ioctl,
diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c
index 6d04a9893..2d6c16e90 100644
--- a/shared-bindings/socket/__init__.c
+++ b/shared-bindings/socket/__init__.c
@@ -500,6 +500,7 @@ mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *
}
STATIC const mp_stream_p_t socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.ioctl = socket_ioctl,
.is_text = false,
};
diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c
index cdde672d3..9c01fba20 100644
--- a/shared-bindings/terminalio/Terminal.c
+++ b/shared-bindings/terminalio/Terminal.c
@@ -112,6 +112,7 @@ STATIC const mp_rom_map_elem_t terminalio_terminal_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(terminalio_terminal_locals_dict, terminalio_terminal_locals_dict_table);
STATIC const mp_stream_p_t terminalio_terminal_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = NULL,
.write = terminalio_terminal_write,
.ioctl = terminalio_terminal_ioctl,
diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c
index 356a81d52..e2df56e95 100644
--- a/shared-bindings/usb_midi/PortIn.c
+++ b/shared-bindings/usb_midi/PortIn.c
@@ -107,6 +107,7 @@ STATIC const mp_rom_map_elem_t usb_midi_portin_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(usb_midi_portin_locals_dict, usb_midi_portin_locals_dict_table);
STATIC const mp_stream_p_t usb_midi_portin_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = usb_midi_portin_read,
.write = NULL,
.ioctl = usb_midi_portin_ioctl,
diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c
index 6f4ce6716..e3eddfaf5 100644
--- a/shared-bindings/usb_midi/PortOut.c
+++ b/shared-bindings/usb_midi/PortOut.c
@@ -89,6 +89,7 @@ STATIC const mp_rom_map_elem_t usb_midi_portout_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(usb_midi_portout_locals_dict, usb_midi_portout_locals_dict_table);
STATIC const mp_stream_p_t usb_midi_portout_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = NULL,
.write = usb_midi_portout_write,
.ioctl = usb_midi_portout_ioctl,
diff --git a/shared-module/audiocore/RawSample.c b/shared-module/audiocore/RawSample.c
index d6bf3a567..a69ddeb65 100644
--- a/shared-module/audiocore/RawSample.c
+++ b/shared-module/audiocore/RawSample.c
@@ -60,6 +60,12 @@ void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t* self,
uint32_t sample_rate) {
self->sample_rate = sample_rate;
}
+uint8_t common_hal_audioio_rawsample_get_bits_per_sample(audioio_rawsample_obj_t* self) {
+ return self->bits_per_sample;
+}
+uint8_t common_hal_audioio_rawsample_get_channel_count(audioio_rawsample_obj_t* self) {
+ return self->channel_count;
+}
void audioio_rawsample_reset_buffer(audioio_rawsample_obj_t* self,
bool single_channel,
diff --git a/shared-module/audiocore/__init__.c b/shared-module/audiocore/__init__.c
index f9762676f..1553dbe96 100644
--- a/shared-module/audiocore/__init__.c
+++ b/shared-module/audiocore/__init__.c
@@ -36,103 +36,37 @@
#include "shared-module/audiomixer/Mixer.h"
uint32_t audiosample_sample_rate(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->sample_rate;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->sample_rate;
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->sample_rate;
- #endif
- }
- return 16000;
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ return proto->sample_rate(MP_OBJ_TO_PTR(sample_obj));
}
uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->bits_per_sample;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->bits_per_sample;
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->bits_per_sample;
- #endif
- }
- return 8;
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ return proto->bits_per_sample(MP_OBJ_TO_PTR(sample_obj));
}
uint8_t audiosample_channel_count(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->channel_count;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->channel_count;
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->channel_count;
- #endif
- }
- return 1;
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ return proto->channel_count(MP_OBJ_TO_PTR(sample_obj));
}
void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- audioio_rawsample_reset_buffer(sample, single_channel, audio_channel);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audioio_wavefile_reset_buffer(file, single_channel, audio_channel);
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audiomixer_mixer_reset_buffer(file, single_channel, audio_channel);
- #endif
- }
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ proto->reset_buffer(MP_OBJ_TO_PTR(sample_obj));
}
audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
bool single_channel,
uint8_t channel,
uint8_t** buffer, uint32_t* buffer_length) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return audioio_rawsample_get_buffer(sample, single_channel, channel, buffer, buffer_length);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length);
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return audiomixer_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length);
- #endif
- }
- return GET_BUFFER_DONE;
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ return proto->get_buffer(MP_OBJ_TO_PTR(sample_obj), single_channel, channel, buffer, buffer_length);
}
void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel,
bool* single_buffer, bool* samples_signed,
uint32_t* max_buffer_length, uint8_t* spacing) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- audioio_rawsample_get_buffer_structure(sample, single_channel, single_buffer,
- samples_signed, max_buffer_length, spacing);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
- max_buffer_length, spacing);
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audiomixer_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
- max_buffer_length, spacing);
- #endif
- }
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ proto->get_buffer_structure(MP_OBJ_TO_PTR(sample_obj), single_channel, single_buffer,
+ samples_signed, max_buffer_length, spacing);
}
diff --git a/shared-module/audiocore/__init__.h b/shared-module/audiocore/__init__.h
index 7aa0c1824..38c1f5aeb 100644
--- a/shared-module/audiocore/__init__.h
+++ b/shared-module/audiocore/__init__.h
@@ -31,6 +31,7 @@
#include <stdint.h>
#include "py/obj.h"
+#include "py/proto.h"
typedef enum {
GET_BUFFER_DONE, // No more data to read
@@ -38,6 +39,28 @@ typedef enum {
GET_BUFFER_ERROR, // Error while reading data.
} audioio_get_buffer_result_t;
+typedef uint32_t (*audiosample_sample_rate_fun)(mp_obj_t);
+typedef uint8_t (*audiosample_bits_per_sample_fun)(mp_obj_t);
+typedef uint8_t (*audiosample_channel_count_fun)(mp_obj_t);
+typedef void (*audiosample_reset_buffer_fun)(mp_obj_t);
+typedef audioio_get_buffer_result_t (*audiosample_get_buffer_fun)(mp_obj_t,
+ bool single_channel, uint8_t channel, uint8_t** buffer,
+ uint32_t* buffer_length);
+typedef void (*audiosample_get_buffer_structure_fun)(mp_obj_t,
+ bool single_channel, bool* single_buffer,
+ bool* samples_signed, uint32_t *max_buffer_length,
+ uint8_t* spacing);
+
+typedef struct _audiosample_p_t {
+ MP_PROTOCOL_HEAD // MP_QSTR_protocol_audiosample
+ audiosample_sample_rate_fun sample_rate;
+ audiosample_bits_per_sample_fun bits_per_sample;
+ audiosample_channel_count_fun channel_count;
+ audiosample_reset_buffer_fun reset_buffer;
+ audiosample_get_buffer_fun get_buffer;
+ audiosample_get_buffer_structure_fun get_buffer_structure;
+} audiosample_p_t;
+
uint32_t audiosample_sample_rate(mp_obj_t sample_obj);
uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj);
uint8_t audiosample_channel_count(mp_obj_t sample_obj);
diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c
index a52489f85..afa3a0632 100644
--- a/shared-module/audiomixer/Mixer.c
+++ b/shared-module/audiomixer/Mixer.c
@@ -76,6 +76,14 @@ uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* sel
return self->sample_rate;
}
+uint8_t common_hal_audiomixer_mixer_get_channel_count(audiomixer_mixer_obj_t* self) {
+ return self->channel_count;
+}
+
+uint8_t common_hal_audiomixer_mixer_get_bits_per_sample(audiomixer_mixer_obj_t* self) {
+ return self->bits_per_sample;
+}
+
bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self) {
for (uint8_t v = 0; v < self->voice_count; v++) {
if (common_hal_audiomixer_mixervoice_get_playing(MP_OBJ_TO_PTR(self->voice[v]))) {