f012e931074c43bda62d5aebf2d846dbd349a035
[apps/low-level-can-service.git] / pb_decode.c
1 /* pb_decode.c -- decode a protobuf using minimal resources
2  *
3  * 2011 Petteri Aimonen <jpa@kapsi.fi>
4  */
5
6 /* Use the GCC warn_unused_result attribute to check that all return values
7  * are propagated correctly. On other compilers and gcc before 3.4.0 just
8  * ignore the annotation.
9  */
10 #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
11     #define checkreturn
12 #else
13     #define checkreturn __attribute__((warn_unused_result))
14 #endif
15
16 #define NANOPB_INTERNALS
17 #include "pb.h"
18 #include "pb_decode.h"
19
20 /**************************************
21  * Declarations internal to this file *
22  **************************************/
23
24 /* Iterator for pb_field_t list */
25 typedef struct {
26     const pb_field_t *start; /* Start of the pb_field_t array */
27     const pb_field_t *pos; /* Current position of the iterator */
28     unsigned field_index; /* Zero-based index of the field. */
29     unsigned required_field_index; /* Zero-based index that counts only the required fields */
30     void *dest_struct; /* Pointer to the destination structure to decode to */
31     void *pData; /* Pointer where to store current field value */
32     void *pSize; /* Pointer where to store the size of current array field */
33 } pb_field_iterator_t;
34
35 typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn;
36
37 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count);
38 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest);
39 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size);
40 static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct);
41 static bool pb_field_next(pb_field_iterator_t *iter);
42 static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag);
43 static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
44 static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
45 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
46 static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type);
47 static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
48 static bool checkreturn find_extension_field(pb_field_iterator_t *iter);
49 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct);
50
51 /* --- Function pointers to field decoders ---
52  * Order in the array must match pb_action_t LTYPE numbering.
53  */
54 static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
55     &pb_dec_varint,
56     &pb_dec_svarint,
57     &pb_dec_fixed32,
58     &pb_dec_fixed64,
59     
60     &pb_dec_bytes,
61     &pb_dec_string,
62     &pb_dec_submessage,
63     NULL /* extensions */
64 };
65
66 /*******************************
67  * pb_istream_t implementation *
68  *******************************/
69
70 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count)
71 {
72     uint8_t *source = (uint8_t*)stream->state;
73     stream->state = source + count;
74     
75     if (buf != NULL)
76     {
77         while (count--)
78             *buf++ = *source++;
79     }
80     
81     return true;
82 }
83
84 bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
85 {
86 #ifndef PB_BUFFER_ONLY
87         if (buf == NULL && stream->callback != buf_read)
88         {
89                 /* Skip input bytes */
90                 uint8_t tmp[16];
91                 while (count > 16)
92                 {
93                         if (!pb_read(stream, tmp, 16))
94                                 return false;
95                         
96                         count -= 16;
97                 }
98                 
99                 return pb_read(stream, tmp, count);
100         }
101 #endif
102
103     if (stream->bytes_left < count)
104         PB_RETURN_ERROR(stream, "end-of-stream");
105     
106 #ifndef PB_BUFFER_ONLY
107     if (!stream->callback(stream, buf, count))
108         PB_RETURN_ERROR(stream, "io error");
109 #else
110     if (!buf_read(stream, buf, count))
111         return false;
112 #endif
113     
114     stream->bytes_left -= count;
115     return true;
116 }
117
118 pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize)
119 {
120     pb_istream_t stream;
121 #ifdef PB_BUFFER_ONLY
122     stream.callback = NULL;
123 #else
124     stream.callback = &buf_read;
125 #endif
126     stream.state = buf;
127     stream.bytes_left = bufsize;
128 #ifndef PB_NO_ERRMSG
129     stream.errmsg = NULL;
130 #endif
131     return stream;
132 }
133
134 /********************
135  * Helper functions *
136  ********************/
137
138 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
139 {
140     uint8_t byte;
141     uint32_t result;
142     
143     if (!pb_read(stream, &byte, 1))
144         return false;
145     
146     if (!(byte & 0x80))
147     {
148         /* Quick case, 1 byte value */
149         result = byte;
150     }
151     else
152     {
153         /* Multibyte case */
154         uint8_t bitpos = 7;
155         result = byte & 0x7F;
156         
157         do
158         {
159             if (bitpos >= 32)
160                 PB_RETURN_ERROR(stream, "varint overflow");
161             
162             if (!pb_read(stream, &byte, 1))
163                 return false;
164             
165             result |= (uint32_t)(byte & 0x7F) << bitpos;
166             bitpos = (uint8_t)(bitpos + 7);
167         } while (byte & 0x80);
168    }
169    
170    *dest = result;
171    return true;
172 }
173
174 bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
175 {
176     uint8_t byte;
177     uint8_t bitpos = 0;
178     uint64_t result = 0;
179     
180     do
181     {
182         if (bitpos >= 64)
183             PB_RETURN_ERROR(stream, "varint overflow");
184         
185         if (!pb_read(stream, &byte, 1))
186             return false;
187
188         result |= (uint64_t)(byte & 0x7F) << bitpos;
189         bitpos = (uint8_t)(bitpos + 7);
190     } while (byte & 0x80);
191     
192     *dest = result;
193     return true;
194 }
195
196 bool checkreturn pb_skip_varint(pb_istream_t *stream)
197 {
198     uint8_t byte;
199     do
200     {
201         if (!pb_read(stream, &byte, 1))
202             return false;
203     } while (byte & 0x80);
204     return true;
205 }
206
207 bool checkreturn pb_skip_string(pb_istream_t *stream)
208 {
209     uint32_t length;
210     if (!pb_decode_varint32(stream, &length))
211         return false;
212     
213     return pb_read(stream, NULL, length);
214 }
215
216 bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof)
217 {
218     uint32_t temp;
219     *eof = false;
220     *wire_type = (pb_wire_type_t) 0;
221     *tag = 0;
222     
223     if (!pb_decode_varint32(stream, &temp))
224     {
225         if (stream->bytes_left == 0)
226             *eof = true;
227
228         return false;
229     }
230     
231     if (temp == 0)
232     {
233         *eof = true; /* Special feature: allow 0-terminated messages. */
234         return false;
235     }
236     
237     *tag = temp >> 3;
238     *wire_type = (pb_wire_type_t)(temp & 7);
239     return true;
240 }
241
242 bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type)
243 {
244     switch (wire_type)
245     {
246         case PB_WT_VARINT: return pb_skip_varint(stream);
247         case PB_WT_64BIT: return pb_read(stream, NULL, 8);
248         case PB_WT_STRING: return pb_skip_string(stream);
249         case PB_WT_32BIT: return pb_read(stream, NULL, 4);
250         default: PB_RETURN_ERROR(stream, "invalid wire_type");
251     }
252 }
253
254 /* Read a raw value to buffer, for the purpose of passing it to callback as
255  * a substream. Size is maximum size on call, and actual size on return.
256  */
257 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size)
258 {
259     size_t max_size = *size;
260     switch (wire_type)
261     {
262         case PB_WT_VARINT:
263             *size = 0;
264             do
265             {
266                 (*size)++;
267                 if (*size > max_size) return false;
268                 if (!pb_read(stream, buf, 1)) return false;
269             } while (*buf++ & 0x80);
270             return true;
271             
272         case PB_WT_64BIT:
273             *size = 8;
274             return pb_read(stream, buf, 8);
275         
276         case PB_WT_32BIT:
277             *size = 4;
278             return pb_read(stream, buf, 4);
279         
280         default: PB_RETURN_ERROR(stream, "invalid wire_type");
281     }
282 }
283
284 /* Decode string length from stream and return a substream with limited length.
285  * Remember to close the substream using pb_close_string_substream().
286  */
287 bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
288 {
289     uint32_t size;
290     if (!pb_decode_varint32(stream, &size))
291         return false;
292     
293     *substream = *stream;
294     if (substream->bytes_left < size)
295         PB_RETURN_ERROR(stream, "parent stream too short");
296     
297     substream->bytes_left = size;
298     stream->bytes_left -= size;
299     return true;
300 }
301
302 void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
303 {
304     stream->state = substream->state;
305
306 #ifndef PB_NO_ERRMSG
307     stream->errmsg = substream->errmsg;
308 #endif
309 }
310
311 static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct)
312 {
313     iter->start = iter->pos = fields;
314     iter->field_index = 0;
315     iter->required_field_index = 0;
316     iter->pData = (char*)dest_struct + iter->pos->data_offset;
317     iter->pSize = (char*)iter->pData + iter->pos->size_offset;
318     iter->dest_struct = dest_struct;
319 }
320
321 static bool pb_field_next(pb_field_iterator_t *iter)
322 {
323     bool notwrapped = true;
324     size_t prev_size = iter->pos->data_size;
325     
326     if (PB_ATYPE(iter->pos->type) == PB_ATYPE_STATIC &&
327         PB_HTYPE(iter->pos->type) == PB_HTYPE_REPEATED)
328     {
329         prev_size *= iter->pos->array_size;
330     }
331     
332     if (iter->pos->tag == 0)
333         return false; /* Only happens with empty message types */
334     
335     if (PB_HTYPE(iter->pos->type) == PB_HTYPE_REQUIRED)
336         iter->required_field_index++;
337     
338     iter->pos++;
339     iter->field_index++;
340     if (iter->pos->tag == 0)
341     {
342         iter->pos = iter->start;
343         iter->field_index = 0;
344         iter->required_field_index = 0;
345         iter->pData = iter->dest_struct;
346         prev_size = 0;
347         notwrapped = false;
348     }
349     
350     iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset;
351     iter->pSize = (char*)iter->pData + iter->pos->size_offset;
352     return notwrapped;
353 }
354
355 static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag)
356 {
357     unsigned start = iter->field_index;
358     
359     do {
360         if (iter->pos->tag == tag &&
361             PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION)
362         {
363             return true;
364         }
365         pb_field_next(iter);
366     } while (iter->field_index != start);
367     
368     return false;
369 }
370
371 /*************************
372  * Decode a single field *
373  *************************/
374
375 static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
376 {
377     pb_type_t type;
378     pb_decoder_t func;
379     
380     type = iter->pos->type;
381     func = PB_DECODERS[PB_LTYPE(type)];
382
383     switch (PB_HTYPE(type))
384     {
385         case PB_HTYPE_REQUIRED:
386             return func(stream, iter->pos, iter->pData);
387             
388         case PB_HTYPE_OPTIONAL:
389             *(bool*)iter->pSize = true;
390             return func(stream, iter->pos, iter->pData);
391     
392         case PB_HTYPE_REPEATED:
393             if (wire_type == PB_WT_STRING
394                 && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE)
395             {
396                 /* Packed array */
397                 bool status = true;
398                 size_t *size = (size_t*)iter->pSize;
399                 pb_istream_t substream;
400                 if (!pb_make_string_substream(stream, &substream))
401                     return false;
402                 
403                 while (substream.bytes_left && *size < iter->pos->array_size)
404                 {
405                     void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size);
406                     if (!func(&substream, iter->pos, pItem))
407                     {
408                         status = false;
409                         break;
410                     }
411                     (*size)++;
412                 }
413                 pb_close_string_substream(stream, &substream);
414                 
415                 if (substream.bytes_left != 0)
416                     PB_RETURN_ERROR(stream, "array overflow");
417                 
418                 return status;
419             }
420             else
421             {
422                 /* Repeated field */
423                 size_t *size = (size_t*)iter->pSize;
424                 void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size);
425                 if (*size >= iter->pos->array_size)
426                     PB_RETURN_ERROR(stream, "array overflow");
427                 
428                 (*size)++;
429                 return func(stream, iter->pos, pItem);
430             }
431
432         default:
433             PB_RETURN_ERROR(stream, "invalid field type");
434     }
435 }
436
437 static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
438 {
439     pb_callback_t *pCallback = (pb_callback_t*)iter->pData;
440     
441 #ifdef PB_OLD_CALLBACK_STYLE
442     void *arg = pCallback->arg;
443 #else
444     void **arg = &(pCallback->arg);
445 #endif
446     
447     if (pCallback->funcs.decode == NULL)
448         return pb_skip_field(stream, wire_type);
449     
450     if (wire_type == PB_WT_STRING)
451     {
452         pb_istream_t substream;
453         
454         if (!pb_make_string_substream(stream, &substream))
455             return false;
456         
457         do
458         {
459             if (!pCallback->funcs.decode(&substream, iter->pos, arg))
460                 PB_RETURN_ERROR(stream, "callback failed");
461         } while (substream.bytes_left);
462         
463         pb_close_string_substream(stream, &substream);
464         return true;
465     }
466     else
467     {
468         /* Copy the single scalar value to stack.
469          * This is required so that we can limit the stream length,
470          * which in turn allows to use same callback for packed and
471          * not-packed fields. */
472         pb_istream_t substream;
473         uint8_t buffer[10];
474         size_t size = sizeof(buffer);
475         
476         if (!read_raw_value(stream, wire_type, buffer, &size))
477             return false;
478         substream = pb_istream_from_buffer(buffer, size);
479         
480         return pCallback->funcs.decode(&substream, iter->pos, arg);
481     }
482 }
483
484 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
485 {
486     switch (PB_ATYPE(iter->pos->type))
487     {
488         case PB_ATYPE_STATIC:
489             return decode_static_field(stream, wire_type, iter);
490         
491         case PB_ATYPE_CALLBACK:
492             return decode_callback_field(stream, wire_type, iter);
493         
494         default:
495             PB_RETURN_ERROR(stream, "invalid field type");
496     }
497 }
498
499 /* Default handler for extension fields. Expects a pb_field_t structure
500  * in extension->type->arg. */
501 static bool checkreturn default_extension_decoder(pb_istream_t *stream,
502     pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type)
503 {
504     const pb_field_t *field = (const pb_field_t*)extension->type->arg;
505     pb_field_iterator_t iter;
506     bool dummy;
507     
508     if (field->tag != tag)
509         return true;
510     
511     iter.start = field;
512     iter.pos = field;
513     iter.field_index = 0;
514     iter.required_field_index = 0;
515     iter.dest_struct = extension->dest;
516     iter.pData = extension->dest;
517     iter.pSize = &dummy;
518     
519     return decode_field(stream, wire_type, &iter);
520 }
521
522 /* Try to decode an unknown field as an extension field. Tries each extension
523  * decoder in turn, until one of them handles the field or loop ends. */
524 static bool checkreturn decode_extension(pb_istream_t *stream,
525     uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
526 {
527     pb_extension_t *extension = *(pb_extension_t* const *)iter->pData;
528     size_t pos = stream->bytes_left;
529     
530     while (extension && pos == stream->bytes_left)
531     {
532         bool status;
533         if (extension->type->decode)
534             status = extension->type->decode(stream, extension, tag, wire_type);
535         else
536             status = default_extension_decoder(stream, extension, tag, wire_type);
537
538         if (!status)
539             return false;
540         
541         extension = extension->next;
542     }
543     
544     return true;
545 }
546
547 /* Step through the iterator until an extension field is found or until all
548  * entries have been checked. There can be only one extension field per
549  * message. Returns false if no extension field is found. */
550 static bool checkreturn find_extension_field(pb_field_iterator_t *iter)
551 {
552     unsigned start = iter->field_index;
553     
554     do {
555         if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION)
556             return true;
557         pb_field_next(iter);
558     } while (iter->field_index != start);
559     
560     return false;
561 }
562
563 /* Initialize message fields to default values, recursively */
564 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
565 {
566     pb_field_iterator_t iter;
567     pb_field_init(&iter, fields, dest_struct);
568     
569     /* Initialize size/has fields and apply default values */
570     do
571     {
572         pb_type_t type;
573         type = iter.pos->type;
574     
575         if (iter.pos->tag == 0)
576             continue;
577         
578         if (PB_ATYPE(type) == PB_ATYPE_STATIC)
579         {
580             /* Initialize the size field for optional/repeated fields to 0. */
581             if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL)
582             {
583                 *(bool*)iter.pSize = false;
584             }
585             else if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
586             {
587                 *(size_t*)iter.pSize = 0;
588                 continue; /* Array is empty, no need to initialize contents */
589             }
590             
591             /* Initialize field contents to default value */
592             if (PB_LTYPE(iter.pos->type) == PB_LTYPE_SUBMESSAGE)
593             {
594                 pb_message_set_to_defaults((const pb_field_t *) iter.pos->ptr, iter.pData);
595             }
596             else if (iter.pos->ptr != NULL)
597             {
598                 memcpy(iter.pData, iter.pos->ptr, iter.pos->data_size);
599             }
600             else
601             {
602                 memset(iter.pData, 0, iter.pos->data_size);
603             }
604         }
605         else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK)
606         {
607             continue; /* Don't overwrite callback */
608         }
609     } while (pb_field_next(&iter));
610 }
611
612 /*********************
613  * Decode all fields *
614  *********************/
615
616 bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
617 {
618     uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0}; /* Used to check for required fields */
619     uint32_t extension_range_start = 0;
620     pb_field_iterator_t iter;
621     
622     pb_field_init(&iter, fields, dest_struct);
623     
624     while (stream->bytes_left)
625     {
626         uint32_t tag;
627         pb_wire_type_t wire_type;
628         bool eof;
629         
630         if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
631         {
632             if (eof)
633                 break;
634             else
635                 return false;
636         }
637         
638         if (!pb_field_find(&iter, tag))
639         {
640             /* No match found, check if it matches an extension. */
641             if (tag >= extension_range_start)
642             {
643                 if (!find_extension_field(&iter))
644                     extension_range_start = (uint32_t)-1;
645                 else
646                     extension_range_start = iter.pos->tag;
647                 
648                 if (tag >= extension_range_start)
649                 {
650                     size_t pos = stream->bytes_left;
651                 
652                     if (!decode_extension(stream, tag, wire_type, &iter))
653                         return false;
654                     
655                     if (pos != stream->bytes_left)
656                     {
657                         /* The field was handled */
658                         continue;                    
659                     }
660                 }
661             }
662         
663             /* No match found, skip data */
664             if (!pb_skip_field(stream, wire_type))
665                 return false;
666             continue;
667         }
668         
669         if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED
670             && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
671         {
672             fields_seen[iter.required_field_index >> 3] |= (uint8_t)(1 << (iter.required_field_index & 7));
673         }
674             
675         if (!decode_field(stream, wire_type, &iter))
676             return false;
677     }
678     
679     /* Check that all required fields were present. */
680     {
681         /* First figure out the number of required fields by
682          * seeking to the end of the field array. Usually we
683          * are already close to end after decoding.
684          */
685         unsigned req_field_count;
686         pb_type_t last_type;
687         unsigned i;
688         do {
689             req_field_count = iter.required_field_index;
690             last_type = iter.pos->type;
691         } while (pb_field_next(&iter));
692         
693         /* Fixup if last field was also required. */
694         if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag)
695             req_field_count++;
696         
697         /* Check the whole bytes */
698         for (i = 0; i < (req_field_count >> 3); i++)
699         {
700             if (fields_seen[i] != 0xFF)
701                 PB_RETURN_ERROR(stream, "missing required field");
702         }
703         
704         /* Check the remaining bits */
705         if (fields_seen[req_field_count >> 3] != (0xFF >> (8 - (req_field_count & 7))))
706             PB_RETURN_ERROR(stream, "missing required field");
707     }
708     
709     return true;
710 }
711
712 bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
713 {
714     pb_message_set_to_defaults(fields, dest_struct);
715     return pb_decode_noinit(stream, fields, dest_struct);
716 }
717
718 bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
719 {
720     pb_istream_t substream;
721     bool status;
722     
723     if (!pb_make_string_substream(stream, &substream))
724         return false;
725     
726     status = pb_decode(&substream, fields, dest_struct);
727     pb_close_string_substream(stream, &substream);
728     return status;
729 }
730
731 /* Field decoders */
732
733 bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
734 {
735     uint64_t value;
736     if (!pb_decode_varint(stream, &value))
737         return false;
738     
739     if (value & 1)
740         *dest = (int64_t)(~(value >> 1));
741     else
742         *dest = (int64_t)(value >> 1);
743     
744     return true;
745 }
746
747 bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
748 {
749     #ifdef __BIG_ENDIAN__
750     uint8_t *bytes = (uint8_t*)dest;
751     uint8_t lebytes[4];
752     
753     if (!pb_read(stream, lebytes, 4))
754         return false;
755     
756     bytes[0] = lebytes[3];
757     bytes[1] = lebytes[2];
758     bytes[2] = lebytes[1];
759     bytes[3] = lebytes[0];
760     return true;
761     #else
762     return pb_read(stream, (uint8_t*)dest, 4);
763     #endif   
764 }
765
766 bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
767 {
768     #ifdef __BIG_ENDIAN__
769     uint8_t *bytes = (uint8_t*)dest;
770     uint8_t lebytes[8];
771     
772     if (!pb_read(stream, lebytes, 8))
773         return false;
774     
775     bytes[0] = lebytes[7];
776     bytes[1] = lebytes[6];
777     bytes[2] = lebytes[5];
778     bytes[3] = lebytes[4];
779     bytes[4] = lebytes[3];
780     bytes[5] = lebytes[2];
781     bytes[6] = lebytes[1];
782     bytes[7] = lebytes[0];
783     return true;
784     #else
785     return pb_read(stream, (uint8_t*)dest, 8);
786     #endif   
787 }
788
789 bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
790 {
791     uint64_t value;
792     if (!pb_decode_varint(stream, &value))
793         return false;
794     
795     switch (field->data_size)
796     {
797         case 1: *(uint8_t*)dest = (uint8_t)value; break;
798         case 2: *(uint16_t*)dest = (uint16_t)value; break;
799         case 4: *(uint32_t*)dest = (uint32_t)value; break;
800         case 8: *(uint64_t*)dest = value; break;
801         default: PB_RETURN_ERROR(stream, "invalid data_size");
802     }
803     
804     return true;
805 }
806
807 bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
808 {
809     int64_t value;
810     if (!pb_decode_svarint(stream, &value))
811         return false;
812     
813     switch (field->data_size)
814     {
815         case 4: *(int32_t*)dest = (int32_t)value; break;
816         case 8: *(int64_t*)dest = value; break;
817         default: PB_RETURN_ERROR(stream, "invalid data_size");
818     }
819     
820     return true;
821 }
822
823 bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)
824 {
825     UNUSED(field);
826     return pb_decode_fixed32(stream, dest);
827 }
828
829 bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
830 {
831     UNUSED(field);
832     return pb_decode_fixed64(stream, dest);
833 }
834
835 bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
836 {
837     pb_bytes_array_t *x = (pb_bytes_array_t*)dest;
838     
839     uint32_t temp;
840     if (!pb_decode_varint32(stream, &temp))
841         return false;
842     x->size = temp;
843     
844     /* Check length, noting the space taken by the size_t header. */
845     if (x->size > field->data_size - offsetof(pb_bytes_array_t, bytes))
846         PB_RETURN_ERROR(stream, "bytes overflow");
847     
848     return pb_read(stream, x->bytes, x->size);
849 }
850
851 bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest)
852 {
853     uint32_t size;
854     bool status;
855     if (!pb_decode_varint32(stream, &size))
856         return false;
857     
858     /* Check length, noting the null terminator */
859     if (size + 1 > field->data_size)
860         PB_RETURN_ERROR(stream, "string overflow");
861     
862     status = pb_read(stream, (uint8_t*)dest, size);
863     *((uint8_t*)dest + size) = 0;
864     return status;
865 }
866
867 bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest)
868 {
869     bool status;
870     pb_istream_t substream;
871     const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr;
872     
873     if (!pb_make_string_substream(stream, &substream))
874         return false;
875     
876     if (field->ptr == NULL)
877         PB_RETURN_ERROR(stream, "invalid field descriptor");
878     
879     /* New array entries need to be initialized, while required and optional
880      * submessages have already been initialized in the top-level pb_decode. */
881     if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED)
882         status = pb_decode(&substream, submsg_fields, dest);
883     else
884         status = pb_decode_noinit(&substream, submsg_fields, dest);
885     
886     pb_close_string_substream(stream, &substream);
887     return status;
888 }