Yay !!!! It works. Thanks a lot. I will post the complete solution for
the AddressBook example, in case someone else faces the same issues as
me.

My only other question was , I have many different .proto files and
hence I would have multiple descriptor files for them (wait is that
true. I believe one can create a single descriptor file for many
different .proto files. So then I would have only ONE descriptor for
all my different messages. Correct ?). Else I would read all the
descriptor files individually and then add them to the same descriptor
pool.  (and I hope that would be possible. Thats what my question
was).

Lastly, I struggled for 4 hours today and could not find an example.
The problem was really finding the relationships between all the
classes. It was not obvious until you pointed them out. Thanks a lot.
Maybe the unit test file would have helped, but having a
straightforward example is even better.

// proto_generic.cpp : Defines the entry point for the console
application.
//


#include <iostream>
#include <fstream>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/descriptor.h>


using namespace google;
using namespace google::protobuf;
using namespace google::protobuf::io;


int _tmain(int argc, _TCHAR* argv[])
{
                // Verify that the version of the library that we linked 
against is
                // compatible with the version of the headers we compiled 
against.
                GOOGLE_PROTOBUF_VERIFY_VERSION;

                //Read in the descriptor file
                ifstream desc_file("E:\\Visual Studio 
2008\\Projects\\proto_buf1\
\addressbook.dsc",ios::in|ios::binary);
                if (!desc_file.good()) {
                        std::cout << "desc file not read...exiting" << 
std::endl;
                        return -1;
                }

                FileDescriptorSet f;
                f.ParseFromIstream(&desc_file);
                f.PrintDebugString();
                std::cout << std::endl;

                //Create a descriptor pool.
        DescriptorPool descriptor_pool;
        for (int i = 0; i < f.file_size(); ++i) {
                        descriptor_pool.BuildFile(f.file(i));
        }

                //Get a descriptor from the pool given the "name" of the 
message.
                const Descriptor* descriptor =
descriptor_pool.FindMessageTypeByName("tutorial.AddressBook");

                // Using the descriptor get a Message.
                DynamicMessageFactory factory;
                Message* my_message = factory.GetPrototype(descriptor)->New();

                //Read in the data file
                ifstream serialized_data_file("E:\\Visual Studio 2008\\Projects\
\proto_buf1\\addressbook.data",ios::in|ios::binary);
                if (!serialized_data_file.good()) {
                        std::cout << "file not read...exiting" << std::endl;
                        return -1;
                }
                my_message->ParseFromIstream(&serialized_data_file);

                //Print out the message
                my_message->PrintDebugString();

                // Optional:  Delete all global objects allocated by 
libprotobuf.
                google::protobuf::ShutdownProtobufLibrary();

                return 0;
}












On Apr 2, 9:39 pm, Jason Hsueh <jas...@google.com> wrote:
> 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