Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Protocol Buffers and XS

by mojotoad (Monsignor)
on Jul 21, 2010 at 21:33 UTC ( #850729=CUFP: print w/ replies, xml ) Need Help??

Google Protocol Buffers are an interesting example of an extensible format for serializing structured data in a portable and efficent manner suitable for streaming across the wire or into storage. The reference implementation accomplishes this in C++, but there are implementations for many other languages. In addition to one that generates pure perl code there also exists one that generates XS code on top of the natively generated C++ libraries.

Below you will find the XS and related components generated by protobuf-perlxs in the examples/simple demo from the distribution. They are presented here for the benefit of anyone lacking compilers, prerequisites, or time to mess with protobuf-perlxs themselves.

  • person.proto
  • Makefile.PL
  • Person.xs
  • person.pb.h
  • person.pb.cc

    Enjoy,
    Matt


    person.proto

    This is the actual protocol buffer specification, which the various protobuf implementations will compile into their particular idiom.

    message Person { required int32 id = 1; required string name = 2; optional string email = 3; } option optimize_for = SPEED;

    Makefile.PL

    use ExtUtils::MakeMaker; $CC = 'g++'; # Generate the C++, XS, and Perl files that we need. my $protoxs = "protoxs --cpp_out=. --out=. person.proto"; print "Generating C++ and Perl/XS sources...\n"; print "$protoxs\n"; `$protoxs`; # Now write the Makefile. WriteMakefile( 'NAME' => 'Person', 'VERSION_FROM' => 'Person.pm', 'OPTIMIZE' => '-O2 -Wall', 'CC' => $CC, 'LD' => '$(CC)', 'CCFLAGS' => '-fno-strict-aliasing', 'OBJECT' => 'person.pb.o Person.o', 'INC' => "", 'LIBS' => [" -lprotobuf"], 'XSOPT' => '-C++', clean => { FILES => "Person.* person.pb.* lib" } );

    Person.xs

    The generated XS code.

    #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif #ifdef do_open #undef do_open #endif #ifdef do_close #undef do_close #endif #ifdef New #undef New #endif #include <stdint.h> #include <sstream> #include <google/protobuf/stubs/common.h> #include <google/protobuf/io/zero_copy_stream.h> #include "person.pb.h" using namespace std; class person_OutputStream : public google::protobuf::io::ZeroCopyOutputStream { public: explicit person_OutputStream(SV * sv) : sv_(sv), len_(0) {} ~person_OutputStream() {} bool Next(void** data, int* size) { STRLEN nlen = len_ << 1; if ( nlen < 16 ) nlen = 16; SvGROW(sv_, nlen); *data = SvEND(sv_) + len_; *size = SvLEN(sv_) - len_; len_ = nlen; return true; } void BackUp(int count) { SvCUR_set(sv_, SvLEN(sv_) - count); } void Sync() { if ( SvCUR(sv_) == 0 ) { SvCUR_set(sv_, len_); } } int64_t ByteCount() const { return (int64_t)SvCUR(sv_); } private: SV * sv_; STRLEN len_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(person_OutputStream); }; typedef ::Person __Person; static ::Person * __Person_from_hashref ( SV * sv0 ) { ::Person * msg0 = new ::Person; if ( SvROK(sv0) && SvTYPE(SvRV(sv0)) == SVt_PVHV ) { HV * hv0 = (HV *)SvRV(sv0); SV ** sv1; if ( (sv1 = hv_fetch(hv0, "id", sizeof("id") - 1, 0)) != NULL ) { msg0->set_id(SvIV(*sv1)); } if ( (sv1 = hv_fetch(hv0, "name", sizeof("name") - 1, 0)) != NULL +) { STRLEN len; char * str; string sval; str = SvPV(*sv1, len); sval.assign(str, len); msg0->set_name(sval); } if ( (sv1 = hv_fetch(hv0, "email", sizeof("email") - 1, 0)) != NUL +L ) { STRLEN len; char * str; string sval; str = SvPV(*sv1, len); sval.assign(str, len); msg0->set_email(sval); } } return msg0; } MODULE = Person PACKAGE = Person PROTOTYPES: ENABLE SV * ::Person::new (...) PREINIT: ::Person * rv = NULL; CODE: if ( strcmp(CLASS,"Person") ) { croak("invalid class %s",CLASS); } if ( items == 2 && ST(1) != Nullsv ) { if ( SvROK(ST(1)) && SvTYPE(SvRV(ST(1))) == SVt_PVHV ) { rv = __Person_from_hashref(ST(1)); } else { STRLEN len; char * str; rv = new ::Person; str = SvPV(ST(1), len); if ( str != NULL ) { rv->ParseFromArray(str, len); } } } else { rv = new ::Person; } RETVAL = newSV(0); sv_setref_pv(RETVAL, "Person", (void *)rv); OUTPUT: RETVAL void DESTROY(svTHIS) SV * svTHIS; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { delete THIS; } void copy_from(svTHIS, sv) SV * svTHIS SV * sv CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL && sv != NULL ) { if ( sv_derived_from(sv, "Person") ) { IV tmp = SvIV((SV *)SvRV(sv)); ::Person * other = INT2PTR(__Person *, tmp); THIS->CopyFrom(*other); } else if ( SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV ) { ::Person * other = __Person_from_hashref(sv); THIS->CopyFrom(*other); delete other; } } void merge_from(svTHIS, sv) SV * svTHIS SV * sv CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL && sv != NULL ) { if ( sv_derived_from(sv, "Person") ) { IV tmp = SvIV((SV *)SvRV(sv)); ::Person * other = INT2PTR(__Person *, tmp); THIS->MergeFrom(*other); } else if ( SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV ) { ::Person * other = __Person_from_hashref(sv); THIS->MergeFrom(*other); delete other; } } void clear(svTHIS) SV * svTHIS CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { THIS->Clear(); } int is_initialized(svTHIS) SV * svTHIS CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { RETVAL = THIS->IsInitialized(); } else { RETVAL = 0; } OUTPUT: RETVAL SV * error_string(svTHIS) SV * svTHIS PREINIT: string estr; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { estr = THIS->InitializationErrorString(); } RETVAL = newSVpv(estr.c_str(), estr.length()); OUTPUT: RETVAL void discard_unkown_fields(svTHIS) SV * svTHIS CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { THIS->DiscardUnknownFields(); } SV * debug_string(svTHIS) SV * svTHIS PREINIT: string dstr; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { dstr = THIS->DebugString(); } RETVAL = newSVpv(dstr.c_str(), dstr.length()); OUTPUT: RETVAL SV * short_debug_string(svTHIS) SV * svTHIS PREINIT: string dstr; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { dstr = THIS->ShortDebugString(); } RETVAL = newSVpv(dstr.c_str(), dstr.length()); OUTPUT: RETVAL int unpack(svTHIS, arg) SV * svTHIS SV * arg PREINIT: STRLEN len; char * str; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { str = SvPV(arg, len); if ( str != NULL ) { RETVAL = THIS->ParseFromArray(str, len); } else { RETVAL = 0; } } else { RETVAL = 0; } OUTPUT: RETVAL SV * pack(svTHIS) SV * svTHIS CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { RETVAL = newSVpvn("", 0); person_OutputStream os(RETVAL); if ( THIS->IsInitialized() ) { if ( THIS->SerializePartialToZeroCopyStream(&os)!= true ) { SvREFCNT_dec(RETVAL); RETVAL = Nullsv; } else { os.Sync(); } } else { croak("Can't serialize message of type 'Person' because it is +missing required fields: %s", THIS->InitializationErrorString().c_str()); } } else { RETVAL = Nullsv; } OUTPUT: RETVAL int length(svTHIS) SV * svTHIS CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { RETVAL = THIS->ByteSize(); } else { RETVAL = 0; } OUTPUT: RETVAL void fields(svTHIS) SV * svTHIS PPCODE: (void)svTHIS; EXTEND(SP, 3); PUSHs(sv_2mortal(newSVpv("id",0))); PUSHs(sv_2mortal(newSVpv("name",0))); PUSHs(sv_2mortal(newSVpv("email",0))); SV * to_hashref(svTHIS) SV * svTHIS CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { HV * hv0 = newHV(); ::Person * msg0 = THIS; if ( msg0->has_id() ) { SV * sv0 = newSViv(msg0->id()); hv_store(hv0, "id", sizeof("id") - 1, sv0, 0); } if ( msg0->has_name() ) { SV * sv0 = newSVpv(msg0->name().c_str(), msg0->name().length() +); hv_store(hv0, "name", sizeof("name") - 1, sv0, 0); } if ( msg0->has_email() ) { SV * sv0 = newSVpv(msg0->email().c_str(), msg0->email().length +()); hv_store(hv0, "email", sizeof("email") - 1, sv0, 0); } RETVAL = newRV_noinc((SV *)hv0); } else { RETVAL = Nullsv; } OUTPUT: RETVAL I32 has_id(svTHIS) SV * svTHIS; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } RETVAL = THIS->has_id(); OUTPUT: RETVAL void clear_id(svTHIS) SV * svTHIS; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } THIS->clear_id(); void id(svTHIS) SV * svTHIS; PREINIT: SV * sv; PPCODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { EXTEND(SP,1); sv = sv_2mortal(newSViv(THIS->id())); PUSHs(sv); } void set_id(svTHIS, svVAL) SV * svTHIS IV svVAL CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } THIS->set_id(svVAL); I32 has_name(svTHIS) SV * svTHIS; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } RETVAL = THIS->has_name(); OUTPUT: RETVAL void clear_name(svTHIS) SV * svTHIS; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } THIS->clear_name(); void name(svTHIS) SV * svTHIS; PREINIT: SV * sv; PPCODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { EXTEND(SP,1); sv = sv_2mortal(newSVpv(THIS->name().c_str(), THIS->name().length())); PUSHs(sv); } void set_name(svTHIS, svVAL) SV * svTHIS SV *svVAL PREINIT: char * str; STRLEN len; string sval; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } str = SvPV(svVAL, len); sval.assign(str, len); THIS->set_name(sval); I32 has_email(svTHIS) SV * svTHIS; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } RETVAL = THIS->has_email(); OUTPUT: RETVAL void clear_email(svTHIS) SV * svTHIS; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } THIS->clear_email(); void email(svTHIS) SV * svTHIS; PREINIT: SV * sv; PPCODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } if ( THIS != NULL ) { EXTEND(SP,1); sv = sv_2mortal(newSVpv(THIS->email().c_str(), THIS->email().length())); PUSHs(sv); } void set_email(svTHIS, svVAL) SV * svTHIS SV *svVAL PREINIT: char * str; STRLEN len; string sval; CODE: ::Person * THIS; if ( sv_derived_from(svTHIS, "Person") ) { IV tmp = SvIV((SV *)SvRV(svTHIS)); THIS = INT2PTR(__Person *, tmp); } else { croak("THIS is not of type Person"); } str = SvPV(svVAL, len); sval.assign(str, len); THIS->set_email(sval);

    person.pb.h

    // Generated by the protocol buffer compiler. DO NOT EDIT! #ifndef PROTOBUF_person_2eproto__INCLUDED #define PROTOBUF_person_2eproto__INCLUDED #include <string> #include <google/protobuf/stubs/common.h> #if GOOGLE_PROTOBUF_VERSION < 2002000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif #if 2002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. #endif #include <google/protobuf/generated_message_util.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/extension_set.h> #include <google/protobuf/generated_message_reflection.h> // Internal implementation detail -- do not call these. void protobuf_AddDesc_person_2eproto(); void protobuf_AssignDesc_person_2eproto(); void protobuf_ShutdownFile_person_2eproto(); class Person; // =================================================================== class Person : public ::google::protobuf::Message { public: Person(); virtual ~Person(); Person(const Person& from); inline Person& operator=(const Person& from) { CopyFrom(from); return *this; } inline const ::google::protobuf::UnknownFieldSet& unknown_fields() c +onst { return _unknown_fields_; } inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() + { return &_unknown_fields_; } static const ::google::protobuf::Descriptor* descriptor(); static const Person& default_instance(); void Swap(Person* other); // implements Message ---------------------------------------------- Person* New() const; void CopyFrom(const ::google::protobuf::Message& from); void MergeFrom(const ::google::protobuf::Message& from); void CopyFrom(const Person& from); void MergeFrom(const Person& from); void Clear(); bool IsInitialized() const; int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google: +:protobuf::uint8* output) const; int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const { _cached_size_ = size; } public: ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- // required int32 id = 1; inline bool has_id() const; inline void clear_id(); static const int kIdFieldNumber = 1; inline ::google::protobuf::int32 id() const; inline void set_id(::google::protobuf::int32 value); // required string name = 2; inline bool has_name() const; inline void clear_name(); static const int kNameFieldNumber = 2; inline const ::std::string& name() const; inline void set_name(const ::std::string& value); inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); // optional string email = 3; inline bool has_email() const; inline void clear_email(); static const int kEmailFieldNumber = 3; inline const ::std::string& email() const; inline void set_email(const ::std::string& value); inline void set_email(const char* value); inline void set_email(const char* value, size_t size); inline ::std::string* mutable_email(); private: ::google::protobuf::UnknownFieldSet _unknown_fields_; mutable int _cached_size_; ::google::protobuf::int32 id_; ::std::string* name_; static const ::std::string _default_name_; ::std::string* email_; static const ::std::string _default_email_; friend void protobuf_AddDesc_person_2eproto(); friend void protobuf_AssignDesc_person_2eproto(); friend void protobuf_ShutdownFile_person_2eproto(); ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? inline bool _has_bit(int index) const { return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; } inline void _set_bit(int index) { _has_bits_[index / 32] |= (1u << (index % 32)); } inline void _clear_bit(int index) { _has_bits_[index / 32] &= ~(1u << (index % 32)); } void InitAsDefaultInstance(); static Person* default_instance_; }; // =================================================================== // =================================================================== // =================================================================== // Person // required int32 id = 1; inline bool Person::has_id() const { return _has_bit(0); } inline void Person::clear_id() { id_ = 0; _clear_bit(0); } inline ::google::protobuf::int32 Person::id() const { return id_; } inline void Person::set_id(::google::protobuf::int32 value) { _set_bit(0); id_ = value; } // required string name = 2; inline bool Person::has_name() const { return _has_bit(1); } inline void Person::clear_name() { if (name_ != &_default_name_) { name_->clear(); } _clear_bit(1); } inline const ::std::string& Person::name() const { return *name_; } inline void Person::set_name(const ::std::string& value) { _set_bit(1); if (name_ == &_default_name_) { name_ = new ::std::string; } name_->assign(value); } inline void Person::set_name(const char* value) { _set_bit(1); if (name_ == &_default_name_) { name_ = new ::std::string; } name_->assign(value); } inline void Person::set_name(const char* value, size_t size) { _set_bit(1); if (name_ == &_default_name_) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* Person::mutable_name() { _set_bit(1); if (name_ == &_default_name_) { name_ = new ::std::string; } return name_; } // optional string email = 3; inline bool Person::has_email() const { return _has_bit(2); } inline void Person::clear_email() { if (email_ != &_default_email_) { email_->clear(); } _clear_bit(2); } inline const ::std::string& Person::email() const { return *email_; } inline void Person::set_email(const ::std::string& value) { _set_bit(2); if (email_ == &_default_email_) { email_ = new ::std::string; } email_->assign(value); } inline void Person::set_email(const char* value) { _set_bit(2); if (email_ == &_default_email_) { email_ = new ::std::string; } email_->assign(value); } inline void Person::set_email(const char* value, size_t size) { _set_bit(2); if (email_ == &_default_email_) { email_ = new ::std::string; } email_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* Person::mutable_email() { _set_bit(2); if (email_ == &_default_email_) { email_ = new ::std::string; } return email_; } #ifndef SWIG namespace google { namespace protobuf { } // namespace google } // namespace protobuf #endif // SWIG #endif // PROTOBUF_person_2eproto__INCLUDED

    person.pb.cc

    // Generated by the protocol buffer compiler. DO NOT EDIT! #define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION #include "person.pb.h" #include <google/protobuf/stubs/once.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/wire_format_lite_inl.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/reflection_ops.h> #include <google/protobuf/wire_format.h> namespace { const ::google::protobuf::Descriptor* Person_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* Person_reflection_ = NULL; } // namespace void protobuf_AssignDesc_person_2eproto() { protobuf_AddDesc_person_2eproto(); const ::google::protobuf::FileDescriptor* file = ::google::protobuf::DescriptorPool::generated_pool()->FindFileByNa +me( "person.proto"); GOOGLE_CHECK(file != NULL); Person_descriptor_ = file->message_type(0); static const int Person_offsets_[3] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, id_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, email_), }; Person_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( Person_descriptor_, Person::default_instance_, Person_offsets_, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, _has_bits +_[0]), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, _unknown_ +fields_), -1, ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(Person)); } namespace { GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); inline void protobuf_AssignDescriptorsOnce() { ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_ +, &protobuf_AssignDesc_person_2eproto); } void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage +( Person_descriptor_, &Person::default_instance()); } } // namespace void protobuf_ShutdownFile_person_2eproto() { delete Person::default_instance_; delete Person_reflection_; } void protobuf_AddDesc_person_2eproto() { static bool already_here = false; if (already_here) return; already_here = true; GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( "\n\014person.proto\"1\n\006Person\022\n\n\002id\030\001 \002(\005 +\022\014\n\004" "name\030\002 \002(\t\022\r\n\005email\030\003 \001(\tB\002H\001", + 69); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "person.proto", &protobuf_RegisterTypes); Person::default_instance_ = new Person(); Person::default_instance_->InitAsDefaultInstance(); ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_pers +on_2eproto); } // Force AddDescriptors() to be called at static initialization time. struct StaticDescriptorInitializer_person_2eproto { StaticDescriptorInitializer_person_2eproto() { protobuf_AddDesc_person_2eproto(); } } static_descriptor_initializer_person_2eproto_; // =================================================================== const ::std::string Person::_default_name_; const ::std::string Person::_default_email_; #ifndef _MSC_VER const int Person::kIdFieldNumber; const int Person::kNameFieldNumber; const int Person::kEmailFieldNumber; #endif // !_MSC_VER Person::Person() { SharedCtor(); } void Person::InitAsDefaultInstance() { } Person::Person(const Person& from) { SharedCtor(); MergeFrom(from); } void Person::SharedCtor() { _cached_size_ = 0; id_ = 0; name_ = const_cast< ::std::string*>(&_default_name_); email_ = const_cast< ::std::string*>(&_default_email_); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } Person::~Person() { SharedDtor(); } void Person::SharedDtor() { if (name_ != &_default_name_) { delete name_; } if (email_ != &_default_email_) { delete email_; } if (this != default_instance_) { } } const ::google::protobuf::Descriptor* Person::descriptor() { protobuf_AssignDescriptorsOnce(); return Person_descriptor_; } const Person& Person::default_instance() { if (default_instance_ == NULL) protobuf_AddDesc_person_2eproto(); r +eturn *default_instance_; } Person* Person::default_instance_ = NULL; Person* Person::New() const { return new Person; } void Person::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { id_ = 0; if (_has_bit(1)) { if (name_ != &_default_name_) { name_->clear(); } } if (_has_bit(2)) { if (email_ != &_default_email_) { email_->clear(); } } } ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); } bool Person::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { #define DO_(EXPRESSION) if (!(EXPRESSION)) return false ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldN +umber(tag)) { // required int32 id = 1; case 1: { if (::google::protobuf::internal::WireFormatLite::GetTagWireTy +pe(tag) != ::google::protobuf::internal::WireFormatLite::WIRETYPE_VAR +INT) { goto handle_uninterpreted; } DO_(::google::protobuf::internal::WireFormatLite::ReadInt32( input, &id_)); _set_bit(0); if (input->ExpectTag(18)) goto parse_name; break; } // required string name = 2; case 2: { if (::google::protobuf::internal::WireFormatLite::GetTagWireTy +pe(tag) != ::google::protobuf::internal::WireFormatLite::WIRETYPE_LEN +GTH_DELIMITED) { goto handle_uninterpreted; } parse_name: DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectTag(26)) goto parse_email; break; } // optional string email = 3; case 3: { if (::google::protobuf::internal::WireFormatLite::GetTagWireTy +pe(tag) != ::google::protobuf::internal::WireFormatLite::WIRETYPE_LEN +GTH_DELIMITED) { goto handle_uninterpreted; } parse_email: DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_email())); ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->email().data(), this->email().length(), ::google::protobuf::internal::WireFormat::PARSE); if (input->ExpectAtEnd()) return true; break; } default: { handle_uninterpreted: if (::google::protobuf::internal::WireFormatLite::GetTagWireTy +pe(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END +_GROUP) { return true; } DO_(::google::protobuf::internal::WireFormat::SkipField( input, tag, mutable_unknown_fields())); break; } } } return true; #undef DO_ } void Person::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { ::google::protobuf::uint8* raw_buffer = output->GetDirectBufferForNB +ytesAndAdvance(_cached_size_); if (raw_buffer != NULL) { Person::SerializeWithCachedSizesToArray(raw_buffer); return; } // required int32 id = 1; if (_has_bit(0)) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this-> +id(), output); } // required string name = 2; if (_has_bit(1)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); ::google::protobuf::internal::WireFormatLite::WriteString( 2, this->name(), output); } // optional string email = 3; if (_has_bit(2)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->email().data(), this->email().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); ::google::protobuf::internal::WireFormatLite::WriteString( 3, this->email(), output); } if (!unknown_fields().empty()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( unknown_fields(), output); } } ::google::protobuf::uint8* Person::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // required int32 id = 1; if (_has_bit(0)) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32T +oArray(1, this->id(), target); } // required string name = 2; if (_has_bit(1)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); target = ::google::protobuf::internal::WireFormatLite::WriteStringToArray +( 2, this->name(), target); } // optional string email = 3; if (_has_bit(2)) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->email().data(), this->email().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); target = ::google::protobuf::internal::WireFormatLite::WriteStringToArray +( 3, this->email(), target); } if (!unknown_fields().empty()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknow +nFieldsToArray( unknown_fields(), target); } return target; } int Person::ByteSize() const { int total_size = 0; if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // required int32 id = 1; if (has_id()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::Int32Size( this->id()); } // required string name = 2; if (has_name()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( this->name()); } // optional string email = 3; if (has_email()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( this->email()); } } if (!unknown_fields().empty()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSi +ze( unknown_fields()); } _cached_size_ = total_size; return total_size; } void Person::MergeFrom(const ::google::protobuf::Message& from) { GOOGLE_CHECK_NE(&from, this); const Person* source = ::google::protobuf::internal::dynamic_cast_if_available<const Pers +on*>( &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { MergeFrom(*source); } } void Person::MergeFrom(const Person& from) { GOOGLE_CHECK_NE(&from, this); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from._has_bit(0)) { set_id(from.id()); } if (from._has_bit(1)) { set_name(from.name()); } if (from._has_bit(2)) { set_email(from.email()); } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } void Person::CopyFrom(const ::google::protobuf::Message& from) { if (&from == this) return; Clear(); MergeFrom(from); } void Person::CopyFrom(const Person& from) { if (&from == this) return; Clear(); MergeFrom(from); } bool Person::IsInitialized() const { if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; return true; } void Person::Swap(Person* other) { if (other != this) { std::swap(id_, other->id_); std::swap(name_, other->name_); std::swap(email_, other->email_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } ::google::protobuf::Metadata Person::GetMetadata() const { protobuf_AssignDescriptorsOnce(); ::google::protobuf::Metadata metadata; metadata.descriptor = Person_descriptor_; metadata.reflection = Person_reflection_; return metadata; }
  • Comment on Protocol Buffers and XS
    Select or Download Code
    Re: Protocol Buffers and XS
    by BenGoldberg (Acolyte) on Dec 28, 2013 at 01:40 UTC

      If you are using Protocol Buffers for cross-language compatibility, it's quite possible that the classes declared in the foo.proto file (person.proto in your example) will clash with the name of some unrelated perl class.

      For example, if someone wrote a Person class, put it on CPAN, and I wanted to use both that Person from CPAN and the example Person class generated by protoxs... I would have a problem.

      It would be very useful to future users of this program if there were an option to allow all of the generated perl modules to have some sort of user-specified prefix.

    Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Node Status?
    node history
    Node Type: CUFP [id://850729]
    Approved by ww
    Front-paged by Arunbear
    help
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others chilling in the Monastery: (5)
    As of 2014-12-20 01:57 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      Is guessing a good strategy for surviving in the IT business?





      Results (95 votes), past polls