If you want to serialize them as one message, make your definition do
exactly that:
message CombinedTypes {
optional int32 int32_val = 1;
optional double double_val = 2;
optional float float_val = 3;
}
Note that you can make the code generator produce effectively the same code
you describe by just defining a wrapper message
message CombinedTypes {
optional Proto_int int_msg = 1;
optional Proto_double double_msg = 2;
optional Proto_float float_msg = 3;
}
When serializing, it does:
1) write tag and type (1, LENGTH_DELIMITED) for Proto_int (e.g., the enum
value you were writing)
2) write length (out->WriteVarint32(int_msg.ByteSize() - you should _not_
use sizeof)
3) write the data
Repeat for double/float. Likewise the generated parsing code will handle
everything for you. The first approach is more efficient though.
On Wed, Aug 25, 2010 at 1:00 AM, bongo <[email protected]> wrote:
> Hi,
>
> I am trying to string up multiple messages of different C++ built-in
> types into one message. Conceptually, it's something like:
>
> codedstream << int_x << float_y << double_z;
>
> I am thinking of implementing:
>
> =====================
> .proto File
> =====================
>
> enum Type
> {
> // Enums that correspond to
> // C++ built-in types
> Tint = 0;
> Tdouble = 0;
> Tfloat = 0;
> }
>
> Proto_int { required int val = 1; }
> Proto_double { required double val = 1; }
> Proto_float { required float val = 1; }
>
> =====================
> C++ code to
> write built-in
> types to protobuf
> =====================
>
> sos = new StringOutputStream(&buf);
> out = new CodedOutputStream(&sos);
>
> ...
>
> // We want to write all 3 of these in ONE protobuf message
> double d = 123.0;
> int i = 456;
> float f = 789.0f;
>
> // Create the messages
> Proto_int msg_int;
> Proto_double msg_double;
> Proto_float msg_float;
>
> msg_int.set_val(i);
> msg_double.set_val(d);
> msg_float.set_val(f);
>
> // Write out the messages:
>
> // 1. First, write out the size of the message ...
> out->WriteVarint32(sizeof(msg_int));
>
> // 2. then the type (so that we know how to parse it when we read
> back) ...
> // QUESTION: WriteVarint32 is used to write ints, what should I use
> to
> // write double/float?
> out->WriteVarint32(Tint);
>
> // 3. then the message itself
> msg_int.SerializeToCodedStream(&out);
>
> // Then repeat 1 - 3 for double and float, using msg_double/Tdouble
> and msg_float/Tfloat respectively.
>
> =====================
> code to READ from
> protobuf and reconstruct
> built-in types
> =====================
>
> bool read() {
>
> ArrayInputStream ais(static_cast<const void *>(&buf[0]),
> buf.size());
> CodedInputStream in(&ais);
>
> google::protobuf::uint32 type = 0;
> google::protobuf::uint32 size = 0;
>
> if (!in.ReadVarint32(&size)) return false;
>
> while(size) {
> if (!in.ReadVarint32(&type)) return false;
>
> CodedInputStream::Limit limit = in.PushLimit(size);
> switch(type) {
> case Tdouble:
> {
> Proto_double p;
> p.ParseFromCodedStream(&in);
> }
> break;
> ... similar code for Tint and Tfloat
> }
>
> =====================
> Question
> =====================
> The above scheme feels very inefficient, and I suspect I am probably
> doing it wrong.
> For example, do I really need to make dummy wrappers like this:
> "Proto_int { required int val = 1; }"
> What is the correct way to achieve my goal stated above?
>
> --
> You received this message because you are subscribed to the Google Groups
> "Protocol Buffers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<protobuf%[email protected]>
> .
> 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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/protobuf?hl=en.