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