summaryrefslogtreecommitdiff
path: root/src/runtime/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
parent537bc249f966064ea0b68e6c1bf1d26e63f0524e (diff)
more compact implementation for GuStringBuf
Diffstat (limited to 'src/runtime/c')
-rw-r--r--src/runtime/c/gu/seq.c63
-rw-r--r--src/runtime/c/gu/seq.h11
-rw-r--r--src/runtime/c/gu/string.c43
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;
}