Ejemplo n.º 1
0
void descriptorTests(){
// Objective is to make this Server class independent of generated protobuf structures
// Move dependency from compile/link-time to run-time.
//
// Read the allProto.desc file descriptor set 
// File generated by protoc --descriptor_set_out=allProto.desc path/to/proto-files.proto (performed by make)
//
//  c++ fstream method for opening the file
//    fstream in("allProto.desc", ios::in | ios::binary);
//    io::IstreamInputStream raw_in(&in);

//  cfile is a c file descriptor (not to be confused with a protobuf FileDescriptor object)
    int cfile = open("allProto.desc", O_RDONLY);
    FileDescriptorSet fds;
//  Parse a FileDescriptorSet object directly from the file
//  Has the format of a protobuf Message - subclass FileDescriptorSet, defined in <google/protobuf/descriptor.pb.h>
//  https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor.pb#FieldOptions_CType.details
    fds.ParseFromFileDescriptor(cfile);
//  Use FileDescriptorSet method to print to screen
    fds.SerializeToOstream(&cout);


// Re-open file. Example of an alternative means for reading 
// FileInputStream
    cfile = open("allProto.desc", O_RDONLY);
    io::FileInputStream fis(cfile);
// Another means may be to use a CodedInputStream, but don't need the extra features at this time
//    e.g.  io::CodedInputStream cis(fis); See http://www.mail-archive.com/[email protected]/msg03417.html
    const void* buffer;
    int size;
    while(fis.Next(&buffer, &size)){
      cout.write((const char*)buffer, size);
      cout << endl << size << endl;
    }
// End of alternative read example
    close(cfile);
	
	

// fds is a protobuf message containing a collection of FileDescriptorProto objects (Message instances)
// There are (several?) ways to convert such objects into live Descriptor objects

// How many files in the set?
    cout << "Num protos " << fds.file_size() << endl;
	
    FileDescriptorProto  fdp;
// Example of indexing and examining properties
    fdp = fds.file(1);
    cout << fdp.name() << endl;

// A DescriptorPool is required: provides methods to identify and manage message types at run-time
// DescriptorPool can be populated from a SimpleDescriptorDatabase, which can be populated with FileDescriptorProto objects
    SimpleDescriptorDatabase sddb;
    for ( int i = 0; i < fds.file_size() ; i++ ){
	   //Iterate over the "file" collection in the FileDescriptorSet
	   //Populate the sddb
       sddb.Add(fds.file(i));
    }
	// Now construct the DescriptorPool
    DescriptorPool dp(&sddb);

	// DynamicMessageFactory is constucted from a populated DescriptorPool
	// DescriptorPool, Descriptor, FieldDescriptor etc.: see descriptor.h  - 
	// https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor
    DynamicMessageFactory dmf(&dp);
    const Descriptor* desc;
    desc = dp.FindMessageTypeByName("Person");
	// Example of dynamically creating a message from a Descriptor, retrieved by name string
    Message *msg = dmf.GetPrototype(desc)->New();

	// Messages with required fields - Need populated. 
	// Requires FieldDescriptor objects to access
    const FieldDescriptor* idField = desc->FindFieldByName("id");
    const FieldDescriptor* nameField = desc->FindFieldByName("name");

	// Reflection object provides R/W access to dynamic message fields, using FieldDescriptors
	// 
	// https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message#Message.GetReflection.details
	// Good example of Reflection at top of that page
    const Reflection *msgRefl = msg->GetReflection();
    msgRefl->SetInt32( msg, idField, 8123);
    msgRefl->SetString( msg, nameField, "Does it work?");

	//Now that required fields are populated, the dynamic message can be serialized and printed out.
    string data;
   // msg->SerializeToString(&data);
    cout << data << endl;

	// Useful examples of dynamic protobuf logic here : http://www.programmershare.com/2803644/
	// (English not very good)
	// 3.4 also describes dynamic compilation Uses google::protobuf::compiler Importer class
	// Another link : dynamic stuff : 
    //  http://stackoverflow.com/questions/11996557/how-to-dynamically-build-a-new-protobuf-from-a-set-of-already-defined-descriptor
	//  https://bitbucket.org/g19fanatic/prototest/src/dfd73a577dcc9bb51cbb3e99319cad352bfc60a8/src/main.cpp?at=master&fileviewer=file-view-default

}