Hi,
sorry for delay. I've been experimenting with that eve since I could return
to this issue. Mostly about composition of project since whenever I try
separate your sources from projects and use them individually I§ve been
getting tons of errors (linking one included). In the end I get along with
static library linked in my project. But putting that aside.
I haven't get as far as to use all your example. I am stuck and fact that
when asking pool for specific message I am getting empty default descriptor
as result. I am attaching my code so far could you please advise where I am
making mistake?
Its just short program where I was trying to figure out how to use it.
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <string>
#include <vector>
#include "descriptor.h"
#include "descriptor.pb.h"
#include "zero_copy_stream_impl.h"
#include "tokenizer.h"
#include "parser.h"
#include "substitute.h"
#include "dynamic_message.h"
using namespace google::protobuf;
class ParserErrorCollector : public io::ErrorCollector
{
public:
ParserErrorCollector() {}
~ParserErrorCollector() {}
std::string text_;
// implements ErrorCollector -------------------------------------
void AddError(int line, int column, const std::string& message)
{
strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", line + 1, column + 1,
message);
}
void AddWarning(int line, int column, const std::string& message)
{
AddError(line, column, "WARNING:" + message);
}
};
bool ParseProtoFile(std::string strFileName, FileDescriptorProto* result);
void main()
{
std::string strFile =
"C:\\Users\\kyjovjan\\Desktop\\ProtoExperiment\\addressbook.proto";
// Build the descriptor pool
DescriptorPool pool;
FileDescriptorProto proto;
ParseProtoFile(strFile, &proto);
pool.BuildFile(proto);
// Suppose you want to parse a message type with a specific type name.
const Descriptor* descriptor = pool.FindMessageTypeByName("AddressBook");
DynamicMessageFactory factory;
Message *message = factory.GetPrototype(descriptor)->New();
}
// Convert .proto files into parsed FileDescriptorProto
bool ParseProtoFile(std::string strFileName, FileDescriptorProto* result)
{
int file_descriptor = open(strFileName.c_str(), O_RDONLY);
ParserErrorCollector errCollector;
io::FileInputStream stream(file_descriptor);
stream.SetCloseOnDelete(true);
io::Tokenizer tokenizer(&stream, &errCollector);
compiler::Parser parser;
return parser.Parse(&tokenizer, result);
return true;
}
On Tuesday, 12 August 2014 19:36:13 UTC+2, Feng Xiao wrote:
>
> Protobuf supports creating message types dynamically at runtime and use
> them for parsing/serialization/etc.
>
> First you need to build up a DescriptorPool
> <https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.h#1141>
>
> that contains all types that you may want to use. There are two approaches
> to construct this pool. One is to call DescriptorPool::BuildFile() directly
> with parsed proto files. For example:
> // Convert .proto files into parsed FileDescriptorProto
> bool ParseProtoFile(string filename, FileDescriptorProto* result) {
> FileInputStream stream(filename);
> google::protobuf::io::Tokenizer tokenizer(&stream);
> google::protobuf::compiler::Parser parser;
> return parser.Parse(&tokenizer, result);
> }
> // Build the descriptor pool
> DescriptorPool pool;
> for (string filename : proto_files) {
> FileDescriptorProto proto;
> ParseProtoFile(filename, &proto);
> pool.BuildFile(proto);
> }
>
> After you have the pool, you can query for a type by its name. For
> example, DescriptorPool::FindMessageTypeByName().
>
> Then to actually parse/serialize/use message types in the pool, you need
> to construct message objects around them. DynamicMessage
> <https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/dynamic_message.h#53>
>
> is used for that:
> // Suppose you want to parse a message type with a specific type name.
> Descriptor* descriptor =
> pool.FindMessageTypeByName(message_type_to_parse);
> DynamicMessageFactory factory;
> unique_ptr<Message> message = factory.GetPrototype(descriptor)->New();
> // Use the message object for parsing/etc.
> message->ParseFromString(input_data);
> // Access a specific field in the message
> FieldDescriptor* field = descriptor->FindFieldByName(field_to_read);
> switch (field->type()) {
> case TYPE_INT32: message->GetReflection()->GetInt32(*message, field);
> break;
> ...
> }
>
> On Mon, Aug 11, 2014 at 9:31 PM, Jan Kyjovský <[email protected]
> <javascript:>> wrote:
>
>> Hi,
>>
>> I have very specific problem. I have data and proto file available and my
>> application should take both and based on external configuration determine
>> how to interpret data (many different types/messages in proto). Yet that
>> can be determine only during run. My question is if there is any support
>> for that, I mean that I will be able to parse proto and decode data based
>> on content of interpret intermediate structures.
>>
>> I have been trying to analyze this possibility directly from codes but
>> not with much success. I would be glad for any guidance.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Protocol Buffers" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected] <javascript:>.
>> To post to this group, send email to [email protected]
>> <javascript:>.
>> Visit this group at http://groups.google.com/group/protobuf.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
--
You received this message because you are subscribed to the Google Groups
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.