From a20fca8c04f95fbf9420d3c6926fd59aa6086c83 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 13 Aug 2024 21:55:36 +1000 Subject: [PATCH] py/ringbuf: Add micropython.ringbuffer() interface for general use. Signed-off-by: Andrew Leech --- py/ringbuf.c | 32 ++++++++--------------------- tests/micropython/ringbuffer.py | 10 +++++++++ tests/micropython/ringbuffer.py.exp | 7 ++++++- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/py/ringbuf.c b/py/ringbuf.c index 9cecdb4a1f5e7..ad82528ea18ae 100644 --- a/py/ringbuf.c +++ b/py/ringbuf.c @@ -143,8 +143,7 @@ static mp_obj_t micropython_ringbuffer_make_new(const mp_obj_type_t *type, size_ // This can be user to no-copy stream an existing data buffer (except final byte). self->ringbuffer.buf = bufinfo.buf; self->ringbuffer.size = bufinfo.len; - self->ringbuffer.iput = bufinfo.len - 1; - self->ringbuffer.iget = 0; + self->ringbuffer.iget = self->ringbuffer.iput = 0; } else { // Allocate new buffer, add one extra to buff_size as ringbuf consumes one byte for tracking. ringbuf_alloc(&(self->ringbuffer), buff_size + 1); @@ -154,12 +153,10 @@ static mp_obj_t micropython_ringbuffer_make_new(const mp_obj_type_t *type, size_ static mp_uint_t micropython_ringbuffer_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { micropython_ringbuffer_obj_t *self = MP_OBJ_TO_PTR(self_in); - size = MIN(size, ringbuf_avail(&self->ringbuffer)); // limit size to available data - - if (size == 0 || ringbuf_get_bytes(&self->ringbuffer, buf_in, size) == -1) { - // no data available - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; + size = MIN(size, ringbuf_avail(&self->ringbuffer)); + uint8_t *dest = buf_in; + for (mp_uint_t i = 0; i < size; i++) { + *dest++ = ringbuf_get(&(self->ringbuffer)); } *errcode = 0; return size; @@ -167,12 +164,10 @@ static mp_uint_t micropython_ringbuffer_read(mp_obj_t self_in, void *buf_in, mp_ static mp_uint_t micropython_ringbuffer_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { micropython_ringbuffer_obj_t *self = MP_OBJ_TO_PTR(self_in); - size = MIN(size, ringbuf_free(&self->ringbuffer)); // limit size to available space - - if (size == 0 || ringbuf_put_bytes(&self->ringbuffer, buf_in, size) == -1) { - // no space available - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; + size = MIN(size, ringbuf_free(&self->ringbuffer)); + const uint8_t *src = buf_in; + for (mp_uint_t i = 0; i < size; i++) { + ringbuf_put(&(self->ringbuffer), *src++); } *errcode = 0; return size; @@ -205,18 +200,9 @@ static mp_obj_t micropython_ringbuffer_any(mp_obj_t self_in) { } static MP_DEFINE_CONST_FUN_OBJ_1(micropython_ringbuffer_any_obj, micropython_ringbuffer_any); -static mp_obj_t micropython_ringbuffer_reset(mp_obj_t self_in) { - micropython_ringbuffer_obj_t *self = MP_OBJ_TO_PTR(self_in); - self->ringbuffer.iget = self->ringbuffer.iput = 0; - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_1(micropython_ringbuffer_reset_obj, micropython_ringbuffer_reset); - static const mp_rom_map_elem_t micropython_ringbuffer_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(µpython_ringbuffer_any_obj) }, - { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(µpython_ringbuffer_reset_obj) }, - { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, diff --git a/tests/micropython/ringbuffer.py b/tests/micropython/ringbuffer.py index 162fe52d6ba64..2b940682dcbaf 100644 --- a/tests/micropython/ringbuffer.py +++ b/tests/micropython/ringbuffer.py @@ -28,7 +28,17 @@ print(rb.read(1)) +# try to write more data than can fit at one go print(rb.write(b"\x00\x01" * 10)) +print(rb.write(b"\x00")) +print(rb.read()) + + +ba = bytearray(17) +rb = micropython.ringbuffer(ba) +print(rb) +print(rb.write(b"\x00\x01" * 10)) +print(rb.write(b"\x00")) print(rb.read()) try: diff --git a/tests/micropython/ringbuffer.py.exp b/tests/micropython/ringbuffer.py.exp index c2335f5a1684f..1de9c4acef233 100644 --- a/tests/micropython/ringbuffer.py.exp +++ b/tests/micropython/ringbuffer.py.exp @@ -5,7 +5,12 @@ b'\x00\x00' 0 b'\x00\x01' -None +b'' 16 +0 +b'\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01' + +16 +0 b'\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01' can't convert NoneType to int