Reorganize the field decoder interface.
[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         return false;
43     
44     if (!stream->callback(stream, buf, count))
45         return false;
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     return false;
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: return false;
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: return false;
186     }
187 }
188
189 /* Decode string length from stream and return a substream with limited length. */
190 static bool substream_callback(pb_istream_t *stream, uint8_t *buf, size_t count)
191 {
192     pb_istream_t *parent = (pb_istream_t*)stream->state;
193     return pb_read(parent, buf, count);
194 }
195
196 bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
197 {
198     uint32_t size;
199     if (!pb_decode_varint32(stream, &size))
200         return false;
201     
202     if (stream->bytes_left < size)
203         return false;
204     
205     substream->callback = &substream_callback;
206     substream->state = stream;
207     substream->bytes_left = size;
208     
209     return true;
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                 size_t *size = (size_t*)iter->pSize;
297                 pb_istream_t substream;
298                 if (!pb_make_string_substream(stream, &substream))
299                     return false;
300                 
301                 while (substream.bytes_left && *size < iter->current->array_size)
302                 {
303                     void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
304                     if (!func(&substream, iter->current, pItem))
305                         return false;
306                     (*size)++;
307                 }
308                 return (substream.bytes_left == 0);
309             }
310             else
311             {
312                 /* Repeated field */
313                 size_t *size = (size_t*)iter->pSize;
314                 void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
315                 if (*size >= iter->current->array_size)
316                     return false;
317                 
318                 (*size)++;
319                 return func(stream, iter->current, pItem);
320             }
321         
322         case PB_HTYPE_CALLBACK:
323         {
324             pb_callback_t *pCallback = (pb_callback_t*)iter->pData;
325             
326             if (pCallback->funcs.decode == NULL)
327                 return pb_skip_field(stream, wire_type);
328             
329             if (wire_type == PB_WT_STRING)
330             {
331                 pb_istream_t substream;
332                 
333                 if (!pb_make_string_substream(stream, &substream))
334                     return false;
335                 
336                 while (substream.bytes_left)
337                 {
338                     if (!pCallback->funcs.decode(&substream, iter->current, pCallback->arg))
339                         return false;
340                 }
341                 
342                 return true;
343             }
344             else
345             {
346                 /* Copy the single scalar value to stack.
347                  * This is required so that we can limit the stream length,
348                  * which in turn allows to use same callback for packed and
349                  * not-packed fields. */
350                 pb_istream_t substream;
351                 uint8_t buffer[10];
352                 size_t size = sizeof(buffer);
353                 
354                 if (!read_raw_value(stream, wire_type, buffer, &size))
355                     return false;
356                 substream = pb_istream_from_buffer(buffer, size);
357                 
358                 return pCallback->funcs.decode(&substream, iter->current, pCallback->arg);
359             }
360         }
361         
362         default:
363             return false;
364     }
365 }
366
367 /* Initialize message fields to default values, recursively */
368 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
369 {
370     pb_field_iterator_t iter;
371     pb_field_init(&iter, fields, dest_struct);
372     
373     /* Initialize size/has fields and apply default values */
374     do
375     {
376         if (iter.current->tag == 0)
377             continue;
378         
379         /* Initialize the size field for optional/repeated fields to 0. */
380         if (PB_HTYPE(iter.current->type) == PB_HTYPE_OPTIONAL)
381         {
382             *(bool*)iter.pSize = false;
383         }
384         else if (PB_HTYPE(iter.current->type) == PB_HTYPE_ARRAY)
385         {
386             *(size_t*)iter.pSize = 0;
387             continue; /* Array is empty, no need to initialize contents */
388         }
389         
390         /* Initialize field contents to default value */
391         if (PB_HTYPE(iter.current->type) == PB_HTYPE_CALLBACK)
392         {
393             continue; /* Don't overwrite callback */
394         }
395         else if (PB_LTYPE(iter.current->type) == PB_LTYPE_SUBMESSAGE)
396         {
397             pb_message_set_to_defaults((const pb_field_t *) iter.current->ptr, iter.pData);
398         }
399         else if (iter.current->ptr != NULL)
400         {
401             memcpy(iter.pData, iter.current->ptr, iter.current->data_size);
402         }
403         else
404         {
405             memset(iter.pData, 0, iter.current->data_size);
406         }
407     } while (pb_field_next(&iter));
408 }
409
410 /*********************
411  * Decode all fields *
412  *********************/
413
414 bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
415 {
416     uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0}; /* Used to check for required fields */
417     pb_field_iterator_t iter;
418     
419     pb_message_set_to_defaults(fields, dest_struct);
420     
421     pb_field_init(&iter, fields, dest_struct);
422     
423     while (stream->bytes_left)
424     {
425         uint32_t tag;
426         pb_wire_type_t wire_type;
427         bool eof;
428         
429         if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
430         {
431             if (eof)
432                 break;
433             else
434                 return false;
435         }
436         
437         if (!pb_field_find(&iter, tag))
438         {
439             /* No match found, skip data */
440             if (!pb_skip_field(stream, wire_type))
441                 return false;
442             continue;
443         }
444         
445         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED
446             && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
447         {
448             fields_seen[iter.required_field_index >> 3] |= 1 << (iter.required_field_index & 7);
449         }
450             
451         if (!decode_field(stream, wire_type, &iter))
452             return false;
453     }
454     
455     /* Check that all required fields were present. */
456     pb_field_init(&iter, fields, dest_struct);
457     do {
458         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED &&
459             iter.required_field_index < PB_MAX_REQUIRED_FIELDS &&
460             !(fields_seen[iter.required_field_index >> 3] & (1 << (iter.required_field_index & 7))))
461         {
462             return false;
463         }
464     } while (pb_field_next(&iter));
465     
466     return true;
467 }
468
469 /* Field decoders */
470
471 bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
472 {
473     uint64_t value;
474     if (!pb_decode_varint(stream, &value))
475         return false;
476     
477     if (value & 1)
478         *dest = ~(value >> 1);
479     else
480         *dest = value >> 1;
481     
482     return true;
483 }
484
485 bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
486 {
487     #ifdef __BIG_ENDIAN__
488     uint8_t *bytes = (uint8_t*)dest;
489     uint8_t lebytes[4];
490     
491     if (!pb_read(stream, lebytes, 4))
492         return false;
493     
494     bytes[0] = lebytes[3];
495     bytes[1] = lebytes[2];
496     bytes[2] = lebytes[1];
497     bytes[3] = lebytes[0];
498     return true;
499     #else
500     return pb_read(stream, (uint8_t*)dest, 4);
501     #endif   
502 }
503
504 bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
505 {
506     #ifdef __BIG_ENDIAN__
507     uint8_t *bytes = (uint8_t*)dest;
508     uint8_t lebytes[8];
509     
510     if (!pb_read(stream, lebytes, 8))
511         return false;
512     
513     bytes[0] = lebytes[7];
514     bytes[1] = lebytes[6];
515     bytes[2] = lebytes[5];
516     bytes[3] = lebytes[4];
517     bytes[4] = lebytes[3];
518     bytes[5] = lebytes[2];
519     bytes[6] = lebytes[1];
520     bytes[7] = lebytes[0];
521     return true;
522     #else
523     return pb_read(stream, (uint8_t*)dest, 8);
524     #endif   
525 }
526
527 bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
528 {
529     uint64_t value;
530     bool status = pb_decode_varint(stream, &value);
531     
532     switch (field->data_size)
533     {
534         case 1: *(uint8_t*)dest = value; break;
535         case 2: *(uint16_t*)dest = value; break;
536         case 4: *(uint32_t*)dest = value; break;
537         case 8: *(uint64_t*)dest = value; break;
538         default: return false;
539     }
540     
541     return status;
542 }
543
544 bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
545 {
546     int64_t value;
547     bool status = pb_decode_svarint(stream, &value);
548     
549     switch (field->data_size)
550     {
551         case 4: *(int32_t*)dest = value; break;
552         case 8: *(int64_t*)dest = value; break;
553         default: return false;
554     }
555     
556     return status;
557 }
558
559 bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)
560 {
561     UNUSED(field);
562     return pb_decode_fixed32(stream, dest);
563 }
564
565 bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
566 {
567     UNUSED(field);
568     return pb_decode_fixed64(stream, dest);
569 }
570
571 bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
572 {
573     pb_bytes_array_t *x = (pb_bytes_array_t*)dest;
574     
575     uint32_t temp;
576     if (!pb_decode_varint32(stream, &temp))
577         return false;
578     x->size = temp;
579     
580     /* Check length, noting the space taken by the size_t header. */
581     if (x->size > field->data_size - offsetof(pb_bytes_array_t, bytes))
582         return false;
583     
584     return pb_read(stream, x->bytes, x->size);
585 }
586
587 bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest)
588 {
589     uint32_t size;
590     bool status;
591     if (!pb_decode_varint32(stream, &size))
592         return false;
593     
594     /* Check length, noting the null terminator */
595     if (size + 1 > field->data_size)
596         return false;
597     
598     status = pb_read(stream, (uint8_t*)dest, size);
599     *((uint8_t*)dest + size) = 0;
600     return status;
601 }
602
603 bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest)
604 {
605     pb_istream_t substream;
606     
607     if (!pb_make_string_substream(stream, &substream))
608         return false;
609     
610     if (field->ptr == NULL)
611         return false;
612     
613     return pb_decode(&substream, (pb_field_t*)field->ptr, dest);
614 }