On Mon, Sep 8, 2014 at 10:32 PM, Jan Kyjovský <[email protected]>
wrote:
> 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);
>
Have you checked the return value of these two method calls?
>
> // Suppose you want to parse a message type with a specific type name.
> const Descriptor* descriptor = pool.FindMessageTypeByName("AddressBook");
>
Does this return NULL or non-NULL? If it's the later, it means you have
successfully constructed the descriptor for 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]>
>> 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].
>>> 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.
>>>
>>
>> --
> 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.
>
--
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.