diff options
author | Petteri Aimonen <jpa@npb.mail.kapsi.fi> | 2011-07-25 20:42:48 +0000 |
---|---|---|
committer | Petteri Aimonen <jpa@npb.mail.kapsi.fi> | 2011-07-25 20:42:48 +0000 |
commit | 14bbe229974b516a82594ec6476488154e8957fa (patch) | |
tree | 178f51c1977a1ef8f83c6911741ddbfb8266a727 /tests/test_decode1.c |
First version of decoding
git-svn-id: https://svn.kapsi.fi/jpa/nanopb@942 e3a754e5-d11d-0410-8d38-ebb782a927b9
Diffstat (limited to 'tests/test_decode1.c')
-rw-r--r-- | tests/test_decode1.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/tests/test_decode1.c b/tests/test_decode1.c new file mode 100644 index 00000000..dc0831a2 --- /dev/null +++ b/tests/test_decode1.c @@ -0,0 +1,102 @@ +#include <stdio.h> +#include <string.h> +#include <stddef.h> +#include "pb_decode.h" + +/* Structures for "Person" message */ + +typedef enum { + Person_PhoneType_MOBILE = 0, + Person_PhoneType_HOME = 1, + Person_PhoneType_WORK = 2, + + _Person_PhoneType_size = 0xFFFFFFFF // Force 32-bit enum +} Person_PhoneType; + +typedef struct { + char number[40]; + bool has_type; + Person_PhoneType type; +} Person_PhoneNumber; + +typedef struct { + char name[40]; + int32_t id; + bool has_email; + char email[40]; + + pb_callback_t phone; +} Person; + +/* Field descriptions */ +#define membersize(st, m) (sizeof ((st*)0)->m) + +const pb_field_t Person_PhoneNumber_fields[] = { + {1, offsetof(Person_PhoneNumber, number), PB_ACT_STRING, membersize(Person_PhoneNumber, number)}, + {2, offsetof(Person_PhoneNumber, has_type), PB_ACT_HAS, membersize(Person_PhoneNumber, has_type)}, + {2, offsetof(Person_PhoneNumber, type), PB_ACT_UINT32, membersize(Person_PhoneNumber, type)}, + PB_LAST_FIELD +}; + +const pb_field_t Person_fields[] = { + {1, offsetof(Person, name), PB_ACT_STRING, membersize(Person, name)}, + {2, offsetof(Person, id), PB_ACT_INT32, membersize(Person, id)}, + {3, offsetof(Person, email), PB_ACT_STRING, membersize(Person, email)}, + {4, offsetof(Person, phone), PB_ACT_SUBMESSAGE, membersize(Person, phone)} +}; + +/* Default value descriptions */ +#define Person_PhoneNumber_default {"", false, Person_PhoneType_HOME}; +#define Person_default {"", 0, false, "", {{0},0}}; + +/* And now, the actual test program */ + +bool print_phonenumber(pb_istream_t *stream, const pb_field_t *field, void *arg) +{ + Person_PhoneNumber x = Person_PhoneNumber_default; + if (!pb_decode(stream, Person_PhoneNumber_fields, &x)) + return false; + + printf("PhoneNumber: number '%s' type '%d'\n", x.number, x.type); + return true; +} + +bool print_person(pb_istream_t *stream) +{ + Person x = Person_default; + x.phone.funcs.decode = &print_phonenumber; + + if (!pb_decode(stream, Person_fields, &x)) + return false; + + printf("Person: name '%s' id '%d' email '%s'\n", x.name, x.id, x.email); + return true; +} + +bool my_read(pb_istream_t *stream, char *buf, size_t count) +{ + char *source = (char*)stream->state; + + if (!stream->bytes_left) + return false; + + if (buf != NULL) + { + memcpy(buf, source, count); + } + + stream->state = source + count; + return true; +} + +int main() +{ + char buffer[512]; + size_t size = fread(buffer, 1, 512, stdin); + + pb_istream_t stream = {&my_read, buffer, size}; + if (!print_person(&stream)) + printf("Parsing failed.\n"); + + return 0; +} |