diff options
author | Josh Haberman <jhaberman@gmail.com> | 2014-01-21 18:38:49 -0800 |
---|---|---|
committer | Josh Haberman <jhaberman@gmail.com> | 2014-01-21 18:38:49 -0800 |
commit | 0fd2f830882402979a83010e89650e7245960d39 (patch) | |
tree | 0968ca9424c5fb2433047519cbd54d3dd8d0b863 /README | |
parent | ce9bba3cb5409844f8f3d7dcc235a9ea30cad090 (diff) |
Sync to internal Google development.
Diffstat (limited to 'README')
-rw-r--r-- | README | 127 |
1 files changed, 36 insertions, 91 deletions
@@ -1,7 +1,8 @@ upb - a small, low-level protocol buffer library -For API documentation, see the header files. +BUILDING +======== To build (the core library is ANSI C99 and has no dependencies): $ make @@ -22,100 +23,44 @@ Issue tracking is on Google Code: A manual is forthcoming, for now see wiki docs at: https://github.com/haberman/upb/wiki +API +=== + +The public C/C++ API is defined by all of the .h files in upb/ except .int.h +files (which are internal-only). + +The .h files define both C and C++ APIs. Both languages have 100% complete and +first-class APIs. The C++ API is a wrapper around the C API, but all of the +wrapping is done in inline methods in .h files, so there is no overhead to this. + +For a more detailed description of the scheme we use to provide both C and C++ +APIs, see: https://github.com/haberman/upb/wiki/CAndCPlusPlusAPI + +All of the code that is under upb/ but *not* under upb/bindings/ forms the +namespace of upb's cross-language public API. For example, the code in +upb/descriptor would be exposed as follows: + + * in C/C++: + #include "upb/descriptor/X.h" + + * in Lua: + require "upb.descriptor" + + * in Python: + import upb.descriptor + + * etc. + +STABILITY / STATUS +================== + 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. +Parsing is becoming stable, but serialization is in very early stages. +The Python bindings are completely broken and Lua only supports schemas for the +moment. CONTACT ======= |