Nanopb has a heavier interface for including sub-messages. Here's an example, from their union structure:

// This is an example of how to handle 'union' style messages
// with nanopb, without allocating memory for all the message types.
//
// There is no official type in Protocol Buffers for describing unions,
// but they are commonly implemented by filling out exactly one of
// several optional fields.

message MsgType1 {
    required int32 value = 1;
}

message MsgType2 {
    required bool value = 1;
}

message MsgType3 {
    required int32 value1 = 1;
    required int32 value2 = 2;
}

message UnionMessage {
    optional MsgType1 msg1 = 1;
    optional MsgType2 msg2 = 2;
    optional MsgType3 msg3 = 3;
}


it's encoded with:

/* This function is the core of the union encoding process. It handles
 * the top-level pb_field_t array manually, in order to encode a correct
 * field tag before the message. The pointer to MsgType_fields array is
 * used as an unique identifier for the message type.
 */
bool encode_unionmessage(pb_ostream_t *stream, const pb_field_t messagetype[], 
const void *message)
{
    const pb_field_t *field;
    for (field = UnionMessage_fields; field->tag != 0; field++)
    {
        if (field->ptr == messagetype)
        {
            /* This is our field, encode the message using it. */
            if (!pb_encode_tag_for_field(stream, field))
                return false;
return pb_encode_submessage(stream, messagetype, message);
        }
    }
/* Didn't find the field for messagetype */
    return false;
}

Their low-level code is necessary because "Usually, nanopb would allocate space to store all of the possible messages at the same time, even though at most one of them will be used at a time. "


My library would encode such a thing by calling the top-level (auto-generated) function:
buf = UnionMessage_to_string(&len, (MY_UnionMessage *)&test);

and providing copy functions for each message. The auto-generated example code to use the interface is below:

void protowr_MsgType1(MsgType1 *out, MY_MsgType1 *a) {
    out->value = a->value;
}
void protowr_MsgType2(MsgType2 *out, MY_MsgType2 *a) {
    out->value = a->value;
}
void protowr_MsgType3(MsgType3 *out, MY_MsgType3 *a) {
    out->value1 = a->value1;
    out->value2 = a->value2;
}
// of course, the programmer would modify this to a case() statement.
void protowr_UnionMessage(UnionMessage *out, MY_UnionMessage *a) {
    out->has_msg1 = a->has_msg1;
    if(a->has_msg1) {
        out->msg1 = a->msg1;
    }
    out->has_msg2 = a->has_msg2;
    if(a->has_msg2) {
        out->msg2 = a->msg2;
    }
    out->has_msg3 = a->has_msg3;
    if(a->has_msg3) {
        out->msg3 = a->msg3;
    }
}

There is no dealing with the byte-level encoding at this level, only copying between a shallow parsed format and your own output data structure, one message at a time. It also doesn't litter message-specific field tags or names anywhere - only high-level, per-message encoding/decoding functions. I don't know if nanopb does this, but some implementations do.

Hope that helps,
~ David.

On 7/25/15 12:40 AM, Michael Haberler wrote:
Hi David,

Am 23.07.2015 um 22:47 schrieb David Rogers <predictivestatm...@gmail.com>:

sprotoc - short for stack protocol buffer compiler is a C-code generator for 
protocol buffers.
It lives at: https://github.com/frobnitzem/sprotoc

I coded it up a year ago and have been using it happily since.
What makes it unique is the ability to write your own copy in/out functions
for each message type so that you aren't stuck with creating a copy of a large 
recursive data structure.
It generates example copy functions so you can get going without reading 
excessive documentation.
how is that different from nanopb (http://koti.kapsi.fi/~jpa/nanopb/) ?

- Michael


--
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 protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
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 protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
Visit this group at http://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.

Reply via email to