diff options
author | Damien George <damien@micropython.org> | 2023-10-13 17:33:29 +1100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2023-10-16 11:22:55 +1100 |
commit | 9c7ea9b14ac0378f580bd8ed55b22ef311eda20b (patch) | |
tree | 71fed46d0b04a3f49833a61a74b009bea46e0852 | |
parent | 516385c4ccbb1f7fa9dbd37a44ed8ae33dcf1942 (diff) | |
download | micropython-9c7ea9b14ac0378f580bd8ed55b22ef311eda20b.tar.gz micropython-9c7ea9b14ac0378f580bd8ed55b22ef311eda20b.zip |
py/obj: Generalise mp_get_buffer so it can raise if a flag is set.
This allows mp_get_buffer_raise() to be changed to a simple inline function
that in the majority of cases costs the same (in code size) to call as the
original mp_get_buffer_raise(), because the flags argument is a constant.
Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r-- | py/obj.c | 16 | ||||
-rw-r--r-- | py/obj.h | 10 |
2 files changed, 14 insertions, 12 deletions
@@ -577,18 +577,12 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity); bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { const mp_obj_type_t *type = mp_obj_get_type(obj); - if (!MP_OBJ_TYPE_HAS_SLOT(type, buffer)) { - return false; + if (MP_OBJ_TYPE_HAS_SLOT(type, buffer) + && MP_OBJ_TYPE_GET_SLOT(type, buffer)(obj, bufinfo, flags & MP_BUFFER_RW) == 0) { + return true; } - int ret = MP_OBJ_TYPE_GET_SLOT(type, buffer)(obj, bufinfo, flags); - if (ret != 0) { - return false; - } - return true; -} - -void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { - if (!mp_get_buffer(obj, bufinfo, flags)) { + if (flags & MP_BUFFER_RAISE_IF_UNSUPPORTED) { mp_raise_TypeError(MP_ERROR_TEXT("object with buffer protocol required")); } + return false; } @@ -585,17 +585,25 @@ typedef struct _mp_getiter_iternext_custom_t { } mp_getiter_iternext_custom_t; // Buffer protocol + typedef struct _mp_buffer_info_t { void *buf; // can be NULL if len == 0 size_t len; // in bytes int typecode; // as per binary.h } mp_buffer_info_t; + #define MP_BUFFER_READ (1) #define MP_BUFFER_WRITE (2) #define MP_BUFFER_RW (MP_BUFFER_READ | MP_BUFFER_WRITE) +#define MP_BUFFER_RAISE_IF_UNSUPPORTED (4) + typedef mp_int_t (*mp_buffer_fun_t)(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); + bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); -void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags); + +static inline void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + mp_get_buffer(obj, bufinfo, flags | MP_BUFFER_RAISE_IF_UNSUPPORTED); +} // This struct will be updated to become a variable sized struct. In order to // use this as a member, or allocate dynamically, use the mp_obj_empty_type_t |