Tests for callback fields

git-svn-id: https://svn.kapsi.fi/jpa/nanopb@974 e3a754e5-d11d-0410-8d38-ebb782a927b9
This commit is contained in:
Petteri Aimonen
2011-09-12 18:53:33 +00:00
parent 35814517ad
commit d4abb63c05
7 changed files with 109 additions and 3 deletions

View File

@@ -201,7 +201,7 @@ Decoding callbacks
bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg);
When decoding, the callback receives a length-limited substring that reads the contents of a single field. The field tag has already been read.
When decoding, the callback receives a length-limited substring that reads the contents of a single field. The field tag has already been read. For *string* and *bytes*, the length value has already been parsed, and is available at *stream->bytes_left*.
The callback will be called multiple times for repeated fields. For packed fields, you can either read multiple values until the stream ends, or leave it to `pb_decode`_ to call your function over and over until all values have been read.

View File

@@ -1,6 +1,6 @@
CFLAGS=-ansi -Wall -Werror -I .. -g -O0 --coverage
LDFLAGS=--coverage
DEPS=../pb_decode.h ../pb_encode.h ../pb.h person.pb.h unittests.h unittestproto.pb.h
DEPS=../pb_decode.h ../pb_encode.h ../pb.h person.pb.h callbacks.pb.h unittests.h unittestproto.pb.h
TESTS=test_decode1 test_encode1 decode_unittests encode_unittests
all: $(TESTS) run_unittests breakpoints
@@ -19,6 +19,8 @@ pb_decode.o: ../pb_decode.c $(DEPS)
test_decode1: test_decode1.o pb_decode.o person.pb.o
test_encode1: test_encode1.o pb_encode.o person.pb.o
test_decode_callbacks: test_decode_callbacks.o pb_decode.o callbacks.pb.o
test_encode_callbacks: test_encode_callbacks.o pb_encode.o callbacks.pb.o
decode_unittests: decode_unittests.o pb_decode.o unittestproto.pb.o
encode_unittests: encode_unittests.o pb_encode.o unittestproto.pb.o
@@ -35,7 +37,7 @@ coverage: run_unittests
gcov pb_encode.gcda
gcov pb_decode.gcda
run_unittests: decode_unittests encode_unittests test_encode1 test_decode1
run_unittests: decode_unittests encode_unittests test_encode1 test_decode1 test_encode_callbacks test_decode_callbacks
rm -f *.gcda
./decode_unittests > /dev/null
@@ -43,6 +45,9 @@ run_unittests: decode_unittests encode_unittests test_encode1 test_decode1
[ "`./test_encode1 | ./test_decode1`" = \
"`./test_encode1 | protoc --decode=Person -I. -I../generator -I/usr/include person.proto`" ]
[ "`./test_encode_callbacks | ./test_decode_callbacks`" = \
"`./test_encode_callbacks | protoc --decode=TestMessage callbacks.proto`" ]
run_fuzztest: test_decode1
bash -c 'I=1; while cat /dev/urandom | ./test_decode1 > /dev/null; do I=$$(($$I+1)); echo -en "\r$$I"; done'

16
tests/callbacks.proto Normal file
View File

@@ -0,0 +1,16 @@
/* Todo: write tests for the rest of these fields, currently only stringvalue
* is tested.
*/
message SubMessage {
optional int32 int32value = 1;
}
message TestMessage {
optional string stringvalue = 1;
optional int32 int32value = 2;
optional fixed32 fixed32value = 3;
optional fixed64 fixed64value = 4;
optional SubMessage submsg = 5;
}

View File

@@ -1,3 +1,7 @@
/* A very simple decoding test case, using person.proto.
* Produces output compatible with protoc --decode.
*/
#include <stdio.h>
#include <pb_decode.h>
#include "person.pb.h"

View File

@@ -0,0 +1,44 @@
/* Decoding testcase for callback fields.
* Run e.g. ./test_encode_callbacks | ./test_decode_callbacks
*/
#include <stdio.h>
#include <pb_decode.h>
#include "callbacks.pb.h"
bool print_string(pb_istream_t *stream, const pb_field_t *field, void *arg)
{
uint8_t buffer[1024];
/* We could read block-by-block to avoid the large buffer... */
if (stream->bytes_left > sizeof(buffer))
return false;
if (!pb_read(stream, buffer, stream->bytes_left))
return false;
/* Print the string, in format comparable with protoc --decode. */
printf("%s: \"%s\"\n", (char*)arg, buffer);
return true;
}
int main()
{
uint8_t buffer[1024];
size_t length = fread(buffer, 1, 1024, stdin);
pb_istream_t stream = pb_istream_from_buffer(buffer, length);
/* Note: empty initializer list initializes the struct with all-0.
* This is recommended so that unused callbacks are set to NULL instead
* of crashing at runtime.
*/
TestMessage testmessage = {};
testmessage.stringvalue.funcs.decode = &print_string;
testmessage.stringvalue.arg = "stringvalue";
if (!pb_decode(&stream, TestMessage_fields, &testmessage))
return 1;
return 0;
}

View File

@@ -1,3 +1,7 @@
/* A very simple encoding test case using person.proto.
* Just puts constant data in the fields.
*/
#include <stdio.h>
#include <pb_encode.h>
#include "person.pb.h"

View File

@@ -0,0 +1,33 @@
/* Encoding testcase for callback fields */
#include <stdio.h>
#include <string.h>
#include <pb_encode.h>
#include "callbacks.pb.h"
bool encode_string(pb_ostream_t *stream, const pb_field_t *field, const void *arg)
{
char *str = "Hello world!";
if (!pb_encode_tag_for_field(stream, field))
return false;
return pb_encode_string(stream, (uint8_t*)str, strlen(str));
}
int main()
{
uint8_t buffer[1024];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, 1024);
TestMessage testmessage = {};
testmessage.stringvalue.funcs.encode = &encode_string;
if (!pb_encode(&stream, TestMessage_fields, &testmessage))
return 1;
if (fwrite(buffer, stream.bytes_written, 1, stdout) != 1)
return 2;
return 0;
}