Search code examples
cprotocol-buffersnanopb

nanopb : get the size of repeated submessages


For a project, I'm trying to decode a repeated number of structs, which I have to fill into a dynamically allocated array, but for this to work, I need to know how many elements the repeated submessage has, in order to allocate the right size beforehand. I'm working with a variable size for the repeated submessages (with no upper limit), so I can't use max_size.

But I can't seem to find any way to retrieve the number of submessages beforehand.

So, does anybody know how to find out the number of submessages in a repeated field?

My only other option I can think of, is to temporarily use a linked list to keep track of all the information, and then after decoding copying the information into an array, but that seems very cumbersome and dirty.


Solution

  • Nanopb by itself optionally supports dynamic allocation, which uses realloc() to incrementally expand the allocated array. To use this, you would define [(nanopb).type = FT_POINTER] in the .proto, and use PB_ENABLE_MALLOC compiler define.

    If you want to count the number of items in the repeated field beforehand, you could use a field callback. Then you could replace the callback with a different one that stores the items in the array and decode the message again. Ideally though you could process the data directly in the callback, instead of storing it to RAM in between.

    However, if this is a memory constrained embedded system (which is what nanopb mainly targets), I would suggest just deciding a reasonable maximum and setting max_size to it. That way if you run out of memory, it will be immediately apparent in testing as the maximum needed amount is always allocated. On systems with small amounts of RAM, you cannot assume that dynamic allocation will predictably succeed. Effects such as memory fragmentation can cause allocations to fail depending on what sequence of allocations has been previously performed.