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)
 {

Reply via email to