9d65504c611c86fd62ea669a2fead500d965dc53
[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(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_message_set_to_defaults(fields, dest_struct);
424     
425     pb_field_init(&iter, fields, dest_struct);
426     
427     while (stream->bytes_left)
428     {
429         uint32_t tag;
430         pb_wire_type_t wire_type;
431         bool eof;
432         
433         if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
434         {
435             if (eof)
436                 break;
437             else
438                 return false;
439         }
440         
441         if (!pb_field_find(&iter, tag))
442         {
443             /* No match found, skip data */
444             if (!pb_skip_field(stream, wire_type))
445                 return false;
446             continue;
447         }
448         
449         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED
450             && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
451         {
452             fields_seen[iter.required_field_index >> 3] |= 1 << (iter.required_field_index & 7);
453         }
454             
455         if (!decode_field(stream, wire_type, &iter))
456             return false;
457     }
458     
459     /* Check that all required fields were present. */
460     pb_field_init(&iter, fields, dest_struct);
461     do {
462         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED &&
463             iter.required_field_index < PB_MAX_REQUIRED_FIELDS &&
464             !(fields_seen[iter.required_field_index >> 3] & (1 << (iter.required_field_index & 7))))
465         {
466             PB_RETURN_ERROR(stream, "missing required field");
467         }
468     } while (pb_field_next(&iter));
469     
470     return true;
471 }
472
473 /* Field decoders */
474
475 bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
476 {
477     uint64_t value;
478     if (!pb_decode_varint(stream, &value))
479         return false;
480     
481     if (value & 1)
482         *dest = ~(value >> 1);
483     else
484         *dest = value >> 1;
485     
486     return true;
487 }
488
489 bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
490 {
491     #ifdef __BIG_ENDIAN__
492     uint8_t *bytes = (uint8_t*)dest;
493     uint8_t lebytes[4];
494     
495     if (!pb_read(stream, lebytes, 4))
496         return false;
497     
498     bytes[0] = lebytes[3];
499     bytes[1] = lebytes[2];
500     bytes[2] = lebytes[1];
501     bytes[3] = lebytes[0];
502     return true;
503     #else
504     return pb_read(stream, (uint8_t*)dest, 4);
505     #endif   
506 }
507
508 bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
509 {
510     #ifdef __BIG_ENDIAN__
511     uint8_t *bytes = (uint8_t*)dest;
512     uint8_t lebytes[8];
513     
514     if (!pb_read(stream, lebytes, 8))
515         return false;
516     
517     bytes[0] = lebytes[7];
518     bytes[1] = lebytes[6];
519     bytes[2] = lebytes[5];
520     bytes[3] = lebytes[4];
521     bytes[4] = lebytes[3];
522     bytes[5] = lebytes[2];
523     bytes[6] = lebytes[1];
524     bytes[7] = lebytes[0];
525     return true;
526     #else
527     return pb_read(stream, (uint8_t*)dest, 8);
528     #endif   
529 }
530
531 bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
532 {
533     uint64_t value;
534     bool status = pb_decode_varint(stream, &value);
535     
536     switch (field->data_size)
537     {
538         case 1: *(uint8_t*)dest = value; break;
539         case 2: *(uint16_t*)dest = value; break;
540         case 4: *(uint32_t*)dest = value; break;
541         case 8: *(uint64_t*)dest = value; break;
542         default: PB_RETURN_ERROR(stream, "invalid data_size");
543     }
544     
545     return status;
546 }
547
548 bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
549 {
550     int64_t value;
551     bool status = pb_decode_svarint(stream, &value);
552     
553     switch (field->data_size)
554     {
555         case 4: *(int32_t*)dest = value; break;
556         case 8: *(int64_t*)dest = value; break;
557         default: PB_RETURN_ERROR(stream, "invalid data_size");
558     }
559     
560     return status;
561 }
562
563 bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)
564 {
565     UNUSED(field);
566     return pb_decode_fixed32(stream, dest);
567 }
568
569 bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
570 {
571     UNUSED(field);
572     return pb_decode_fixed64(stream, dest);
573 }
574
575 bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
576 {
577     pb_bytes_array_t *x = (pb_bytes_array_t*)dest;
578     
579     uint32_t temp;
580     if (!pb_decode_varint32(stream, &temp))
581         return false;
582     x->size = temp;
583     
584     /* Check length, noting the space taken by the size_t header. */
585     if (x->size > field->data_size - offsetof(pb_bytes_array_t, bytes))
586         PB_RETURN_ERROR(stream, "bytes overflow");
587     
588     return pb_read(stream, x->bytes, x->size);
589 }
590
591 bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest)
592 {
593     uint32_t size;
594     bool status;
595     if (!pb_decode_varint32(stream, &size))
596         return false;
597     
598     /* Check length, noting the null terminator */
599     if (size + 1 > field->data_size)
600         PB_RETURN_ERROR(stream, "string overflow");
601     
602     status = pb_read(stream, (uint8_t*)dest, size);
603     *((uint8_t*)dest + size) = 0;
604     return status;
605 }
606
607 bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest)
608 {
609     bool status;
610     pb_istream_t substream;
611     
612     if (!pb_make_string_substream(stream, &substream))
613         return false;
614     
615     if (field->ptr == NULL)
616         PB_RETURN_ERROR(stream, "invalid field descriptor");
617     
618     status = pb_decode(&substream, (pb_field_t*)field->ptr, dest);
619     pb_close_string_substream(stream, &substream);
620     return status;
621 }