Clean up one (uint64_t) cast.
[apps/agl-service-can-low-level.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 /* The warn_unused_result attribute appeared first in gcc-3.4.0 */
7 #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
8     #define checkreturn
9 #else
10     /* Verify that we remember to check all return values for proper error propagation */
11     #define checkreturn __attribute__((warn_unused_result))
12 #endif
13
14 #define NANOPB_INTERNALS
15 #include "pb.h"
16 #include "pb_decode.h"
17 #include <string.h>
18
19 typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn;
20
21 /* --- Function pointers to field decoders ---
22  * Order in the array must match pb_action_t LTYPE numbering.
23  */
24 static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
25     &pb_dec_varint,
26     &pb_dec_svarint,
27     &pb_dec_fixed32,
28     &pb_dec_fixed64,
29     
30     &pb_dec_bytes,
31     &pb_dec_string,
32     &pb_dec_submessage
33 };
34
35 /**************
36  * pb_istream *
37  **************/
38
39 bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
40 {
41     if (stream->bytes_left < count)
42         PB_RETURN_ERROR(stream, "end-of-stream");
43     
44     if (!stream->callback(stream, buf, count))
45         PB_RETURN_ERROR(stream, "io error");
46     
47     stream->bytes_left -= count;
48     return true;
49 }
50
51 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count)
52 {
53     uint8_t *source = (uint8_t*)stream->state;
54     
55     if (buf != NULL)
56         memcpy(buf, source, count);
57     
58     stream->state = source + count;
59     return true;
60 }
61
62 pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize)
63 {
64     pb_istream_t stream;
65     stream.callback = &buf_read;
66     stream.state = buf;
67     stream.bytes_left = bufsize;
68     return stream;
69 }
70
71 /********************
72  * Helper functions *
73  ********************/
74
75 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
76 {
77     uint64_t temp;
78     bool status = pb_decode_varint(stream, &temp);
79     *dest = (uint32_t)temp;
80     return status;
81 }
82
83 bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
84 {
85     uint8_t byte;
86     uint8_t bitpos = 0;
87     *dest = 0;
88     
89     while (bitpos < 64 && pb_read(stream, &byte, 1))
90     {
91         *dest |= (uint64_t)(byte & 0x7F) << bitpos;
92         bitpos += 7;
93         
94         if (!(byte & 0x80))
95             return true;
96     }
97     
98     PB_RETURN_ERROR(stream, "varint overflow");
99 }
100
101 bool checkreturn pb_skip_varint(pb_istream_t *stream)
102 {
103     uint8_t byte;
104     do
105     {
106         if (!pb_read(stream, &byte, 1))
107             return false;
108     } while (byte & 0x80);
109     return true;
110 }
111
112 bool checkreturn pb_skip_string(pb_istream_t *stream)
113 {
114     uint32_t length;
115     if (!pb_decode_varint32(stream, &length))
116         return false;
117     
118     return pb_read(stream, NULL, length);
119 }
120
121 bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof)
122 {
123     uint32_t temp;
124     *eof = false;
125     *wire_type = (pb_wire_type_t) 0;
126     *tag = 0;
127     
128     if (!pb_decode_varint32(stream, &temp))
129     {
130         if (stream->bytes_left == 0)
131             *eof = true;
132
133         return false;
134     }
135     
136     if (temp == 0)
137     {
138         *eof = true; /* Special feature: allow 0-terminated messages. */
139         return false;
140     }
141     
142     *tag = temp >> 3;
143     *wire_type = (pb_wire_type_t)(temp & 7);
144     return true;
145 }
146
147 bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type)
148 {
149     switch (wire_type)
150     {
151         case PB_WT_VARINT: return pb_skip_varint(stream);
152         case PB_WT_64BIT: return pb_read(stream, NULL, 8);
153         case PB_WT_STRING: return pb_skip_string(stream);
154         case PB_WT_32BIT: return pb_read(stream, NULL, 4);
155         default: PB_RETURN_ERROR(stream, "invalid wire_type");
156     }
157 }
158
159 /* Read a raw value to buffer, for the purpose of passing it to callback as
160  * a substream. Size is maximum size on call, and actual size on return.
161  */
162 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size)
163 {
164     size_t max_size = *size;
165     switch (wire_type)
166     {
167         case PB_WT_VARINT:
168             *size = 0;
169             do
170             {
171                 (*size)++;
172                 if (*size > max_size) return false;
173                 if (!pb_read(stream, buf, 1)) return false;
174             } while (*buf++ & 0x80);
175             return true;
176             
177         case PB_WT_64BIT:
178             *size = 8;
179             return pb_read(stream, buf, 8);
180         
181         case PB_WT_32BIT:
182             *size = 4;
183             return pb_read(stream, buf, 4);
184         
185         default: PB_RETURN_ERROR(stream, "invalid wire_type");
186     }
187 }
188
189 /* Decode string length from stream and return a substream with limited length.
190  * Remember to close the substream using pb_close_string_substream().
191  */
192 bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
193 {
194     uint32_t size;
195     if (!pb_decode_varint32(stream, &size))
196         return false;
197     
198     *substream = *stream;
199     if (substream->bytes_left < size)
200         PB_RETURN_ERROR(stream, "parent stream too short");
201     
202     substream->bytes_left = size;
203     stream->bytes_left -= size;
204     return true;
205 }
206
207 void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
208 {
209     stream->state = substream->state;
210 }
211
212 /* Iterator for pb_field_t list */
213 typedef struct {
214     const pb_field_t *start; /* Start of the pb_field_t array */
215     const pb_field_t *current; /* Current position of the iterator */
216     int field_index; /* Zero-based index of the field. */
217     int required_field_index; /* Zero-based index that counts only the required fields */
218     void *dest_struct; /* Pointer to the destination structure to decode to */
219     void *pData; /* Pointer where to store current field value */
220     void *pSize; /* Pointer where to store the size of current array field */
221 } pb_field_iterator_t;
222
223 static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct)
224 {
225     iter->start = iter->current = fields;
226     iter->field_index = 0;
227     iter->required_field_index = 0;
228     iter->pData = (char*)dest_struct + iter->current->data_offset;
229     iter->pSize = (char*)iter->pData + iter->current->size_offset;
230     iter->dest_struct = dest_struct;
231 }
232
233 static bool pb_field_next(pb_field_iterator_t *iter)
234 {
235     bool notwrapped = true;
236     size_t prev_size = iter->current->data_size;
237     
238     if (PB_HTYPE(iter->current->type) == PB_HTYPE_ARRAY)
239         prev_size *= iter->current->array_size;
240     
241     if (PB_HTYPE(iter->current->type) == PB_HTYPE_REQUIRED)
242         iter->required_field_index++;
243     
244     iter->current++;
245     iter->field_index++;
246     if (iter->current->tag == 0)
247     {
248         iter->current = iter->start;
249         iter->field_index = 0;
250         iter->required_field_index = 0;
251         iter->pData = iter->dest_struct;
252         prev_size = 0;
253         notwrapped = false;
254     }
255     
256     iter->pData = (char*)iter->pData + prev_size + iter->current->data_offset;
257     iter->pSize = (char*)iter->pData + iter->current->size_offset;
258     return notwrapped;
259 }
260
261 static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag)
262 {
263     int start = iter->field_index;
264     
265     do {
266         if (iter->current->tag == tag)
267             return true;
268         pb_field_next(iter);
269     } while (iter->field_index != start);
270     
271     return false;
272 }
273
274 /*************************
275  * Decode a single field *
276  *************************/
277
278 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
279 {
280     pb_decoder_t func = PB_DECODERS[PB_LTYPE(iter->current->type)];
281     
282     switch (PB_HTYPE(iter->current->type))
283     {
284         case PB_HTYPE_REQUIRED:
285             return func(stream, iter->current, iter->pData);
286             
287         case PB_HTYPE_OPTIONAL:
288             *(bool*)iter->pSize = true;
289             return func(stream, iter->current, iter->pData);
290     
291         case PB_HTYPE_ARRAY:
292             if (wire_type == PB_WT_STRING
293                 && PB_LTYPE(iter->current->type) <= PB_LTYPE_LAST_PACKABLE)
294             {
295                 /* Packed array */
296                 bool status;
297                 size_t *size = (size_t*)iter->pSize;
298                 pb_istream_t substream;
299                 if (!pb_make_string_substream(stream, &substream))
300                     return false;
301                 
302                 while (substream.bytes_left && *size < iter->current->array_size)
303                 {
304                     void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
305                     if (!func(&substream, iter->current, pItem))
306                         return false;
307                     (*size)++;
308                 }
309                 status = (substream.bytes_left == 0);
310                 pb_close_string_substream(stream, &substream);
311                 return status;
312             }
313             else
314             {
315                 /* Repeated field */
316                 size_t *size = (size_t*)iter->pSize;
317                 void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
318                 if (*size >= iter->current->array_size)
319                     PB_RETURN_ERROR(stream, "array overflow");
320                 
321                 (*size)++;
322                 return func(stream, iter->current, pItem);
323             }
324         
325         case PB_HTYPE_CALLBACK:
326         {
327             pb_callback_t *pCallback = (pb_callback_t*)iter->pData;
328             
329             if (pCallback->funcs.decode == NULL)
330                 return pb_skip_field(stream, wire_type);
331             
332             if (wire_type == PB_WT_STRING)
333             {
334                 pb_istream_t substream;
335                 
336                 if (!pb_make_string_substream(stream, &substream))
337                     return false;
338                 
339                 while (substream.bytes_left)
340                 {
341                     if (!pCallback->funcs.decode(&substream, iter->current, pCallback->arg))
342                         PB_RETURN_ERROR(stream, "callback failed");
343                 }
344                 
345                 pb_close_string_substream(stream, &substream);
346                 return true;
347             }
348             else
349             {
350                 /* Copy the single scalar value to stack.
351                  * This is required so that we can limit the stream length,
352                  * which in turn allows to use same callback for packed and
353                  * not-packed fields. */
354                 pb_istream_t substream;
355                 uint8_t buffer[10];
356                 size_t size = sizeof(buffer);
357                 
358                 if (!read_raw_value(stream, wire_type, buffer, &size))
359                     return false;
360                 substream = pb_istream_from_buffer(buffer, size);
361                 
362                 return pCallback->funcs.decode(&substream, iter->current, pCallback->arg);
363             }
364         }
365         
366         default:
367             PB_RETURN_ERROR(stream, "invalid field type");
368     }
369 }
370
371 /* Initialize message fields to default values, recursively */
372 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
373 {
374     pb_field_iterator_t iter;
375     pb_field_init(&iter, fields, dest_struct);
376     
377     /* Initialize size/has fields and apply default values */
378     do
379     {
380         if (iter.current->tag == 0)
381             continue;
382         
383         /* Initialize the size field for optional/repeated fields to 0. */
384         if (PB_HTYPE(iter.current->type) == PB_HTYPE_OPTIONAL)
385         {
386             *(bool*)iter.pSize = false;
387         }
388         else if (PB_HTYPE(iter.current->type) == PB_HTYPE_ARRAY)
389         {
390             *(size_t*)iter.pSize = 0;
391             continue; /* Array is empty, no need to initialize contents */
392         }
393         
394         /* Initialize field contents to default value */
395         if (PB_HTYPE(iter.current->type) == PB_HTYPE_CALLBACK)
396         {
397             continue; /* Don't overwrite callback */
398         }
399         else if (PB_LTYPE(iter.current->type) == PB_LTYPE_SUBMESSAGE)
400         {
401             pb_message_set_to_defaults((const pb_field_t *) iter.current->ptr, iter.pData);
402         }
403         else if (iter.current->ptr != NULL)
404         {
405             memcpy(iter.pData, iter.current->ptr, iter.current->data_size);
406         }
407         else
408         {
409             memset(iter.pData, 0, iter.current->data_size);
410         }
411     } while (pb_field_next(&iter));
412 }
413
414 /*********************
415  * Decode all fields *
416  *********************/
417
418 bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
419 {
420     uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0}; /* Used to check for required fields */
421     pb_field_iterator_t iter;
422     
423     pb_field_init(&iter, fields, dest_struct);
424     
425     while (stream->bytes_left)
426     {
427         uint32_t tag;
428         pb_wire_type_t wire_type;
429         bool eof;
430         
431         if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
432         {
433             if (eof)
434                 break;
435             else
436                 return false;
437         }
438         
439         if (!pb_field_find(&iter, tag))
440         {
441             /* No match found, skip data */
442             if (!pb_skip_field(stream, wire_type))
443                 return false;
444             continue;
445         }
446         
447         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED
448             && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
449         {
450             fields_seen[iter.required_field_index >> 3] |= 1 << (iter.required_field_index & 7);
451         }
452             
453         if (!decode_field(stream, wire_type, &iter))
454             return false;
455     }
456     
457     /* Check that all required fields were present. */
458     pb_field_init(&iter, fields, dest_struct);
459     do {
460         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED &&
461             iter.required_field_index < PB_MAX_REQUIRED_FIELDS &&
462             !(fields_seen[iter.required_field_index >> 3] & (1 << (iter.required_field_index & 7))))
463         {
464             PB_RETURN_ERROR(stream, "missing required field");
465         }
466     } while (pb_field_next(&iter));
467     
468     return true;
469 }
470
471 bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
472 {
473     pb_message_set_to_defaults(fields, dest_struct);
474     return pb_decode_noinit(stream, fields, dest_struct);
475 }
476
477 /* Field decoders */
478
479 bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
480 {
481     uint64_t value;
482     if (!pb_decode_varint(stream, &value))
483         return false;
484     
485     if (value & 1)
486         *dest = ~(value >> 1);
487     else
488         *dest = value >> 1;
489     
490     return true;
491 }
492
493 bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
494 {
495     #ifdef __BIG_ENDIAN__
496     uint8_t *bytes = (uint8_t*)dest;
497     uint8_t lebytes[4];
498     
499     if (!pb_read(stream, lebytes, 4))
500         return false;
501     
502     bytes[0] = lebytes[3];
503     bytes[1] = lebytes[2];
504     bytes[2] = lebytes[1];
505     bytes[3] = lebytes[0];
506     return true;
507     #else
508     return pb_read(stream, (uint8_t*)dest, 4);
509     #endif   
510 }
511
512 bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
513 {
514     #ifdef __BIG_ENDIAN__
515     uint8_t *bytes = (uint8_t*)dest;
516     uint8_t lebytes[8];
517     
518     if (!pb_read(stream, lebytes, 8))
519         return false;
520     
521     bytes[0] = lebytes[7];
522     bytes[1] = lebytes[6];
523     bytes[2] = lebytes[5];
524     bytes[3] = lebytes[4];
525     bytes[4] = lebytes[3];
526     bytes[5] = lebytes[2];
527     bytes[6] = lebytes[1];
528     bytes[7] = lebytes[0];
529     return true;
530     #else
531     return pb_read(stream, (uint8_t*)dest, 8);
532     #endif   
533 }
534
535 bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
536 {
537     uint64_t value;
538     bool status = pb_decode_varint(stream, &value);
539     
540     switch (field->data_size)
541     {
542         case 1: *(uint8_t*)dest = value; break;
543         case 2: *(uint16_t*)dest = value; break;
544         case 4: *(uint32_t*)dest = value; break;
545         case 8: *(uint64_t*)dest = value; break;
546         default: PB_RETURN_ERROR(stream, "invalid data_size");
547     }
548     
549     return status;
550 }
551
552 bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
553 {
554     int64_t value;
555     bool status = pb_decode_svarint(stream, &value);
556     
557     switch (field->data_size)
558     {
559         case 4: *(int32_t*)dest = value; break;
560         case 8: *(int64_t*)dest = value; break;
561         default: PB_RETURN_ERROR(stream, "invalid data_size");
562     }
563     
564     return status;
565 }
566
567 bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)
568 {
569     UNUSED(field);
570     return pb_decode_fixed32(stream, dest);
571 }
572
573 bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
574 {
575     UNUSED(field);
576     return pb_decode_fixed64(stream, dest);
577 }
578
579 bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
580 {
581     pb_bytes_array_t *x = (pb_bytes_array_t*)dest;
582     
583     uint32_t temp;
584     if (!pb_decode_varint32(stream, &temp))
585         return false;
586     x->size = temp;
587     
588     /* Check length, noting the space taken by the size_t header. */
589     if (x->size > field->data_size - offsetof(pb_bytes_array_t, bytes))
590         PB_RETURN_ERROR(stream, "bytes overflow");
591     
592     return pb_read(stream, x->bytes, x->size);
593 }
594
595 bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest)
596 {
597     uint32_t size;
598     bool status;
599     if (!pb_decode_varint32(stream, &size))
600         return false;
601     
602     /* Check length, noting the null terminator */
603     if (size + 1 > field->data_size)
604         PB_RETURN_ERROR(stream, "string overflow");
605     
606     status = pb_read(stream, (uint8_t*)dest, size);
607     *((uint8_t*)dest + size) = 0;
608     return status;
609 }
610
611 bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest)
612 {
613     bool status;
614     pb_istream_t substream;
615     const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr;
616     
617     if (!pb_make_string_substream(stream, &substream))
618         return false;
619     
620     if (field->ptr == NULL)
621         PB_RETURN_ERROR(stream, "invalid field descriptor");
622     
623     /* New array entries need to be initialized, while required and optional
624      * submessages have already been initialized in the top-level pb_decode. */
625     if (PB_HTYPE(field->type) == PB_HTYPE_ARRAY)
626         status = pb_decode(&substream, submsg_fields, dest);
627     else
628         status = pb_decode_noinit(&substream, submsg_fields, dest);
629     
630     pb_close_string_substream(stream, &substream);
631     return status;
632 }