Added a more complex example. See Test3_protobuf.c

This commit is contained in:
jmjatlanta 2016-12-09 05:58:34 -05:00
parent 69a6f1516f
commit a443c699cf
6 changed files with 150 additions and 1 deletions

View file

@ -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;

View file

@ -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
View 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
View 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);

View file

@ -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;

View file

@ -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
};