summaryrefslogtreecommitdiff
path: root/bindings
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2011-12-22 11:37:01 -0800
committerJoshua Haberman <jhaberman@gmail.com>2011-12-22 11:37:01 -0800
commit1bcab1377de6afe8c0f9c895cdba04baacf3e4a5 (patch)
tree4d478ccff5da0dee3c217c01f815ee1764965501 /bindings
parentb5f5ee867e6c91b77490dc8894236f17a47bde00 (diff)
Sync with internal Google development.
This breaks the open-source build, will follow up with a change to fix it.
Diffstat (limited to 'bindings')
-rw-r--r--bindings/cpp/upb/bytestream.cc39
-rw-r--r--bindings/cpp/upb/bytestream.hpp238
-rw-r--r--bindings/cpp/upb/def.hpp77
-rw-r--r--bindings/cpp/upb/handlers.hpp95
-rw-r--r--bindings/cpp/upb/pb/decoder.hpp83
-rw-r--r--bindings/cpp/upb/upb.hpp23
6 files changed, 458 insertions, 97 deletions
diff --git a/bindings/cpp/upb/bytestream.cc b/bindings/cpp/upb/bytestream.cc
new file mode 100644
index 0000000..df0797e
--- /dev/null
+++ b/bindings/cpp/upb/bytestream.cc
@@ -0,0 +1,39 @@
+//
+// upb - a minimalist implementation of protocol buffers.
+//
+// Copyright (c) 2011 Google Inc. See LICENSE for details.
+// Author: Josh Haberman <jhaberman@gmail.com>
+
+#include "bytestream.hpp"
+
+namespace upb {
+
+upb_bytesrc_vtbl* ByteSourceBase::vtable() {
+ static upb_bytesrc_vtbl vtbl = {
+ &ByteSourceBase::VFetch,
+ &ByteSourceBase::VDiscard,
+ &ByteSourceBase::VCopy,
+ &ByteSourceBase::VGetPtr,
+ };
+ return &vtbl;
+}
+
+upb_bytesuccess_t ByteSourceBase::VFetch(void *src, uint64_t ofs, size_t *len) {
+ return static_cast<ByteSourceBase*>(src)->Fetch(ofs, len);
+}
+
+void ByteSourceBase::VCopy(
+ const void *src, uint64_t ofs, size_t len, char* dest) {
+ static_cast<const ByteSourceBase*>(src)->Copy(ofs, len, dest);
+}
+
+void ByteSourceBase::VDiscard(void *src, uint64_t ofs) {
+ static_cast<ByteSourceBase*>(src)->Discard(ofs);
+}
+
+const char * ByteSourceBase::VGetPtr(
+ const void *src, uint64_t ofs, size_t* len) {
+ return static_cast<const ByteSourceBase*>(src)->GetPtr(ofs, len);
+}
+
+} // namespace upb
diff --git a/bindings/cpp/upb/bytestream.hpp b/bindings/cpp/upb/bytestream.hpp
new file mode 100644
index 0000000..968d542
--- /dev/null
+++ b/bindings/cpp/upb/bytestream.hpp
@@ -0,0 +1,238 @@
+//
+// upb - a minimalist implementation of protocol buffers.
+//
+// Copyright (c) 2011 Google Inc. See LICENSE for details.
+// Author: Josh Haberman <jhaberman@gmail.com>
+//
+// This file defines three core interfaces:
+// - upb::ByteSink: for writing streams of data.
+// - upb::ByteSource: for reading streams of data.
+// - upb::ByteRegion: for reading from a specific region of a ByteSource;
+// should be used by decoders instead of using a ByteSource directly.
+//
+// These interfaces are used by streaming encoders and decoders: for example, a
+// protobuf parser gets its input from a upb::ByteRegion. They are virtual
+// base classes so concrete implementations can get the data from a fd, a
+// FILE*, a string, etc.
+//
+// A ByteRegion represents a region of data from a ByteSource.
+//
+// Parsers get data from this interface instead of a bytesrc because we often
+// want to parse only a specific region of the input. For example, if we parse
+// a string from our input but know that the string represents a protobuf, we
+// can pass its ByteRegion to an appropriate protobuf parser.
+//
+// Since the bytes may be coming from a file or network socket, bytes must be
+// fetched before they can be read (though in some cases this fetch may be a
+// no-op). "fetch" is the only operation on a byteregion that could fail or
+// block, because it is the only operation that actually performs I/O.
+//
+// Bytes can be discarded when they are no longer needed. Parsers should
+// always discard bytes they no longer need, both so the buffers can be freed
+// when possible and to give better visibility into what bytes the parser is
+// still using.
+//
+// start discard read fetch end
+// ofs ofs ofs ofs ofs
+// | |--->Discard() | |--->Fetch() |
+// V V V V V
+// +-------------+-------------------------+-----------------+-----------------+
+// | discarded | | | fetchable |
+// +-------------+-------------------------+-----------------+-----------------+
+// | <------------- loaded ------------------> |
+// | <- available -> |
+// | <---------- remaining ----------> |
+//
+// Note that the start offset may be something other than zero! A byteregion
+// is a view into an underlying bytesrc stream, and the region may start
+// somewhere other than the beginning of that stream.
+//
+// The region can be either delimited or nondelimited. A non-delimited region
+// will keep returning data until the underlying data source returns EOF. A
+// delimited region will return EOF at a predetermined offset.
+//
+// end
+// ofs
+// |
+// V
+// +-----------------------+
+// | delimited region | <-- hard EOF, even if data source has more data.
+// +-----------------------+
+//
+// +------------------------
+// | nondelimited region Z <-- won't return EOF until data source hits EOF.
+// +------------------------
+
+#ifndef UPB_BYTESTREAM_HPP
+#define UPB_BYTESTREAM_HPP
+
+#include "upb/bytestream.h"
+#include "upb/upb.hpp"
+
+namespace upb {
+
+typedef upb_bytesuccess_t ByteSuccess;
+
+// Implement this interface to vend bytes to ByteRegions which will be used by
+// a decoder.
+class ByteSourceBase : public upb_bytesrc {
+ public:
+ ByteSourceBase() { upb_bytesrc_init(this, vtable()); }
+ virtual ~ByteSourceBase() { upb_bytesrc_uninit(this); }
+
+ // Fetches at least one byte starting at ofs, setting *len to the actual
+ // number of bytes fetched (or 0 on EOF or error: see return value for
+ // details). It is valid for bytes to be fetched multiple times, as long as
+ // the bytes have not been previously discarded.
+ virtual ByteSuccess Fetch(uint64_t ofs, size_t* len) = 0;
+
+ // Discards all data prior to ofs (except data that is pinned, if pinning
+ // support is added -- see TODO below).
+ virtual void Discard(uint64_t ofs) = 0;
+
+ // Copies "len" bytes of data from ofs to "dst", which must be at least "len"
+ // bytes long. The given region must not be discarded.
+ virtual void Copy(uint64_t ofs, size_t len, char *dst) const = 0;
+
+ // Returns a pointer to the bytesrc's internal buffer, storing in *len how
+ // much data is available. The given offset must not be discarded. The
+ // returned buffer is valid for as long as its bytes are not discarded (in
+ // the case that part of the returned buffer is discarded, only the
+ // non-discarded bytes remain valid).
+ virtual const char *GetPtr(uint64_t ofs, size_t *len) const = 0;
+
+ // TODO: Add if/when there is a demonstrated need:
+ //
+ // // When the caller pins a region (which must not be already discarded), it
+ // // is guaranteed that the region will not be discarded (nor will the
+ // // bytesrc be destroyed) until the region is unpinned. However, not all
+ // // bytesrc's support pinning; a false return indicates that a pin was not
+ // // possible.
+ // virtual bool Pin(uint64_t ofs, size_t len);
+ //
+ // // Releases some number of pinned bytes from the beginning of a pinned
+ // // region (which may be fewer than the total number of bytes pinned).
+ // virtual void Unpin(uint64_t ofs, size_t len, size_t bytes_to_release);
+ //
+ // Adding pinning support would also involve adding a "pin_ofs" parameter to
+ // upb_bytesrc_fetch, so that the fetch can extend an already-pinned region.
+ private:
+ static upb_bytesrc_vtbl* vtable();
+ static upb_bytesuccess_t VFetch(void*, uint64_t, size_t*);
+ static void VDiscard(void*, uint64_t);
+ static void VCopy(const void*, uint64_t, size_t, char*);
+ static const char *VGetPtr(const void*, uint64_t, size_t*);
+};
+
+class ByteRegion : public upb_byteregion {
+ public:
+ static const uint64_t kNondelimited = UPB_NONDELIMITED;
+
+ ByteRegion() { upb_byteregion_init(this); }
+ ~ByteRegion() { upb_byteregion_uninit(this); }
+
+ // Accessors for the regions bounds -- the meaning of these is described in
+ // the diagram above.
+ uint64_t start_ofs() const { return upb_byteregion_startofs(this); }
+ uint64_t discard_ofs() const { return upb_byteregion_discardofs(this); }
+ uint64_t fetch_ofs() const { return upb_byteregion_fetchofs(this); }
+ uint64_t end_ofs() const { return upb_byteregion_endofs(this); }
+
+ // Returns how many bytes are fetched and available for reading starting from
+ // offset "offset".
+ uint64_t BytesAvailable(uint64_t offset) const {
+ return upb_byteregion_available(this, offset);
+ }
+
+ // Returns the total number of bytes remaining after offset "offset", or
+ // kNondelimited if the byteregion is non-delimited.
+ uint64_t BytesRemaining(uint64_t offset) const {
+ return upb_byteregion_remaining(this, offset);
+ }
+
+ uint64_t Length() const { return upb_byteregion_len(this); }
+
+ // Sets the value of this byteregion to be a subset of the given byteregion's
+ // data. The caller is responsible for releasing this region before the src
+ // region is released (unless the region is first pinned, if pinning support
+ // is added. see below).
+ void Reset(const upb_byteregion *src, uint64_t ofs, uint64_t len) {
+ upb_byteregion_reset(this, src, ofs, len);
+ }
+ void Release() { upb_byteregion_release(this); }
+
+ // Attempts to fetch more data, extending the fetched range of this
+ // byteregion. Returns true if the fetched region was extended by at least
+ // one byte, false on EOF or error (see *s for details).
+ ByteSuccess Fetch() { return upb_byteregion_fetch(this); }
+
+ // Fetches all remaining data, returning false if the operation failed (see
+ // *s for details). May only be used on delimited byteregions.
+ ByteSuccess FetchAll() { return upb_byteregion_fetchall(this); }
+
+ // Discards bytes from the byteregion up until ofs (which must be greater or
+ // equal to discard_ofs()). It is valid to discard bytes that have not been
+ // fetched (such bytes will never be fetched) but it is an error to discard
+ // past the end of a delimited byteregion.
+ void Discard(uint64_t ofs) { return upb_byteregion_discard(this, ofs); }
+
+ // Copies "len" bytes of data into "dst", starting at ofs. The specified
+ // region must be available.
+ void Copy(uint64_t ofs, size_t len, char *dst) const {
+ upb_byteregion_copy(this, ofs, len, dst);
+ }
+
+ // Copies all bytes from the byteregion into dst. Requires that the entire
+ // byteregion is fetched and that none has been discarded.
+ void CopyAll(char *dst) const {
+ upb_byteregion_copyall(this, dst);
+ }
+
+ // Returns a pointer to the internal buffer for the byteregion starting at
+ // offset "ofs." Stores the number of bytes available in this buffer in *len.
+ // The returned buffer is invalidated when the byteregion is reset or
+ // released, or when the bytes are discarded. If the byteregion is not
+ // currently pinned, the pointer is only valid for the lifetime of the parent
+ // byteregion.
+ const char *GetPtr(uint64_t ofs, size_t *len) const {
+ return upb_byteregion_getptr(this, ofs, len);
+ }
+
+ // Copies the contents of the byteregion into a newly-allocated,
+ // NULL-terminated string. Requires that the byteregion is fully fetched.
+ char *StrDup() const {
+ return upb_byteregion_strdup(this);
+ }
+
+ // TODO: add if/when there is a demonstrated need.
+ //
+ // // Pins this byteregion's bytes in memory, allowing it to outlive its
+ // // parent byteregion. Normally a byteregion may only be used while its
+ // // parent is still valid, but a pinned byteregion may continue to be used
+ // // until it is reset or released. A byteregion must be fully fetched to
+ // // be pinned (this implies that the byteregion must be delimited).
+ // //
+ // // In some cases this operation may cause the input data to be copied.
+ // //
+ // // void Pin();
+};
+
+class StringSource : public upb_stringsrc {
+ public:
+ StringSource() : upb_stringsrc() { upb_stringsrc_init(this); }
+ ~StringSource() { upb_stringsrc_uninit(this); }
+
+ void Reset(const char* data, size_t len) {
+ upb_stringsrc_reset(this, data, len);
+ }
+
+ ByteRegion* AllBytes() {
+ return static_cast<ByteRegion*>(upb_stringsrc_allbytes(this));
+ }
+
+ upb_bytesrc* ByteSource() { return upb_stringsrc_bytesrc(this); }
+};
+
+} // namespace upb
+
+#endif
diff --git a/bindings/cpp/upb/def.hpp b/bindings/cpp/upb/def.hpp
index ac9aff1..030ba40 100644
--- a/bindings/cpp/upb/def.hpp
+++ b/bindings/cpp/upb/def.hpp
@@ -1,42 +1,41 @@
-/*
- * upb - a minimalist implementation of protocol buffers.
- *
- * Copyright (c) 2011 Google Inc. See LICENSE for details.
- * Author: Josh Haberman <jhaberman@gmail.com>
- *
- * The set of upb::*Def classes and upb::SymbolTable allow for defining and
- * manipulating schema information (as defined in .proto files).
- *
- * Defs go through two distinct phases of life:
- *
- * 1. MUTABLE: when first created, the properties of the def can be set freely
- * (for example a message's name, its list of fields, the name/number of
- * fields, etc). During this phase the def is *not* thread-safe, and may
- * not be used for any purpose except to set its properties (it can't be
- * used to parse anything, create any messages in memory, etc).
- *
- * 2. FINALIZED: after being added to a symtab (which links the defs together)
- * the defs become finalized (thread-safe and immutable). Programs may only
- * access defs through a CONST POINTER during this stage -- upb_symtab will
- * help you out with this requirement by only vending const pointers, but
- * you need to make sure not to use any non-const pointers you still have
- * sitting around. In practice this means that you may not call any setters
- * on the defs (or functions that themselves call the setters). If you want
- * to modify an existing immutable def, copy it with upb_*_dup(), modify the
- * copy, and add the modified def to the symtab (replacing the existing
- * def).
- *
- * You can test for which stage of life a def is in by calling
- * upb::Def::IsMutable(). This is particularly useful for dynamic language
- * bindings, which must properly guarantee that the dynamic language cannot
- * break the rules laid out above.
- *
- * It would be possible to make the defs thread-safe during stage 1 by using
- * mutexes internally and changing any methods returning pointers to return
- * copies instead. This could be important if we are integrating with a VM or
- * interpreter that does not naturally serialize access to wrapped objects (for
- * example, in the case of Python this is not necessary because of the GIL).
- */
+//
+// upb - a minimalist implementation of protocol buffers.
+//
+// Copyright (c) 2011 Google Inc. See LICENSE for details.
+// Author: Josh Haberman <jhaberman@gmail.com>
+//
+// The set of upb::*Def classes and upb::SymbolTable allow for defining and
+// manipulating schema information (as defined in .proto files).
+//
+// Defs go through two distinct phases of life:
+//
+// 1. MUTABLE: when first created, the properties of the def can be set freely
+// (for example a message's name, its list of fields, the name/number of
+// fields, etc). During this phase the def is *not* thread-safe, and may
+// not be used for any purpose except to set its properties (it can't be
+// used to parse anything, create any messages in memory, etc).
+//
+// 2. FINALIZED: after being added to a symtab (which links the defs together)
+// the defs become finalized (thread-safe and immutable). Programs may only
+// access defs through a CONST POINTER during this stage -- upb_symtab will
+// help you out with this requirement by only vending const pointers, but
+// you need to make sure not to use any non-const pointers you still have
+// sitting around. In practice this means that you may not call any setters
+// on the defs (or functions that themselves call the setters). If you want
+// to modify an existing immutable def, copy it with upb_*_dup(), modify the
+// copy, and add the modified def to the symtab (replacing the existing
+// def).
+//
+// You can test for which stage of life a def is in by calling
+// upb::Def::IsMutable(). This is particularly useful for dynamic language
+// bindings, which must properly guarantee that the dynamic language cannot
+// break the rules laid out above.
+//
+// It would be possible to make the defs thread-safe during stage 1 by using
+// mutexes internally and changing any methods returning pointers to return
+// copies instead. This could be important if we are integrating with a VM or
+// interpreter that does not naturally serialize access to wrapped objects (for
+// example, in the case of Python this is not necessary because of the GIL).
#ifndef UPB_DEF_HPP
#define UPB_DEF_HPP
diff --git a/bindings/cpp/upb/handlers.hpp b/bindings/cpp/upb/handlers.hpp
index 07683f6..d356a33 100644
--- a/bindings/cpp/upb/handlers.hpp
+++ b/bindings/cpp/upb/handlers.hpp
@@ -1,15 +1,14 @@
-/*
- * upb - a minimalist implementation of protocol buffers.
- *
- * Copyright (c) 2011 Google Inc. See LICENSE for details.
- * Author: Josh Haberman <jhaberman@gmail.com>
- *
- * upb::Handlers is a generic visitor-like interface for iterating over a
- * stream of protobuf data. You can register function pointers that will be
- * called for each message and/or field as the data is being parsed or iterated
- * over, without having to know the source format that we are parsing from.
- * This decouples the parsing logic from the processing logic.
- */
+//
+// upb - a minimalist implementation of protocol buffers.
+//
+// Copyright (c) 2011 Google Inc. See LICENSE for details.
+// Author: Josh Haberman <jhaberman@gmail.com>
+//
+// upb::Handlers is a generic visitor-like interface for iterating over a
+// stream of protobuf data. You can register function pointers that will be
+// called for each message and/or field as the data is being parsed or iterated
+// over, without having to know the source format that we are parsing from.
+// This decouples the parsing logic from the processing logic.
#ifndef UPB_HANDLERS_HPP
#define UPB_HANDLERS_HPP
@@ -18,6 +17,7 @@
namespace upb {
+typedef upb_fieldtype_t FieldType;
typedef upb_flow_t Flow;
class MessageHandlers;
@@ -30,8 +30,8 @@ class FieldHandlers : public upb_fhandlers {
// The FieldHandlers will live at least as long as the upb::Handlers to
// which it belongs, but can be Ref'd/Unref'd to make it live longer (which
// will prolong the life of the underlying upb::Handlers also).
- void Ref() const { upb_fhandlers_ref(this); }
- void Unref() const { upb_fhandlers_unref(this); }
+ void Ref() { upb_fhandlers_ref(this); }
+ void Unref() { upb_fhandlers_unref(this); }
// Functions to set this field's handlers.
// These return "this" so they can be conveniently chained, eg.
@@ -46,13 +46,13 @@ class FieldHandlers : public upb_fhandlers {
upb_fhandlers_setstartseq(this, h); return this;
}
FieldHandlers* SetEndSequenceHandler(EndFieldHandler* h) {
- upb_fhandlers_endseq(this, h); return this;
+ upb_fhandlers_setendseq(this, h); return this;
}
FieldHandlers* SetStartSubmessageHandler(StartFieldHandler* h) {
upb_fhandlers_setstartsubmsg(this, h); return this;
}
FieldHandlers* SetEndSubmessageHandler(EndFieldHandler* h) {
- upb_fhandlers_endsubmsg(this, h); return this;
+ upb_fhandlers_setendsubmsg(this, h); return this;
}
// Get/Set the field's bound value, which will be passed to its handlers.
@@ -62,27 +62,20 @@ class FieldHandlers : public upb_fhandlers {
}
// Returns the MessageHandlers to which we belong.
- MessageHandlers* GetMessageHandlers() const {
- return upb_fhandlers_msg(this);
- }
-
+ MessageHandlers* GetMessageHandlers() const;
// Returns the MessageHandlers for this field's submessage (invalid to call
// unless this field's type UPB_TYPE(MESSAGE) or UPB_TYPE(GROUP).
- MessageHandlers* GetSubMessageHandlers() const {
- return upb_fhandlers_submsg(this);
- }
-
+ MessageHandlers* GetSubMessageHandlers() const;
// If set to >=0, the given hasbit will be set after the value callback is
- // called (relative to the current closure).
- int32_t GetValueHasbit() const { return upb_fhandler_valuehasbit(this); }
- void SetValueHasbit(int32_t bit) { upb_fhandler_setvaluehasbit(this, bit); }
+ // called (offset relative to the current closure).
+ int32_t GetValueHasbit() const { return upb_fhandlers_getvaluehasbit(this); }
+ void SetValueHasbit(int32_t bit) { upb_fhandlers_setvaluehasbit(this, bit); }
private:
FieldHandlers(); // Only created by upb::Handlers.
~FieldHandlers(); // Only destroyed by refcounting.
};
-
class MessageHandlers : public upb_mhandlers {
public:
typedef upb_startmsg_handler StartMessageHandler;
@@ -91,8 +84,8 @@ class MessageHandlers : public upb_mhandlers {
// The MessageHandlers will live at least as long as the upb::Handlers to
// which it belongs, but can be Ref'd/Unref'd to make it live longer (which
// will prolong the life of the underlying upb::Handlers also).
- void Ref() const { upb_mhandlers_ref(this); }
- void Unref() const { upb_mhandlers_unref(this); }
+ void Ref() { upb_mhandlers_ref(this); }
+ void Unref() { upb_mhandlers_unref(this); }
// Functions to set this message's handlers.
// These return "this" so they can be conveniently chained, eg.
@@ -107,12 +100,10 @@ class MessageHandlers : public upb_mhandlers {
}
// Functions to create new FieldHandlers for this message.
- FieldHandlers* NewFieldHandlers(uint32_t fieldnum, upb_fieldtype_t type,
+ FieldHandlers* NewFieldHandlers(uint32_t fieldnum, FieldType type,
bool repeated) {
- return upb_mhandlers_newfhandlers(this, fieldnum, type, repeated);
- }
- FieldHandlers* NewFieldHandlers(FieldDef* f) {
- return upb_mhandlers_newfhandlers_fordef(f);
+ return static_cast<FieldHandlers*>(
+ upb_mhandlers_newfhandlers(this, fieldnum, type, repeated));
}
// Like the previous but for MESSAGE or GROUP fields. For GROUP fields, the
@@ -120,15 +111,10 @@ class MessageHandlers : public upb_mhandlers {
FieldHandlers* NewFieldHandlersForSubmessage(uint32_t n, const char *name,
FieldType type, bool repeated,
MessageHandlers* subm) {
- return upb_mhandlers_newsubmsgfhandlers(this, n, type, repeated, subm);
- }
-
- FieldHandlers* NewFieldHandlersForSubmessage(FieldDef* f,
- MessageHandlers* subm) {
- return upb_mhandlers_newsubmsgfhandlers_fordef(f);
+ return static_cast<FieldHandlers*>(
+ upb_mhandlers_newfhandlers_subm(this, n, type, repeated, subm));
}
-
private:
MessageHandlers(); // Only created by upb::Handlers.
~MessageHandlers(); // Only destroyed by refcounting.
@@ -137,26 +123,31 @@ class MessageHandlers : public upb_mhandlers {
class Handlers : public upb_handlers {
public:
// Creates a new Handlers instance.
- Handlers* New() { return static_cast<Handlers*>(upb_handlers_new()); }
+ static Handlers* New() { return static_cast<Handlers*>(upb_handlers_new()); }
void Ref() { upb_handlers_ref(this); }
void Unref() { upb_handlers_unref(this); }
// Returns a new MessageHandlers object. The first such message that is
// obtained will be the top-level message for this Handlers object.
- MessageHandlers* NewMessageHandlers() { return upb_handlers_newmhandlers(this); }
-
- // Freezes the handlers against future modification. Handlers must be
- // finalized before they can be passed to a data producer. After Finalize()
- // has been called, you may only call const methods on the Handlers and its
- // MessageHandlers/FieldHandlers.
- void Finalize() { upb_handlers_finalize(this); }
+ MessageHandlers* NewMessageHandlers() {
+ return static_cast<MessageHandlers*>(upb_handlers_newmhandlers(this));
+ }
private:
- FieldHandlers(); // Only created by Handlers::New().
- ~FieldHandlers(); // Only destroyed by refcounting.
+ Handlers(); // Only created by Handlers::New().
+ ~Handlers(); // Only destroyed by refcounting.
};
+
+MessageHandlers* FieldHandlers::GetMessageHandlers() const {
+ return static_cast<MessageHandlers*>(upb_fhandlers_getmsg(this));
+}
+
+MessageHandlers* FieldHandlers::GetSubMessageHandlers() const {
+ return static_cast<MessageHandlers*>(upb_fhandlers_getsubmsg(this));
+}
+
} // namespace upb
#endif
diff --git a/bindings/cpp/upb/pb/decoder.hpp b/bindings/cpp/upb/pb/decoder.hpp
new file mode 100644
index 0000000..05bcb8a
--- /dev/null
+++ b/bindings/cpp/upb/pb/decoder.hpp
@@ -0,0 +1,83 @@
+//
+// upb - a minimalist implementation of protocol buffers.
+//
+// Copyright (c) 2011 Google Inc. See LICENSE for details.
+// Author: Josh Haberman <jhaberman@gmail.com>
+//
+// upb::Decoder is a high performance, streaming decoder for protobuf
+// data that works by getting its input data from a ubp::ByteRegion and calling
+// into a upb::Handlers.
+//
+// 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.
+
+#ifndef UPB_PB_DECODER_HPP
+#define UPB_PB_DECODER_HPP
+
+#include "upb/pb/decoder.h"
+
+#include "upb/bytestream.hpp"
+#include "upb/upb.hpp"
+
+namespace upb {
+
+class DecoderPlan : public upb_decoderplan {
+ public:
+ static DecoderPlan* New(Handlers* h, bool allow_jit) {
+ return static_cast<DecoderPlan*>(upb_decoderplan_new(h, allow_jit));
+ }
+ void Unref() { upb_decoderplan_unref(this); }
+
+ // 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 HasJitCode() { return upb_decoderplan_hasjitcode(this); }
+
+ private:
+ DecoderPlan() {} // Only constructed by New
+};
+
+class Decoder : public upb_decoder {
+ public:
+ Decoder() { upb_decoder_init(this); }
+ ~Decoder() { upb_decoder_uninit(this); }
+
+ // Resets the plan that the decoder will parse from. This will also reset the
+ // decoder's input to be uninitialized -- 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 ResetInput() or Decode().
+ void ResetPlan(DecoderPlan* plan, int32_t msg_offset) {
+ upb_decoder_resetplan(this, plan, msg_offset);
+ }
+
+ // Resets the input of the 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.
+ //
+ // ResetInput() must be called before Decode() but may be called more than
+ // once. "input" must live until the decoder destroyed or ResetInput is
+ // called again. "c" is the closure that will be passed to the handlers.
+ void ResetInput(ByteRegion* byte_region, void* c) {
+ upb_decoder_resetinput(this, byte_region, c);
+ }
+
+ // Decodes serialized data (calling Handlers as the data is parsed) until
+ // error or EOF (see status() for details).
+ Success Decode() { return upb_decoder_decode(this); }
+
+ const upb::Status& status() {
+ return static_cast<const upb::Status&>(*upb_decoder_status(this));
+ }
+};
+
+} // namespace upb
+
+#endif
diff --git a/bindings/cpp/upb/upb.hpp b/bindings/cpp/upb/upb.hpp
index 4fb337d..226859c 100644
--- a/bindings/cpp/upb/upb.hpp
+++ b/bindings/cpp/upb/upb.hpp
@@ -1,23 +1,34 @@
-/*
- * upb - a minimalist implementation of protocol buffers.
- *
- * Copyright (c) 2011 Google Inc. See LICENSE for details.
- * Author: Josh Haberman <jhaberman@gmail.com>
- */
+//
+// upb - a minimalist implementation of protocol buffers.
+//
+// Copyright (c) 2011 Google Inc. See LICENSE for details.
+// Author: Josh Haberman <jhaberman@gmail.com>
#ifndef UPB_HPP
#define UPB_HPP
#include "upb/upb.h"
+#include <iostream>
namespace upb {
+typedef upb_success_t Success;
+
class Status : public upb_status {
public:
Status() { upb_status_init(this); }
~Status() { upb_status_uninit(this); }
+ bool ok() const { return upb_ok(this); }
+ bool eof() const { return upb_eof(this); }
+
const char *GetString() const { return upb_status_getstr(this); }
+ void SetEof() { upb_status_seteof(this); }
+ void SetErrorLiteral(const char* msg) {
+ upb_status_seterrliteral(this, msg);
+ }
+
+ void Clear() { upb_status_clear(this); }
};
class Value : public upb_value {
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback