From ba2dc6b53c8dd840651fc9e2c10790989b9cee9f Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 28 Jun 2020 19:46:47 +0200 Subject: WIP: Make Writer always write to a ByteSink --- src/byte_sink.h | 79 ++++++++++++++++++++------------------------------------- 1 file changed, 27 insertions(+), 52 deletions(-) (limited to 'src/byte_sink.h') diff --git a/src/byte_sink.h b/src/byte_sink.h index 1be84b48..b90cf4a5 100644 --- a/src/byte_sink.h +++ b/src/byte_sink.h @@ -17,79 +17,54 @@ #ifndef SERD_BYTE_SINK_H #define SERD_BYTE_SINK_H -#include "serd_internal.h" -#include "system.h" - #include "serd/serd.h" #include #include -typedef struct SerdByteSinkImpl { - SerdWriteFunc sink; - void* stream; - char* buf; - size_t size; - size_t block_size; -} SerdByteSink; +typedef enum { + TO_BUFFER, ///< Writing to a user-provided buffer + TO_FILENAME, ///< Writing to a file we opened + TO_FILE, ///< Writing to a user-provided file + TO_FUNCTION, ///< Writing to a user-provided function +} SerdByteSinkType; -static inline SerdByteSink -serd_byte_sink_new(SerdWriteFunc sink, void* stream, size_t block_size) -{ - SerdByteSink bsink; - bsink.sink = sink; - bsink.stream = stream; - bsink.size = 0; - bsink.block_size = block_size; - bsink.buf = ((block_size > 1) - ? (char*)serd_bufalloc(block_size) - : NULL); - return bsink; -} - -static inline void -serd_byte_sink_flush(SerdByteSink* bsink) -{ - if (bsink->block_size > 1 && bsink->size > 0) { - bsink->sink(bsink->buf, 1, bsink->size, bsink->stream); - bsink->size = 0; - } -} - -static inline void -serd_byte_sink_free(SerdByteSink* bsink) -{ - serd_byte_sink_flush(bsink); - free(bsink->buf); - bsink->buf = NULL; -} +struct SerdByteSinkImpl { + SerdWriteFunc write_func; ///< User sink for TO_FUNCTION + void* stream; ///< Handle for TO_FILE* and TO_FUNCTION + char* buf; ///< Local buffer iff block_size > 1 + size_t size; ///< Bytes written so far in this chunk + size_t block_size; ///< Size of chunks to write + SerdByteSinkType type; ///< Type of output +}; static inline size_t -serd_byte_sink_write(const void* buf, size_t len, SerdByteSink* bsink) +serd_byte_sink_write(const void* buf, size_t len, SerdByteSink* const sink) { if (len == 0) { return 0; - } else if (bsink->block_size == 1) { - return bsink->sink(buf, 1, len, bsink->stream); + } else if (sink->block_size == 1) { + return sink->write_func(buf, 1, len, sink->stream); } const size_t orig_len = len; while (len) { - const size_t space = bsink->block_size - bsink->size; - const size_t n = MIN(space, len); + const size_t space = sink->block_size - sink->size; + const size_t n = space < len ? space : len; // Write as much as possible into the remaining buffer space - memcpy(bsink->buf + bsink->size, buf, n); - bsink->size += n; - buf = (const char*)buf + n; - len -= n; + memcpy(sink->buf + sink->size, buf, n); + sink->size += n; + buf = (const char*)buf + n; + len -= n; // Flush page if buffer is full - if (bsink->size == bsink->block_size) { - bsink->sink(bsink->buf, 1, bsink->block_size, bsink->stream); - bsink->size = 0; + if (sink->size == sink->block_size) { + sink->write_func(sink->buf, 1, sink->block_size, sink->stream); + sink->size = 0; } } + return orig_len; } -- cgit v1.2.1