Protobuf Examples C++ and Java (2)

This sample .proto is taken from http://www.indelible.org/ink/protobuf-polymorphism/. Also see example 1

animal.proto


 package animal;

option java_outer_classname = "Animals";

message Cat
{
    optional bool declawed = 1;
}

message Dog
{
    optional uint32 bones_buried = 1;
}

message Animal
{
    required float weight = 1;
    optional Dog dog = 2;
    optional Cat cat = 3;
}

animal.cpp


#include 
#include "animal.pb.h"
using namespace std;
using namespace animal;

int main()
{
  Cat cat1;
  cat1.set_declawed(true);

  Animal animal;
  animal.set_weight(10.4);
  Cat* cat = animal.mutable_cat();

  cat->set_declawed(true);


  Dog *dog = animal.mutable_dog();
  dog->set_bones_buried (32);

  string s;
  animal.SerializeToString(&s);

  Animal animal2;

  animal2.ParseFromString(s);

  printf("weight %f\n", animal2.weight());

  if (animal.has_cat())
  {
    printf("cat %d\n", animal.cat().declawed());
  }

  if (animal.has_dog())
  {
    printf("dog %d\n", animal.dog().bones_buried());
  }

  return 0;
} 

animal.java


import animal.Animals;
import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.*;
import java.io.IOException;

 
class AnimalExample {

 
    public static void main(String[] args) throws Exception {

        Animals.Animal animal =  Animals.Animal.newBuilder().
            setWeight(10.4F)
            .setDog(Animals.Dog.newBuilder().setBonesBuried(32).build())
            .setCat(Animals.Cat.newBuilder().setDeclawed(true).build())
            .build();
        
        

        byte[] data = animal.toByteArray();

        Animals.Animal animal2 = Animals.Animal.newBuilder().mergeFrom(data).build();
        
        System.out.println("Animal weight " + animal2.getWeight());

        if (animal2.hasCat()) {

            System.out.println("Cat " + animal2.getCat().getDeclawed());
        }

        if (animal2.hasDog()){
            System.out.println("Dog " + animal2.getDog().getBonesBuried());
        }
    }
    
}
 

Protobuf Examples for C++ and Java (1)

This sample .proto is taken from http://blog.wolfman.com/articles/2011/11/23/how-to-implement-polymorphic-protocol-buffers-in-java. The groovy is rewritten in Java and C++. Also see example 2

example.proto


package example;

option java_outer_classname = "Commands";

message BaseCommand {
        extensions 100 to max;

        enum CommandType {
                VERSION = 1;
                LOGIN   = 2;
        }
        required CommandType type = 1;
}


message Version {
        extend BaseCommand {
                required Version cmd = 100;
        }

        required fixed32 protocol = 1;
        required fixed32 versions = 2;
}

message Login {
        extend BaseCommand {
                required Login cmd = 101;
        }
        required string username = 1;
        required string password = 2;
}

example.cpp


#include 
#include "example.pb.h"
using namespace std;
using namespace example;

int main()
{
  string sl;


  BaseCommand b;


#if 0
  Version ver;
  ver.set_versions(10);
  ver.set_protocol(15);

  
  b.MutableExtension(Version::cmd)->set_versions(10);
  b.MutableExtension(Version::cmd)->set_protocol(15);

  b.set_type( BaseCommand::VERSION);
#else
  b.set_type( BaseCommand::LOGIN);

  b.MutableExtension(Login::cmd)->set_username("rain");
  b.MutableExtension(Login::cmd)->set_password("heavy");
  

#endif
  b.SerializeToString(&sl);


  printf("%d\n", sl.length());

  BaseCommand* bcmd = new BaseCommand();
  if (bcmd->ParseFromString(sl))
  {
    printf("ParsePartialFromString ok\n");
  }
  

  printf("%d\n", bcmd->type());
  switch(bcmd->type())
  {
    case BaseCommand::LOGIN:
    {
      printf("login\n");
      printf("%s %s\n", b.MutableExtension(Login::cmd)->username().c_str(), b.MutableExtension(Login::cmd)->password().c_str());

      break;
    }
    case BaseCommand::VERSION:
    {
      printf("version\n");


      printf("%d %d\n", b.MutableExtension(Version::cmd)->versions(), b.MutableExtension(Version::cmd)->protocol());
      break;
    }
    default:
      break;
  }

  return 1;
}

example.java


import example.Commands;
import example.Commands.BaseCommand;
import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.ExtensionRegistry;
import java.io.IOException;

 
class ProtoBufExample {
        // Helper which wraps the BaseCommand around the extension command
        static  BaseCommand wrap(BaseCommand.CommandType type, GeneratedMessage.GeneratedExtension extension, Type cmd) {
                return BaseCommand.newBuilder().setType(type).setExtension(extension, cmd).build();
        }
 
        ExtensionRegistry registry;
 
        ProtoBufExample() {
                // we need to register all the extensions and tell the decoder about them
                // otherwise the extension will be ignored
                registry= ExtensionRegistry.newInstance();
                Commands.registerAllExtensions(registry);
        }
 
