On Fri, Apr 2, 2010 at 6:20 PM, Navin <ng06d...@gmail.com> wrote:

> I went on a tangent with the use of TextFormat::Parse. I somehow
> thought that would help me read the data, but you have clarified, that
> would not work.
>
> So I think we are back to what you originally outlined. I believe i do
> NEED the descriptor files. Correct ?
>

Yes, you need them in order to use DynamicMessage.


>
> 1.  //Open the descriptor file that I generated using protoc
>         ifstream desc_file("E:\\Visual Studio 2008\\Projects\\proto_buf1\
> \msg.protocomp",ios::in|ios::binary);
>
>
> 2.      FileDescriptorSet f;
>        f.ParseFromIstream(&desc_file);
>
> 3. //Create a descriptor pool.
>         DescriptorPool descriptor_pool;
>        for (int i = 0; i < f.file_size(); ++i) {
>                        descriptor_pool.BuildFile(f.file(i));
>        }
>
> 4.  //Get a descriptor from the pool given the "name" of the message.
>     const Descriptor* descriptor =
> descriptor_pool.FindMessageTypeByName("...");
>
> 5.// Using the descriptor get a Message.
>         DynamicMessageFactory factory;
>        Message* my_message = factory.GetPrototype(descriptor)->New();
>
>
> 6. // Now can I use something  like this to read it and print it out.
>        ifstream serialized_data_file("E:\\Visual Studio 2008\\Projects\
> \proto_buf1\\person.pb",ios::in);
>        my_message->ParseFromIstream(&serialized_data_file)
>
>        my_message->PrintDebugString();
>
>
> Can you confirm this is right.


Yep, looks good.

I could not find ONE example on the net
> to do this. So the idea is if I have all the descriptor files, I can
> read any of the serialized messages. Correct ?
>

Assuming you know the type of the serialized message, yes.


>
> Lastly, is there a way to read-in all the descriptor files together
> and create ONE descriptor pool ? Can I just add to the single instance
> of descriptor_pool above ?
>

I'm not sure what you mean by this. In the snippet above you're adding all
the files in the FileDescriptorSet to the same instance of DescriptorPool.
What would you like to do instead?


>
> Thanks a lot. Protobuf should add an example to their package.


Would the use in dynamic_message_unittest.cc have helped? It basically does
what's described here, except it gets the descriptor protos from the
compiled-in types.


