1*c8d645caSAndroid Build Coastguard Worker /* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. 2*c8d645caSAndroid Build Coastguard Worker * The main function is pb_encode. You also need an output stream, and the 3*c8d645caSAndroid Build Coastguard Worker * field descriptions created by nanopb_generator.py. 4*c8d645caSAndroid Build Coastguard Worker */ 5*c8d645caSAndroid Build Coastguard Worker 6*c8d645caSAndroid Build Coastguard Worker #ifndef PB_ENCODE_H_INCLUDED 7*c8d645caSAndroid Build Coastguard Worker #define PB_ENCODE_H_INCLUDED 8*c8d645caSAndroid Build Coastguard Worker 9*c8d645caSAndroid Build Coastguard Worker #include "pb.h" 10*c8d645caSAndroid Build Coastguard Worker 11*c8d645caSAndroid Build Coastguard Worker #ifdef __cplusplus 12*c8d645caSAndroid Build Coastguard Worker extern "C" { 13*c8d645caSAndroid Build Coastguard Worker #endif 14*c8d645caSAndroid Build Coastguard Worker 15*c8d645caSAndroid Build Coastguard Worker /* Structure for defining custom output streams. You will need to provide 16*c8d645caSAndroid Build Coastguard Worker * a callback function to write the bytes to your storage, which can be 17*c8d645caSAndroid Build Coastguard Worker * for example a file or a network socket. 18*c8d645caSAndroid Build Coastguard Worker * 19*c8d645caSAndroid Build Coastguard Worker * The callback must conform to these rules: 20*c8d645caSAndroid Build Coastguard Worker * 21*c8d645caSAndroid Build Coastguard Worker * 1) Return false on IO errors. This will cause encoding to abort. 22*c8d645caSAndroid Build Coastguard Worker * 2) You can use state to store your own data (e.g. buffer pointer). 23*c8d645caSAndroid Build Coastguard Worker * 3) pb_write will update bytes_written after your callback runs. 24*c8d645caSAndroid Build Coastguard Worker * 4) Substreams will modify max_size and bytes_written. Don't use them 25*c8d645caSAndroid Build Coastguard Worker * to calculate any pointers. 26*c8d645caSAndroid Build Coastguard Worker */ 27*c8d645caSAndroid Build Coastguard Worker struct pb_ostream_s 28*c8d645caSAndroid Build Coastguard Worker { 29*c8d645caSAndroid Build Coastguard Worker #ifdef PB_BUFFER_ONLY 30*c8d645caSAndroid Build Coastguard Worker /* Callback pointer is not used in buffer-only configuration. 31*c8d645caSAndroid Build Coastguard Worker * Having an int pointer here allows binary compatibility but 32*c8d645caSAndroid Build Coastguard Worker * gives an error if someone tries to assign callback function. 33*c8d645caSAndroid Build Coastguard Worker * Also, NULL pointer marks a 'sizing stream' that does not 34*c8d645caSAndroid Build Coastguard Worker * write anything. 35*c8d645caSAndroid Build Coastguard Worker */ 36*c8d645caSAndroid Build Coastguard Worker int *callback; 37*c8d645caSAndroid Build Coastguard Worker #else 38*c8d645caSAndroid Build Coastguard Worker bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); 39*c8d645caSAndroid Build Coastguard Worker #endif 40*c8d645caSAndroid Build Coastguard Worker void *state; /* Free field for use by callback implementation. */ 41*c8d645caSAndroid Build Coastguard Worker size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ 42*c8d645caSAndroid Build Coastguard Worker size_t bytes_written; /* Number of bytes written so far. */ 43*c8d645caSAndroid Build Coastguard Worker 44*c8d645caSAndroid Build Coastguard Worker #ifndef PB_NO_ERRMSG 45*c8d645caSAndroid Build Coastguard Worker const char *errmsg; 46*c8d645caSAndroid Build Coastguard Worker #endif 47*c8d645caSAndroid Build Coastguard Worker }; 48*c8d645caSAndroid Build Coastguard Worker 49*c8d645caSAndroid Build Coastguard Worker /*************************** 50*c8d645caSAndroid Build Coastguard Worker * Main encoding functions * 51*c8d645caSAndroid Build Coastguard Worker ***************************/ 52*c8d645caSAndroid Build Coastguard Worker 53*c8d645caSAndroid Build Coastguard Worker /* Encode a single protocol buffers message from C structure into a stream. 54*c8d645caSAndroid Build Coastguard Worker * Returns true on success, false on any failure. 55*c8d645caSAndroid Build Coastguard Worker * The actual struct pointed to by src_struct must match the description in fields. 56*c8d645caSAndroid Build Coastguard Worker * All required fields in the struct are assumed to have been filled in. 57*c8d645caSAndroid Build Coastguard Worker * 58*c8d645caSAndroid Build Coastguard Worker * Example usage: 59*c8d645caSAndroid Build Coastguard Worker * MyMessage msg = {}; 60*c8d645caSAndroid Build Coastguard Worker * uint8_t buffer[64]; 61*c8d645caSAndroid Build Coastguard Worker * pb_ostream_t stream; 62*c8d645caSAndroid Build Coastguard Worker * 63*c8d645caSAndroid Build Coastguard Worker * msg.field1 = 42; 64*c8d645caSAndroid Build Coastguard Worker * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); 65*c8d645caSAndroid Build Coastguard Worker * pb_encode(&stream, MyMessage_fields, &msg); 66*c8d645caSAndroid Build Coastguard Worker */ 67*c8d645caSAndroid Build Coastguard Worker bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); 68*c8d645caSAndroid Build Coastguard Worker 69*c8d645caSAndroid Build Coastguard Worker /* Same as pb_encode, but prepends the length of the message as a varint. 70*c8d645caSAndroid Build Coastguard Worker * Corresponds to writeDelimitedTo() in Google's protobuf API. 71*c8d645caSAndroid Build Coastguard Worker */ 72*c8d645caSAndroid Build Coastguard Worker bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); 73*c8d645caSAndroid Build Coastguard Worker 74*c8d645caSAndroid Build Coastguard Worker /* Same as pb_encode, but appends a null byte to the message for termination. 75*c8d645caSAndroid Build Coastguard Worker * NOTE: This behaviour is not supported in most other protobuf implementations, so pb_encode_delimited() 76*c8d645caSAndroid Build Coastguard Worker * is a better option for compatibility. 77*c8d645caSAndroid Build Coastguard Worker */ 78*c8d645caSAndroid Build Coastguard Worker bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); 79*c8d645caSAndroid Build Coastguard Worker 80*c8d645caSAndroid Build Coastguard Worker /* Encode the message to get the size of the encoded data, but do not store 81*c8d645caSAndroid Build Coastguard Worker * the data. */ 82*c8d645caSAndroid Build Coastguard Worker bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct); 83*c8d645caSAndroid Build Coastguard Worker 84*c8d645caSAndroid Build Coastguard Worker /************************************** 85*c8d645caSAndroid Build Coastguard Worker * Functions for manipulating streams * 86*c8d645caSAndroid Build Coastguard Worker **************************************/ 87*c8d645caSAndroid Build Coastguard Worker 88*c8d645caSAndroid Build Coastguard Worker /* Create an output stream for writing into a memory buffer. 89*c8d645caSAndroid Build Coastguard Worker * The number of bytes written can be found in stream.bytes_written after 90*c8d645caSAndroid Build Coastguard Worker * encoding the message. 91*c8d645caSAndroid Build Coastguard Worker * 92*c8d645caSAndroid Build Coastguard Worker * Alternatively, you can use a custom stream that writes directly to e.g. 93*c8d645caSAndroid Build Coastguard Worker * a file or a network socket. 94*c8d645caSAndroid Build Coastguard Worker */ 95*c8d645caSAndroid Build Coastguard Worker pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); 96*c8d645caSAndroid Build Coastguard Worker 97*c8d645caSAndroid Build Coastguard Worker /* Pseudo-stream for measuring the size of a message without actually storing 98*c8d645caSAndroid Build Coastguard Worker * the encoded data. 99*c8d645caSAndroid Build Coastguard Worker * 100*c8d645caSAndroid Build Coastguard Worker * Example usage: 101*c8d645caSAndroid Build Coastguard Worker * MyMessage msg = {}; 102*c8d645caSAndroid Build Coastguard Worker * pb_ostream_t stream = PB_OSTREAM_SIZING; 103*c8d645caSAndroid Build Coastguard Worker * pb_encode(&stream, MyMessage_fields, &msg); 104*c8d645caSAndroid Build Coastguard Worker * printf("Message size is %d\n", stream.bytes_written); 105*c8d645caSAndroid Build Coastguard Worker */ 106*c8d645caSAndroid Build Coastguard Worker #ifndef PB_NO_ERRMSG 107*c8d645caSAndroid Build Coastguard Worker #define PB_OSTREAM_SIZING {0,0,0,0,0} 108*c8d645caSAndroid Build Coastguard Worker #else 109*c8d645caSAndroid Build Coastguard Worker #define PB_OSTREAM_SIZING {0,0,0,0} 110*c8d645caSAndroid Build Coastguard Worker #endif 111*c8d645caSAndroid Build Coastguard Worker 112*c8d645caSAndroid Build Coastguard Worker /* Function to write into a pb_ostream_t stream. You can use this if you need 113*c8d645caSAndroid Build Coastguard Worker * to append or prepend some custom headers to the message. 114*c8d645caSAndroid Build Coastguard Worker */ 115*c8d645caSAndroid Build Coastguard Worker bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); 116*c8d645caSAndroid Build Coastguard Worker 117*c8d645caSAndroid Build Coastguard Worker 118*c8d645caSAndroid Build Coastguard Worker /************************************************ 119*c8d645caSAndroid Build Coastguard Worker * Helper functions for writing field callbacks * 120*c8d645caSAndroid Build Coastguard Worker ************************************************/ 121*c8d645caSAndroid Build Coastguard Worker 122*c8d645caSAndroid Build Coastguard Worker /* Encode field header based on type and field number defined in the field 123*c8d645caSAndroid Build Coastguard Worker * structure. Call this from the callback before writing out field contents. */ 124*c8d645caSAndroid Build Coastguard Worker bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field); 125*c8d645caSAndroid Build Coastguard Worker 126*c8d645caSAndroid Build Coastguard Worker /* Encode field header by manually specifying wire type. You need to use this 127*c8d645caSAndroid Build Coastguard Worker * if you want to write out packed arrays from a callback field. */ 128*c8d645caSAndroid Build Coastguard Worker bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); 129*c8d645caSAndroid Build Coastguard Worker 130*c8d645caSAndroid Build Coastguard Worker /* Encode an integer in the varint format. 131*c8d645caSAndroid Build Coastguard Worker * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ 132*c8d645caSAndroid Build Coastguard Worker #ifndef PB_WITHOUT_64BIT 133*c8d645caSAndroid Build Coastguard Worker bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); 134*c8d645caSAndroid Build Coastguard Worker #else 135*c8d645caSAndroid Build Coastguard Worker bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); 136*c8d645caSAndroid Build Coastguard Worker #endif 137*c8d645caSAndroid Build Coastguard Worker 138*c8d645caSAndroid Build Coastguard Worker /* Encode an integer in the zig-zagged svarint format. 139*c8d645caSAndroid Build Coastguard Worker * This works for sint32 and sint64. */ 140*c8d645caSAndroid Build Coastguard Worker #ifndef PB_WITHOUT_64BIT 141*c8d645caSAndroid Build Coastguard Worker bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); 142*c8d645caSAndroid Build Coastguard Worker #else 143*c8d645caSAndroid Build Coastguard Worker bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); 144*c8d645caSAndroid Build Coastguard Worker #endif 145*c8d645caSAndroid Build Coastguard Worker 146*c8d645caSAndroid Build Coastguard Worker /* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ 147*c8d645caSAndroid Build Coastguard Worker bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); 148*c8d645caSAndroid Build Coastguard Worker 149*c8d645caSAndroid Build Coastguard Worker /* Encode a fixed32, sfixed32 or float value. 150*c8d645caSAndroid Build Coastguard Worker * You need to pass a pointer to a 4-byte wide C variable. */ 151*c8d645caSAndroid Build Coastguard Worker bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); 152*c8d645caSAndroid Build Coastguard Worker 153*c8d645caSAndroid Build Coastguard Worker #ifndef PB_WITHOUT_64BIT 154*c8d645caSAndroid Build Coastguard Worker /* Encode a fixed64, sfixed64 or double value. 155*c8d645caSAndroid Build Coastguard Worker * You need to pass a pointer to a 8-byte wide C variable. */ 156*c8d645caSAndroid Build Coastguard Worker bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); 157*c8d645caSAndroid Build Coastguard Worker #endif 158*c8d645caSAndroid Build Coastguard Worker 159*c8d645caSAndroid Build Coastguard Worker /* Encode a submessage field. 160*c8d645caSAndroid Build Coastguard Worker * You need to pass the pb_field_t array and pointer to struct, just like 161*c8d645caSAndroid Build Coastguard Worker * with pb_encode(). This internally encodes the submessage twice, first to 162*c8d645caSAndroid Build Coastguard Worker * calculate message size and then to actually write it out. 163*c8d645caSAndroid Build Coastguard Worker */ 164*c8d645caSAndroid Build Coastguard Worker bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); 165*c8d645caSAndroid Build Coastguard Worker 166*c8d645caSAndroid Build Coastguard Worker #ifdef __cplusplus 167*c8d645caSAndroid Build Coastguard Worker } /* extern "C" */ 168*c8d645caSAndroid Build Coastguard Worker #endif 169*c8d645caSAndroid Build Coastguard Worker 170*c8d645caSAndroid Build Coastguard Worker #endif 171