mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-20 00:22:51 -06:00
more compact implementation for GuStringBuf
This commit is contained in:
@@ -100,7 +100,7 @@ gu_seq_free(GuSeq* seq)
|
|||||||
gu_mem_buf_free(seq);
|
gu_mem_buf_free(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
gu_buf_require(GuBuf* buf, size_t req_len)
|
gu_buf_require(GuBuf* buf, size_t req_len)
|
||||||
{
|
{
|
||||||
if (req_len <= buf->avail_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);
|
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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -178,10 +178,7 @@ GuSeq*
|
|||||||
gu_buf_freeze(GuBuf* buf, GuPool* pool);
|
gu_buf_freeze(GuBuf* buf, GuPool* pool);
|
||||||
#endif // GU_SEQ_H_
|
#endif // GU_SEQ_H_
|
||||||
|
|
||||||
#if defined(GU_OUT_H_) && !defined(GU_SEQ_H_OUT_)
|
#ifdef GU_STRING_H_
|
||||||
#define GU_SEQ_H_OUT_
|
void
|
||||||
|
gu_buf_require(GuBuf* buf, size_t req_len);
|
||||||
GuOut*
|
#endif // GU_STRING_H_
|
||||||
gu_buf_out(GuBuf* buf, GuPool* pool);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <gu/out.h>
|
#include <gu/out.h>
|
||||||
#include <gu/seq.h>
|
|
||||||
#include <gu/map.h>
|
#include <gu/map.h>
|
||||||
#include <gu/string.h>
|
#include <gu/string.h>
|
||||||
|
#include <gu/seq.h>
|
||||||
#include <gu/utf8.h>
|
#include <gu/utf8.h>
|
||||||
#include <gu/assert.h>
|
#include <gu/assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -10,16 +10,55 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct GuStringBuf {
|
struct GuStringBuf {
|
||||||
|
GuOutStream stream;
|
||||||
GuBuf* buf;
|
GuBuf* buf;
|
||||||
GuOut* out;
|
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*
|
GuStringBuf*
|
||||||
gu_string_buf(GuPool* pool)
|
gu_string_buf(GuPool* pool)
|
||||||
{
|
{
|
||||||
GuStringBuf* sbuf = gu_new(GuStringBuf, 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->buf = gu_new_buf(char, pool);
|
||||||
sbuf->out = gu_buf_out(sbuf->buf, pool);
|
sbuf->out = gu_new_out(&sbuf->stream, pool);
|
||||||
return sbuf;
|
return sbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user