diff options
Diffstat (limited to 'src/runtime/c')
| -rw-r--r-- | src/runtime/c/gu/seq.c | 63 | ||||
| -rw-r--r-- | src/runtime/c/gu/seq.h | 11 | ||||
| -rw-r--r-- | src/runtime/c/gu/string.c | 43 |
3 files changed, 46 insertions, 71 deletions
diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c index a923081b3..88b762a04 100644 --- a/src/runtime/c/gu/seq.c +++ b/src/runtime/c/gu/seq.c @@ -100,7 +100,7 @@ gu_seq_free(GuSeq* seq) gu_mem_buf_free(seq); } -static void +void gu_buf_require(GuBuf* buf, size_t req_len) { if (req_len <= buf->avail_len) { @@ -364,64 +364,3 @@ gu_buf_heapify(GuBuf *buf, GuOrder *order) gu_heap_siftup(buf, order, value, i); } } - -typedef struct GuBufOut GuBufOut; -struct GuBufOut -{ - GuOutStream stream; - GuBuf* buf; -}; - -static size_t -gu_buf_out_output(GuOutStream* stream, const uint8_t* src, size_t sz, - GuExn* err) -{ - (void) err; - GuBufOut* bout = gu_container(stream, GuBufOut, stream); - GuBuf* buf = bout->buf; - gu_assert(sz % buf->elem_size == 0); - size_t len = sz / buf->elem_size; - gu_buf_push_n(bout->buf, src, len); - return len; -} - -static uint8_t* -gu_buf_outbuf_begin(GuOutStream* stream, size_t req, size_t* sz_out, GuExn* err) -{ - (void) req; - (void) err; - GuBufOut* bout = gu_container(stream, GuBufOut, stream); - GuBuf* buf = bout->buf; - size_t esz = buf->elem_size; - size_t len = gu_buf_length(buf); - gu_buf_require(buf, len + (req + esz - 1) / esz); - size_t avail = buf->avail_len; - gu_assert(len < avail); - *sz_out = esz * (avail - len); - return &buf->seq->data[len * esz]; -} - -static void -gu_buf_outbuf_end(GuOutStream* stream, size_t sz, GuExn* err) -{ - (void) err; - GuBufOut* bout = gu_container(stream, GuBufOut, stream); - GuBuf* buf = bout->buf; - size_t len = gu_buf_length(buf); - size_t elem_size = buf->elem_size; - gu_require(sz % elem_size == 0); - gu_require(sz < elem_size * (len - buf->avail_len)); - buf->seq->len = len + (sz / elem_size); -} - -GuOut* -gu_buf_out(GuBuf* buf, GuPool* pool) -{ - GuBufOut* bout = gu_new(GuBufOut, pool); - bout->stream.output = gu_buf_out_output; - bout->stream.begin_buf = gu_buf_outbuf_begin; - bout->stream.end_buf = gu_buf_outbuf_end; - bout->stream.flush = NULL; - bout->buf = buf; - return gu_new_out(&bout->stream, pool); -} diff --git a/src/runtime/c/gu/seq.h b/src/runtime/c/gu/seq.h index a555f0bad..f7446728e 100644 --- a/src/runtime/c/gu/seq.h +++ b/src/runtime/c/gu/seq.h @@ -178,10 +178,7 @@ GuSeq* gu_buf_freeze(GuBuf* buf, GuPool* pool); #endif // GU_SEQ_H_ -#if defined(GU_OUT_H_) && !defined(GU_SEQ_H_OUT_) -#define GU_SEQ_H_OUT_ - -GuOut* -gu_buf_out(GuBuf* buf, GuPool* pool); - -#endif +#ifdef GU_STRING_H_ +void +gu_buf_require(GuBuf* buf, size_t req_len); +#endif // GU_STRING_H_ diff --git a/src/runtime/c/gu/string.c b/src/runtime/c/gu/string.c index 3a61a33c2..d380fca49 100644 --- a/src/runtime/c/gu/string.c +++ b/src/runtime/c/gu/string.c @@ -1,7 +1,7 @@ #include <gu/out.h> -#include <gu/seq.h> #include <gu/map.h> #include <gu/string.h> +#include <gu/seq.h> #include <gu/utf8.h> #include <gu/assert.h> #include <stdlib.h> @@ -10,16 +10,55 @@ #endif struct GuStringBuf { + GuOutStream stream; GuBuf* buf; GuOut* out; }; +static size_t +gu_string_buf_output(GuOutStream* stream, const uint8_t* src, size_t sz, + GuExn* err) +{ + (void) err; + GuStringBuf* sbuf = gu_container(stream, GuStringBuf, stream); + gu_buf_push_n(sbuf->buf, src, sz); + return sz; +} + +static uint8_t* +gu_string_buf_begin(GuOutStream* stream, size_t req, size_t* sz_out, GuExn* err) +{ + (void) req; + (void) err; + GuStringBuf* sbuf = gu_container(stream, GuStringBuf, stream); + size_t len = gu_buf_length(sbuf->buf); + gu_buf_require(sbuf->buf, len + req); + size_t avail = sbuf->buf->avail_len; + gu_assert(len < avail); + *sz_out = (avail - len); + return (uint8_t*) gu_buf_index(sbuf->buf, char, len); +} + +static void +gu_string_buf_end(GuOutStream* stream, size_t sz, GuExn* err) +{ + (void) err; + GuStringBuf* sbuf = gu_container(stream, GuStringBuf, stream); + size_t len = gu_buf_length(sbuf->buf); + gu_require(sz < len - sbuf->buf->avail_len); + sbuf->buf->seq->len = len + sz; +} + GuStringBuf* gu_string_buf(GuPool* pool) { GuStringBuf* sbuf = gu_new(GuStringBuf, pool); + sbuf->stream.output = gu_string_buf_output; + sbuf->stream.begin_buf = gu_string_buf_begin; + sbuf->stream.end_buf = gu_string_buf_end; + sbuf->stream.flush = NULL; sbuf->buf = gu_new_buf(char, pool); - sbuf->out = gu_buf_out(sbuf->buf, pool); + sbuf->out = gu_new_out(&sbuf->stream, pool); return sbuf; } |
