Set the defaults properly for newly allocated submessages.
Also, pb_dec_submessage() should have used calloc() instead of malloc() in the first place. git-svn-id: https://svn.kapsi.fi/jpa/nanopb-dev@1083 e3a754e5-d11d-0410-8d38-ebb782a927b9
This commit is contained in:
committed by
Petteri Aimonen
parent
f7c8dd81d4
commit
ba93b65e9f
@@ -15,7 +15,7 @@ Overall structure
|
|||||||
For the runtime program, you always need *pb.h* for type declarations.
|
For the runtime program, you always need *pb.h* for type declarations.
|
||||||
Depending on whether you want to encode, decode, or both, you also need *pb_encode.h/c* or *pb_decode.h/c*.
|
Depending on whether you want to encode, decode, or both, you also need *pb_encode.h/c* or *pb_decode.h/c*.
|
||||||
|
|
||||||
If your *.proto* file encodes submessages or other fields using pointers, you must compile *pb_decode.c* with a preprocessor macro named *MALLOC_HEADER* that is the name of a header with definitions (either as functions or macros) for *malloc()*, *realloc()* and *free()*. For a typical hosted configuration, this should be *<stdlib.h>*.
|
If your *.proto* file encodes submessages or other fields using pointers, you must compile *pb_decode.c* with a preprocessor macro named *MALLOC_HEADER* that is the name of a header with definitions (either as functions or macros) for *calloc()*, *realloc()* and *free()*. For a typical hosted configuration, this should be *<stdlib.h>*.
|
||||||
|
|
||||||
The high-level encoding and decoding functions take an array of *pb_field_t* structures, which describes the fields of a message structure. Usually you want these autogenerated from a *.proto* file. The tool script *nanopb_generator.py* accomplishes this.
|
The high-level encoding and decoding functions take an array of *pb_field_t* structures, which describes the fields of a message structure. Usually you want these autogenerated from a *.proto* file. The tool script *nanopb_generator.py* accomplishes this.
|
||||||
|
|
||||||
|
|||||||
@@ -661,10 +661,11 @@ bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field
|
|||||||
#ifdef MALLOC_HEADER
|
#ifdef MALLOC_HEADER
|
||||||
if (*(void**)dest == NULL)
|
if (*(void**)dest == NULL)
|
||||||
{
|
{
|
||||||
void *object = malloc(msg->size);
|
void *object = calloc(1, msg->size);
|
||||||
if (!object)
|
if (!object)
|
||||||
return false;
|
return false;
|
||||||
*(void**)dest = object;
|
*(void**)dest = object;
|
||||||
|
pb_message_set_to_defaults(msg, object);
|
||||||
dest = object;
|
dest = object;
|
||||||
} else {
|
} else {
|
||||||
dest = *(void**)dest;
|
dest = *(void**)dest;
|
||||||
|
|||||||
@@ -287,12 +287,12 @@ int main()
|
|||||||
|
|
||||||
memset(&dest, 0, sizeof(dest));
|
memset(&dest, 0, sizeof(dest));
|
||||||
#ifdef MALLOC_HEADER
|
#ifdef MALLOC_HEADER
|
||||||
TEST((s = S("\x0A\x01\x61\x12\x01\x62\x2A\x01\x65\x32\x01\x66\x3A\x00"
|
TEST((s = S("\x0A\x01\x61\x12\x01\x62\x1A\x00\x2A\x01\x65\x32\x01\x66"
|
||||||
"\x42\x01\x63\x4A\x01\x64"),
|
"\x3A\x00\x42\x01\x63\x4A\x01\x64"),
|
||||||
pb_decode(&s, PointerContainer_msg, &dest)))
|
pb_decode(&s, PointerContainer_msg, &dest)))
|
||||||
TEST(0 == strcmp(dest.text, "a"))
|
TEST(0 == strcmp(dest.text, "a"))
|
||||||
TEST(dest.blob.size == 1 && dest.blob.bytes[0] == 'b')
|
TEST(dest.blob.size == 1 && dest.blob.bytes[0] == 'b')
|
||||||
TEST(dest.submsg == NULL)
|
TEST(dest.submsg != NULL && dest.submsg->data == 10)
|
||||||
TEST(dest.rtext_count == 1 && (0 == strcmp(dest.rtext[0], "e")))
|
TEST(dest.rtext_count == 1 && (0 == strcmp(dest.rtext[0], "e")))
|
||||||
TEST(dest.rblob_count == 1 && dest.rblob[0].size == 1 &&
|
TEST(dest.rblob_count == 1 && dest.rblob[0].size == 1 &&
|
||||||
dest.rblob[0].bytes[0] == 'f')
|
dest.rblob[0].bytes[0] == 'f')
|
||||||
@@ -301,8 +301,8 @@ int main()
|
|||||||
TEST(dest.oblob.size == 1 && dest.oblob.bytes[0] == 'd')
|
TEST(dest.oblob.size == 1 && dest.oblob.bytes[0] == 'd')
|
||||||
TEST(pb_clean(PointerContainer_msg, &dest));
|
TEST(pb_clean(PointerContainer_msg, &dest));
|
||||||
#else
|
#else
|
||||||
TEST((s = S("\x0A\x01\x61\x12\x01\x62\x2A\x01\x65\x32\x01\x66\x3A\x00"
|
TEST((s = S("\x0A\x01\x61\x12\x01\x62\x2A\x01\x65\x32\x01\x66\x01\x66"
|
||||||
"\x42\x01\x63\x4A\x01\x64"),
|
"\x3A\x00\x42\x01\x63\x4A\x01\x64"),
|
||||||
!pb_decode(&s, PointerContainer_msg, &dest)))
|
!pb_decode(&s, PointerContainer_msg, &dest)))
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ int main()
|
|||||||
uint8_t buffer[128];
|
uint8_t buffer[128];
|
||||||
pb_ostream_t s;
|
pb_ostream_t s;
|
||||||
PointerContainer msg;
|
PointerContainer msg;
|
||||||
PointerContainer msg2;
|
DefaultContainer msg2;
|
||||||
IntegerArray msg3;
|
IntegerArray msg3;
|
||||||
|
|
||||||
COMMENT("Test pb_encode with pointer fields.")
|
COMMENT("Test pb_encode with pointer fields.")
|
||||||
@@ -285,7 +285,7 @@ int main()
|
|||||||
msg.blob.bytes = (uint8_t*)"b";
|
msg.blob.bytes = (uint8_t*)"b";
|
||||||
msg.submsg = &msg2;
|
msg.submsg = &msg2;
|
||||||
TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg),
|
TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg),
|
||||||
"\x0A\x01\x61\x12\x01\x62"))
|
"\x0A\x01\x61\x12\x01\x62\x1A\x00"))
|
||||||
|
|
||||||
memset(&msg3, 0, sizeof(msg3));
|
memset(&msg3, 0, sizeof(msg3));
|
||||||
msg.rtext_count = 1;
|
msg.rtext_count = 1;
|
||||||
@@ -296,7 +296,7 @@ int main()
|
|||||||
msg.rsubmsg_count = 1;
|
msg.rsubmsg_count = 1;
|
||||||
msg.rsubmsg[0] = &msg3;
|
msg.rsubmsg[0] = &msg3;
|
||||||
TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg),
|
TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg),
|
||||||
"\x0A\x01\x61\x12\x01\x62"
|
"\x0A\x01\x61\x12\x01\x62\x1A\x00"
|
||||||
"\x2A\x01\x65\x32\x01\x66\x3A\x00"));
|
"\x2A\x01\x65\x32\x01\x66\x3A\x00"));
|
||||||
|
|
||||||
PointerContainer_set(msg, otext);
|
PointerContainer_set(msg, otext);
|
||||||
@@ -305,7 +305,7 @@ int main()
|
|||||||
msg.oblob.size = 1;
|
msg.oblob.size = 1;
|
||||||
msg.oblob.bytes = (uint8_t*)"d";
|
msg.oblob.bytes = (uint8_t*)"d";
|
||||||
TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg),
|
TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg),
|
||||||
"\x0A\x01\x61\x12\x01\x62"
|
"\x0A\x01\x61\x12\x01\x62\x1A\x00"
|
||||||
"\x2A\x01\x65\x32\x01\x66\x3A\x00"
|
"\x2A\x01\x65\x32\x01\x66\x3A\x00"
|
||||||
"\x42\x01\x63\x4A\x01\x64"));
|
"\x42\x01\x63\x4A\x01\x64"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,14 @@ message CallbackContainerContainer {
|
|||||||
required CallbackContainer submsg = 1;
|
required CallbackContainer submsg = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message DefaultContainer {
|
||||||
|
optional int32 data = 1 [default = 10];
|
||||||
|
}
|
||||||
|
|
||||||
message PointerContainer {
|
message PointerContainer {
|
||||||
required string text = 1 [(nanopb).pointer = true];
|
required string text = 1 [(nanopb).pointer = true];
|
||||||
required bytes blob = 2 [(nanopb).pointer = true];
|
required bytes blob = 2 [(nanopb).pointer = true];
|
||||||
optional PointerContainer submsg = 3 [(nanopb).pointer = true];
|
required DefaultContainer submsg = 3 [(nanopb).pointer = true];
|
||||||
// This should be rejected:
|
// This should be rejected:
|
||||||
// required int32 data = 4 [(nanopb).pointer = true];
|
// required int32 data = 4 [(nanopb).pointer = true];
|
||||||
repeated string rtext = 5 [(nanopb).pointer = true, (nanopb).max_count = 10];
|
repeated string rtext = 5 [(nanopb).pointer = true, (nanopb).max_count = 10];
|
||||||
|
|||||||
Reference in New Issue
Block a user