added encode / decode for length delimited fields
This commit is contained in:
parent
9983fbbb83
commit
2d926dbd21
2 changed files with 58 additions and 15 deletions
57
protobuf.c
57
protobuf.c
|
@ -7,6 +7,47 @@
|
||||||
#include "varint.h"
|
#include "varint.h"
|
||||||
#include "protobuf.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
|
* encode a string into the buffer
|
||||||
* @param field_number the field number
|
* @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,
|
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) {
|
size_t max_buffer_length, size_t* bytes_written) {
|
||||||
// push the field number and wire type together
|
return protobuf_encode_length_delimited(field_number, field_type, incoming, strlen(incoming), buffer, max_buffer_length, bytes_written);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
16
protobuf.h
16
protobuf.h
|
@ -20,6 +20,22 @@ enum WireType {
|
||||||
WIRETYPE_32BIT
|
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
|
* encode a string into the buffer
|
||||||
* @param field_number the field number
|
* @param field_number the field number
|
||||||
|
|
Loading…
Reference in a new issue