Skip to content

Commit

Permalink
py/ringbuf: Add micropython.ringbuffer() interface for general use.
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Leech <[email protected]>
  • Loading branch information
pi-anl committed Aug 13, 2024
1 parent 787df37 commit a20fca8
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 24 deletions.
32 changes: 9 additions & 23 deletions py/ringbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -154,25 +153,21 @@ 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;
}

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;
Expand Down Expand Up @@ -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(&micropython_ringbuffer_any_obj) },
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&micropython_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) },
Expand Down
10 changes: 10 additions & 0 deletions tests/micropython/ringbuffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 6 additions & 1 deletion tests/micropython/ringbuffer.py.exp
Original file line number Diff line number Diff line change
Expand Up @@ -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'
<ringbuffer>
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

0 comments on commit a20fca8

Please sign in to comment.