Fixed protobuf bugs and added 3rd example of a complex object
This commit is contained in:
parent
a443c699cf
commit
9983fbbb83
5 changed files with 34 additions and 6 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
1
varint.c
1
varint.c
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue