reentrant decode?

28 views
Skip to first unread message

David Jacobowitz

unread,
Sep 30, 2023, 11:41:30 PM9/30/23
to nanopb

I develop on a platform using a custom cooperative task queue and very little memory.

I'd like to decode a largeish protobuf that consists of a few levels of nested repeated submessages, and do it with a minimal of copy buffers. At the bottom of these nests, the data is used to kick off some longer-running activities, like use of a serial port of crypto engine.

Right now I have been experimenting with using callbacks that call callbacks, and at the bottom, rather than copy the bytes into some struct, the function "does something" with those bytes. Typically, those functions will themselves take a completion callback as an argument, but because I am walking a tree I don't have any easy way to pop out and return; I have to wait for the leaf task to complete before decoding the next.

Is there a natural way with nanopb to get a behavior where the pb_decode() function only advances one field through the protobuf and return a pointer to the next thing to decode, rather than running through to completion?

Does that even make sense?

Best,
Dave J


Petteri Aimonen

unread,
Oct 1, 2023, 2:43:16 AM10/1/23
to nan...@googlegroups.com
Hi,

Not with pb_decode(), but using the other functions yes.
I call this "manual decoding" - it is a bit laborious but allows good control
on the decoding process.

Something like:

while (pb_decode_tag(&istream, &wire_type, &tag, &eof))
{
switch (tag)
{
case MyMessage_myfield_tag:
pb_decode_varint(....);

case MyMessage_mysubmsg_tag:
pb_decode_delimited(...);

/* Or alternatively: pb_make_string_substream() and further manual decoding */

...

default:
pb_skip_field(&istream, wire_type);
}
}

Usually you would do this for the top-level message or a few levels, until
you get to the actual contents, and then use pb_decode_delimited() to parse
the submessage containing multiple fields.

--
Petteri

David Jacobowitz

unread,
Oct 1, 2023, 4:04:05 PM10/1/23
to nanopb
Thanks, I'll give this a try!
Reply all
Reply to author
Forward
0 new messages