summaryrefslogtreecommitdiff
path: root/core/upb_stream_vtbl.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/upb_stream_vtbl.h')
-rw-r--r--core/upb_stream_vtbl.h110
1 files changed, 101 insertions, 9 deletions
diff --git a/core/upb_stream_vtbl.h b/core/upb_stream_vtbl.h
index ba2670e..96f6cfe 100644
--- a/core/upb_stream_vtbl.h
+++ b/core/upb_stream_vtbl.h
@@ -5,6 +5,21 @@
* interfaces. Only components that are implementing these interfaces need
* to worry about this file.
*
+ * This is tedious; this is the place in upb where I most wish I had a C++
+ * feature. In C++ the compiler would generate this all for me. If there's
+ * any consolation, it's that I have a bit of flexibility you don't have in
+ * C++: I could, with preprocessor magic alone "de-virtualize" this interface
+ * for a particular source file. Say I had a C file that called a upb_src,
+ * but didn't want to pay the virtual function overhead. I could define:
+ *
+ * #define upb_src_getdef(src) upb_decoder_getdef((upb_decoder*)src)
+ * #define upb_src_stargmsg(src) upb_decoder_startmsg(upb_decoder*)src)
+ * // etc.
+ *
+ * The source file is compatible with the regular upb_src interface, but here
+ * we bind it to a particular upb_src (upb_decoder), which could lead to
+ * improved performance at a loss of flexibility for this one upb_src client.
+ *
* Copyright (c) 2010 Joshua Haberman. See LICENSE for details.
*/
@@ -39,12 +54,13 @@ typedef bool (*upb_src_endmsg_fptr)(upb_src *src);
// upb_sink.
typedef bool (*upb_sink_putdef_fptr)(upb_sink *sink, struct _upb_fielddef *def);
typedef bool (*upb_sink_putval_fptr)(upb_sink *sink, upb_value val);
+typedef bool (*upb_sink_putstr_fptr)(upb_sink *sink, upb_string *str);
typedef bool (*upb_sink_startmsg_fptr)(upb_sink *sink);
typedef bool (*upb_sink_endmsg_fptr)(upb_sink *sink);
// upb_bytesrc.
-typedef upb_string *(*upb_bytesrc_get_fptr)(upb_bytesrc *src);
-typedef void (*upb_bytesrc_recycle_fptr)(upb_bytesrc *src, upb_string *str);
+typedef bool (*upb_bytesrc_get_fptr)(
+ upb_bytesrc *src, upb_string *str, upb_strlen_t minlen);
typedef bool (*upb_bytesrc_append_fptr)(
upb_bytesrc *src, upb_string *str, upb_strlen_t len);
@@ -62,11 +78,22 @@ typedef struct {
} upb_src_vtable;
typedef struct {
+ upb_sink_putdef_fptr putdef;
+ upb_sink_putval_fptr putval;
+ upb_sink_putstr_fptr putstr;
+ upb_sink_startmsg_fptr startmsg;
+ upb_sink_endmsg_fptr endmsg;
+} upb_sink_vtable;
+
+typedef struct {
upb_bytesrc_get_fptr get;
upb_bytesrc_append_fptr append;
- upb_bytesrc_recycle_fptr recycle;
} upb_bytesrc_vtable;
+typedef struct {
+ upb_bytesink_put_fptr put;
+} upb_bytesink_vtable;
+
// "Base Class" definitions; components that implement these interfaces should
// contain one of these structures.
@@ -74,9 +101,12 @@ struct upb_src {
upb_src_vtable *vtbl;
upb_status status;
bool eof;
-#ifndef NDEBUG
- int state; // For debug-mode checking of API usage.
-#endif
+};
+
+struct upb_sink {
+ upb_sink_vtable *vtbl;
+ upb_status status;
+ bool eof;
};
struct upb_bytesrc {
@@ -85,13 +115,34 @@ struct upb_bytesrc {
bool eof;
};
+struct upb_bytesink {
+ upb_bytesink_vtable *vtbl;
+ upb_status status;
+ bool eof;
+};
+
INLINE void upb_src_init(upb_src *s, upb_src_vtable *vtbl) {
s->vtbl = vtbl;
s->eof = false;
upb_status_init(&s->status);
-#ifndef DEBUG
- // TODO: initialize debug-mode checking.
-#endif
+}
+
+INLINE void upb_sink_init(upb_sink *s, upb_sink_vtable *vtbl) {
+ s->vtbl = vtbl;
+ s->eof = false;
+ upb_status_init(&s->status);
+}
+
+INLINE void upb_bytesrc_init(upb_bytesrc *s, upb_bytesrc_vtable *vtbl) {
+ s->vtbl = vtbl;
+ s->eof = false;
+ upb_status_init(&s->status);
+}
+
+INLINE void upb_bytesink_init(upb_bytesink *s, upb_bytesink_vtable *vtbl) {
+ s->vtbl = vtbl;
+ s->eof = false;
+ upb_status_init(&s->status);
}
// Implementation of virtual function dispatch.
@@ -136,6 +187,47 @@ bool upb_src_getuint64(upb_src *src, uint64_t *val);
bool upb_src_getfloat(upb_src *src, float *val);
bool upb_src_getdouble(upb_src *src, double *val);
+// upb_bytesrc
+INLINE bool upb_bytesrc_get(
+ upb_bytesrc *bytesrc, upb_string *str, upb_strlen_t minlen) {
+ return bytesrc->vtbl->get(bytesrc, str, minlen);
+}
+
+INLINE bool upb_bytesrc_append(
+ upb_bytesrc *bytesrc, upb_string *str, upb_strlen_t len) {
+ return bytesrc->vtbl->append(bytesrc, str, len);
+}
+
+// upb_sink
+INLINE bool upb_sink_putdef(upb_sink *sink, struct _upb_fielddef *def) {
+ return sink->vtbl->putdef(sink, def);
+}
+INLINE bool upb_sink_putval(upb_sink *sink, upb_value val) {
+ return sink->vtbl->putval(sink, val);
+}
+INLINE bool upb_sink_putstr(upb_sink *sink, upb_string *str) {
+ return sink->vtbl->putstr(sink, str);
+}
+INLINE bool upb_sink_startmsg(upb_sink *sink) {
+ return sink->vtbl->startmsg(sink);
+}
+INLINE bool upb_sink_endmsg(upb_sink *sink) {
+ return sink->vtbl->endmsg(sink);
+}
+
+INLINE upb_status *upb_sink_status(upb_sink *sink) { return &sink->status; }
+
+// upb_bytesink
+INLINE int32_t upb_bytesink_put(upb_bytesink *sink, upb_string *str) {
+ return sink->vtbl->put(sink, str);
+}
+INLINE upb_status *upb_bytesink_status(upb_bytesink *sink) {
+ return &sink->status;
+}
+
+// upb_bytesink
+
+
#ifdef __cplusplus
} /* extern "C" */
#endif
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback