Nanopb is a plain-C implementation of Google's Protocol Buffers data format. It is targeted at 32 bit microcontrollers, but is also fit for other embedded systems with tight (2-10 kB ROM, <1 kB RAM) memory constraints.

Dependents:   FBRLogger Dumb_box_rev2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pb_decode.c Source File

pb_decode.c

00001 /* pb_decode.c -- decode a protobuf using minimal resources
00002  *
00003  * 2011 Petteri Aimonen <jpa@kapsi.fi>
00004  */
00005 
00006 /* The warn_unused_result attribute appeared first in gcc-3.4.0 */
00007 #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
00008     #define checkreturn
00009 #else
00010     /* Verify that we remember to check all return values for proper error propagation */
00011     #define checkreturn __attribute__((warn_unused_result))
00012 #endif
00013 
00014 #define NANOPB_INTERNALS
00015 #include "pb.h"
00016 #include "pb_decode.h"
00017 #include <string.h>
00018 
00019 typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn;
00020 
00021 /* --- Function pointers to field decoders ---
00022  * Order in the array must match pb_action_t LTYPE numbering.
00023  */
00024 static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
00025     &pb_dec_varint,
00026     &pb_dec_svarint,
00027     &pb_dec_fixed32,
00028     &pb_dec_fixed64,
00029     
00030     &pb_dec_bytes,
00031     &pb_dec_string,
00032     &pb_dec_submessage
00033 };
00034 
00035 /**************
00036  * pb_istream *
00037  **************/
00038 
00039 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count)
00040 {
00041     uint8_t *source = (uint8_t*)stream->state;
00042     stream->state = source + count;
00043     
00044     if (buf != NULL)
00045     {
00046         while (count--)
00047             *buf++ = *source++;
00048     }
00049     
00050     return true;
00051 }
00052 
00053 bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
00054 {
00055 #ifndef PB_BUFFER_ONLY
00056     if (buf == NULL && stream->callback != buf_read)
00057     {
00058         /* Skip input bytes */
00059         uint8_t tmp[16];
00060         while (count > 16)
00061         {
00062             if (!pb_read(stream, tmp, 16))
00063                 return false;
00064             
00065             count -= 16;
00066         }
00067         
00068         return pb_read(stream, tmp, count);
00069     }
00070 #endif
00071 
00072     if (stream->bytes_left < count)
00073         PB_RETURN_ERROR(stream, "end-of-stream");
00074     
00075 #ifndef PB_BUFFER_ONLY
00076     if (!stream->callback(stream, buf, count))
00077         PB_RETURN_ERROR(stream, "io error");
00078 #else
00079     if (!buf_read(stream, buf, count))
00080         return false;
00081 #endif
00082     
00083     stream->bytes_left -= count;
00084     return true;
00085 }
00086 
00087 pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize)
00088 {
00089     pb_istream_t stream;
00090 #ifdef PB_BUFFER_ONLY
00091     stream.callback = NULL;
00092 #else
00093     stream.callback = &buf_read;
00094 #endif
00095     stream.state = buf;
00096     stream.bytes_left = bufsize;
00097 #ifndef PB_NO_ERRMSG
00098     stream.errmsg = NULL;
00099 #endif
00100     return stream;
00101 }
00102 
00103 /********************
00104  * Helper functions *
00105  ********************/
00106 
00107 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
00108 {
00109     uint8_t byte;
00110     uint32_t result;
00111     
00112     if (!pb_read(stream, &byte, 1))
00113         return false;
00114     
00115     if (!(byte & 0x80))
00116     {
00117         /* Quick case, 1 byte value */
00118         result = byte;
00119     }
00120     else
00121     {
00122         /* Multibyte case */
00123         uint8_t bitpos = 7;
00124         result = byte & 0x7F;
00125         
00126         do
00127         {
00128             if (bitpos >= 32)
00129                 PB_RETURN_ERROR(stream, "varint overflow");
00130             
00131             if (!pb_read(stream, &byte, 1))
00132                 return false;
00133             
00134             result |= (uint32_t)(byte & 0x7F) << bitpos;
00135             bitpos = (uint8_t)(bitpos + 7);
00136         } while (byte & 0x80);
00137    }
00138    
00139    *dest = result;
00140    return true;
00141 }
00142 
00143 bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
00144 {
00145     uint8_t byte;
00146     uint8_t bitpos = 0;
00147     uint64_t result = 0;
00148     
00149     do
00150     {
00151         if (bitpos >= 64)
00152             PB_RETURN_ERROR(stream, "varint overflow");
00153         
00154         if (!pb_read(stream, &byte, 1))
00155             return false;
00156 
00157         result |= (uint64_t)(byte & 0x7F) << bitpos;
00158         bitpos = (uint8_t)(bitpos + 7);
00159     } while (byte & 0x80);
00160     
00161     *dest = result;
00162     return true;
00163 }
00164 
00165 bool checkreturn pb_skip_varint(pb_istream_t *stream)
00166 {
00167     uint8_t byte;
00168     do
00169     {
00170         if (!pb_read(stream, &byte, 1))
00171             return false;
00172     } while (byte & 0x80);
00173     return true;
00174 }
00175 
00176 bool checkreturn pb_skip_string(pb_istream_t *stream)
00177 {
00178     uint32_t length;
00179     if (!pb_decode_varint32(stream, &length))
00180         return false;
00181     
00182     return pb_read(stream, NULL, length);
00183 }
00184 
00185 bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof)
00186 {
00187     uint32_t temp;
00188     *eof = false;
00189     *wire_type = (pb_wire_type_t) 0;
00190     *tag = 0;
00191     
00192     if (!pb_decode_varint32(stream, &temp))
00193     {
00194         if (stream->bytes_left == 0)
00195             *eof = true;
00196 
00197         return false;
00198     }
00199     
00200     if (temp == 0)
00201     {
00202         *eof = true; /* Special feature: allow 0-terminated messages. */
00203         return false;
00204     }
00205     
00206     *tag = temp >> 3;
00207     *wire_type = (pb_wire_type_t)(temp & 7);
00208     return true;
00209 }
00210 
00211 bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type)
00212 {
00213     switch (wire_type)
00214     {
00215         case PB_WT_VARINT: return pb_skip_varint(stream);
00216         case PB_WT_64BIT: return pb_read(stream, NULL, 8);
00217         case PB_WT_STRING: return pb_skip_string(stream);
00218         case PB_WT_32BIT: return pb_read(stream, NULL, 4);
00219         default: PB_RETURN_ERROR(stream, "invalid wire_type");
00220     }
00221 }
00222 
00223 /* Read a raw value to buffer, for the purpose of passing it to callback as
00224  * a substream. Size is maximum size on call, and actual size on return.
00225  */
00226 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size)
00227 {
00228     size_t max_size = *size;
00229     switch (wire_type)
00230     {
00231         case PB_WT_VARINT:
00232             *size = 0;
00233             do
00234             {
00235                 (*size)++;
00236                 if (*size > max_size) return false;
00237                 if (!pb_read(stream, buf, 1)) return false;
00238             } while (*buf++ & 0x80);
00239             return true;
00240             
00241         case PB_WT_64BIT:
00242             *size = 8;
00243             return pb_read(stream, buf, 8);
00244         
00245         case PB_WT_32BIT:
00246             *size = 4;
00247             return pb_read(stream, buf, 4);
00248         
00249         default: PB_RETURN_ERROR(stream, "invalid wire_type");
00250     }
00251 }
00252 
00253 /* Decode string length from stream and return a substream with limited length.
00254  * Remember to close the substream using pb_close_string_substream().
00255  */
00256 bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
00257 {
00258     uint32_t size;
00259     if (!pb_decode_varint32(stream, &size))
00260         return false;
00261     
00262     *substream = *stream;
00263     if (substream->bytes_left < size)
00264         PB_RETURN_ERROR(stream, "parent stream too short");
00265     
00266     substream->bytes_left = size;
00267     stream->bytes_left -= size;
00268     return true;
00269 }
00270 
00271 void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
00272 {
00273     stream->state = substream->state;
00274 
00275 #ifndef PB_NO_ERRMSG
00276     stream->errmsg = substream->errmsg;
00277 #endif
00278 }
00279 
00280 /* Iterator for pb_field_t list */
00281 typedef struct {
00282     const pb_field_t *start; /* Start of the pb_field_t array */
00283     const pb_field_t *current; /* Current position of the iterator */
00284     unsigned field_index; /* Zero-based index of the field. */
00285     unsigned required_field_index; /* Zero-based index that counts only the required fields */
00286     void *dest_struct; /* Pointer to the destination structure to decode to */
00287     void *pData; /* Pointer where to store current field value */
00288     void *pSize; /* Pointer where to store the size of current array field */
00289 } pb_field_iterator_t;
00290 
00291 static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct)
00292 {
00293     iter->start = iter->current = fields;
00294     iter->field_index = 0;
00295     iter->required_field_index = 0;
00296     iter->pData = (char*)dest_struct + iter->current->data_offset;
00297     iter->pSize = (char*)iter->pData + iter->current->size_offset;
00298     iter->dest_struct = dest_struct;
00299 }
00300 
00301 static bool pb_field_next(pb_field_iterator_t *iter)
00302 {
00303     bool notwrapped = true;
00304     size_t prev_size = iter->current->data_size;
00305     
00306     if (PB_HTYPE(iter->current->type) == PB_HTYPE_ARRAY)
00307         prev_size *= iter->current->array_size;
00308     
00309     if (PB_HTYPE(iter->current->type) == PB_HTYPE_REQUIRED)
00310         iter->required_field_index++;
00311     
00312     iter->current++;
00313     iter->field_index++;
00314     if (iter->current->tag == 0)
00315     {
00316         iter->current = iter->start;
00317         iter->field_index = 0;
00318         iter->required_field_index = 0;
00319         iter->pData = iter->dest_struct;
00320         prev_size = 0;
00321         notwrapped = false;
00322     }
00323     
00324     iter->pData = (char*)iter->pData + prev_size + iter->current->data_offset;
00325     iter->pSize = (char*)iter->pData + iter->current->size_offset;
00326     return notwrapped;
00327 }
00328 
00329 static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag)
00330 {
00331     unsigned start = iter->field_index;
00332     
00333     do {
00334         if (iter->current->tag == tag)
00335             return true;
00336         pb_field_next(iter);
00337     } while (iter->field_index != start);
00338     
00339     return false;
00340 }
00341 
00342 /*************************
00343  * Decode a single field *
00344  *************************/
00345 
00346 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
00347 {
00348     pb_decoder_t func = PB_DECODERS[PB_LTYPE(iter->current->type)];
00349     
00350     switch (PB_HTYPE(iter->current->type))
00351     {
00352         case PB_HTYPE_REQUIRED:
00353             return func(stream, iter->current, iter->pData);
00354             
00355         case PB_HTYPE_OPTIONAL:
00356             *(bool*)iter->pSize = true;
00357             return func(stream, iter->current, iter->pData);
00358     
00359         case PB_HTYPE_ARRAY:
00360             if (wire_type == PB_WT_STRING
00361                 && PB_LTYPE(iter->current->type) <= PB_LTYPE_LAST_PACKABLE)
00362             {
00363                 /* Packed array */
00364                 bool status = true;
00365                 size_t *size = (size_t*)iter->pSize;
00366                 pb_istream_t substream;
00367                 if (!pb_make_string_substream(stream, &substream))
00368                     return false;
00369                 
00370                 while (substream.bytes_left && *size < iter->current->array_size)
00371                 {
00372                     void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
00373                     if (!func(&substream, iter->current, pItem))
00374                     {
00375                         status = false;
00376                         break;
00377                     }
00378                     (*size)++;
00379                 }
00380                 pb_close_string_substream(stream, &substream);
00381                 
00382                 if (substream.bytes_left != 0)
00383                     PB_RETURN_ERROR(stream, "array overflow");
00384                 
00385                 return status;
00386             }
00387             else
00388             {
00389                 /* Repeated field */
00390                 size_t *size = (size_t*)iter->pSize;
00391                 void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
00392                 if (*size >= iter->current->array_size)
00393                     PB_RETURN_ERROR(stream, "array overflow");
00394                 
00395                 (*size)++;
00396                 return func(stream, iter->current, pItem);
00397             }
00398         
00399         case PB_HTYPE_CALLBACK:
00400         {
00401             pb_callback_t *pCallback = (pb_callback_t*)iter->pData;
00402             
00403             if (pCallback->funcs.decode == NULL)
00404                 return pb_skip_field(stream, wire_type);
00405             
00406             if (wire_type == PB_WT_STRING)
00407             {
00408                 pb_istream_t substream;
00409                 
00410                 if (!pb_make_string_substream(stream, &substream))
00411                     return false;
00412                 
00413                 while (substream.bytes_left)
00414                 {
00415                     if (!pCallback->funcs.decode(&substream, iter->current, pCallback->arg))
00416                         PB_RETURN_ERROR(stream, "callback failed");
00417                 }
00418                 
00419                 pb_close_string_substream(stream, &substream);
00420                 return true;
00421             }
00422             else
00423             {
00424                 /* Copy the single scalar value to stack.
00425                  * This is required so that we can limit the stream length,
00426                  * which in turn allows to use same callback for packed and
00427                  * not-packed fields. */
00428                 pb_istream_t substream;
00429                 uint8_t buffer[10];
00430                 size_t size = sizeof(buffer);
00431                 
00432                 if (!read_raw_value(stream, wire_type, buffer, &size))
00433                     return false;
00434                 substream = pb_istream_from_buffer(buffer, size);
00435                 
00436                 return pCallback->funcs.decode(&substream, iter->current, pCallback->arg);
00437             }
00438         }
00439         
00440         default:
00441             PB_RETURN_ERROR(stream, "invalid field type");
00442     }
00443 }
00444 
00445 /* Initialize message fields to default values, recursively */
00446 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
00447 {
00448     pb_field_iterator_t iter;
00449     pb_field_init(&iter, fields, dest_struct);
00450     
00451     /* Initialize size/has fields and apply default values */
00452     do
00453     {
00454         if (iter.current->tag == 0)
00455             continue;
00456         
00457         /* Initialize the size field for optional/repeated fields to 0. */
00458         if (PB_HTYPE(iter.current->type) == PB_HTYPE_OPTIONAL)
00459         {
00460             *(bool*)iter.pSize = false;
00461         }
00462         else if (PB_HTYPE(iter.current->type) == PB_HTYPE_ARRAY)
00463         {
00464             *(size_t*)iter.pSize = 0;
00465             continue; /* Array is empty, no need to initialize contents */
00466         }
00467         
00468         /* Initialize field contents to default value */
00469         if (PB_HTYPE(iter.current->type) == PB_HTYPE_CALLBACK)
00470         {
00471             continue; /* Don't overwrite callback */
00472         }
00473         else if (PB_LTYPE(iter.current->type) == PB_LTYPE_SUBMESSAGE)
00474         {
00475             pb_message_set_to_defaults((const pb_field_t *) iter.current->ptr, iter.pData);
00476         }
00477         else if (iter.current->ptr != NULL)
00478         {
00479             memcpy(iter.pData, iter.current->ptr, iter.current->data_size);
00480         }
00481         else
00482         {
00483             memset(iter.pData, 0, iter.current->data_size);
00484         }
00485     } while (pb_field_next(&iter));
00486 }
00487 
00488 /*********************
00489  * Decode all fields *
00490  *********************/
00491 
00492 bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
00493 {
00494     uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0}; /* Used to check for required fields */
00495     pb_field_iterator_t iter;
00496     
00497     pb_field_init(&iter, fields, dest_struct);
00498     
00499     while (stream->bytes_left)
00500     {
00501         uint32_t tag;
00502         pb_wire_type_t wire_type;
00503         bool eof;
00504         
00505         if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
00506         {
00507             if (eof)
00508                 break;
00509             else
00510                 return false;
00511         }
00512         
00513         if (!pb_field_find(&iter, tag))
00514         {
00515             /* No match found, skip data */
00516             if (!pb_skip_field(stream, wire_type))
00517                 return false;
00518             continue;
00519         }
00520         
00521         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED
00522             && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
00523         {
00524             fields_seen[iter.required_field_index >> 3] |= (uint8_t)(1 << (iter.required_field_index & 7));
00525         }
00526             
00527         if (!decode_field(stream, wire_type, &iter))
00528             return false;
00529     }
00530     
00531     /* Check that all required fields were present. */
00532     {
00533         /* First figure out the number of required fields by
00534          * seeking to the end of the field array. Usually we
00535          * are already close to end after decoding.
00536          */
00537         unsigned req_field_count;
00538         pb_type_t last_type;
00539         unsigned i;
00540         do {
00541             req_field_count = iter.required_field_index;
00542             last_type = iter.current->type;
00543         } while (pb_field_next(&iter));
00544         
00545         /* Fixup if last field was also required. */
00546         if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED)
00547             req_field_count++;
00548         
00549         /* Check the whole bytes */
00550         for (i = 0; i < (req_field_count >> 3); i++)
00551         {
00552             if (fields_seen[i] != 0xFF)
00553                 PB_RETURN_ERROR(stream, "missing required field");
00554         }
00555         
00556         /* Check the remaining bits */
00557         if (fields_seen[req_field_count >> 3] != (0xFF >> (8 - (req_field_count & 7))))
00558             PB_RETURN_ERROR(stream, "missing required field");
00559     }
00560     
00561     return true;
00562 }
00563 
00564 bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
00565 {
00566     pb_message_set_to_defaults(fields, dest_struct);
00567     return pb_decode_noinit(stream, fields, dest_struct);
00568 }
00569 
00570 /* Field decoders */
00571 
00572 bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
00573 {
00574     uint64_t value;
00575     if (!pb_decode_varint(stream, &value))
00576         return false;
00577     
00578     if (value & 1)
00579         *dest = (int64_t)(~(value >> 1));
00580     else
00581         *dest = (int64_t)(value >> 1);
00582     
00583     return true;
00584 }
00585 
00586 bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
00587 {
00588     #ifdef __BIG_ENDIAN__
00589     uint8_t *bytes = (uint8_t*)dest;
00590     uint8_t lebytes[4];
00591     
00592     if (!pb_read(stream, lebytes, 4))
00593         return false;
00594     
00595     bytes[0] = lebytes[3];
00596     bytes[1] = lebytes[2];
00597     bytes[2] = lebytes[1];
00598     bytes[3] = lebytes[0];
00599     return true;
00600     #else
00601     return pb_read(stream, (uint8_t*)dest, 4);
00602     #endif   
00603 }
00604 
00605 bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
00606 {
00607     #ifdef __BIG_ENDIAN__
00608     uint8_t *bytes = (uint8_t*)dest;
00609     uint8_t lebytes[8];
00610     
00611     if (!pb_read(stream, lebytes, 8))
00612         return false;
00613     
00614     bytes[0] = lebytes[7];
00615     bytes[1] = lebytes[6];
00616     bytes[2] = lebytes[5];
00617     bytes[3] = lebytes[4];
00618     bytes[4] = lebytes[3];
00619     bytes[5] = lebytes[2];
00620     bytes[6] = lebytes[1];
00621     bytes[7] = lebytes[0];
00622     return true;
00623     #else
00624     return pb_read(stream, (uint8_t*)dest, 8);
00625     #endif   
00626 }
00627 
00628 bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
00629 {
00630     uint64_t value;
00631     bool status = pb_decode_varint(stream, &value);
00632     
00633     switch (field->data_size)
00634     {
00635         case 1: *(uint8_t*)dest = (uint8_t)value; break;
00636         case 2: *(uint16_t*)dest = (uint16_t)value; break;
00637         case 4: *(uint32_t*)dest = (uint32_t)value; break;
00638         case 8: *(uint64_t*)dest = value; break;
00639         default: PB_RETURN_ERROR(stream, "invalid data_size");
00640     }
00641     
00642     return status;
00643 }
00644 
00645 bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
00646 {
00647     int64_t value;
00648     bool status = pb_decode_svarint(stream, &value);
00649     
00650     switch (field->data_size)
00651     {
00652         case 4: *(int32_t*)dest = (int32_t)value; break;
00653         case 8: *(int64_t*)dest = value; break;
00654         default: PB_RETURN_ERROR(stream, "invalid data_size");
00655     }
00656     
00657     return status;
00658 }
00659 
00660 bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)
00661 {
00662     UNUSED(field);
00663     return pb_decode_fixed32(stream, dest);
00664 }
00665 
00666 bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
00667 {
00668     UNUSED(field);
00669     return pb_decode_fixed64(stream, dest);
00670 }
00671 
00672 bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
00673 {
00674     pb_bytes_array_t *x = (pb_bytes_array_t*)dest;
00675     
00676     uint32_t temp;
00677     if (!pb_decode_varint32(stream, &temp))
00678         return false;
00679     x->size = temp;
00680     
00681     /* Check length, noting the space taken by the size_t header. */
00682     if (x->size > field->data_size - offsetof(pb_bytes_array_t, bytes))
00683         PB_RETURN_ERROR(stream, "bytes overflow");
00684     
00685     return pb_read(stream, x->bytes, x->size);
00686 }
00687 
00688 bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest)
00689 {
00690     uint32_t size;
00691     bool status;
00692     if (!pb_decode_varint32(stream, &size))
00693         return false;
00694     
00695     /* Check length, noting the null terminator */
00696     if (size + 1 > field->data_size)
00697         PB_RETURN_ERROR(stream, "string overflow");
00698     
00699     status = pb_read(stream, (uint8_t*)dest, size);
00700     *((uint8_t*)dest + size) = 0;
00701     return status;
00702 }
00703 
00704 bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest)
00705 {
00706     bool status;
00707     pb_istream_t substream;
00708     const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr;
00709     
00710     if (!pb_make_string_substream(stream, &substream))
00711         return false;
00712     
00713     if (field->ptr == NULL)
00714         PB_RETURN_ERROR(stream, "invalid field descriptor");
00715     
00716     /* New array entries need to be initialized, while required and optional
00717      * submessages have already been initialized in the top-level pb_decode. */
00718     if (PB_HTYPE(field->type) == PB_HTYPE_ARRAY)
00719         status = pb_decode(&substream, submsg_fields, dest);
00720     else
00721         status = pb_decode_noinit(&substream, submsg_fields, dest);
00722     
00723     pb_close_string_substream(stream, &substream);
00724     return status;
00725 }