        BaseCommand buildVersion(int v1, int v2) {
                Commands.Version vers= Commands.Version.newBuilder().setProtocol(v1).setVersions(v2).build();
                // BaseCommand bcmd= BaseCommand.newBuilder().setType(BaseCommand.CommandType.VERSION).setExtension(Commands.Version.cmd, vers).build();
                return wrap(BaseCommand.CommandType.VERSION, Commands.Version.cmd, vers);
        }
 
        BaseCommand buildLogin(String username, String password) {
                Commands.Login l= Commands.Login.newBuilder().setUsername(username).setPassword(password).build();
                return wrap(BaseCommand.CommandType.LOGIN, Commands.Login.cmd, l);
        }
 
        BaseCommand decodeIt(byte [] ba) {
                // use the registry so extensions will be decoded
            try{
                BaseCommand b=BaseCommand.newBuilder().mergeFrom(ba, registry).build();
                return b;
            }
            catch (IOException e) {
                System.out.println("Unable to create  " +e.getMessage());
                return buildVersion(0,1);
            }

        }

 
    public static void main(String[] args) throws Exception {
        ProtoBufExample pb= new ProtoBufExample();
        BaseCommand b= pb.buildVersion(1234, 5678);
        //BaseCommand b= pb.buildLogin("user1", "test");
 
        System.out.println(b);
        System.out.println ("size: " + b.toByteArray().length);
 
        BaseCommand decoded= pb.decodeIt(b.toByteArray());
 
        System.out.println ("We got a "+ decoded.getType() +" message");
 
        // We can switch on the CommandType enum and extract the specific command type (extension) we got
        switch(decoded.getType()) {
        case VERSION:
            System.out.println (decoded.getExtension(Commands.Version.cmd));
            break;
                
        case LOGIN:
            System.out.println (decoded.getExtension(Commands.Login.cmd));
            break;
 
        default:
            System.out.println ("Don't know this type");
        }
    }
    
}

Using Protobuf


C++


$ SRC_DIR=`pwd`
$ ../protobuf-2.4.1/src/protoc -I=$SRC_DIR --cpp_out=. $SRC_DIR/addressbook.proto

$ g++ addressbook.pb.cc writeMsg.cpp -o writeMsg -I ../protobuf-2.4.1/src -L ../protobuf-2.4.1/src/.libs/ -l protobuf

$ export LD_LIBRARY_PATH=../protobuf-2.4.1/src/.libs

$ ./writeMsg address.txt

$ g++ addressbook.pb.cc readMsg.cpp -o readMsg -I ../protobuf-2.4.1/src -L ../protobuf-2.4.1/src/.libs/ -l protobuf

$ ./readMsg address.txt

Person ID: 12
  Name: me
  E-mail address: me@t.net
  Home phone #: 123533333

$ ls
addressbook.pb.cc  addressbook.proto  readMsg      writeMsg
addressbook.pb.h   address.txt        readMsg.cpp  writeMsg.cpp

Java


 ../protobuf-2.4.1/src/protoc  --java_out=../protobuf-2.4.1/java/src/main/java -I ../protobuf-2.4.1/src ../protobuf-2.4.1/src/google/protobuf/descriptor.proto

cd ../protobuf-2.4.1/java/src/main/java/com/google/protobuf
javac *
cd -

export CLASSPATH=../protobuf-2.4.1/java/src/main/java:.

javac com/example/tutorial/Addressbook.java 

javac writeMsg.java

java AddPerson

javac readMsg.java 

java ListPeople ../c++/address.txt

Person ID: 12
  Name: me
  E-mail address: me@t.net
  Home phone #: 123533333

Current Week Number

$ date +%W
42

rpmbuild with rpmrc

RPM_DIR=`pwd`/rpm
echo "%_topdir $RPM_DIR" > rpmmacros
echo "macrofiles:     /usr/lib/rpm/macros:/usr/lib/rpm/%{_target}/macros:/usr/lib/rpm/redhat/macros:/etc/rpm/macros.*:/etc/rpm/macros:/etc/rpm/%{_target}/macros:~/.rpmmacros:rpmmacros" > rpmrc

mkdir -p $RPM_DIR/{BUILD,RPMS,SOURCES,SPECS,SRPMS}

rpmbuild --rcfile rpmrc --rebuild some.source.rpm

rpmbuild --rcfile rpmrc --define 'dist .el5' -without java -without python \
 --target=x86_64 -ba rpm/SPECS/protobuf.spec
or redefine topdir as
rpmbuild --define "_topdir /home/user/rpmdir" --define 'dist .el5' \
 -without java -without python  --target=x86_64 -ba rpm/SPECS/protobuf.spec

use one thread to build for easy debugging
$ cat ~/.rpmmacros 
%_smp_mflags  -j1

RPM Spec File

Show Spec Macros

rpm --showrc
rpm --eval %{_tmppath}
rpm --eval %{_libdir}

Variables

${LINUX_VERSION}   # shell environment var
%{LINUX_VERSION}     # marco var
%define LINUX_VERSION ${LINUX_VERSION}    # ${LINUX_VERSION} not evaluated
%define LINUX_VERSION $(echo ${LINUX_VERSION}) # evaluated ${LINUX_VERSION}= 2.6.32.1

More Macros

http://www.rpm.org/wiki/PackagerDocs/Macros