LCOV - code coverage report
Current view: top level - alltypes_proto3_callback - encode_alltypes_callback.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 225 227 99.1 %
Date: 2023-02-14 20:10:26 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields.
       2             :  * Note that normally there would be no reason to use callback fields for this,
       3             :  * because each encoder defined here only gives a single field.
       4             :  */
       5             : 
       6             : #include <stdio.h>
       7             : #include <stdlib.h>
       8             : #include <string.h>
       9             : #include <pb_encode.h>
      10             : #include "alltypes.pb.h"
      11             : #include "test_helpers.h"
      12             : 
      13           8 : static bool write_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      14             : {
      15          16 :     return pb_encode_tag_for_field(stream, field) &&
      16           8 :            pb_encode_varint(stream, (intptr_t)*arg);
      17             : }
      18             : 
      19           2 : static bool write_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      20             : {
      21           4 :     return pb_encode_tag_for_field(stream, field) &&
      22           2 :            pb_encode_svarint(stream, (intptr_t)*arg);
      23             : }
      24             : 
      25           3 : static bool write_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      26             : {
      27           6 :     return pb_encode_tag_for_field(stream, field) &&
      28           3 :            pb_encode_fixed32(stream, *arg);
      29             : }
      30             : 
      31           2 : static bool write_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      32             : {
      33           4 :     return pb_encode_tag_for_field(stream, field) &&
      34           2 :            pb_encode_fixed64(stream, *arg);
      35             : }
      36             : 
      37           1 : static bool write_double(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      38             : {
      39             : #ifdef PB_CONVERT_DOUBLE_FLOAT
      40             :     if (sizeof(double) == sizeof(float))
      41             :         return pb_encode_tag_for_field(stream, field) &&
      42             :                pb_encode_float_as_double(stream, *(float*)*arg);
      43             : #endif
      44             : 
      45           2 :     return pb_encode_tag_for_field(stream, field) &&
      46           1 :            pb_encode_fixed64(stream, *arg);
      47             : }
      48             : 
      49           3 : static bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      50             : {
      51           6 :     return pb_encode_tag_for_field(stream, field) &&
      52           3 :            pb_encode_string(stream, *arg, strlen(*arg));
      53             : }
      54             : 
      55           2 : static bool write_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      56             : {
      57             :    
      58           4 :     return pb_encode_tag_for_field(stream, field) &&
      59           2 :            pb_encode_submessage(stream, SubMessage_fields, *arg);
      60             : }
      61             : 
      62           1 : static bool write_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      63             : {
      64           1 :     EmptyMessage emptymsg = {0};
      65           2 :     return pb_encode_tag_for_field(stream, field) &&
      66           1 :            pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg);
      67             : }
      68             : 
      69          12 : static bool write_repeated_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      70             : {
      71          24 :     return pb_encode_tag_for_field(stream, field) &&
      72          24 :            pb_encode_varint(stream, 0) &&
      73          24 :            pb_encode_tag_for_field(stream, field) &&
      74          24 :            pb_encode_varint(stream, 0) &&
      75          24 :            pb_encode_tag_for_field(stream, field) &&
      76          24 :            pb_encode_varint(stream, 0) &&
      77          24 :            pb_encode_tag_for_field(stream, field) &&
      78          24 :            pb_encode_varint(stream, 0) &&
      79          36 :            pb_encode_tag_for_field(stream, field) &&
      80          12 :            pb_encode_varint(stream, (intptr_t)*arg);
      81             : }
      82             : 
      83           4 : static bool write_repeated_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      84             : {
      85           8 :     return pb_encode_tag_for_field(stream, field) &&
      86           8 :            pb_encode_svarint(stream, 0) &&
      87           8 :            pb_encode_tag_for_field(stream, field) &&
      88           8 :            pb_encode_svarint(stream, 0) &&
      89           8 :            pb_encode_tag_for_field(stream, field) &&
      90           8 :            pb_encode_svarint(stream, 0) &&
      91           8 :            pb_encode_tag_for_field(stream, field) &&
      92           8 :            pb_encode_svarint(stream, 0) &&
      93          12 :            pb_encode_tag_for_field(stream, field) &&
      94           4 :            pb_encode_svarint(stream, (intptr_t)*arg);
      95             : }
      96             : 
      97           6 : static bool write_repeated_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
      98             : {
      99           6 :     uint32_t dummy = 0;
     100             : 
     101             :     /* Make it a packed field */
     102          12 :     return pb_encode_tag(stream, PB_WT_STRING, field->tag) &&
     103          12 :            pb_encode_varint(stream, 5 * 4) && /* Number of bytes */
     104          12 :            pb_encode_fixed32(stream, &dummy) &&
     105          12 :            pb_encode_fixed32(stream, &dummy) &&
     106          12 :            pb_encode_fixed32(stream, &dummy) &&
     107          18 :            pb_encode_fixed32(stream, &dummy) &&
     108           6 :            pb_encode_fixed32(stream, *arg);
     109             : }
     110             : 
     111           4 : static bool write_repeated_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
     112             : {
     113           4 :     uint64_t dummy = 0;
     114             : 
     115             :     /* Make it a packed field */
     116           8 :     return pb_encode_tag(stream, PB_WT_STRING, field->tag) &&
     117           8 :            pb_encode_varint(stream, 5 * 8) && /* Number of bytes */
     118           8 :            pb_encode_fixed64(stream, &dummy) &&
     119           8 :            pb_encode_fixed64(stream, &dummy) &&
     120           8 :            pb_encode_fixed64(stream, &dummy) &&
     121          12 :            pb_encode_fixed64(stream, &dummy) &&
     122           4 :            pb_encode_fixed64(stream, *arg);
     123             : }
     124             : 
     125           2 : static bool write_repeated_double(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
     126             : {
     127           2 :     uint64_t dummy = 0;
     128             : 
     129             : #ifdef PB_CONVERT_DOUBLE_FLOAT
     130             :     if (sizeof(double) == sizeof(float))
     131             :         return pb_encode_tag(stream, PB_WT_STRING, field->tag) &&
     132             :                pb_encode_varint(stream, 5 * 8) && /* Number of bytes */
     133             :                pb_encode_float_as_double(stream, 0.0f) &&
     134             :                pb_encode_float_as_double(stream, 0.0f) &&
     135             :                pb_encode_float_as_double(stream, 0.0f) &&
     136             :                pb_encode_float_as_double(stream, 0.0f) &&
     137             :                pb_encode_float_as_double(stream, *(float*)*arg);
     138             : #endif
     139             : 
     140             :     /* Make it a packed field */
     141           4 :     return pb_encode_tag(stream, PB_WT_STRING, field->tag) &&
     142           4 :            pb_encode_varint(stream, 5 * 8) && /* Number of bytes */
     143           4 :            pb_encode_fixed64(stream, &dummy) &&
     144           4 :            pb_encode_fixed64(stream, &dummy) &&
     145           4 :            pb_encode_fixed64(stream, &dummy) &&
     146           6 :            pb_encode_fixed64(stream, &dummy) &&
     147           2 :            pb_encode_fixed64(stream, *arg);
     148             : }
     149             : 
     150           6 : static bool write_repeated_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
     151             : {
     152          12 :     return pb_encode_tag_for_field(stream, field) &&
     153          12 :            pb_encode_string(stream, 0, 0) &&
     154          12 :            pb_encode_tag_for_field(stream, field) &&
     155          12 :            pb_encode_string(stream, 0, 0) &&
     156          12 :            pb_encode_tag_for_field(stream, field) &&
     157          12 :            pb_encode_string(stream, 0, 0) &&
     158          12 :            pb_encode_tag_for_field(stream, field) &&
     159          12 :            pb_encode_string(stream, 0, 0) &&
     160          18 :            pb_encode_tag_for_field(stream, field) &&
     161           6 :            pb_encode_string(stream, *arg, strlen(*arg));
     162             : }
     163             : 
     164           2 : static bool write_repeated_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
     165             : {
     166           2 :     SubMessage dummy = {""};
     167             : 
     168           4 :     return pb_encode_tag_for_field(stream, field) &&
     169           4 :            pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
     170           4 :            pb_encode_tag_for_field(stream, field) &&
     171           4 :            pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
     172           4 :            pb_encode_tag_for_field(stream, field) &&
     173           4 :            pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
     174           4 :            pb_encode_tag_for_field(stream, field) &&
     175           4 :            pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
     176           6 :            pb_encode_tag_for_field(stream, field) &&
     177           2 :            pb_encode_submessage(stream, SubMessage_fields, *arg);
     178             : }
     179             : 
     180           2 : static bool write_limits(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
     181             : {
     182           2 :     Limits limits = {0};
     183           2 :     limits.int32_min  = INT32_MIN;
     184           2 :     limits.int32_max  = INT32_MAX;
     185           2 :     limits.uint32_min = 0;
     186           2 :     limits.uint32_max = UINT32_MAX;
     187           2 :     limits.int64_min  = INT64_MIN;
     188           2 :     limits.int64_max  = INT64_MAX;
     189           2 :     limits.uint64_min = 0;
     190           2 :     limits.uint64_max = UINT64_MAX;
     191           2 :     limits.enum_min   = HugeEnum_Negative;
     192           2 :     limits.enum_max   = HugeEnum_Positive;
     193             :    
     194           4 :     return pb_encode_tag_for_field(stream, field) &&
     195           2 :            pb_encode_submessage(stream, Limits_fields, &limits);
     196             : }
     197             : 
     198           2 : static bool write_repeated_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
     199             : {
     200           2 :     EmptyMessage emptymsg = {0};
     201           4 :     return pb_encode_tag_for_field(stream, field) &&
     202           4 :            pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
     203           4 :            pb_encode_tag_for_field(stream, field) &&
     204           4 :            pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
     205           4 :            pb_encode_tag_for_field(stream, field) &&
     206           4 :            pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
     207           4 :            pb_encode_tag_for_field(stream, field) &&
     208           4 :            pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
     209           6 :            pb_encode_tag_for_field(stream, field) &&
     210           2 :            pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg);
     211             : }
     212             : 
     213           2 : int main(int argc, char **argv)
     214             : {
     215           2 :     int mode = (argc > 1) ? atoi(argv[1]) : 0;
     216             : 
     217             :     /* Values for use from callbacks through pointers. */
     218           2 :     uint32_t    rep_fixed32     = 2008;
     219           2 :     int32_t     rep_sfixed32    = -2009;
     220           2 :     float       rep_float       = 2010.0f;
     221           2 :     uint64_t    rep_fixed64     = 2011;
     222           2 :     int64_t     rep_sfixed64    = -2012;
     223           2 :     double      rep_double      = 2013.0;
     224           2 :     SubMessage  rep_submsg      = {"2016", 2016, 2016};
     225             :     
     226           2 :     uint32_t    sng_fixed32     = 3048;
     227           2 :     int32_t     sng_sfixed32    = 3049;
     228           2 :     float       sng_float       = 3050.0f;
     229           2 :     uint64_t    sng_fixed64     = 3051;
     230           2 :     int64_t     sng_sfixed64    = 3052;
     231           2 :     double      sng_double      = 3053.0f;
     232           2 :     SubMessage  sng_submsg      = {"3056", 3056};
     233             :     
     234           2 :     SubMessage  oneof_msg1      = {"4059", 4059};
     235             : 
     236           2 :     AllTypes alltypes = AllTypes_init_zero;
     237             :     
     238             :     /* Bind callbacks for repeated fields */
     239           2 :     alltypes.rep_int32.funcs.encode = &write_repeated_varint;
     240           2 :     alltypes.rep_int32.arg = (void*)-2001;
     241             :     
     242           2 :     alltypes.rep_int64.funcs.encode = &write_repeated_varint;
     243           2 :     alltypes.rep_int64.arg = (void*)-2002;
     244             :     
     245           2 :     alltypes.rep_uint32.funcs.encode = &write_repeated_varint;
     246           2 :     alltypes.rep_uint32.arg = (void*)2003;
     247             :     
     248           2 :     alltypes.rep_uint64.funcs.encode = &write_repeated_varint;
     249           2 :     alltypes.rep_uint64.arg = (void*)2004;
     250             :     
     251           2 :     alltypes.rep_sint32.funcs.encode = &write_repeated_svarint;
     252           2 :     alltypes.rep_sint32.arg = (void*)-2005;
     253             :     
     254           2 :     alltypes.rep_sint64.funcs.encode = &write_repeated_svarint;
     255           2 :     alltypes.rep_sint64.arg = (void*)-2006;
     256             :     
     257           2 :     alltypes.rep_bool.funcs.encode = &write_repeated_varint;
     258           2 :     alltypes.rep_bool.arg = (void*)true;
     259             :     
     260           2 :     alltypes.rep_fixed32.funcs.encode = &write_repeated_fixed32;
     261           2 :     alltypes.rep_fixed32.arg = &rep_fixed32;
     262             : 
     263           2 :     alltypes.rep_sfixed32.funcs.encode = &write_repeated_fixed32;
     264           2 :     alltypes.rep_sfixed32.arg = &rep_sfixed32;
     265             :     
     266           2 :     alltypes.rep_float.funcs.encode = &write_repeated_fixed32;
     267           2 :     alltypes.rep_float.arg = &rep_float;
     268             :     
     269           2 :     alltypes.rep_fixed64.funcs.encode = &write_repeated_fixed64;
     270           2 :     alltypes.rep_fixed64.arg = &rep_fixed64;
     271             : 
     272           2 :     alltypes.rep_sfixed64.funcs.encode = &write_repeated_fixed64;
     273           2 :     alltypes.rep_sfixed64.arg = &rep_sfixed64;
     274             :     
     275           2 :     alltypes.rep_double.funcs.encode = &write_repeated_double;
     276           2 :     alltypes.rep_double.arg = &rep_double;
     277             :     
     278           2 :     alltypes.rep_string.funcs.encode = &write_repeated_string;
     279           2 :     alltypes.rep_string.arg = "2014";
     280             :     
     281           2 :     alltypes.rep_bytes.funcs.encode = &write_repeated_string;
     282           2 :     alltypes.rep_bytes.arg = "2015";
     283             :     
     284           2 :     alltypes.rep_submsg.funcs.encode = &write_repeated_submsg;
     285           2 :     alltypes.rep_submsg.arg = &rep_submsg;
     286             :     
     287           2 :     alltypes.rep_enum.funcs.encode = &write_repeated_varint;
     288           2 :     alltypes.rep_enum.arg = (void*)MyEnum_Truth;
     289             :     
     290           2 :     alltypes.rep_emptymsg.funcs.encode = &write_repeated_emptymsg;
     291             :     
     292           2 :     alltypes.rep_fbytes.funcs.encode = &write_repeated_string;
     293           2 :     alltypes.rep_fbytes.arg = "2019";
     294             :     
     295           2 :     alltypes.req_limits.funcs.encode = &write_limits;
     296             :     
     297             :     /* Bind callbacks for singular fields */
     298           2 :     if (mode != 0)
     299             :     {
     300           1 :         alltypes.sng_int32.funcs.encode = &write_varint;
     301           1 :         alltypes.sng_int32.arg = (void*)3041;
     302             :         
     303           1 :         alltypes.sng_int64.funcs.encode = &write_varint;
     304           1 :         alltypes.sng_int64.arg = (void*)3042;
     305             :         
     306           1 :         alltypes.sng_uint32.funcs.encode = &write_varint;
     307           1 :         alltypes.sng_uint32.arg = (void*)3043;
     308             :         
     309           1 :         alltypes.sng_uint64.funcs.encode = &write_varint;
     310           1 :         alltypes.sng_uint64.arg = (void*)3044;
     311             :         
     312           1 :         alltypes.sng_sint32.funcs.encode = &write_svarint;
     313           1 :         alltypes.sng_sint32.arg = (void*)3045;
     314             :         
     315           1 :         alltypes.sng_sint64.funcs.encode = &write_svarint;
     316           1 :         alltypes.sng_sint64.arg = (void*)3046;
     317             :         
     318           1 :         alltypes.sng_bool.funcs.encode = &write_varint;
     319           1 :         alltypes.sng_bool.arg = (void*)true;
     320             : 
     321           1 :         alltypes.sng_fixed32.funcs.encode = &write_fixed32;
     322           1 :         alltypes.sng_fixed32.arg = &sng_fixed32;
     323             :         
     324           1 :         alltypes.sng_sfixed32.funcs.encode = &write_fixed32;
     325           1 :         alltypes.sng_sfixed32.arg = &sng_sfixed32;
     326             :         
     327           1 :         alltypes.sng_float.funcs.encode = &write_fixed32;
     328           1 :         alltypes.sng_float.arg = &sng_float;
     329             :         
     330           1 :         alltypes.sng_fixed64.funcs.encode = &write_fixed64;
     331           1 :         alltypes.sng_fixed64.arg = &sng_fixed64;
     332             :         
     333           1 :         alltypes.sng_sfixed64.funcs.encode = &write_fixed64;
     334           1 :         alltypes.sng_sfixed64.arg = &sng_sfixed64;
     335             :         
     336           1 :         alltypes.sng_double.funcs.encode = &write_double;
     337           1 :         alltypes.sng_double.arg = &sng_double;
     338             :         
     339           1 :         alltypes.sng_string.funcs.encode = &write_string;
     340           1 :         alltypes.sng_string.arg = "3054";
     341             :         
     342           1 :         alltypes.sng_bytes.funcs.encode = &write_string;
     343           1 :         alltypes.sng_bytes.arg = "3055";
     344             :         
     345           1 :         alltypes.sng_submsg.funcs.encode = &write_submsg;
     346           1 :         alltypes.sng_submsg.arg = &sng_submsg;
     347             :         
     348           1 :         alltypes.sng_enum.funcs.encode = &write_varint;
     349           1 :         alltypes.sng_enum.arg = (void*)MyEnum_Truth;
     350             :         
     351           1 :         alltypes.sng_emptymsg.funcs.encode = &write_emptymsg;
     352             : 
     353           1 :         alltypes.sng_fbytes.funcs.encode = &write_string;
     354           1 :         alltypes.sng_fbytes.arg = "3059";
     355             : 
     356           1 :         alltypes.oneof_msg1.funcs.encode = &write_submsg;
     357           1 :         alltypes.oneof_msg1.arg = &oneof_msg1;
     358             :     }
     359             :     
     360           2 :     alltypes.end.funcs.encode = &write_varint;
     361           2 :     alltypes.end.arg = (void*)1099;
     362             :     
     363             :     {
     364             :         uint8_t buffer[2048];
     365           2 :         pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
     366             :         
     367             :         /* Now encode it and check if we succeeded. */
     368           2 :         if (pb_encode(&stream, AllTypes_fields, &alltypes))
     369             :         {
     370             :             SET_BINARY_MODE(stdout);
     371           2 :             fwrite(buffer, 1, stream.bytes_written, stdout);
     372           2 :             return 0; /* Success */
     373             :         }
     374             :         else
     375             :         {
     376           0 :             fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
     377           0 :             return 1; /* Failure */
     378             :         }
     379             :     }
     380             : }

Generated by: LCOV version 1.14