Protocol Buffers - Google's data interchange format (grpc依赖) https://developers.google.com/protocol-buffers/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Josh Haberman 7d3e2bd2c4 Sync with 8 months of Google-internal development. 12 years ago
benchmarks Sync with 8 months of Google-internal development. 12 years ago
bindings Sync with 8 months of Google-internal development. 12 years ago
dynasm Sync with 8 months of Google-internal development. 12 years ago
examples Sync with internal Google development. 13 years ago
tests Sync with 8 months of Google-internal development. 12 years ago
tools Sync with 8 months of Google-internal development. 12 years ago
upb Sync with 8 months of Google-internal development. 12 years ago
.gitignore Makefile is much improved ("make deps" works again, etc). 16 years ago
LICENSE Update copyright to be Google Inc. 14 years ago
Makefile Sync with 8 months of Google-internal development. 12 years ago
README Sync with 8 months of Google-internal development. 12 years ago
perf-regression-test.py Decoder redesign in preparation for packed fields and start/endseq. 14 years ago
perf-tests.sh Fix perf-tests.sh to skip building non-upb tests. 13 years ago

README


upb - a small, low-level protocol buffer library

For API documentation, see the header files.

To build (the core library is ANSI C99 and has no dependencies):
$ make

Other useful targets:
$ make test
$ make benchmark
$ make lua (requires lua libraries to be installed)

The tests and benchmarks have the following dependencies
(Ubuntu package names in parentheses):
- Google's protobuf compiler + libraries (protobuf-compiler, libprotobuf-dev)
- Lua binary and libraries (lua5.1, liblua5.1-dev)

Issue tracking is on Google Code:
http://code.google.com/p/upb/issues/list

A manual is forthcoming, for now see wiki docs at:
https://github.com/haberman/upb/wiki

API and ABI are both subject to change! Please do not distribute as a shared
library for this reason (for now at least).

TODO
====

The issue tracker contains small-to-medium tasks that need doing; but here are
the major things that are broken or not yet implemented yet:

- serialization isn't written yet (only deserialization)


C/C++ API
=========

upb's main interfaces are defined in .h files (like upb/def.h). These header
files are coded in such a way that they are not only compatible with C and C++
but provide idiomatic interfaces to both (functions for C, classes for C++).

Here is the general strategy/pattern for this. I'll explain it piece by piece.

// This defines a type called upb::Foo in C++ or upb_foo in C. In both cases
// there is a typedef for upb_foo, which is important since this is how the
// C functions are defined (which are exposed to both C and C++).

#ifdef __cplusplus
namespace upb { class Foo; }
typedef upb::Foo upb_foo;
extern "C" {
#else
struct upb_foo;
typedef struct upb_foo upb_foo;
#endif

// Here is the actual definition of the class/struct. In C++ we get a class
// called upb::Foo and in C we get a struct called "struct upb_foo", but both
// have the same members and the C++ version is "standard-layout" according
// to C++11. This means that the two should be compatible.
//
// In addition to being completely accessible from C, it also provides C++
// niceities like methods (instead of bare functions). We also get
// encapsulation in C++, even though this is impossible to provide in C. We
// provide all method documentation in the C++ class, since the class/method
// syntax is nicer to read than the bare functions of C.

#ifdef __cplusplus

class upb::Foo {
public:
// Method documentation for DoBar().
void DoBar(int32_t x);

// Method documentation for IsSpicy().
bool IsSpicy();

private:

#else
struct upb_foo {
#endif
int32_t private_member;
};

// Next follows the C API, which is how the functionality is actually
// implemented. We omit documentation here because everything was documented
// in the C++ class, and it's easy to match the functions 1:1 to the C++
// methods.
void upb_foo_dobar(upb_foo *f, int32_t x);
bool upb_foo_isspicy(upb_foo *f);

// Finally we include inline definitions of the C++ methods, which are nothing
// but this wrappers around the C functions. Since these are inline, the C++
// API imposes no overhead.

#ifdef __cplusplus
} // extern "C"

namespace upb {
inline void Foo::DoBar(int32_t x) { upb_foo_dobar(this, x); }
inline bool Foo::IsSpicy() { return upb_foo_isspicy(this); }
}
#endif

This scheme works pretty nicely. It adds a bit of noise to the header file, but
gives nice, zero-overhead APIs to both C and C++ without having to duplicate
the API documentation.

The biggest bummer is that there isn't any good way to use C++ inheritance
even for types which are trying to express inheritance in C. C++ just doesn't
give any guarantees about how it will arrange data members in base classes,
so we can't use C++ inheritance while interoperating with C layouts. The
biggest effect of this is that we can't get C++'s nice implicit upcasts; all
upcasts have to be explicit, which is a pain.


CONTACT
=======

Author: Josh Haberman (jhaberman@gmail.com, haberman@google.com)
See LICENSE for copyright information.