From bd84932da7104f2f27ab8d420bdc6b090d1c8f31 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 7 Jan 2024 15:19:10 +0100 Subject: [PATCH] Berry add `string` to `bytes()` --- CHANGELOG.md | 1 + lib/libesp32/berry/src/be_byteslib.c | 44 +++++++++++++++++++++++----- lib/libesp32/berry/tests/bytes.be | 19 ++++++++++++ 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66b447fad6de..c3fdbe4c4abe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ All notable changes to this project will be documented in this file. - HASPmota `haspmota.page_show()` to change page (#20333) - Berry `introspect.set()` for class attributes (#20339) - Support negative power on BL0942 using index 5..8 (#20322) +- Berry add `string` to `bytes()` ### Breaking Changed - Refactoring of Berry `animate` module for WS2812 Leds (#20236) diff --git a/lib/libesp32/berry/src/be_byteslib.c b/lib/libesp32/berry/src/be_byteslib.c index c26a45df28aa..8d351997d44d 100644 --- a/lib/libesp32/berry/src/be_byteslib.c +++ b/lib/libesp32/berry/src/be_byteslib.c @@ -309,6 +309,17 @@ static size_t buf_add_buf(buf_impl* attr, buf_impl* attr2) return attr->len; } +static size_t buf_add_raw(buf_impl* attr, const void* buf_raw, int32_t len) +{ + uint8_t *buf = (uint8_t*) buf_raw; + if ((len > 0) && (attr->len + len <= attr->size)) { + for (int32_t i = 0; i < len; i++) { + attr->bufptr[attr->len++] = buf[i]; + } + } + return attr->len; +} + static uint8_t buf_get1(buf_impl* attr, int offset) { if ((offset >= 0) && (offset < attr->len)) { @@ -1211,17 +1222,26 @@ static int m_merge(bvm *vm) int argc = be_top(vm); buf_impl attr = m_read_attributes(vm, 1); /* no resize yet */ check_ptr(vm, &attr); - if (argc >= 2 && be_isbytes(vm, 2)) { - buf_impl attr2 = m_read_attributes(vm, 2); - check_ptr(vm, &attr2); + if (argc >= 2 && (be_isbytes(vm, 2) || be_isstring(vm, 2))) { + const uint8_t * buf; + int32_t buf_len; + if (be_isbytes(vm, 2)) { + buf_impl attr2 = m_read_attributes(vm, 2); + check_ptr(vm, &attr2); + buf = attr2.bufptr; + buf_len = attr2.len; + } else { + buf = (const uint8_t *)be_tostring(vm, 2); + buf_len = strlen((const char *)buf); + } /* allocate new object */ - bytes_new_object(vm, attr.len + attr2.len); + bytes_new_object(vm, attr.len + buf_len); buf_impl attr3 = m_read_attributes(vm, -1); check_ptr(vm, &attr3); buf_add_buf(&attr3, &attr); - buf_add_buf(&attr3, &attr2); + buf_add_raw(&attr3, buf, buf_len); m_write_attributes(vm, -1, &attr3); /* update instance */ be_return(vm); /* return self */ @@ -1249,13 +1269,23 @@ static int m_connect(bvm *vm) buf_impl attr = m_read_attributes(vm, 1); check_ptr(vm, &attr); if (attr.fixed) { be_raise(vm, BYTES_RESIZE_ERROR, BYTES_RESIZE_MESSAGE); } - if (argc >= 2 && (be_isbytes(vm, 2) || be_isint(vm, 2))) { + if (argc >= 2 && (be_isbytes(vm, 2) || be_isint(vm, 2) || be_isstring(vm, 2))) { if (be_isint(vm, 2)) { bytes_resize(vm, &attr, attr.len + 1); /* resize */ buf_add1(&attr, be_toint(vm, 2)); m_write_attributes(vm, 1, &attr); /* update instance */ be_pushvalue(vm, 1); be_return(vm); /* return self */ + } else if (be_isstring(vm, 2)) { + const char *str = be_tostring(vm, 2); + size_t str_len = strlen(str); + if (str_len > 0) { + bytes_resize(vm, &attr, attr.len + str_len); /* resize */ + buf_add_raw(&attr, str, str_len); + m_write_attributes(vm, 1, &attr); /* update instance */ + } + be_pushvalue(vm, 1); + be_return(vm); /* return self */ } else { buf_impl attr2 = m_read_attributes(vm, 2); check_ptr(vm, &attr2); @@ -1266,7 +1296,7 @@ static int m_connect(bvm *vm) be_return(vm); /* return self */ } } - be_raise(vm, "type_error", "operand must be bytes or int"); + be_raise(vm, "type_error", "operand must be bytes or int or string"); be_return_nil(vm); /* return self */ } diff --git a/lib/libesp32/berry/tests/bytes.be b/lib/libesp32/berry/tests/bytes.be index 6a481d62cc49..4621747b11b4 100644 --- a/lib/libesp32/berry/tests/bytes.be +++ b/lib/libesp32/berry/tests/bytes.be @@ -103,6 +103,13 @@ assert(str(b) == "bytes('1122334455')") b = b2 + b1 assert(str(b) == "bytes('3344551122')") +#- + for string -# +b1 = bytes("AA") +b = b1 + '' +assert(str(b) == "bytes('AA')") +b = b1 + '01' +assert(str(b) == "bytes('AA3031')") + #- .. -# b1 = bytes("1122") b2 = bytes("334455") @@ -111,6 +118,13 @@ assert(str(b1) == "bytes('1122334455')") assert(str(b2) == "bytes('334455')") assert(str(b) == "bytes('1122334455')") +#- .. with string -# +b1 = bytes("AA") +b1 .. '' +assert(str(b1) == "bytes('AA')") +b1 .. '01' +assert(str(b1) == "bytes('AA3031')") + #- item -# b = bytes("334455") assert(b[0] == 0x33) @@ -257,3 +271,8 @@ assert(!bytes()) assert(bool(bytes("00")) == true) assert(bytes("01").tobool() == true) assert(bytes("02")) + +# retrieving 3-bytes little/big endian +a = bytes("01020304") +assert(a.get(1, 3) == 0x040302) +assert(a.get(1, -3) == 0x020304)