Added a more complex example. See Test3_protobuf.c
This commit is contained in:
parent
69a6f1516f
commit
a443c699cf
6 changed files with 150 additions and 1 deletions
|
@ -23,6 +23,7 @@ int protobuf_encode_string(int field_number, enum WireType field_type, const cha
|
|||
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;
|
||||
|
|
|
@ -2,7 +2,7 @@ CC = gcc
|
|||
CFLAGS = -O0 -g3 -Wall -I../
|
||||
LFLAGS =
|
||||
DEPS = ../protobuf.h
|
||||
OBJS = testit.o ../protobuf.o ../varint.o Test1_protobuf.o Test2_protobuf.o
|
||||
OBJS = testit.o ../protobuf.o ../varint.o Test1_protobuf.o Test2_protobuf.o Test3_protobuf.o
|
||||
|
||||
%.o: %.c $(DEPS)
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
|
69
test/Test3_protobuf.c
Normal file
69
test/Test3_protobuf.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "protobuf.h"
|
||||
#include "varint.h"
|
||||
#include "Test3_protobuf.h"
|
||||
|
||||
enum WireType Test3_message_fields[] = { WIRETYPE_LENGTH_DELIMITED, WIRETYPE_VARINT, WIRETYPE_LENGTH_DELIMITED };
|
||||
|
||||
int Test3_new(struct Test3** test3) {
|
||||
*test3 = (struct Test3*)malloc(sizeof(struct Test3));
|
||||
if (*test3 == NULL)
|
||||
return 0;
|
||||
(*test3)->a_string = NULL;
|
||||
(*test3)->an_int = 0;
|
||||
(*test3)->test2 = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Test3_free(struct Test3* test3) {
|
||||
if (test3->a_string != NULL)
|
||||
free(test3->a_string);
|
||||
if (test3->test2 != NULL)
|
||||
Test2_free(test3->test2);
|
||||
free(test3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Test3_protobuf_encode(struct Test3* incoming, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) {
|
||||
size_t bytes_used;
|
||||
*bytes_written = 0;
|
||||
protobuf_encode_string(1, Test3_message_fields[0], incoming->a_string, buffer, max_buffer_length, &bytes_used);
|
||||
*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);
|
||||
}
|
||||
|
||||
int Test3_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Test3** output) {
|
||||
size_t pos = 0;
|
||||
if (Test3_new(output) == 0)
|
||||
return 0;
|
||||
|
||||
while (pos < buffer_length) { // loop through buffer
|
||||
size_t bytes_read = 0;
|
||||
int field_no;
|
||||
enum WireType field_type;
|
||||
if (protobuf_decode_field_and_type(&buffer[pos], buffer_length, &field_no, &field_type, &bytes_read) == 0) {
|
||||
Test3_free(*output);
|
||||
return 0;
|
||||
}
|
||||
pos += bytes_read;
|
||||
switch (field_no) {
|
||||
case(1):
|
||||
protobuf_decode_string(&buffer[pos], buffer_length - pos, &((*output)->a_string), &bytes_read);
|
||||
pos += bytes_read;
|
||||
break;
|
||||
case (2):
|
||||
(*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));
|
||||
pos += bytes_read;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
22
test/Test3_protobuf.h
Normal file
22
test/Test3_protobuf.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Test3_protobuf.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "protobuf.h"
|
||||
|
||||
#include "Test2_protobuf.h"
|
||||
|
||||
struct Test3 {
|
||||
char* a_string;
|
||||
int an_int;
|
||||
struct Test2* test2;
|
||||
};
|
||||
|
||||
int Test3_new(struct Test3** test1);
|
||||
int Test3_free(struct Test3* test1);
|
||||
|
||||
int Test3_protobuf_encode(struct Test3* incoming, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written);
|
||||
int Test3_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Test3** output);
|
||||
|
|
@ -17,10 +17,65 @@
|
|||
* int Test1_protobuf_encode(struct Test1* incoming, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written);
|
||||
* int Test1_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Test1** output);
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Test3_protobuf.h"
|
||||
#include "Test1_protobuf.h"
|
||||
#include "Test2_protobuf.h"
|
||||
|
||||
int test_complex_protobuf() {
|
||||
int buffer_length = 255;
|
||||
size_t bytes_used = 0;
|
||||
unsigned char buffer[buffer_length];
|
||||
|
||||
// build the objects
|
||||
struct Test2* test2;
|
||||
Test2_new(&test2);
|
||||
struct Test3* test3;
|
||||
Test3_new(&test3);
|
||||
test3->test2 = test2;
|
||||
|
||||
// set values
|
||||
test3->a_string = malloc(15);
|
||||
strcpy(test3->a_string, "Hello, World!");
|
||||
test3->an_int = 29;
|
||||
test3->test2->a = malloc(10);
|
||||
strcpy(test3->test2->a, "Testing");
|
||||
|
||||
// encode
|
||||
Test3_protobuf_encode(test3, buffer, buffer_length, &bytes_used);
|
||||
|
||||
// decode
|
||||
struct Test3* results;
|
||||
Test3_protobuf_decode(buffer, bytes_used, &results);
|
||||
|
||||
// view results
|
||||
if (strcmp(results->a_string, test3->a_string) != 0) {
|
||||
printf("String a does not match: %s vs %s\n", test3->a_string, results->a_string);
|
||||
Test3_free(test3);
|
||||
Test3_free(results);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results->an_int != test3->an_int) {
|
||||
printf("Integers do not match: %d vs %d\n", test3->an_int, results->an_int);
|
||||
Test3_free(test3);
|
||||
Test3_free(results);
|
||||
return 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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int test_rightshift() {
|
||||
struct Test1 test1;
|
||||
test1.a = 0;
|
||||
|
|
|
@ -19,6 +19,7 @@ const char* names[] = {
|
|||
"test_write_negative",
|
||||
"test_write_string",
|
||||
"test_rightshift",
|
||||
"test_complex_protobuf",
|
||||
"test_varint"
|
||||
};
|
||||
|
||||
|
@ -27,6 +28,7 @@ int (*funcs[])(void) = {
|
|||
test_write_negative,
|
||||
test_write_string,
|
||||
test_rightshift,
|
||||
test_complex_protobuf,
|
||||
test_varint
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue