Expanding the tests to better cover decoding from memory buffer.
authorPetteri Aimonen <jpa@npb.mail.kapsi.fi>
Fri, 30 Dec 2011 08:57:27 +0000 (08:57 +0000)
committerPetteri Aimonen <jpa@npb.mail.kapsi.fi>
Fri, 30 Dec 2011 08:57:27 +0000 (08:57 +0000)
git-svn-id: https://svn.kapsi.fi/jpa/nanopb@1090 e3a754e5-d11d-0410-8d38-ebb782a927b9

tests/Makefile
tests/test_decode1.c
tests/test_decode2.c [new file with mode: 0644]
tests/test_encode1.c

index a942b78..899a686 100644 (file)
@@ -18,6 +18,7 @@ pb_decode.o: ../pb_decode.c $(DEPS)
        $(CC) $(CFLAGS) -c -o $@ $<
 
 test_decode1: test_decode1.o pb_decode.o person.pb.o
+test_decode2: test_decode2.o pb_decode.o person.pb.o
 test_encode1: test_encode1.o pb_encode.o person.pb.o
 test_encode2: test_encode2.o pb_encode.o person.pb.o
 test_decode_callbacks: test_decode_callbacks.o pb_decode.o callbacks.pb.o
@@ -38,7 +39,7 @@ coverage: run_unittests
        gcov pb_encode.gcda
        gcov pb_decode.gcda
 
-run_unittests: decode_unittests encode_unittests test_encode1 test_encode2 test_decode1 test_encode_callbacks test_decode_callbacks
+run_unittests: decode_unittests encode_unittests test_encode1 test_encode2 test_decode1 test_decode2 test_encode_callbacks test_decode_callbacks
        rm -f *.gcda
        
        ./decode_unittests > /dev/null
@@ -49,6 +50,9 @@ run_unittests: decode_unittests encode_unittests test_encode1 test_encode2 test_
 
        [ "`./test_encode2 | ./test_decode1`" = \
        "`./test_encode2 | protoc --decode=Person -I. -I../generator -I/usr/include person.proto`" ]
+
+       [ "`./test_encode2 | ./test_decode2`" = \
+       "`./test_encode2 | 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`" ]
index 3b72f66..78781dd 100644 (file)
@@ -57,33 +57,16 @@ bool print_person(pb_istream_t *stream)
     return true;
 }
 
-/* This binds the pb_istream_t to stdin */
-bool callback(pb_istream_t *stream, uint8_t *buf, size_t count)
+int main()
 {
-    FILE *file = (FILE*)stream->state;
-    bool status;
-    
-    if (buf == NULL)
-    {
-       /* Skipping data */
-        while (count-- && fgetc(file) != EOF);
-        return count == 0;
-    }
-    
-    status = (fread(buf, 1, count, file) == count);
+    /* Read the data into buffer */
+    uint8_t buffer[512];
+    size_t count = fread(buffer, 1, sizeof(buffer), stdin);
     
-    if (feof(file))
-        stream->bytes_left = 0;
+    /* Construct a pb_istream_t for reading from the buffer */
+    pb_istream_t stream = pb_istream_from_buffer(buffer, count);
     
-    return status;
-}
-
-int main()
-{
-    /* Maximum size is specified to prevent infinite length messages from
-     * hanging this in the fuzz test.
-     */
-    pb_istream_t stream = {&callback, stdin, 10000};
+    /* Decode and print out the stuff */
     if (!print_person(&stream))
     {
         printf("Parsing failed.\n");
diff --git a/tests/test_decode2.c b/tests/test_decode2.c
new file mode 100644 (file)
index 0000000..d38e625
--- /dev/null
@@ -0,0 +1,90 @@
+/* Same as test_decode1 but reads from stdin directly.
+ */
+
+#include <stdio.h>
+#include <pb_decode.h>
+#include "person.pb.h"
+
+/* This function is called once from main(), it handles
+   the decoding and printing.
+   Ugly copy-paste from test_decode1.c. */
+bool print_person(pb_istream_t *stream)
+{
+    int i;
+    Person person;
+    
+    if (!pb_decode(stream, Person_fields, &person))
+        return false;
+    
+    /* Now the decoding is done, rest is just to print stuff out. */
+
+    printf("name: \"%s\"\n", person.name);
+    printf("id: %ld\n", (long)person.id);
+    
+    if (person.has_email)
+        printf("email: \"%s\"\n", person.email);
+    
+    for (i = 0; i < person.phone_count; i++)
+    {
+        Person_PhoneNumber *phone = &person.phone[i];
+        printf("phone {\n");
+        printf("  number: \"%s\"\n", phone->number);
+        
+        if (phone->has_type)
+        {
+            switch (phone->type)
+            {
+                case Person_PhoneType_WORK:
+                    printf("  type: WORK\n");
+                    break;
+                
+                case Person_PhoneType_HOME:
+                    printf("  type: HOME\n");
+                    break;
+                
+                case Person_PhoneType_MOBILE:
+                    printf("  type: MOBILE\n");
+                    break;
+            }
+        }
+        printf("}\n");
+    }
+    
+    return true;
+}
+
+/* This binds the pb_istream_t to stdin */
+bool callback(pb_istream_t *stream, uint8_t *buf, size_t count)
+{
+    FILE *file = (FILE*)stream->state;
+    bool status;
+    
+    if (buf == NULL)
+    {
+       /* Skipping data */
+        while (count-- && fgetc(file) != EOF);
+        return count == 0;
+    }
+    
+    status = (fread(buf, 1, count, file) == count);
+    
+    if (feof(file))
+        stream->bytes_left = 0;
+    
+    return status;
+}
+
+int main()
+{
+    /* Maximum size is specified to prevent infinite length messages from
+     * hanging this in the fuzz test.
+     */
+    pb_istream_t stream = {&callback, stdin, 10000};
+    if (!print_person(&stream))
+    {
+        printf("Parsing failed.\n");
+        return 1;
+    } else {
+        return 0;
+    }
+}
index c5131e4..2e97829 100644 (file)
@@ -22,7 +22,7 @@ int main()
     /* Now encode it and check if we succeeded. */
     if (pb_encode(&stream, Person_fields, &person))
     {
-        fwrite(buffer, stream.bytes_written, 1, stdout);
+        fwrite(buffer, 1, stream.bytes_written, stdout);
         return 0; /* Success */
     }
     else