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 int field_no = field_number << 3;
|
||||||
unsigned long long field = field_no | field_type;
|
unsigned long long field = field_no | field_type;
|
||||||
size_t bytes_processed;
|
size_t bytes_processed;
|
||||||
|
*bytes_written = 0;
|
||||||
// field type & number
|
// field type & number
|
||||||
varint_encode(field, buffer, max_buffer_length, &bytes_processed);
|
varint_encode(field, buffer, max_buffer_length, &bytes_processed);
|
||||||
*bytes_written += bytes_processed;
|
*bytes_written += bytes_processed;
|
||||||
|
|
|
@ -2,7 +2,7 @@ CC = gcc
|
||||||
CFLAGS = -O0 -g3 -Wall -I../
|
CFLAGS = -O0 -g3 -Wall -I../
|
||||||
LFLAGS =
|
LFLAGS =
|
||||||
DEPS = ../protobuf.h
|
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)
|
%.o: %.c $(DEPS)
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
$(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_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);
|
* 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 "Test1_protobuf.h"
|
||||||
#include "Test2_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() {
|
int test_rightshift() {
|
||||||
struct Test1 test1;
|
struct Test1 test1;
|
||||||
test1.a = 0;
|
test1.a = 0;
|
||||||
|
|
|
@ -19,6 +19,7 @@ const char* names[] = {
|
||||||
"test_write_negative",
|
"test_write_negative",
|
||||||
"test_write_string",
|
"test_write_string",
|
||||||
"test_rightshift",
|
"test_rightshift",
|
||||||
|
"test_complex_protobuf",
|
||||||
"test_varint"
|
"test_varint"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ int (*funcs[])(void) = {
|
||||||
test_write_negative,
|
test_write_negative,
|
||||||
test_write_string,
|
test_write_string,
|
||||||
test_rightshift,
|
test_rightshift,
|
||||||
|
test_complex_protobuf,
|
||||||
test_varint
|
test_varint
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue