Change the substream implementation in pb_decode.
[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 #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 = (pb_wire_type_t) 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 static bool substream_callback(pb_istream_t *stream, uint8_t *buf, size_t count)
190 {
191     pb_istream_t *parent = (pb_istream_t*)stream->state;
192     return pb_read(parent, buf, count);
193 }
194
195 static bool checkreturn make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
196 {
197     uint32_t size;
198     if (!pb_decode_varint32(stream, &size))
199         return false;
200     
201     if (stream->bytes_left < size)
202         return false;
203     
204     substream->callback = &substream_callback;
205     substream->state = stream;
206     substream->bytes_left = size;
207     
208     return true;
209 }
210
211 /* Iterator for pb_field_t list */
212 typedef struct {
213     const pb_field_t *start; /* Start of the pb_field_t array */
214     const pb_field_t *current; /* Current position of the iterator */
215     int field_index; /* Zero-based index of the field. */
216     int required_field_index; /* Zero-based index that counts only the required fields */
217     void *dest_struct; /* Pointer to the destination structure to decode to */
218     void *pData; /* Pointer where to store current field value */
219     void *pSize; /* Pointer where to store the size of current array field */
220 } pb_field_iterator_t;
221
222 static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct)
223 {
224     iter->start = iter->current = fields;
225     iter->field_index = 0;
226     iter->required_field_index = 0;
227     iter->pData = (char*)dest_struct + iter->current->data_offset;
228     iter->pSize = (char*)iter->pData + iter->current->size_offset;
229     iter->dest_struct = dest_struct;
230 }
231
232 static bool pb_field_next(pb_field_iterator_t *iter)
233 {
234     bool notwrapped = true;
235     size_t prev_size = iter->current->data_size;
236     
237     if (PB_HTYPE(iter->current->type) == PB_HTYPE_ARRAY)
238         prev_size *= iter->current->array_size;
239     
240     if (PB_HTYPE(iter->current->type) == PB_HTYPE_REQUIRED)
241         iter->required_field_index++;
242     
243     iter->current++;
244     iter->field_index++;
245     if (iter->current->tag == 0)
246     {
247         iter->current = iter->start;
248         iter->field_index = 0;
249         iter->required_field_index = 0;
250         iter->pData = iter->dest_struct;
251         prev_size = 0;
252         notwrapped = false;
253     }
254     
255     iter->pData = (char*)iter->pData + prev_size + iter->current->data_offset;
256     iter->pSize = (char*)iter->pData + iter->current->size_offset;
257     return notwrapped;
258 }
259
260 static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag)
261 {
262     int start = iter->field_index;
263     
264     do {
265         if (iter->current->tag == tag)
266             return true;
267         pb_field_next(iter);
268     } while (iter->field_index != start);
269     
270     return false;
271 }
272
273 /*************************
274  * Decode a single field *
275  *************************/
276
277 static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
278 {
279     pb_decoder_t func = PB_DECODERS[PB_LTYPE(iter->current->type)];
280     
281     switch (PB_HTYPE(iter->current->type))
282     {
283         case PB_HTYPE_REQUIRED:
284             return func(stream, iter->current, iter->pData);
285             
286         case PB_HTYPE_OPTIONAL:
287             *(bool*)iter->pSize = true;
288             return func(stream, iter->current, iter->pData);
289     
290         case PB_HTYPE_ARRAY:
291             if (wire_type == PB_WT_STRING
292                 && PB_LTYPE(iter->current->type) <= PB_LTYPE_LAST_PACKABLE)
293             {
294                 /* Packed array */
295                 size_t *size = (size_t*)iter->pSize;
296                 pb_istream_t substream;
297                 if (!make_string_substream(stream, &substream))
298                     return false;
299                 
300                 while (substream.bytes_left && *size < iter->current->array_size)
301                 {
302                     void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
303                     if (!func(&substream, iter->current, pItem))
304                         return false;
305                     (*size)++;
306                 }
307                 return (substream.bytes_left == 0);
308             }
309             else
310             {
311                 /* Repeated field */
312                 size_t *size = (size_t*)iter->pSize;
313                 void *pItem = (uint8_t*)iter->pData + iter->current->data_size * (*size);
314                 if (*size >= iter->current->array_size)
315                     return false;
316                 
317                 (*size)++;
318                 return func(stream, iter->current, pItem);
319             }
320         
321         case PB_HTYPE_CALLBACK:
322         {
323             pb_callback_t *pCallback = (pb_callback_t*)iter->pData;
324             
325             if (pCallback->funcs.decode == NULL)
326                 return pb_skip_field(stream, wire_type);
327             
328             if (wire_type == PB_WT_STRING)
329             {
330                 pb_istream_t substream;
331                 
332                 if (!make_string_substream(stream, &substream))
333                     return false;
334                 
335                 while (substream.bytes_left)
336                 {
337                     if (!pCallback->funcs.decode(&substream, iter->current, pCallback->arg))
338                         return false;
339                 }
340                 
341                 return true;
342             }
343             else
344             {
345                 /* Copy the single scalar value to stack.
346                  * This is required so that we can limit the stream length,
347                  * which in turn allows to use same callback for packed and
348                  * not-packed fields. */
349                 pb_istream_t substream;
350                 uint8_t buffer[10];
351                 size_t size = sizeof(buffer);
352                 
353                 if (!read_raw_value(stream, wire_type, buffer, &size))
354                     return false;
355                 substream = pb_istream_from_buffer(buffer, size);
356                 
357                 return pCallback->funcs.decode(&substream, iter->current, pCallback->arg);
358             }
359         }
360         
361         default:
362             return false;
363     }
364 }
365
366 /* Initialize message fields to default values, recursively */
367 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
368 {
369     pb_field_iterator_t iter;
370     pb_field_init(&iter, fields, dest_struct);
371     
372     /* Initialize size/has fields and apply default values */
373     do
374     {
375         if (iter.current->tag == 0)
376             continue;
377         
378         /* Initialize the size field for optional/repeated fields to 0. */
379         if (PB_HTYPE(iter.current->type) == PB_HTYPE_OPTIONAL)
380         {
381             *(bool*)iter.pSize = false;
382         }
383         else if (PB_HTYPE(iter.current->type) == PB_HTYPE_ARRAY)
384         {
385             *(size_t*)iter.pSize = 0;
386             continue; /* Array is empty, no need to initialize contents */
387         }
388         
389         /* Initialize field contents to default value */
390         if (PB_HTYPE(iter.current->type) == PB_HTYPE_CALLBACK)
391         {
392             continue; /* Don't overwrite callback */
393         }
394         else if (PB_LTYPE(iter.current->type) == PB_LTYPE_SUBMESSAGE)
395         {
396             pb_message_set_to_defaults((const pb_field_t *) iter.current->ptr, iter.pData);
397         }
398         else if (iter.current->ptr != NULL)
399         {
400             memcpy(iter.pData, iter.current->ptr, iter.current->data_size);
401         }
402         else
403         {
404             memset(iter.pData, 0, iter.current->data_size);
405         }
406     } while (pb_field_next(&iter));
407 }
408
409 /*********************
410  * Decode all fields *
411  *********************/
412
413 bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
414 {
415     uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0}; /* Used to check for required fields */
416     pb_field_iterator_t iter;
417     
418     pb_message_set_to_defaults(fields, dest_struct);
419     
420     pb_field_init(&iter, fields, dest_struct);
421     
422     while (stream->bytes_left)
423     {
424         uint32_t tag;
425         pb_wire_type_t wire_type;
426         bool eof;
427         
428         if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
429         {
430             if (eof)
431                 break;
432             else
433                 return false;
434         }
435         
436         if (!pb_field_find(&iter, tag))
437         {
438             /* No match found, skip data */
439             if (!pb_skip_field(stream, wire_type))
440                 return false;
441             continue;
442         }
443         
444         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED
445             && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
446         {
447             fields_seen[iter.required_field_index >> 3] |= 1 << (iter.required_field_index & 7);
448         }
449             
450         if (!decode_field(stream, wire_type, &iter))
451             return false;
452     }
453     
454     /* Check that all required fields were present. */
455     pb_field_init(&iter, fields, dest_struct);
456     do {
457         if (PB_HTYPE(iter.current->type) == PB_HTYPE_REQUIRED &&
458             iter.required_field_index < PB_MAX_REQUIRED_FIELDS &&
459             !(fields_seen[iter.required_field_index >> 3] & (1 << (iter.required_field_index & 7))))
460         {
461             return false;
462         }
463     } while (pb_field_next(&iter));
464     
465     return true;
466 }
467
468 /* Field decoders */
469
470 /* Copy destsize bytes from src so that values are casted properly.
471  * On little endian machine, copy first n bytes of src
472  * On big endian machine, copy last n bytes of src
473  * srcsize must always be larger than destsize
474  */
475 static void endian_copy(void *dest, void *src, size_t destsize, size_t srcsize)
476 {
477 #ifdef __BIG_ENDIAN__
478     memcpy(dest, (char*)src + (srcsize - destsize), destsize);
479 #else
480     UNUSED(srcsize);
481     memcpy(dest, src, destsize);
482 #endif
483 }
484
485 bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
486 {
487     uint64_t temp;
488     bool status = pb_decode_varint(stream, &temp);
489     endian_copy(dest, &temp, field->data_size, sizeof(temp));
490     return status;
491 }
492
493 bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
494 {
495     uint64_t temp;
496     bool status = pb_decode_varint(stream, &temp);
497     temp = (temp >> 1) ^ -(int64_t)(temp & 1);
498     endian_copy(dest, &temp, field->data_size, sizeof(temp));
499     return status;
500 }
501
502 bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)
503 {
504 #ifdef __BIG_ENDIAN__
505     uint8_t bytes[4] = {0};
506     bool status = pb_read(stream, bytes, 4);
507     if (status) {
508         uint8_t *d = (uint8_t*)dest;
509         d[0] = bytes[3];
510         d[1] = bytes[2];
511         d[2] = bytes[1];
512         d[3] = bytes[0];
513     }
514     return status;
515 #else
516     UNUSED(field);
517     return pb_read(stream, (uint8_t*)dest, 4);
518 #endif
519 }
520
521 bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
522 {
523 #ifdef __BIG_ENDIAN__
524     uint8_t bytes[8] = {0};
525     bool status = pb_read(stream, bytes, 8);
526     if (status) {
527         uint8_t *d = (uint8_t*)dest;
528         d[0] = bytes[7];
529         d[1] = bytes[6];
530         d[2] = bytes[5]; 
531         d[3] = bytes[4];
532         d[4] = bytes[3];
533         d[5] = bytes[2];
534         d[6] = bytes[1];
535         d[7] = bytes[0];
536     }
537     return status;
538 #else
539     UNUSED(field);
540     return pb_read(stream, (uint8_t*)dest, 8);
541 #endif
542 }
543
544 bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
545 {
546     pb_bytes_array_t *x = (pb_bytes_array_t*)dest;
547     
548     uint32_t temp;
549     if (!pb_decode_varint32(stream, &temp))
550         return false;
551     x->size = temp;
552     
553     /* Check length, noting the space taken by the size_t header. */
554     if (x->size > field->data_size - offsetof(pb_bytes_array_t, bytes))
555         return false;
556     
557     return pb_read(stream, x->bytes, x->size);
558 }
559
560 bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest)
561 {
562     uint32_t size;
563     bool status;
564     if (!pb_decode_varint32(stream, &size))
565         return false;
566     
567     /* Check length, noting the null terminator */
568     if (size + 1 > field->data_size)
569         return false;
570     
571     status = pb_read(stream, (uint8_t*)dest, size);
572     *((uint8_t*)dest + size) = 0;
573     return status;
574 }
575
576 bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest)
577 {
578     pb_istream_t substream;
579     
580     if (!make_string_substream(stream, &substream))
581         return false;
582     
583     if (field->ptr == NULL)
584         return false;
585     
586     return pb_decode(&substream, (pb_field_t*)field->ptr, dest);
587 }