summaryrefslogtreecommitdiff
path: root/src/runtime/c/gu/string.c
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2014-12-24 14:20:30 +0000
committerkr.angelov <kr.angelov@gmail.com>2014-12-24 14:20:30 +0000
commit8fd24c3839e7d171e0c4170ae17b26c7ff5aec1b (patch)
tree5a6d6c94bf4ca039bdac1b9ce0287ba0d00de0d0 /src/runtime/c/gu/string.c
parent537bc249f966064ea0b68e6c1bf1d26e63f0524e (diff)
more compact implementation for GuStringBuf
Diffstat (limited to 'src/runtime/c/gu/string.c')
-rw-r--r--src/runtime/c/gu/string.c43
1 files changed, 41 insertions, 2 deletions
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;
}