here is my proto file
import "nanopb.proto";
message Person {
required string name = 1 [(nanopb).max_size = 40];
required int32 id = 2;
optional string email = 3 [(nanopb).max_size = 40];
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1 [(nanopb).max_size = 40];
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4 [(nanopb).max_count = 5];
}
// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1;
}
and the C program.
Person person = {"test", 1, true, "te...@test.com"};
uint8_t buffer[512];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
/* Now encode it and check if we succeeded. */
if (pb_encode(&stream, Person_fields, &person))
{
fwrite(buffer, 1, stream.bytes_written, stdout);
return 0; /* Success */
}
else
{
fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
return 1; /* Failure */
}
protoc -I. -I/home/maheshv/nanopb/nanopb/generator -I/usr/include -I../../../gpb/protobuf-2.5.0/src/ -onanodbmahesh.pb nanopb_mahesh.proto
python /home/maheshv/nanopb/nanopb/generator/nanopb_generator.py nanodbmahesh.pb
cc -ansi -Wall -Werror -I. -I.. -g -O0 --coverage -fstack-protector-all -c -o nanopb_pack.o nanopb_pack.c
cc -DPB_BUFFER_ONLY -ansi -Wall -Werror -I. -I.. -g -O0 --coverage -fstack-protector-all -pedantic -Wextra -Wcast-qual -Wlogical-op -Wconversion -c -o nanodbmahesh.pb.o nanodbmahesh.pb.c
cc --coverage nanopb_pack.o pb_decode.o pb_encode.o nanodbmahesh.pb.o -o ./a.out
I run a.out > e
xxd ./e
0000000: 0a04 7465 7374 1001 1a0d 7465 7374 4074 ..test....test@t
0000010: 6573 742e 636f 6d est.com
This file does not get parsed correctly from the python side.
bash-4.1$ python list_people.py ./e
Traceback (most recent call last):
File "list_people.py", line 35, in <module>
address_book.ParseFromString(f.read())
File "/usr/lib/python2.6/site-packages/protobuf-2.5.0-py2.6.egg/google/protobuf/message.py", line 182, in ParseFromString
self.MergeFromString(serialized)
File "/usr/lib/python2.6/site-packages/protobuf-2.5.0-py2.6.egg/google/protobuf/internal/python_message.py", line 795, in MergeFromString
if self._InternalParse(serialized, 0, length) != length:
File "/usr/lib/python2.6/site-packages/protobuf-2.5.0-py2.6.egg/google/protobuf/internal/python_message.py", line 827, in InternalParse
pos = field_decoder(buffer, new_pos, end, self, field_dict)
File "/usr/lib/python2.6/site-packages/protobuf-2.5.0-py2.6.egg/google/protobuf/internal/decoder.py", line 526, in DecodeRepeatedField
raise _DecodeError('Unexpected end-group tag.')
google.protobuf.message.DecodeError: Unexpected end-group tag.
Comparison with another file that parsed correctly
bash-4.1$ xxd ./e
0000000: 0a04 7465 7374 1001 1a0d 7465 7374 4074 ..test....test@t
0000010: 6573 742e 636f 6d est.com
bash-4.1$ xxd ./y
0000000: 0a17 0a04 7465 7374 1001 1a0d 7465 7374 ....test....test
0000010: 4074 6573 742e 636f 6d @test.com
Notice the two extra bytes 0x17 in the y file.
Question : why is the tag not getting generated in nanopb?
Appreciate anh help.
Mahesh
Thanks for the quick reply.
I am redirecting the output of the nanopb program to a file and reading it
from python google protobuf.
./a.out > e
python list_people.py ./e
I noticed that the second byte in the google protobuf generated addressbook
(17) in 0x0a17 is the size of the data (23 bytes).
Not sure what 0x0a is.
Are you saying that dumping the output to a file is causing this issue?
Pardon the dumb question but Is this how it is done?
Person person = {"test", 1, true, "te...@test.com"};
AddressBook address_book ;
memcpy(&address_book.person, &person , sizeof(Person));
This compiled and ran but I still don't get the tag :(
bool encode_person(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
char* name = "test";
char* email = "te...@test.com";
if (!pb_encode_tag_for_field(stream, field)) {
printf(" %s returning false \n", __FUNCTION__);
return false;
}
pb_encode_string(stream, (uint8_t *)name, strlen(name));
pb_encode_varint(stream, 1);
pb_encode_string(stream, (uint8_t *)email, strlen(email));
return true;
}
main() {
AddressBook address_book ;
uint8_t buffer[1024];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
address_book.person.funcs.encode = &encode_person;
/* Now encode it and check if we succeeded. */
if (pb_encode(&stream, AddressBook_fields , &address_book))
{
fwrite(buffer, 1, stream.bytes_written, stdout);
return 0; /* Success */
}
else
{
fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
return 1; /* Failure */
}
}
./a.out > e
xxd ./e
0000000: 0a04 7465 7374 010d 7465 7374 4074 6573 ..test..test@tes
0000010: 742e 636f 6d t.com
--
Petteri
--
You received this message because you are subscribed to a topic in the Google Groups "nanopb" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/nanopb/cIhC7iZnBa8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to nanopb+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
bool encode_person(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
#if 0
char* name = "test";
char* email = "te...@test.com";
#endif
Person person = {"test", 1, true, "te...@test.com"};
if (!pb_encode_tag_for_field(stream, field)) {
printf(" %s returning false \n", __FUNCTION__);
return false;
}
#if 0
pb_encode_string(stream, (uint8_t *)name, strlen(name));
pb_encode_varint(stream, 1);
pb_encode_string(stream, (uint8_t *)email, strlen(email));
#endif
if (!pb_encode_submessage(stream, Person_fields, &person))
return false;