summaryrefslogtreecommitdiff
path: root/upb/sink.c
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2013-12-20 17:40:40 -0800
committerJosh Haberman <jhaberman@gmail.com>2013-12-20 17:40:40 -0800
commitce9bba3cb5409844f8f3d7dcc235a9ea30cad090 (patch)
tree6c4e0a7c023c790a278f3616c749280c8da205af /upb/sink.c
parentaa8db6ab5ea18848247b8c4ac4715cf344941e94 (diff)
Sync from Google-internal development.
Diffstat (limited to 'upb/sink.c')
-rw-r--r--upb/sink.c413
1 files changed, 0 insertions, 413 deletions
diff --git a/upb/sink.c b/upb/sink.c
deleted file mode 100644
index 8f810ee..0000000
--- a/upb/sink.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * upb - a minimalist implementation of protocol buffers.
- *
- * Copyright (c) 2011-2012 Google Inc. See LICENSE for details.
- * Author: Josh Haberman <jhaberman@gmail.com>
- */
-
-#include "upb/sink.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-static void upb_sink_init(upb_sink *s, const upb_handlers *h, upb_pipeline *p);
-static void upb_sink_resetobj(void *obj);
-static const upb_frametype upb_sink_frametype;
-
-static bool chkstack(upb_sink *s) {
- if (s->top + 1 >= s->limit) {
- upb_status_seterrliteral(&s->pipeline_->status_, "Nesting too deep.");
- return false;
- } else {
- return true;
- }
-}
-
-#define alignof(type) offsetof (struct { char c; type member; }, member)
-
-typedef union { double u; void *p; long l; } maxalign_t;
-static const size_t maxalign = alignof(maxalign_t);
-
-static void *align_up(void *p) {
- if (!p) return NULL;
- uintptr_t val = (uintptr_t)p;
- uintptr_t aligned =
- val % maxalign == 0 ? val : val + maxalign - (val % maxalign);
- return (void*)aligned;
-}
-
-void *upb_realloc(void *ud, void *ptr, size_t size) {
- UPB_UNUSED(ud);
- return realloc(ptr, size);
-}
-
-
-/* upb_pipeline ***************************************************************/
-
-// For the moment we get fixed-size blocks of this size, but we could change
-// this strategy if necessary.
-#define BLOCK_SIZE 8192
-
-struct region {
- struct region *prev;
- maxalign_t data[1]; // Region data follows.
-};
-
-size_t regionsize(size_t usable_size) {
- return sizeof(struct region) - sizeof(maxalign_t) + usable_size;
-}
-
-struct obj {
- struct obj *prev;
- const upb_frametype *ft;
- maxalign_t data; // Region data follows.
-};
-
-size_t objsize(size_t memsize) {
- return sizeof(struct obj) - sizeof(maxalign_t) + memsize;
-}
-
-void upb_pipeline_init(upb_pipeline *p, void *initial_mem, size_t initial_size,
- void *(*realloc)(void *ud, void *ptr, size_t bytes),
- void *ud) {
- p->realloc = realloc;
- p->ud = ud;
- p->bump_top = initial_mem;
- p->bump_limit = initial_mem ? initial_mem + initial_size : NULL;
- p->region_head = NULL;
- p->obj_head = NULL;
- p->last_alloc = NULL;
- upb_status_init(&p->status_);
-}
-
-void upb_pipeline_uninit(upb_pipeline *p) {
- for (struct obj *o = p->obj_head; o; o = o->prev) {
- if (o->ft->uninit)
- o->ft->uninit(&o->data);
- }
-
- for (struct region *r = p->region_head; r; ) {
- struct region *prev = r->prev;
- p->realloc(p->ud, r, 0);
- r = prev;
- }
- upb_status_uninit(&p->status_);
-}
-
-void *upb_pipeline_alloc(upb_pipeline *p, size_t bytes) {
- void *mem = align_up(p->bump_top);
- if (!mem || mem > p->bump_limit || p->bump_limit - mem < bytes) {
- size_t size = regionsize(UPB_MAX(BLOCK_SIZE, bytes));
- struct region *r;
- if (!p->realloc || !(r = p->realloc(p->ud, NULL, size))) {
- return NULL;
- }
- r->prev = p->region_head;
- p->region_head = r;
- p->bump_limit = (char*)r + size;
- mem = &r->data[0];
- assert(p->bump_limit > mem);
- assert(p->bump_limit - mem >= bytes);
- }
- p->bump_top = mem + bytes;
- p->last_alloc = mem;
- return mem;
-}
-
-void *upb_pipeline_realloc(upb_pipeline *p, void *ptr,
- size_t oldsize, size_t bytes) {
- if (ptr && ptr == p->last_alloc &&
- p->bump_limit - ptr >= bytes) {
- p->bump_top = ptr + bytes;
- return ptr;
- } else {
- void *mem = upb_pipeline_alloc(p, bytes);
- memcpy(mem, ptr, oldsize);
- return mem;
- }
-}
-
-void *upb_pipeline_allocobj(upb_pipeline *p, const upb_frametype *ft) {
- struct obj *obj = upb_pipeline_alloc(p, objsize(ft->size));
- if (!obj) return NULL;
-
- obj->prev = p->obj_head;
- obj->ft = ft;
- p->obj_head = obj;
- if (ft->init) ft->init(&obj->data, p);
- return &obj->data;
-}
-
-void upb_pipeline_reset(upb_pipeline *p) {
- upb_status_clear(&p->status_);
- for (struct obj *o = p->obj_head; o; o = o->prev) {
- if (o->ft->reset)
- o->ft->reset(&o->data);
- }
-}
-
-upb_sink *upb_pipeline_newsink(upb_pipeline *p, const upb_handlers *handlers) {
- upb_sink *s = upb_pipeline_allocobj(p, &upb_sink_frametype);
- upb_sink_init(s, handlers, p);
- return s;
-}
-
-const upb_status *upb_pipeline_status(const upb_pipeline *p) {
- return &p->status_;
-}
-
-typedef struct {
- const upb_handlers *h;
-} handlersref_t;
-
-static void freehandlersref(void *r) {
- handlersref_t *ref = r;
- upb_handlers_unref(ref->h, &ref->h);
-}
-
-static const upb_frametype handlersref_frametype = {
- sizeof(handlersref_t),
- NULL,
- freehandlersref,
- NULL,
-};
-
-void upb_pipeline_donateref(
- upb_pipeline *p, const upb_handlers *h, const void *owner) {
- handlersref_t *ref = upb_pipeline_allocobj(p, &handlersref_frametype);
- upb_handlers_donateref(h, owner, &ref->h);
- ref->h = h;
-}
-
-
-/* upb_sink *******************************************************************/
-
-static const upb_frametype upb_sink_frametype = {
- sizeof(upb_sink),
- NULL,
- NULL,
- upb_sink_resetobj,
-};
-
-void upb_sink_reset(upb_sink *s, void *closure) {
- s->top = s->stack;
- s->top->closure = closure;
-}
-
-static void upb_sink_resetobj(void *obj) {
- upb_sink *s = obj;
- s->top = s->stack;
-}
-
-static void upb_sink_init(upb_sink *s, const upb_handlers *h, upb_pipeline *p) {
- s->pipeline_ = p;
- s->stack = upb_pipeline_alloc(p, sizeof(*s->stack) * UPB_SINK_MAX_NESTING);
- s->top = s->stack;
- s->limit = s->stack + UPB_SINK_MAX_NESTING;
- s->top->h = h;
- if (h->ft) {
- s->top->closure = upb_pipeline_allocobj(p, h->ft);
- }
-}
-
-upb_pipeline *upb_sink_pipeline(const upb_sink *s) {
- return s->pipeline_;
-}
-
-void *upb_sink_getobj(const upb_sink *s) {
- return s->stack[0].closure;
-}
-
-bool upb_sink_startmsg(upb_sink *s) {
- const upb_handlers *h = s->top->h;
- upb_startmsg_handler *startmsg =
- (upb_startmsg_handler *)upb_handlers_gethandler(h, UPB_STARTMSG_SELECTOR);
- if (startmsg) {
- const void *hd = upb_handlers_gethandlerdata(h, UPB_STARTMSG_SELECTOR);
- bool ok = startmsg(s->top->closure, hd);
- if (!ok) return false;
- }
- return true;
-}
-
-bool upb_sink_endmsg(upb_sink *s) {
- const upb_handlers *h = s->top->h;
- upb_endmsg_handler *endmsg =
- (upb_endmsg_handler *)upb_handlers_gethandler(h, UPB_ENDMSG_SELECTOR);
- if (endmsg) {
- const void *hd = upb_handlers_gethandlerdata(h, UPB_ENDMSG_SELECTOR);
- bool ok = endmsg(s->top->closure, hd, &s->pipeline_->status_);
- if (!ok) return false;
- }
- return true;
-}
-
-#define PUTVAL(type, ctype) \
- bool upb_sink_put ## type(upb_sink *s, upb_selector_t sel, ctype val) { \
- const upb_handlers *h = s->top->h; \
- upb_ ## type ## _handler *handler = (upb_ ## type ## _handler*) \
- upb_handlers_gethandler(h, sel); \
- if (handler) { \
- const void *hd = upb_handlers_gethandlerdata(h, sel); \
- bool ok = handler(s->top->closure, hd, val); \
- if (!ok) return false; \
- } \
- return true; \
- }
-
-PUTVAL(int32, int32_t);
-PUTVAL(int64, int64_t);
-PUTVAL(uint32, uint32_t);
-PUTVAL(uint64, uint64_t);
-PUTVAL(float, float);
-PUTVAL(double, double);
-PUTVAL(bool, bool);
-#undef PUTVAL
-
-size_t upb_sink_putstring(upb_sink *s, upb_selector_t sel,
- const char *buf, size_t n) {
- const upb_handlers *h = s->top->h;
- upb_string_handler *handler =
- (upb_string_handler*)upb_handlers_gethandler(h, sel);
-
- if (handler) {
- const void *hd = upb_handlers_gethandlerdata(h, sel);;
- n = handler(s->top->closure, hd, buf, n);
- }
-
- return n;
-}
-
-bool upb_sink_startseq(upb_sink *s, upb_selector_t sel) {
- if (!chkstack(s)) return false;
-
- void *subc = s->top->closure;
- const upb_handlers *h = s->top->h;
- upb_startfield_handler *startseq =
- (upb_startfield_handler*)upb_handlers_gethandler(h, sel);
-
- if (startseq) {
- const void *hd = upb_handlers_gethandlerdata(h, sel);
- subc = startseq(s->top->closure, hd);
- if (subc == UPB_BREAK) {
- return false;
- }
- }
-
- s->top->selector = upb_handlers_getendselector(sel);
- ++s->top;
- s->top->h = h;
- s->top->closure = subc;
- return true;
-}
-
-bool upb_sink_endseq(upb_sink *s, upb_selector_t sel) {
- --s->top;
- assert(sel == s->top->selector);
-
- const upb_handlers *h = s->top->h;
- upb_endfield_handler *endseq =
- (upb_endfield_handler*)upb_handlers_gethandler(h, sel);
-
- if (endseq) {
- const void *hd = upb_handlers_gethandlerdata(h, sel);
- bool ok = endseq(s->top->closure, hd);
- if (!ok) {
- ++s->top;
- return false;
- }
- }
-
- return true;
-}
-
-bool upb_sink_startstr(upb_sink *s, upb_selector_t sel, size_t size_hint) {
- if (!chkstack(s)) return false;
-
- void *subc = s->top->closure;
- const upb_handlers *h = s->top->h;
- upb_startstr_handler *startstr =
- (upb_startstr_handler*)upb_handlers_gethandler(h, sel);
-
- if (startstr) {
- const void *hd = upb_handlers_gethandlerdata(h, sel);
- subc = startstr(s->top->closure, hd, size_hint);
- if (subc == UPB_BREAK) {
- return false;
- }
- }
-
- s->top->selector = upb_handlers_getendselector(sel);
- ++s->top;
- s->top->h = h;
- s->top->closure = subc;
- return true;
-}
-
-bool upb_sink_endstr(upb_sink *s, upb_selector_t sel) {
- --s->top;
- assert(sel == s->top->selector);
- const upb_handlers *h = s->top->h;
- upb_endfield_handler *endstr =
- (upb_endfield_handler*)upb_handlers_gethandler(h, sel);
-
- if (endstr) {
- const void *hd = upb_handlers_gethandlerdata(h, sel);
- bool ok = endstr(s->top->closure, hd);
- if (!ok) {
- ++s->top;
- return false;
- }
- }
-
- return true;
-}
-
-bool upb_sink_startsubmsg(upb_sink *s, upb_selector_t sel) {
- if (!chkstack(s)) return false;
-
- void *subc = s->top->closure;
- const upb_handlers *h = s->top->h;
- upb_startfield_handler *startsubmsg =
- (upb_startfield_handler*)upb_handlers_gethandler(h, sel);
-
- if (startsubmsg) {
- const void *hd = upb_handlers_gethandlerdata(h, sel);
- subc = startsubmsg(s->top->closure, hd);
- if (subc == UPB_BREAK) {
- return false;
- }
- }
-
- s->top->selector= upb_handlers_getendselector(sel);
- ++s->top;
- s->top->h = upb_handlers_getsubhandlers_sel(h, sel);
- // TODO: should add support for submessages without any handlers
- assert(s->top->h);
- s->top->closure = subc;
- return true;
-}
-
-bool upb_sink_endsubmsg(upb_sink *s, upb_selector_t sel) {
- --s->top;
-
- assert(sel == s->top->selector);
- const upb_handlers *h = s->top->h;
- upb_endfield_handler *endsubmsg =
- (upb_endfield_handler*)upb_handlers_gethandler(h, sel);
-
- if (endsubmsg) {
- const void *hd = upb_handlers_gethandlerdata(h, sel);
- bool ok = endsubmsg(s->top->closure, hd);
- if (!ok) {
- ++s->top;
- return false;
- }
- }
-
- return true;
-}
-
-const upb_handlers *upb_sink_tophandlers(upb_sink *s) {
- return s->top->h;
-}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback