summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2023-10-13 17:33:29 +1100
committerDamien George <damien@micropython.org>2023-10-16 11:22:55 +1100
commit9c7ea9b14ac0378f580bd8ed55b22ef311eda20b (patch)
tree71fed46d0b04a3f49833a61a74b009bea46e0852
parent516385c4ccbb1f7fa9dbd37a44ed8ae33dcf1942 (diff)
downloadmicropython-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.c16
-rw-r--r--py/obj.h10
2 files changed, 14 insertions, 12 deletions
diff --git a/py/obj.c b/py/obj.c
index d013eb3d02..5e01198b6f 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -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;
}
diff --git a/py/obj.h b/py/obj.h
index 3c2176832d..56ae62172f 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -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