Extend inline / fixed length bytes array support (issue #244)
[apps/agl-service-can-low-level.git] / pb_encode.c
1 /* pb_encode.c -- encode a protobuf using minimal resources
2  *
3  * 2011 Petteri Aimonen <jpa@kapsi.fi>
4  */
5
6 #include "pb.h"
7 #include "pb_encode.h"
8 #include "pb_common.h"
9
10 /* Use the GCC warn_unused_result attribute to check that all return values
11  * are propagated correctly. On other compilers and gcc before 3.4.0 just
12  * ignore the annotation.
13  */
14 #if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
15     #define checkreturn
16 #else
17     #define checkreturn __attribute__((warn_unused_result))
18 #endif
19
20 /**************************************
21  * Declarations internal to this file *
22  **************************************/
23 typedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn;
24
25 static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
26 static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func);
27 static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
28 static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);
29 static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
30 static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
31 static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
32 static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
33 static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src);
34 static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src);
35 static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src);
36 static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src);
37 static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src);
38 static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src);
39
40 /* --- Function pointers to field encoders ---
41  * Order in the array must match pb_action_t LTYPE numbering.
42  */
43 static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = {
44     &pb_enc_varint,
45     &pb_enc_uvarint,
46     &pb_enc_svarint,
47     &pb_enc_fixed32,
48     &pb_enc_fixed64,
49     
50     &pb_enc_bytes,
51     &pb_enc_string,
52     &pb_enc_submessage,
53     NULL, /* extensions */
54     &pb_enc_fixed_length_bytes
55 };
56
57 /*******************************
58  * pb_ostream_t implementation *
59  *******************************/
60
61 static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
62 {
63     size_t i;
64     pb_byte_t *dest = (pb_byte_t*)stream->state;
65     stream->state = dest + count;
66     
67     for (i = 0; i < count; i++)
68         dest[i] = buf[i];
69     
70     return true;
71 }
72
73 pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize)
74 {
75     pb_ostream_t stream;
76 #ifdef PB_BUFFER_ONLY
77     stream.callback = (void*)1; /* Just a marker value */
78 #else
79     stream.callback = &buf_write;
80 #endif
81     stream.state = buf;
82     stream.max_size = bufsize;
83     stream.bytes_written = 0;
84 #ifndef PB_NO_ERRMSG
85     stream.errmsg = NULL;
86 #endif
87     return stream;
88 }
89
90 bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
91 {
92     if (stream->callback != NULL)
93     {
94         if (stream->bytes_written + count > stream->max_size)
95             PB_RETURN_ERROR(stream, "stream full");
96
97 #ifdef PB_BUFFER_ONLY
98         if (!buf_write(stream, buf, count))
99             PB_RETURN_ERROR(stream, "io error");
100 #else        
101         if (!stream->callback(stream, buf, count))
102             PB_RETURN_ERROR(stream, "io error");
103 #endif
104     }
105     
106     stream->bytes_written += count;
107     return true;
108 }
109
110 /*************************
111  * Encode a single field *
112  *************************/
113
114 /* Encode a static array. Handles the size calculations and possible packing. */
115 static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field,
116                          const void *pData, size_t count, pb_encoder_t func)
117 {
118     size_t i;
119     const void *p;
120     size_t size;
121     
122     if (count == 0)
123         return true;
124
125     if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size)
126         PB_RETURN_ERROR(stream, "array max size exceeded");
127     
128     /* We always pack arrays if the datatype allows it. */
129     if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE)
130     {
131         if (!pb_encode_tag(stream, PB_WT_STRING, field->tag))
132             return false;
133         
134         /* Determine the total size of packed array. */
135         if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32)
136         {
137             size = 4 * count;
138         }
139         else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64)
140         {
141             size = 8 * count;
142         }
143         else
144         { 
145             pb_ostream_t sizestream = PB_OSTREAM_SIZING;
146             p = pData;
147             for (i = 0; i < count; i++)
148             {
149                 if (!func(&sizestream, field, p))
150                     return false;
151                 p = (const char*)p + field->data_size;
152             }
153             size = sizestream.bytes_written;
154         }
155         
156         if (!pb_encode_varint(stream, (uint64_t)size))
157             return false;
158         
159         if (stream->callback == NULL)
160             return pb_write(stream, NULL, size); /* Just sizing.. */
161         
162         /* Write the data */
163         p = pData;
164         for (i = 0; i < count; i++)
165         {
166             if (!func(stream, field, p))
167                 return false;
168             p = (const char*)p + field->data_size;
169         }
170     }
171     else
172     {
173         p = pData;
174         for (i = 0; i < count; i++)
175         {
176             if (!pb_encode_tag_for_field(stream, field))
177                 return false;
178
179             /* Normally the data is stored directly in the array entries, but
180              * for pointer-type string and bytes fields, the array entries are
181              * actually pointers themselves also. So we have to dereference once
182              * more to get to the actual data. */
183             if (PB_ATYPE(field->type) == PB_ATYPE_POINTER &&
184                 (PB_LTYPE(field->type) == PB_LTYPE_STRING ||
185                  PB_LTYPE(field->type) == PB_LTYPE_BYTES))
186             {
187                 if (!func(stream, field, *(const void* const*)p))
188                     return false;      
189             }
190             else
191             {
192                 if (!func(stream, field, p))
193                     return false;
194             }
195             p = (const char*)p + field->data_size;
196         }
197     }
198     
199     return true;
200 }
201
202 /* In proto3, all fields are optional and are only encoded if their value is "non-zero".
203  * This function implements the check for the zero value. */
204 static bool pb_check_proto3_default_value(const pb_field_t *field, const void *pData)
205 {
206     if(PB_LTYPE(field->type) == PB_LTYPE_BYTES)
207     {
208         const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)pData;
209         return bytes->size == 0;
210     }
211     else if (PB_LTYPE(field->type) == PB_LTYPE_STRING)
212     {
213         return *(const char*)pData == '\0';
214     }
215     else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED_LENGTH_BYTES)
216     {
217         /* Fixed length bytes is only empty if its length is fixed
218          * as 0. Which would be pretty strange, but we can check
219          * it anyway. */
220         return field->data_size == 0;
221     }
222         else
223         {
224             /* PB_LTYPE_VARINT, UVARINT, SVARINT, FIXED32, FIXED64,
225              * SUBMESSAGE, EXTENSION: These all have integer or pointer
226              * value which can be compared with 0. This does the check
227              * byte-by-byte to avoid the switch-cast logic used in
228              * pb_enc_varint(). (Casting to char* is safe with regards
229              * to C strict aliasing rules.)
230              */
231             uint_fast8_t i;
232             const char *p = (const char*)pData;
233             for (i = 0; i < field->data_size; i++)
234             {
235                 if (p[i] != 0)
236                 {
237                     return false;
238                 }
239             }
240
241             return true;
242         }
243 }
244
245 /* Encode a field with static or pointer allocation, i.e. one whose data
246  * is available to the encoder directly. */
247 static bool checkreturn encode_basic_field(pb_ostream_t *stream,
248     const pb_field_t *field, const void *pData)
249 {
250     pb_encoder_t func;
251     bool implicit_has;
252     const void *pSize = &implicit_has;
253     
254     func = PB_ENCODERS[PB_LTYPE(field->type)];
255     
256     if (field->size_offset)
257     {
258         /* Static optional, repeated or oneof field */
259         pSize = (const char*)pData + field->size_offset;
260     }
261     else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL)
262     {
263         /* Proto3 style field, optional but without explicit has_ field. */
264         implicit_has = !pb_check_proto3_default_value(field, pData);
265     }
266     else
267     {
268         /* Required field, always present */
269         implicit_has = true;
270     }
271
272     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
273     {
274         /* pData is a pointer to the field, which contains pointer to
275          * the data. If the 2nd pointer is NULL, it is interpreted as if
276          * the has_field was false.
277          */
278         pData = *(const void* const*)pData;
279         implicit_has = (pData != NULL);
280     }
281
282     switch (PB_HTYPE(field->type))
283     {
284         case PB_HTYPE_REQUIRED:
285             if (!pData)
286                 PB_RETURN_ERROR(stream, "missing required field");
287             if (!pb_encode_tag_for_field(stream, field))
288                 return false;
289             if (!func(stream, field, pData))
290                 return false;
291             break;
292         
293         case PB_HTYPE_OPTIONAL:
294             if (*(const bool*)pSize)
295             {
296                 if (!pb_encode_tag_for_field(stream, field))
297                     return false;
298             
299                 if (!func(stream, field, pData))
300                     return false;
301             }
302             break;
303         
304         case PB_HTYPE_REPEATED:
305             if (!encode_array(stream, field, pData, *(const pb_size_t*)pSize, func))
306                 return false;
307             break;
308         
309         case PB_HTYPE_ONEOF:
310             if (*(const pb_size_t*)pSize == field->tag)
311             {
312                 if (!pb_encode_tag_for_field(stream, field))
313                     return false;
314
315                 if (!func(stream, field, pData))
316                     return false;
317             }
318             break;
319             
320         default:
321             PB_RETURN_ERROR(stream, "invalid field type");
322     }
323     
324     return true;
325 }
326
327 /* Encode a field with callback semantics. This means that a user function is
328  * called to provide and encode the actual data. */
329 static bool checkreturn encode_callback_field(pb_ostream_t *stream,
330     const pb_field_t *field, const void *pData)
331 {
332     const pb_callback_t *callback = (const pb_callback_t*)pData;
333     
334 #ifdef PB_OLD_CALLBACK_STYLE
335     const void *arg = callback->arg;
336 #else
337     void * const *arg = &(callback->arg);
338 #endif    
339     
340     if (callback->funcs.encode != NULL)
341     {
342         if (!callback->funcs.encode(stream, field, arg))
343             PB_RETURN_ERROR(stream, "callback error");
344     }
345     return true;
346 }
347
348 /* Encode a single field of any callback or static type. */
349 static bool checkreturn encode_field(pb_ostream_t *stream,
350     const pb_field_t *field, const void *pData)
351 {
352     switch (PB_ATYPE(field->type))
353     {
354         case PB_ATYPE_STATIC:
355         case PB_ATYPE_POINTER:
356             return encode_basic_field(stream, field, pData);
357         
358         case PB_ATYPE_CALLBACK:
359             return encode_callback_field(stream, field, pData);
360         
361         default:
362             PB_RETURN_ERROR(stream, "invalid field type");
363     }
364 }
365
366 /* Default handler for extension fields. Expects to have a pb_field_t
367  * pointer in the extension->type->arg field. */
368 static bool checkreturn default_extension_encoder(pb_ostream_t *stream,
369     const pb_extension_t *extension)
370 {
371     const pb_field_t *field = (const pb_field_t*)extension->type->arg;
372     
373     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
374     {
375         /* For pointer extensions, the pointer is stored directly
376          * in the extension structure. This avoids having an extra
377          * indirection. */
378         return encode_field(stream, field, &extension->dest);
379     }
380     else
381     {
382         return encode_field(stream, field, extension->dest);
383     }
384 }
385
386 /* Walk through all the registered extensions and give them a chance
387  * to encode themselves. */
388 static bool checkreturn encode_extension_field(pb_ostream_t *stream,
389     const pb_field_t *field, const void *pData)
390 {
391     const pb_extension_t *extension = *(const pb_extension_t* const *)pData;
392     PB_UNUSED(field);
393     
394     while (extension)
395     {
396         bool status;
397         if (extension->type->encode)
398             status = extension->type->encode(stream, extension);
399         else
400             status = default_extension_encoder(stream, extension);
401
402         if (!status)
403             return false;
404         
405         extension = extension->next;
406     }
407     
408     return true;
409 }
410
411 /*********************
412  * Encode all fields *
413  *********************/
414
415 static void *remove_const(const void *p)
416 {
417     /* Note: this casts away const, in order to use the common field iterator
418      * logic for both encoding and decoding. */
419     union {
420         void *p1;
421         const void *p2;
422     } t;
423     t.p2 = p;
424     return t.p1;
425 }
426
427 bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
428 {
429     pb_field_iter_t iter;
430     if (!pb_field_iter_begin(&iter, fields, remove_const(src_struct)))
431         return true; /* Empty message type */
432     
433     do {
434         if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION)
435         {
436             /* Special case for the extension field placeholder */
437             if (!encode_extension_field(stream, iter.pos, iter.pData))
438                 return false;
439         }
440         else
441         {
442             /* Regular field */
443             if (!encode_field(stream, iter.pos, iter.pData))
444                 return false;
445         }
446     } while (pb_field_iter_next(&iter));
447     
448     return true;
449 }
450
451 bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
452 {
453     return pb_encode_submessage(stream, fields, src_struct);
454 }
455
456 bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct)
457 {
458     pb_ostream_t stream = PB_OSTREAM_SIZING;
459     
460     if (!pb_encode(&stream, fields, src_struct))
461         return false;
462     
463     *size = stream.bytes_written;
464     return true;
465 }
466
467 /********************
468  * Helper functions *
469  ********************/
470 bool checkreturn pb_encode_varint(pb_ostream_t *stream, uint64_t value)
471 {
472     pb_byte_t buffer[10];
473     size_t i = 0;
474     
475     if (value <= 0x7F)
476     {
477         pb_byte_t v = (pb_byte_t)value;
478         return pb_write(stream, &v, 1);
479     }
480     
481     while (value)
482     {
483         buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80);
484         value >>= 7;
485         i++;
486     }
487     buffer[i-1] &= 0x7F; /* Unset top bit on last byte */
488     
489     return pb_write(stream, buffer, i);
490 }
491
492 bool checkreturn pb_encode_svarint(pb_ostream_t *stream, int64_t value)
493 {
494     uint64_t zigzagged;
495     if (value < 0)
496         zigzagged = ~((uint64_t)value << 1);
497     else
498         zigzagged = (uint64_t)value << 1;
499     
500     return pb_encode_varint(stream, zigzagged);
501 }
502
503 bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value)
504 {
505     uint32_t val = *(const uint32_t*)value;
506     pb_byte_t bytes[4];
507     bytes[0] = (pb_byte_t)(val & 0xFF);
508     bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
509     bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
510     bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
511     return pb_write(stream, bytes, 4);
512 }
513
514 bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value)
515 {
516     uint64_t val = *(const uint64_t*)value;
517     pb_byte_t bytes[8];
518     bytes[0] = (pb_byte_t)(val & 0xFF);
519     bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
520     bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
521     bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
522     bytes[4] = (pb_byte_t)((val >> 32) & 0xFF);
523     bytes[5] = (pb_byte_t)((val >> 40) & 0xFF);
524     bytes[6] = (pb_byte_t)((val >> 48) & 0xFF);
525     bytes[7] = (pb_byte_t)((val >> 56) & 0xFF);
526     return pb_write(stream, bytes, 8);
527 }
528
529 bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number)
530 {
531     uint64_t tag = ((uint64_t)field_number << 3) | wiretype;
532     return pb_encode_varint(stream, tag);
533 }
534
535 bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field)
536 {
537     pb_wire_type_t wiretype;
538     switch (PB_LTYPE(field->type))
539     {
540         case PB_LTYPE_VARINT:
541         case PB_LTYPE_UVARINT:
542         case PB_LTYPE_SVARINT:
543             wiretype = PB_WT_VARINT;
544             break;
545         
546         case PB_LTYPE_FIXED32:
547             wiretype = PB_WT_32BIT;
548             break;
549         
550         case PB_LTYPE_FIXED64:
551             wiretype = PB_WT_64BIT;
552             break;
553         
554         case PB_LTYPE_BYTES:
555         case PB_LTYPE_STRING:
556         case PB_LTYPE_SUBMESSAGE:
557         case PB_LTYPE_FIXED_LENGTH_BYTES:
558             wiretype = PB_WT_STRING;
559             break;
560         
561         default:
562             PB_RETURN_ERROR(stream, "invalid field type");
563     }
564     
565     return pb_encode_tag(stream, wiretype, field->tag);
566 }
567
568 bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size)
569 {
570     if (!pb_encode_varint(stream, (uint64_t)size))
571         return false;
572     
573     return pb_write(stream, buffer, size);
574 }
575
576 bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
577 {
578     /* First calculate the message size using a non-writing substream. */
579     pb_ostream_t substream = PB_OSTREAM_SIZING;
580     size_t size;
581     bool status;
582     
583     if (!pb_encode(&substream, fields, src_struct))
584     {
585 #ifndef PB_NO_ERRMSG
586         stream->errmsg = substream.errmsg;
587 #endif
588         return false;
589     }
590     
591     size = substream.bytes_written;
592     
593     if (!pb_encode_varint(stream, (uint64_t)size))
594         return false;
595     
596     if (stream->callback == NULL)
597         return pb_write(stream, NULL, size); /* Just sizing */
598     
599     if (stream->bytes_written + size > stream->max_size)
600         PB_RETURN_ERROR(stream, "stream full");
601         
602     /* Use a substream to verify that a callback doesn't write more than
603      * what it did the first time. */
604     substream.callback = stream->callback;
605     substream.state = stream->state;
606     substream.max_size = size;
607     substream.bytes_written = 0;
608 #ifndef PB_NO_ERRMSG
609     substream.errmsg = NULL;
610 #endif
611     
612     status = pb_encode(&substream, fields, src_struct);
613     
614     stream->bytes_written += substream.bytes_written;
615     stream->state = substream.state;
616 #ifndef PB_NO_ERRMSG
617     stream->errmsg = substream.errmsg;
618 #endif
619     
620     if (substream.bytes_written != size)
621         PB_RETURN_ERROR(stream, "submsg size changed");
622     
623     return status;
624 }
625
626 /* Field encoders */
627
628 static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
629 {
630     int64_t value = 0;
631     
632     if (field->data_size == sizeof(int_least8_t))
633         value = *(const int_least8_t*)src;
634     else if (field->data_size == sizeof(int_least16_t))
635         value = *(const int_least16_t*)src;
636     else if (field->data_size == sizeof(int32_t))
637         value = *(const int32_t*)src;
638     else if (field->data_size == sizeof(int64_t))
639         value = *(const int64_t*)src;
640     else
641         PB_RETURN_ERROR(stream, "invalid data_size");
642     
643     return pb_encode_varint(stream, (uint64_t)value);
644 }
645
646 static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
647 {
648     uint64_t value = 0;
649     
650     if (field->data_size == sizeof(uint_least8_t))
651         value = *(const uint_least8_t*)src;
652     else if (field->data_size == sizeof(uint_least16_t))
653         value = *(const uint_least16_t*)src;
654     else if (field->data_size == sizeof(uint32_t))
655         value = *(const uint32_t*)src;
656     else if (field->data_size == sizeof(uint64_t))
657         value = *(const uint64_t*)src;
658     else
659         PB_RETURN_ERROR(stream, "invalid data_size");
660     
661     return pb_encode_varint(stream, value);
662 }
663
664 static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
665 {
666     int64_t value = 0;
667     
668     if (field->data_size == sizeof(int_least8_t))
669         value = *(const int_least8_t*)src;
670     else if (field->data_size == sizeof(int_least16_t))
671         value = *(const int_least16_t*)src;
672     else if (field->data_size == sizeof(int32_t))
673         value = *(const int32_t*)src;
674     else if (field->data_size == sizeof(int64_t))
675         value = *(const int64_t*)src;
676     else
677         PB_RETURN_ERROR(stream, "invalid data_size");
678     
679     return pb_encode_svarint(stream, value);
680 }
681
682 static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src)
683 {
684     PB_UNUSED(field);
685     return pb_encode_fixed64(stream, src);
686 }
687
688 static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src)
689 {
690     PB_UNUSED(field);
691     return pb_encode_fixed32(stream, src);
692 }
693
694 static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
695 {
696     const pb_bytes_array_t *bytes = NULL;
697
698     bytes = (const pb_bytes_array_t*)src;
699     
700     if (src == NULL)
701     {
702         /* Treat null pointer as an empty bytes field */
703         return pb_encode_string(stream, NULL, 0);
704     }
705     
706     if (PB_ATYPE(field->type) == PB_ATYPE_STATIC &&
707         PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) > field->data_size)
708     {
709         PB_RETURN_ERROR(stream, "bytes size exceeded");
710     }
711     
712     return pb_encode_string(stream, bytes->bytes, bytes->size);
713 }
714
715 static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src)
716 {
717     size_t size = 0;
718     size_t max_size = field->data_size;
719     const char *p = (const char*)src;
720     
721     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
722         max_size = (size_t)-1;
723
724     if (src == NULL)
725     {
726         size = 0; /* Treat null pointer as an empty string */
727     }
728     else
729     {
730         /* strnlen() is not always available, so just use a loop */
731         while (size < max_size && *p != '\0')
732         {
733             size++;
734             p++;
735         }
736     }
737
738     return pb_encode_string(stream, (const pb_byte_t*)src, size);
739 }
740
741 static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src)
742 {
743     if (field->ptr == NULL)
744         PB_RETURN_ERROR(stream, "invalid field descriptor");
745     
746     return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src);
747 }
748
749 static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
750 {
751     return pb_encode_string(stream, (const pb_byte_t*)src, field->data_size);
752 }
753