>
>
>
>
>
> On Apr 2, 6:21 pm, Jason Hsueh <jas...@google.com> wrote:
> > On Fri, Apr 2, 2010 at 2:40 PM, Navin <ng06d...@gmail.com> wrote:
> > > I believe I get the piece about constructing a message for a specific
> > > type given a descriptor file.
> >
> > > About your last statement:
> > > "If person.pb contains the serialized (binary) data for your proto,
> > > you
> > > should be using one of the Message::ParseFrom* routines. "
> >
> > > My understanding was I needed a "Person" object, before I could use
> > > the "Parse" routines and hence I went through this trail of getting a
> > > descriptor file and then constructing a Message(of type Person) and
> > > then using that to Parse.
> >
> > I was just trying to differentiate between the serialized format and the
> > text format. In your original email you stated that the file contained
> the
> > serialized data. However, the code snippet you gave was using
> > TextFormat::Parse. You should only use that method to parse data produced
> by
> > TextFormat::Print. The routines in Message deal with the serialized
> format.
> >
> >
> >
> > > Are you saying that I do not need any descriptors etc at all. Given
> > > ANY data file (which is a serialized proto buf file) I can use
> > > Message::Parse and print it out ???
> >
> > Message is an abstract class. Given the serialized data and an instance
> of
> > Message, you can invoke ParseFrom*. The trick is getting the instance of
> > Message - you either need to use the correct generated class (in this
> case
> > Person), or else use DynamicMessage to emulate that type. Since you want
> > your code to work with arbitrary types, and not be constrained to reading
> > encoded data for a Person message, you should use DynamicMessage. Does
> that
> > make sense?
> >
> >
> >
> > > For e.g. I see that protoc --decode_raw < person.pb does indeed print
> > > it out correctly (without any descriptor OR any .proto file), so I
> > > think this may be possible.
> >
> > This just reads the wire format without any type information. The wire
> > format is a dense encoding and many field types may be represented using
> the
> > same encoding, so doing this will not necessarily give you the data you
> > want. For instance, doubles and fixed size 64-bit integers are encoded in
> > the same way on the wire. If you had serialized a message containing a
> > double field, --decode_raw would interpret that data as a 64-bit little
> > endian value - it doesn't know that the value is actually a double.
> >
> >
> >
> > > In summary all I want to do is given ANY serialized message in a file,
> > > I want to load it and print its contents out. That all.
> >
> > > Thanks again.
> >
> > > On Apr 2, 1:42 pm, Jason Hsueh <jas...@google.com> wrote:
> > > > On Fri, Apr 2, 2010 at 9:13 AM, Navin <ng06d...@gmail.com> wrote:
> > > > > 1. For the person example, I create a descriptor as follows:
> > > > > "E:\Desktop\prototype_MAIN\protoc.exe" person.proto --
> > > > > descriptor_set_out=msg.protocomp
> >
> > > > > 2. I create a Person object and serialized it to file. "person.pb"
> >
> > > > > 3. I want to write a program to "print" the Person object using
> ONLY
> > > > > its descriptor. I know there is a way, but I cannot seem to get all
> > > > > the APIs correct.
> >
> > > > > 4. Here is what I have done.
> > > > >        ifstream desc_file("E:\\Visual Studio 2008\\Projects\
> > > > > \proto_buf1\\msg.protocomp",ios::in);
> > > > >        if (desc_file.bad()) {
> > > > >                std::cout << "desc file not read...exiting" <<
> > > std::endl;
> > > > >                return -1;
> > > > >        }
> >
> > > > >        FileDescriptorSet f;
> > > > >        f.ParseFromIstream(&desc_file);
> >
> > > >        f.PrintDebugString();
> >
> > > > >        FileDescriptorProto fdp = f.file(0);
> > > > >        fdp.PrintDebugString();
> >
> > > > >        DescriptorProto dp = fdp.message_type(0);
> > > > >        dp.PrintDebugString();
> >
> > > > > Now what ? I need a copy of "Message" that I can pass as input to
> > > > > Parse, I think. I also may need DynamicMessage etc, and possibly
> also
> > > > > the following:
> >
> > > > Yes, you should construct a DynamicMessage. To do this, you'll need
> to
> > > build
> > > > the descriptor protos into a pool. For instance:
> >
> > > > DescriptorPool descriptor_pool;
> > > > for (int i = 0; i < f.file_size(); ++i) {
> > > >   descriptor_pool.BuildFile(f.file(i));}
> >
> > > > const Descriptor* descriptor =
> > > descriptor_pool.FindMessageTypeByName("...");
> > > > DynamicMessageFactory factory;
> > > > Message* my_message = factory.GetPrototype(descriptor)->New();
> > > > ...
> > > > delete my_message;
> >
> > > > (You should probably check the return values of most of these calls -
> > > > BuildFile() may return NULL, for instance. You also probably want to
> have
> > > > some mechanism for specifying the message type, since you generally
> won't
> > > be
> > > > able to assume that it's the first message in the first file)
> >
> > > > >        ifstream input_file("E:\\Visual Studio 2008\\Projects\
> > > > > \proto_buf1\\Debug\\person.pb",ios::in);
> > > > >        if (input_file.bad()) {
> > > > >                std::cout << "file not read...exiting" << std::endl;
> > > > >                return -1;
> > > > >        }
> >
> > > > >        IstreamInputStream is(&input_file);
> >
> > > > >        TextFormat::Parse(&is,(msg));
> >
> > > > If person.pb contains the serialized (binary) data for your proto,
> you
> > > > should be using one of the Message::ParseFrom* routines.
> >
> > > > >        msg->PrintDebugString();
> >
> > > > > Any simple example is GREATLY appreciated. Thanks.
> >
> > > > > --
> > > > > You received this message because you are subscribed to the Google
> > > Groups
> > > > > "Protocol Buffers" group.
> > > > > To post to this group, send email to proto...@googlegroups.com.
> > > > > To unsubscribe from this group, send email to
> > > > > protobuf+unsubscr...@googlegroups.com<protobuf%2bunsubscr...@googlegroups.com>
> <protobuf%2bunsubscr...@googlegroups.com<protobuf%252bunsubscr...@googlegroups.com>
> >
> > > <protobuf%2bunsubscr...@googlegroups.com<protobuf%252bunsubscr...@googlegroups.com>
> <protobuf%252bunsubscr...@googlegroups.com<protobuf%25252bunsubscr...@googlegroups.com>
> >
> >
> > > > > .
> > > > > For more options, visit this group at
> > > > >http://groups.google.com/group/protobuf?hl=en.
> >
> > > --
> > > You received this message because you are subscribed to the Google
> Groups
> > > "Protocol Buffers" group.
> > > To post to this group, send email to proto...@googlegroups.com.
> > > To unsubscribe from this group, send email to
> > > protobuf+unsubscr...@googlegroups.com<protobuf%2bunsubscr...@googlegroups.com>
> <protobuf%2bunsubscr...@googlegroups.com<protobuf%252bunsubscr...@googlegroups.com>
> >
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/protobuf?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Protocol Buffers" group.
> To post to this group, send email to proto...@googlegroups.com.
> To unsubscribe from this group, send email to
> protobuf+unsubscr...@googlegroups.com<protobuf%2bunsubscr...@googlegroups.com>
> .
> For more options, visit this group at
> http://groups.google.com/group/protobuf?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To post to this group, send email to proto...@googlegroups.com.
To unsubscribe from this group, send email to 
protobuf+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en.

Reply via email to