From 1bcab1377de6afe8c0f9c895cdba04baacf3e4a5 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 22 Dec 2011 11:37:01 -0800 Subject: Sync with internal Google development. This breaks the open-source build, will follow up with a change to fix it. --- upb/pb/decoder.h | 102 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 25 deletions(-) (limited to 'upb/pb/decoder.h') diff --git a/upb/pb/decoder.h b/upb/pb/decoder.h index c35bec4..13e5774 100644 --- a/upb/pb/decoder.h +++ b/upb/pb/decoder.h @@ -21,15 +21,43 @@ extern "C" { #endif -/* upb_decoder *****************************************************************/ +/* upb_decoderplan ************************************************************/ + +// A decoderplan contains whatever data structures and generated (JIT-ted) code +// are necessary to decode protobuf data of a specific type to a specific set +// of handlers. By generating the plan ahead of time, we avoid having to +// redo this work every time we decode. +// +// A decoderplan is threadsafe, meaning that it can be used concurrently by +// different upb_decoders in different threads. However, the upb_decoders are +// *not* thread-safe. +struct _upb_decoderplan; +typedef struct _upb_decoderplan upb_decoderplan; + +// TODO: add parameter for a list of other decoder plans that we can share +// generated code with. +upb_decoderplan *upb_decoderplan_new(upb_handlers *h, bool allowjit); +void upb_decoderplan_unref(upb_decoderplan *p); + +// Returns true if the plan contains JIT-ted code. This may not be the same as +// the "allowjit" parameter to the constructor if support for JIT-ting was not +// compiled in. +bool upb_decoderplan_hasjitcode(upb_decoderplan *p); + + +/* upb_decoder ****************************************************************/ struct dasm_State; typedef struct _upb_decoder { - upb_byteregion *input; // Input data (serialized). - upb_dispatcher dispatcher; // Dispatcher to which we push parsed data. - upb_status *status; // Where we will store any errors that occur. - upb_byteregion str_byteregion; // For passing string data to callbacks. + upb_decoderplan *plan; + int msg_offset; // Which message from the plan is top-level. + upb_byteregion *input; // Input data (serialized), not owned. + upb_dispatcher dispatcher; // Dispatcher to which we push parsed data. + upb_status status; // Where we store errors that occur. + upb_byteregion str_byteregion; // For passing string data to callbacks. + + upb_inttable *dispatch_table; // Current input buffer and its stream offset. const char *buf, *ptr, *end; @@ -37,40 +65,64 @@ typedef struct _upb_decoder { // End of the delimited region, relative to ptr, or NULL if not in this buf. const char *delim_end; + // True if the top stack frame represents a packed field. bool top_is_packed; #ifdef UPB_USE_JIT_X64 // For JIT, which doesn't do bounds checks in the middle of parsing a field. const char *jit_end, *effective_end; // == MIN(jit_end, submsg_end) - - // JIT-generated machine code (else NULL). - char *jit_code; - size_t jit_size; - char *debug_info; - - struct dasm_State *dynasm; #endif // For exiting the decoder on error. sigjmp_buf exitjmp; } upb_decoder; -// Initializes/uninitializes a decoder for calling into the given handlers -// or to write into the given msgdef, given its accessors). Takes a ref -// on the handlers. -void upb_decoder_init(upb_decoder *d, upb_handlers *h); +void upb_decoder_init(upb_decoder *d); void upb_decoder_uninit(upb_decoder *d); -// Resets the internal state of an already-allocated decoder. This puts it in a -// state where it has not seen any data, and expects the next data to be from -// the beginning of a new protobuf. Decoders must be reset before they can be -// used. A decoder can be reset multiple times. "input" must live until the -// decoder is reset again (or destroyed). -void upb_decoder_reset(upb_decoder *d, upb_byteregion *input, void *closure); +// Resets the plan that the decoder will parse from. "msg_offset" indicates +// which message from the plan will be used as the top-level message. +// +// This will also reset the decoder's input to be uninitialized -- +// upb_decoder_resetinput() must be called before parsing can occur. The plan +// must live until the decoder is destroyed or reset to a different plan. +// +// Must be called before upb_decoder_resetinput() or upb_decoder_decode(). +void upb_decoder_resetplan(upb_decoder *d, upb_decoderplan *p, int msg_offset); + +// Resets the input of an already-allocated decoder. This puts it in a state +// where it has not seen any data, and expects the next data to be from the +// beginning of a new protobuf. Decoders must have their input reset before +// they can be used. A decoder can have its input reset multiple times. +// "input" must live until the decoder is destroyed or has it input reset +// again. "c" is the closure that will be passed to the handlers. +// +// Must be called before upb_decoder_decode(). +void upb_decoder_resetinput(upb_decoder *d, upb_byteregion *input, void *c); + +// Decodes serialized data (calling handlers as the data is parsed), returning +// the success of the operation (call upb_decoder_status() for details). +upb_success_t upb_decoder_decode(upb_decoder *d); + +INLINE const upb_status *upb_decoder_status(upb_decoder *d) { + return &d->status; +} + +// Implementation details + +struct _upb_decoderplan { + upb_handlers *handlers; // owns reference. + +#ifdef UPB_USE_JIT_X64 + // JIT-generated machine code (else NULL). + char *jit_code; + size_t jit_size; + char *debug_info; -// Decodes serialized data (calling handlers as the data is parsed) until error -// or EOF (see *status for details). -void upb_decoder_decode(upb_decoder *d, upb_status *status); + // This pointer is allocated by dasm_init() and freed by dasm_free(). + struct dasm_State *dynasm; +#endif +}; #ifdef __cplusplus } /* extern "C" */ -- cgit v1.2.3