summaryrefslogtreecommitdiff
path: root/upb/sink.c
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2016-12-14 12:22:06 -0800
committerGitHub <noreply@github.com>2016-12-14 12:22:06 -0800
commitd5d2eadee5ef2348866d34b3d6e4a616c09576b9 (patch)
tree30e4ed2ea864c824fd137d7f783fd51ef66ee2bb /upb/sink.c
parent076a82ee7edf35fb5f2a3430535e21a6dbd4cd6d (diff)
parent6cccfe16493c9c88ea198ca37af915179ccf7eaf (diff)
Merge pull request #75 from haberman/msg
Basic serialization for upb_msg and Lua.
Diffstat (limited to 'upb/sink.c')
-rw-r--r--upb/sink.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/upb/sink.c b/upb/sink.c
new file mode 100644
index 0000000..e6ede49
--- /dev/null
+++ b/upb/sink.c
@@ -0,0 +1,89 @@
+
+#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_ASSERT(new_size > 0);
+ 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