summaryrefslogtreecommitdiff
path: root/upb/sink.c
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2016-12-12 18:47:55 +0000
committerJosh Haberman <jhaberman@gmail.com>2016-12-12 18:52:20 +0000
commit15c388b819ebfebb83851950893413041288970f (patch)
tree2c266da71bda82fdcc641f4af9bf0e406396f49f /upb/sink.c
parent076a82ee7edf35fb5f2a3430535e21a6dbd4cd6d (diff)
Basic serialization for upb_msg and Lua.
Doesn't yet include strings, submessages, maps, or repeated fields.
Diffstat (limited to 'upb/sink.c')
-rw-r--r--upb/sink.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/upb/sink.c b/upb/sink.c
new file mode 100644
index 0000000..ed0972b
--- /dev/null
+++ b/upb/sink.c
@@ -0,0 +1,88 @@
+
+#include "upb/sink.h"
+
+bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink *sink) {
+ void *subc;
+ bool ret;
+ upb_bufhandle handle;
+ upb_bufhandle_init(&handle);
+ upb_bufhandle_setbuf(&handle, buf, 0);
+ ret = upb_bytessink_start(sink, len, &subc);
+ if (ret && len != 0) {
+ ret = (upb_bytessink_putbuf(sink, subc, buf, len, &handle) >= len);
+ }
+ if (ret) {
+ ret = upb_bytessink_end(sink);
+ }
+ upb_bufhandle_uninit(&handle);
+ return ret;
+}
+
+struct upb_bufsink {
+ upb_byteshandler handler;
+ upb_bytessink sink;
+ upb_env *env;
+ char *ptr;
+ size_t len, size;
+};
+
+static void *upb_bufsink_start(void *_sink, const void *hd, size_t size_hint) {
+ upb_bufsink *sink = _sink;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(size_hint);
+ sink->len = 0;
+ return sink;
+}
+
+static size_t upb_bufsink_string(void *_sink, const void *hd, const char *ptr,
+ size_t len, const upb_bufhandle *handle) {
+ upb_bufsink *sink = _sink;
+ size_t new_size = sink->size;
+
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ while (sink->len + len > new_size) {
+ new_size *= 2;
+ }
+
+ if (new_size != sink->size) {
+ sink->ptr = upb_env_realloc(sink->env, sink->ptr, sink->size, new_size);
+ sink->size = new_size;
+ }
+
+ memcpy(sink->ptr + sink->len, ptr, len);
+ sink->len += len;
+
+ return len;
+}
+
+upb_bufsink *upb_bufsink_new(upb_env *env) {
+ upb_bufsink *sink = upb_env_malloc(env, sizeof(upb_bufsink));
+ upb_byteshandler_init(&sink->handler);
+ upb_byteshandler_setstartstr(&sink->handler, upb_bufsink_start, NULL);
+ upb_byteshandler_setstring(&sink->handler, upb_bufsink_string, NULL);
+
+ upb_bytessink_reset(&sink->sink, &sink->handler, sink);
+
+ sink->env = env;
+ sink->size = 32;
+ sink->ptr = upb_env_malloc(env, sink->size);
+ sink->len = 0;
+
+ return sink;
+}
+
+void upb_bufsink_free(upb_bufsink *sink) {
+ upb_env_free(sink->env, sink->ptr);
+ upb_env_free(sink->env, sink);
+}
+
+upb_bytessink *upb_bufsink_sink(upb_bufsink *sink) {
+ return &sink->sink;
+}
+
+const char *upb_bufsink_getdata(const upb_bufsink *sink, size_t *len) {
+ *len = sink->len;
+ return sink->ptr;
+}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback