From 87b2c69c15716b96a294f5918878fb8b7b9a0b40 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 17 Jul 2010 12:56:04 -0700 Subject: Fleshed out upb_stdio and upb_textprinter. test_decoder now compiles and links! But it doesn't work yet. --- core/upb_stream.h | 5 ++- core/upb_stream_vtbl.h | 110 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 105 insertions(+), 10 deletions(-) (limited to 'core') diff --git a/core/upb_stream.h b/core/upb_stream.h index 9147e45..b7400c5 100644 --- a/core/upb_stream.h +++ b/core/upb_stream.h @@ -111,7 +111,10 @@ bool upb_sink_putdef(upb_sink *sink, struct _upb_fielddef *def); bool upb_sink_putval(upb_sink *sink, upb_value val); bool upb_sink_putstr(upb_sink *sink, upb_string *str); -// Ends a submessage. +// Starts/ends a submessage. upb_sink_startmsg may seem redundant, but a +// client could have a submessage already serialized, and therefore put it +// as a string instead of its individual elements. +bool upb_sink_startmsg(upb_sink *sink); bool upb_sink_endmsg(upb_sink *sink); // Returns the current error status for the stream. 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); @@ -61,12 +77,23 @@ typedef struct { upb_src_endmsg_fptr endmsg; } 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 -- cgit v1.2.3