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 ?

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. 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 ?

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 ?

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






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>
>
> > > > .
> > > > 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