summaryrefslogtreecommitdiff
path: root/upb/pb/decoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'upb/pb/decoder.h')
-rw-r--r--upb/pb/decoder.h294
1 files changed, 111 insertions, 183 deletions
diff --git a/upb/pb/decoder.h b/upb/pb/decoder.h
index 7c1877a..709db49 100644
--- a/upb/pb/decoder.h
+++ b/upb/pb/decoder.h
@@ -21,20 +21,13 @@
namespace upb {
namespace pb {
class CodeCache;
-class Decoder;
-class DecoderMethod;
+class DecoderPtr;
+class DecoderMethodPtr;
class DecoderMethodOptions;
} /* namespace pb */
} /* namespace upb */
#endif
-UPB_DECLARE_TYPE(upb::pb::CodeCache, upb_pbcodecache)
-UPB_DECLARE_TYPE(upb::pb::Decoder, upb_pbdecoder)
-UPB_DECLARE_TYPE(upb::pb::DecoderMethodOptions, upb_pbdecodermethodopts)
-
-UPB_DECLARE_DERIVED_TYPE(upb::pb::DecoderMethod, upb::RefCounted,
- upb_pbdecodermethod, upb_refcounted)
-
/* The maximum number of bytes we are required to buffer internally between
* calls to the decoder. The value is 14: a 5 byte unknown tag plus ten-byte
* varint, less one because we are buffering an incomplete value.
@@ -42,83 +35,111 @@ UPB_DECLARE_DERIVED_TYPE(upb::pb::DecoderMethod, upb::RefCounted,
* Should only be used by unit tests. */
#define UPB_DECODER_MAX_RESIDUAL_BYTES 14
-#ifdef __cplusplus
+/* upb_pbdecodermethod ********************************************************/
-/* The parameters one uses to construct a DecoderMethod.
- * TODO(haberman): move allowjit here? Seems more convenient for users.
- * TODO(haberman): move this to be heap allocated for ABI stability. */
-class upb::pb::DecoderMethodOptions {
- public:
- /* Parameter represents the destination handlers that this method will push
- * to. */
- explicit DecoderMethodOptions(const Handlers* dest_handlers);
+struct upb_pbdecodermethod;
+typedef struct upb_pbdecodermethod upb_pbdecodermethod;
- /* Should the decoder push submessages to lazy handlers for fields that have
- * them? The caller should set this iff the lazy handlers expect data that is
- * in protobuf binary format and the caller wishes to lazy parse it. */
- void set_lazy(bool lazy);
-#else
-struct upb_pbdecodermethodopts {
+#ifdef __cplusplus
+extern "C" {
#endif
- const upb_handlers *handlers;
- bool lazy;
-};
+
+const upb_handlers *upb_pbdecodermethod_desthandlers(
+ const upb_pbdecodermethod *m);
+const upb_byteshandler *upb_pbdecodermethod_inputhandler(
+ const upb_pbdecodermethod *m);
+bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m);
#ifdef __cplusplus
+} /* extern "C" */
/* Represents the code to parse a protobuf according to a destination
* Handlers. */
-class upb::pb::DecoderMethod {
+class upb::pb::DecoderMethodPtr {
public:
- /* Include base methods from upb::ReferenceCounted. */
- UPB_REFCOUNTED_CPPMETHODS
+ DecoderMethodPtr() : ptr_(nullptr) {}
+ DecoderMethodPtr(const upb_pbdecodermethod* ptr) : ptr_(ptr) {}
+
+ const upb_pbdecodermethod* ptr() { return ptr_; }
/* The destination handlers that are statically bound to this method.
* This method is only capable of outputting to a sink that uses these
* handlers. */
- const Handlers* dest_handlers() const;
+ const Handlers *dest_handlers() const {
+ return upb_pbdecodermethod_desthandlers(ptr_);
+ }
/* The input handlers for this decoder method. */
- const BytesHandler* input_handler() const;
+ const BytesHandler* input_handler() const {
+ return upb_pbdecodermethod_inputhandler(ptr_);
+ }
/* Whether this method is native. */
- bool is_native() const;
-
- /* Convenience method for generating a DecoderMethod without explicitly
- * creating a CodeCache. */
- static reffed_ptr<const DecoderMethod> New(const DecoderMethodOptions& opts);
+ bool is_native() const {
+ return upb_pbdecodermethod_isnative(ptr_);
+ }
private:
- UPB_DISALLOW_POD_OPS(DecoderMethod, upb::pb::DecoderMethod)
+ const upb_pbdecodermethod* ptr_;
};
#endif
+/* upb_pbdecoder **************************************************************/
+
/* Preallocation hint: decoder won't allocate more bytes than this when first
* constructed. This hint may be an overestimate for some build configurations.
* But if the decoder library is upgraded without recompiling the application,
* it may be an underestimate. */
#define UPB_PB_DECODER_SIZE 4416
+struct upb_pbdecoder;
+typedef struct upb_pbdecoder upb_pbdecoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+upb_pbdecoder *upb_pbdecoder_create(upb_arena *arena,
+ const upb_pbdecodermethod *method,
+ upb_sink output, upb_status *status);
+const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d);
+upb_bytessink upb_pbdecoder_input(upb_pbdecoder *d);
+uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d);
+size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d);
+bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max);
+void upb_pbdecoder_reset(upb_pbdecoder *d);
+
#ifdef __cplusplus
+} /* extern "C" */
/* A Decoder receives binary protobuf data on its input sink and pushes the
* decoded data to its output sink. */
-class upb::pb::Decoder {
+class upb::pb::DecoderPtr {
public:
+ DecoderPtr() : ptr_(nullptr) {}
+ DecoderPtr(upb_pbdecoder* ptr) : ptr_(ptr) {}
+
+ upb_pbdecoder* ptr() { return ptr_; }
+
/* Constructs a decoder instance for the given method, which must outlive this
* decoder. Any errors during parsing will be set on the given status, which
* must also outlive this decoder.
*
* The sink must match the given method. */
- static Decoder* Create(Environment* env, const DecoderMethod* method,
- Sink* output);
+ static DecoderPtr Create(Arena *arena, DecoderMethodPtr method,
+ upb::Sink output, Status *status) {
+ return DecoderPtr(upb_pbdecoder_create(arena->ptr(), method.ptr(),
+ output.sink(), status->ptr()));
+ }
/* Returns the DecoderMethod this decoder is parsing from. */
- const DecoderMethod* method() const;
+ const DecoderMethodPtr method() const {
+ return DecoderMethodPtr(upb_pbdecoder_method(ptr_));
+ }
/* The sink on which this decoder receives input. */
- BytesSink* input();
+ BytesSink input() { return BytesSink(upb_pbdecoder_input(ptr())); }
/* Returns number of bytes successfully parsed.
*
@@ -127,7 +148,7 @@ class upb::pb::Decoder {
*
* This value may not be up-to-date when called from inside a parsing
* callback. */
- uint64_t BytesParsed() const;
+ uint64_t BytesParsed() { return upb_pbdecoder_bytesparsed(ptr()); }
/* Gets/sets the parsing nexting limit. If the total number of nested
* submessages and repeated fields hits this limit, parsing will fail. This
@@ -136,31 +157,55 @@ class upb::pb::Decoder {
*
* Setting the limit will fail if the parser is currently suspended at a depth
* greater than this, or if memory allocation of the stack fails. */
- size_t max_nesting() const;
- bool set_max_nesting(size_t max);
+ size_t max_nesting() { return upb_pbdecoder_maxnesting(ptr()); }
+ bool set_max_nesting(size_t max) { return upb_pbdecoder_maxnesting(ptr()); }
- void Reset();
+ void Reset() { upb_pbdecoder_reset(ptr()); }
static const size_t kSize = UPB_PB_DECODER_SIZE;
private:
- UPB_DISALLOW_POD_OPS(Decoder, upb::pb::Decoder)
+ upb_pbdecoder *ptr_;
};
#endif /* __cplusplus */
+/* upb_pbcodecache ************************************************************/
+
+/* Lazily builds and caches decoder methods that will push data to the given
+ * handlers. The destination handlercache must outlive this object. */
+
+struct upb_pbcodecache;
+typedef struct upb_pbcodecache upb_pbcodecache;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+upb_pbcodecache *upb_pbcodecache_new(upb_handlercache *dest);
+void upb_pbcodecache_free(upb_pbcodecache *c);
+bool upb_pbcodecache_allowjit(const upb_pbcodecache *c);
+void upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow);
+void upb_pbcodecache_setlazy(upb_pbcodecache *c, bool lazy);
+const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c,
+ const upb_msgdef *md);
+
#ifdef __cplusplus
+} /* extern "C" */
/* A class for caching protobuf processing code, whether bytecode for the
* interpreted decoder or machine code for the JIT.
*
- * This class is not thread-safe.
- *
- * TODO(haberman): move this to be heap allocated for ABI stability. */
+ * This class is not thread-safe. */
class upb::pb::CodeCache {
public:
- CodeCache();
- ~CodeCache();
+ CodeCache(upb::HandlerCache *dest)
+ : ptr_(upb_pbcodecache_new(dest->ptr()), upb_pbcodecache_free) {}
+ CodeCache(CodeCache&&) = default;
+ CodeCache& operator=(CodeCache&&) = default;
+
+ upb_pbcodecache* ptr() { return ptr_.get(); }
+ const upb_pbcodecache* ptr() const { return ptr_.get(); }
/* Whether the cache is allowed to generate machine code. Defaults to true.
* There is no real reason to turn it off except for testing or if you are
@@ -169,144 +214,27 @@ class upb::pb::CodeCache {
* Note that allow_jit = true does not *guarantee* that the code will be JIT
* compiled. If this platform is not supported or the JIT was not compiled
* in, the code may still be interpreted. */
- bool allow_jit() const;
+ bool allow_jit() const { return upb_pbcodecache_allowjit(ptr()); }
/* This may only be called when the object is first constructed, and prior to
- * any code generation, otherwise returns false and does nothing. */
- bool set_allow_jit(bool allow);
+ * any code generation. */
+ void set_allow_jit(bool allow) { upb_pbcodecache_setallowjit(ptr(), allow); }
- /* Returns a DecoderMethod that can push data to the given handlers.
- * If a suitable method already exists, it will be returned from the cache.
- *
- * Specifying the destination handlers here allows the DecoderMethod to be
- * statically bound to the destination handlers if possible, which can allow
- * more efficient decoding. However the returned method may or may not
- * actually be statically bound. But in all cases, the returned method can
- * push data to the given handlers. */
- const DecoderMethod *GetDecoderMethod(const DecoderMethodOptions& opts);
+ /* Should the decoder push submessages to lazy handlers for fields that have
+ * them? The caller should set this iff the lazy handlers expect data that is
+ * in protobuf binary format and the caller wishes to lazy parse it. */
+ void set_lazy(bool lazy) { upb_pbcodecache_setlazy(ptr(), lazy); }
- /* If/when someone needs to explicitly create a dynamically-bound
- * DecoderMethod*, we can add a method to get it here. */
+ /* Returns a DecoderMethod that can push data to the given handlers.
+ * If a suitable method already exists, it will be returned from the cache. */
+ const DecoderMethodPtr Get(MessageDefPtr md) {
+ return DecoderMethodPtr(upb_pbcodecache_get(ptr(), md.ptr()));
+ }
private:
- UPB_DISALLOW_COPY_AND_ASSIGN(CodeCache)
-#else
-struct upb_pbcodecache {
-#endif
- bool allow_jit_;
-
- /* Array of mgroups. */
- upb_inttable groups;
+ std::unique_ptr<upb_pbcodecache, decltype(&upb_pbcodecache_free)> ptr_;
};
-UPB_BEGIN_EXTERN_C
-
-upb_pbdecoder *upb_pbdecoder_create(upb_env *e,
- const upb_pbdecodermethod *method,
- upb_sink *output);
-const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d);
-upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d);
-uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d);
-size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d);
-bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max);
-void upb_pbdecoder_reset(upb_pbdecoder *d);
-
-void upb_pbdecodermethodopts_init(upb_pbdecodermethodopts *opts,
- const upb_handlers *h);
-void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy);
-
-
-/* Include refcounted methods like upb_pbdecodermethod_ref(). */
-UPB_REFCOUNTED_CMETHODS(upb_pbdecodermethod, upb_pbdecodermethod_upcast)
-
-const upb_handlers *upb_pbdecodermethod_desthandlers(
- const upb_pbdecodermethod *m);
-const upb_byteshandler *upb_pbdecodermethod_inputhandler(
- const upb_pbdecodermethod *m);
-bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m);
-const upb_pbdecodermethod *upb_pbdecodermethod_new(
- const upb_pbdecodermethodopts *opts, const void *owner);
-
-void upb_pbcodecache_init(upb_pbcodecache *c);
-void upb_pbcodecache_uninit(upb_pbcodecache *c);
-bool upb_pbcodecache_allowjit(const upb_pbcodecache *c);
-bool upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow);
-const upb_pbdecodermethod *upb_pbcodecache_getdecodermethod(
- upb_pbcodecache *c, const upb_pbdecodermethodopts *opts);
-
-UPB_END_EXTERN_C
-
-#ifdef __cplusplus
-
-namespace upb {
-
-namespace pb {
-
-/* static */
-inline Decoder* Decoder::Create(Environment* env, const DecoderMethod* m,
- Sink* sink) {
- return upb_pbdecoder_create(env, m, sink);
-}
-inline const DecoderMethod* Decoder::method() const {
- return upb_pbdecoder_method(this);
-}
-inline BytesSink* Decoder::input() {
- return upb_pbdecoder_input(this);
-}
-inline uint64_t Decoder::BytesParsed() const {
- return upb_pbdecoder_bytesparsed(this);
-}
-inline size_t Decoder::max_nesting() const {
- return upb_pbdecoder_maxnesting(this);
-}
-inline bool Decoder::set_max_nesting(size_t max) {
- return upb_pbdecoder_setmaxnesting(this, max);
-}
-inline void Decoder::Reset() { upb_pbdecoder_reset(this); }
-
-inline DecoderMethodOptions::DecoderMethodOptions(const Handlers* h) {
- upb_pbdecodermethodopts_init(this, h);
-}
-inline void DecoderMethodOptions::set_lazy(bool lazy) {
- upb_pbdecodermethodopts_setlazy(this, lazy);
-}
-
-inline const Handlers* DecoderMethod::dest_handlers() const {
- return upb_pbdecodermethod_desthandlers(this);
-}
-inline const BytesHandler* DecoderMethod::input_handler() const {
- return upb_pbdecodermethod_inputhandler(this);
-}
-inline bool DecoderMethod::is_native() const {
- return upb_pbdecodermethod_isnative(this);
-}
-/* static */
-inline reffed_ptr<const DecoderMethod> DecoderMethod::New(
- const DecoderMethodOptions &opts) {
- const upb_pbdecodermethod *m = upb_pbdecodermethod_new(&opts, &m);
- return reffed_ptr<const DecoderMethod>(m, &m);
-}
-
-inline CodeCache::CodeCache() {
- upb_pbcodecache_init(this);
-}
-inline CodeCache::~CodeCache() {
- upb_pbcodecache_uninit(this);
-}
-inline bool CodeCache::allow_jit() const {
- return upb_pbcodecache_allowjit(this);
-}
-inline bool CodeCache::set_allow_jit(bool allow) {
- return upb_pbcodecache_setallowjit(this, allow);
-}
-inline const DecoderMethod *CodeCache::GetDecoderMethod(
- const DecoderMethodOptions& opts) {
- return upb_pbcodecache_getdecodermethod(this, &opts);
-}
-
-} /* namespace pb */
-} /* namespace upb */
-
#endif /* __cplusplus */
#endif /* UPB_DECODER_H_ */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback