This is an automated email from the ASF dual-hosted git repository. jerzy pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit c594f5426adbd58ec4683a081f300d13f116d5ed Author: Jerzy Kasenberg <[email protected]> AuthorDate: Fri Feb 21 14:52:58 2025 +0100 util/stream: Add memory output stream Such stream can be setup so plain memory buffer can be used as destination for stream write functions. Signed-off-by: Jerzy Kasenberg <[email protected]> --- util/stream/include/stream/stream.h | 16 ++++++++++++ util/stream/src/stream.c | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/util/stream/include/stream/stream.h b/util/stream/include/stream/stream.h index ac23e361c..1cea39dd4 100644 --- a/util/stream/include/stream/stream.h +++ b/util/stream/include/stream/stream.h @@ -124,6 +124,13 @@ struct mem_in_stream { uint32_t read_ptr; }; +struct mem_out_stream { + struct out_stream_vft *vft; + uint8_t *buf; + uint32_t size; + int write_ptr; +}; + #define OSTREAM_DEF(type) \ static int type ## _write(struct out_stream *ostream, const uint8_t *buf, uint32_t count); \ static int type ## _flush(struct out_stream *ostream); \ @@ -231,6 +238,15 @@ int stream_pump(struct in_stream *istream, struct out_stream *ostream, uint32_t */ void mem_istream_init(struct mem_in_stream *mem, const uint8_t *buf, uint32_t size); +/** + * Initialize output stream that will receive data into provided buffer + * + * @param mem - stream to initialize + * @param buf - memory to store written data + * @param size - size of buf + */ +void mem_ostream_init(struct mem_out_stream *mem, uint8_t *buf, uint32_t size); + static inline int ostream_write_uint8(struct out_stream *ostream, uint8_t data) { diff --git a/util/stream/src/stream.c b/util/stream/src/stream.c index 80473505b..1ab0c7f26 100644 --- a/util/stream/src/stream.c +++ b/util/stream/src/stream.c @@ -76,6 +76,55 @@ mem_istream_init(struct mem_in_stream *mem, const uint8_t *buf, uint32_t size) mem->read_ptr = 0; } +static int +mem_ostream_write(struct out_stream *ostream, const uint8_t *buf, uint32_t count) +{ + struct mem_out_stream *mem = (struct mem_out_stream *)ostream; + int skip = 0; + int write = count; + + /* If write_ptr is negative drop data and update write_ptr */ + if (mem->write_ptr < 0) { + skip = min(-mem->write_ptr, count); + mem->write_ptr += skip; + write -= skip; + } + + if (mem->write_ptr >= 0 && write > 0 && buf != NULL && mem->write_ptr < mem->size) { + if (write > mem->size - mem->write_ptr) { + write = mem->size - mem->write_ptr; + } + if (mem->buf) { + memcpy(mem->buf + mem->write_ptr, buf + skip, write); + } + } + mem->write_ptr += count - skip; + + return count; +} + +static int +mem_ostream_flush(struct out_stream *ostream) +{ + (void)ostream; + + return 0; +} + +struct out_stream_vft mem_ostream_vft = { + .write = mem_ostream_write, + .flush = mem_ostream_flush, +}; + +void +mem_ostream_init(struct mem_out_stream *mem, uint8_t *buf, uint32_t size) +{ + mem->vft = &mem_ostream_vft; + mem->buf = buf; + mem->size = size; + mem->write_ptr = 0; +} + int ostream_write(struct out_stream *ostream, const uint8_t *buf, uint32_t count, bool flush) {
