summaryrefslogtreecommitdiffstats
path: root/tests/oneof
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2015-01-04 19:39:37 +0200
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2015-01-04 19:39:37 +0200
commit7713d43bc3d448358a04393c4e44dd12a768bdea (patch)
tree140573b1d78947739e5f46721d681a580a4d3030 /tests/oneof
parenta0f0440394ac3b38105dfad09366f95011c5d8d3 (diff)
Implement support for oneofs (C unions).
Basic test included, should probably add an oneof to the AllTypes test also. Update issue 131 Status: Started
Diffstat (limited to 'tests/oneof')
-rw-r--r--tests/oneof/SConscript22
-rw-r--r--tests/oneof/decode_oneof.c72
-rw-r--r--tests/oneof/encode_oneof.c64
-rw-r--r--tests/oneof/oneof.proto18
4 files changed, 176 insertions, 0 deletions
diff --git a/tests/oneof/SConscript b/tests/oneof/SConscript
new file mode 100644
index 00000000..19845278
--- /dev/null
+++ b/tests/oneof/SConscript
@@ -0,0 +1,22 @@
+# Test the 'oneof' feature for generating C unions.
+
+Import('env')
+
+env.NanopbProto('oneof')
+
+enc = env.Program(['encode_oneof.c',
+ 'oneof.pb.c',
+ '$COMMON/pb_encode.o',
+ '$COMMON/pb_common.o'])
+
+dec = env.Program(['decode_oneof.c',
+ 'oneof.pb.c',
+ '$COMMON/pb_decode.o',
+ '$COMMON/pb_common.o'])
+
+env.RunTest("message1.pb", enc, ARGS = ['1'])
+env.RunTest("message1.txt", [dec, 'message1.pb'], ARGS = ['1'])
+env.RunTest("message2.pb", enc, ARGS = ['2'])
+env.RunTest("message2.txt", [dec, 'message2.pb'], ARGS = ['2'])
+env.RunTest("message3.pb", enc, ARGS = ['3'])
+env.RunTest("message3.txt", [dec, 'message3.pb'], ARGS = ['3'])
diff --git a/tests/oneof/decode_oneof.c b/tests/oneof/decode_oneof.c
new file mode 100644
index 00000000..e94becc7
--- /dev/null
+++ b/tests/oneof/decode_oneof.c
@@ -0,0 +1,72 @@
+/* Decode a message using oneof fields */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pb_decode.h>
+#include "oneof.pb.h"
+#include "test_helpers.h"
+#include "unittests.h"
+
+int main(int argc, char **argv)
+{
+ uint8_t buffer[OneOfMessage_size];
+ OneOfMessage msg = OneOfMessage_init_zero;
+ pb_istream_t stream;
+ size_t count;
+ int option;
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "Usage: encode_oneof [number]\n");
+ return 1;
+ }
+ option = atoi(argv[1]);
+
+ SET_BINARY_MODE(stdin);
+ count = fread(buffer, 1, sizeof(buffer), stdin);
+
+ if (!feof(stdin))
+ {
+ printf("Message does not fit in buffer\n");
+ return 1;
+ }
+
+ stream = pb_istream_from_buffer(buffer, count);
+
+ if (!pb_decode(&stream, OneOfMessage_fields, &msg))
+ {
+ printf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
+ return 1;
+ }
+
+ {
+ int status = 0;
+
+ /* Check that the basic fields work normally */
+ TEST(msg.prefix == 123);
+ TEST(msg.suffix == 321);
+
+ /* Check that we got the right oneof according to command line */
+ if (option == 1)
+ {
+ TEST(msg.which_values == OneOfMessage_first_tag);
+ TEST(msg.values.first == 999);
+ }
+ else if (option == 2)
+ {
+ TEST(msg.which_values == OneOfMessage_second_tag);
+ TEST(strcmp(msg.values.second, "abcd") == 0);
+ }
+ else if (option == 3)
+ {
+ TEST(msg.which_values == OneOfMessage_third_tag);
+ TEST(msg.values.third.array[0] == 1);
+ TEST(msg.values.third.array[1] == 2);
+ TEST(msg.values.third.array[2] == 3);
+ TEST(msg.values.third.array[3] == 4);
+ TEST(msg.values.third.array[4] == 5);
+ }
+
+ return status;
+ }
+} \ No newline at end of file
diff --git a/tests/oneof/encode_oneof.c b/tests/oneof/encode_oneof.c
new file mode 100644
index 00000000..913d2d43
--- /dev/null
+++ b/tests/oneof/encode_oneof.c
@@ -0,0 +1,64 @@
+/* Encode a message using oneof fields */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pb_encode.h>
+#include "oneof.pb.h"
+#include "test_helpers.h"
+
+int main(int argc, char **argv)
+{
+ uint8_t buffer[OneOfMessage_size];
+ OneOfMessage msg = OneOfMessage_init_zero;
+ pb_ostream_t stream;
+ int option;
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "Usage: encode_oneof [number]\n");
+ return 1;
+ }
+ option = atoi(argv[1]);
+
+ /* Prefix and suffix are used to test that the union does not disturb
+ * other fields in the same message. */
+ msg.prefix = 123;
+
+ /* We encode one of the 'values' fields based on command line argument */
+ if (option == 1)
+ {
+ msg.which_values = OneOfMessage_first_tag;
+ msg.values.first = 999;
+ }
+ else if (option == 2)
+ {
+ msg.which_values = OneOfMessage_second_tag;
+ strcpy(msg.values.second, "abcd");
+ }
+ else if (option == 3)
+ {
+ msg.which_values = OneOfMessage_third_tag;
+ msg.values.third.array_count = 5;
+ msg.values.third.array[0] = 1;
+ msg.values.third.array[1] = 2;
+ msg.values.third.array[2] = 3;
+ msg.values.third.array[3] = 4;
+ msg.values.third.array[4] = 5;
+ }
+
+ msg.suffix = 321;
+
+ stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+
+ if (pb_encode(&stream, OneOfMessage_fields, &msg))
+ {
+ SET_BINARY_MODE(stdout);
+ fwrite(buffer, 1, stream.bytes_written, stdout);
+ return 0;
+ }
+ else
+ {
+ fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
+ return 1;
+ }
+}
diff --git a/tests/oneof/oneof.proto b/tests/oneof/oneof.proto
new file mode 100644
index 00000000..a89ef131
--- /dev/null
+++ b/tests/oneof/oneof.proto
@@ -0,0 +1,18 @@
+import 'nanopb.proto';
+
+message SubMessage
+{
+ repeated int32 array = 1 [(nanopb).max_count = 8];
+}
+
+message OneOfMessage
+{
+ required int32 prefix = 1;
+ oneof values
+ {
+ int32 first = 5;
+ string second = 6 [(nanopb).max_size = 8];
+ SubMessage third = 7;
+ }
+ required int32 suffix = 99;
+}