added encode / decode for length delimited fields

master
jmjatlanta 2016-12-12 06:26:00 -05:00
parent 9983fbbb83
commit 2d926dbd21
2 changed files with 58 additions and 15 deletions

View File

@ -7,6 +7,47 @@
#include "varint.h"
#include "protobuf.h"
int protobuf_encode_length_delimited(int field_number, enum WireType field_type, const char* incoming, size_t incoming_length,
unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written)
{
// push the field number and wire type together
unsigned int field_no = field_number << 3;
unsigned long long field = field_no | field_type;
size_t bytes_processed;
*bytes_written = 0;
// field type & number
varint_encode(field, buffer, max_buffer_length, &bytes_processed);
*bytes_written += bytes_processed;
// field size
varint_encode(incoming_length, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_processed);
*bytes_written += bytes_processed;
// field value
memcpy(&buffer[*bytes_written], incoming, incoming_length);
*bytes_written += incoming_length;
return 1;
}
int protobuf_decode_length_delimited(const unsigned char* buffer, size_t buffer_length, char** results, size_t *results_length, size_t* bytes_read) {
size_t pos = 0;
*bytes_read = 0;
// grab the field size
*results_length = varint_decode(&buffer[pos], buffer_length - pos, bytes_read);
pos += *bytes_read;
// allocate memory
*results = malloc(sizeof(char) * (*results_length));
if ((*results) == NULL)
return 0;
// copy the bytes
memcpy((*results), &buffer[pos], (*results_length));
pos += (*results_length);
*bytes_read = pos;
return 1;
}
/***
* encode a string into the buffer
* @param field_number the field number
@ -19,21 +60,7 @@
*/
int protobuf_encode_string(int field_number, enum WireType field_type, const char* incoming, unsigned char* buffer,
size_t max_buffer_length, size_t* bytes_written) {
// push the field number and wire type together
unsigned int field_no = field_number << 3;
unsigned long long field = field_no | field_type;
size_t bytes_processed;
*bytes_written = 0;
// field type & number
varint_encode(field, buffer, max_buffer_length, &bytes_processed);
*bytes_written += bytes_processed;
// field size
varint_encode(strlen(incoming), &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_processed);
*bytes_written += bytes_processed;
// field value
memcpy(&buffer[*bytes_written], incoming, strlen(incoming));
*bytes_written += strlen(incoming);
return 1;
return protobuf_encode_length_delimited(field_number, field_type, incoming, strlen(incoming), buffer, max_buffer_length, bytes_written);
}
/***

View File

@ -20,6 +20,22 @@ enum WireType {
WIRETYPE_32BIT
};
/***
* Encode a length delimited field into the buffer
* @param field_number the field number
* @param wire_type the wire type
* @param incoming the values
* @param incoming_length the lenght of incoming
* @param buffer the pointer to where to place the encoded value
* @param max_buffer_length the buffer length remaining
* @param bytes_written the number of bytes written
* @returns true(1) on success
*/
int protobuf_encode_length_delimited(int field_number, enum WireType wire_type, const char* incoming, size_t incoming_length,
unsigned char* buffer, size_t max_buffer_size, size_t* bytes_written);
int protobuf_decode_length_delimited(const unsigned char* buffer, size_t buffer_length, char** results, size_t *results_length, size_t* bytes_read);
/***
* encode a string into the buffer
* @param field_number the field number