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