Fixed protobuf bugs and added 3rd example of a complex object

This commit is contained in:
jmjatlanta 2016-12-09 14:13:59 -05:00
parent a443c699cf
commit 9983fbbb83
5 changed files with 34 additions and 6 deletions

View file

@ -48,6 +48,7 @@ int protobuf_encode_string(int field_number, enum WireType field_type, const cha
*/
int protobuf_encode_varint(int field_number, enum WireType field_type, unsigned long long incoming, unsigned char* buffer,
size_t max_buffer_length, size_t* bytes_written) {
*bytes_written = 0;
// push the field number and wire type together
unsigned int field_no = field_number << 3;
unsigned long long field = field_no | field_type;
@ -72,17 +73,20 @@ int protobuf_encode_varint(int field_number, enum WireType field_type, unsigned
*/
int protobuf_decode_string(const unsigned char* buffer, size_t buffer_length, char** results, size_t* bytes_read) {
size_t pos = 0;
*bytes_read = 0;
// grab the field size
int length = varint_decode(&buffer[pos], buffer_length - pos, bytes_read);
pos += *bytes_read;
// allocate memory
*results = malloc(sizeof(char) * length);
*results = malloc(sizeof(char) * length + 1);
if ((*results) == NULL)
return 0;
// copy the string
memcpy((*results), &buffer[pos], length);
// don't forget the null
(*results)[length] = 0;
pos += length;
*bytes_read = pos;
@ -98,9 +102,10 @@ int protobuf_decode_string(const unsigned char* buffer, size_t buffer_length, ch
* @param bytes_read the number of bytes read from the buffer
*/
int protobuf_decode_field_and_type(const unsigned char* buffer, int buffer_length, int *field_no, enum WireType *field_type, size_t* bytes_read) {
*bytes_read = 0;
unsigned long long field = varint_decode(buffer, buffer_length, bytes_read);
*field_no = field >> 3;
*field_type = field | *field_no;
*field_type = field & *field_no;
return 1;
}

View file

@ -38,6 +38,7 @@ int Test1_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Te
Test1_free(*output);
return 0;
}
pos += bytes_read;
switch (field_no) {
case (1):
(*output)->a = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read);

View file

@ -33,7 +33,16 @@ int Test3_protobuf_encode(struct Test3* incoming, unsigned char* buffer, size_t
*bytes_written += bytes_used;
protobuf_encode_varint(2, Test3_message_fields[1], incoming->an_int, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
*bytes_written += bytes_used;
return Test2_protobuf_encode(incoming->test2, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
// write Test2 to safe area
int pos = *bytes_written + 11;
size_t test2_size = 0;
int retVal = Test2_protobuf_encode(incoming->test2, &buffer[pos], max_buffer_length - pos, &test2_size);
protobuf_encode_varint(3, Test3_message_fields[2], test2_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
*bytes_written += bytes_used;
// now move the encoded Test2 to the correct area
memcpy(&buffer[*bytes_written], &buffer[pos], test2_size);
*bytes_written += test2_size;
return retVal;
}
int Test3_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Test3** output) {
@ -59,10 +68,13 @@ int Test3_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Te
(*output)->an_int = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read);
pos += bytes_read;
break;
case(3):
Test2_protobuf_decode(&buffer[pos], buffer_length - pos, &((*output)->test2));
case(3): {
size_t test2_size = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read);
pos += bytes_read;
Test2_protobuf_decode(&buffer[pos], buffer_length - pos, &((*output)->test2));
pos += test2_size;
break;
}
}
}
return 1;

View file

@ -65,7 +65,7 @@ int test_complex_protobuf() {
return 0;
}
if (strcmp(results->test2->a, test3->test2->a) == 0) {
if (strcmp(results->test2->a, test3->test2->a) != 0) {
printf("String a does not match: %s vs %s\n", test3->test2->a, results->test2->a);
Test3_free(test3);
Test3_free(results);
@ -145,6 +145,15 @@ int test_write_simple() {
return 0;
}
struct Test1* results;
retVal = Test1_protobuf_decode(buffer, bytes_written, &results);
if (results->a != test1.a) {
printf("Incorrect results after decode");
Test1_free(results);
return 0;
}
return 1;
}

View file

@ -61,6 +61,7 @@ unsigned char* varint_encode(const unsigned long long n, unsigned char* buf, int
*/
unsigned long long varint_decode(const unsigned char* buf, int len, size_t* bytes) {
unsigned long long result = 0;
if (bytes != NULL) *bytes = 0;
int bits = 0;
const unsigned char* ptr = buf;
unsigned long long ll;