Fix bytes type setter to work with byte sequences with embedded NULLs.
Patch from Alkis Evlogimenos <alkis@evlogimenos.com>.
This commit is contained in:
parent
40ee551715
commit
928ebb6b55
3 changed files with 76 additions and 22 deletions
|
@ -96,8 +96,14 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
|
|||
|
||||
printer->Print(variables_,
|
||||
"inline const ::std::string& $name$() const;\n"
|
||||
"inline void set_$name$(const ::std::string& value);\n"
|
||||
"inline void set_$name$(const char* value);\n");
|
||||
"inline void set_$name$(const ::std::string& value);\n");
|
||||
if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
|
||||
printer->Print(variables_,
|
||||
"inline void set_$name$(const char* value, size_t size);\n");
|
||||
} else {
|
||||
printer->Print(variables_,
|
||||
"inline void set_$name$(const char* value);\n");
|
||||
}
|
||||
|
||||
printer->Print(variables_,
|
||||
"inline ::std::string* mutable_$name$();\n");
|
||||
|
@ -121,14 +127,28 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
|
|||
" $name$_ = new ::std::string;\n"
|
||||
" }\n"
|
||||
" $name$_->assign(value);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(const char* value) {\n"
|
||||
" _set_bit($index$);\n"
|
||||
" if ($name$_ == &_default_$name$_) {\n"
|
||||
" $name$_ = new ::std::string;\n"
|
||||
" }\n"
|
||||
" $name$_->assign(value);\n"
|
||||
"}\n");
|
||||
|
||||
if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
|
||||
printer->Print(variables_,
|
||||
"inline void $classname$::set_$name$(const char* value, size_t size) {\n"
|
||||
" _set_bit($index$);\n"
|
||||
" if ($name$_ == &_default_$name$_) {\n"
|
||||
" $name$_ = new ::std::string;\n"
|
||||
" }\n"
|
||||
" $name$_->assign(value, size);\n"
|
||||
"}\n");
|
||||
} else {
|
||||
printer->Print(variables_,
|
||||
"inline void $classname$::set_$name$(const char* value) {\n"
|
||||
" _set_bit($index$);\n"
|
||||
" if ($name$_ == &_default_$name$_) {\n"
|
||||
" $name$_ = new ::std::string;\n"
|
||||
" }\n"
|
||||
" $name$_->assign(value);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
printer->Print(variables_,
|
||||
"inline ::std::string* $classname$::mutable_$name$() {\n"
|
||||
" _set_bit($index$);\n"
|
||||
|
@ -245,10 +265,18 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
|
|||
"inline const ::std::string& $name$(int index) const;\n"
|
||||
"inline ::std::string* mutable_$name$(int index);\n"
|
||||
"inline void set_$name$(int index, const ::std::string& value);\n"
|
||||
"inline void set_$name$(int index, const char* value);\n"
|
||||
"inline ::std::string* add_$name$();\n"
|
||||
"inline void add_$name$(const ::std::string& value);\n"
|
||||
"inline void add_$name$(const char* value);\n");
|
||||
"inline void add_$name$(const ::std::string& value);\n");
|
||||
|
||||
if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
|
||||
printer->Print(variables_,
|
||||
"inline void set_$name$(int index, const char* value, size_t size);\n"
|
||||
"inline void add_$name$(const char* value, size_t size);\n");
|
||||
} else {
|
||||
printer->Print(variables_,
|
||||
"inline void set_$name$(int index, const char* value);\n"
|
||||
"inline void add_$name$(const char* value);\n");
|
||||
}
|
||||
|
||||
if (descriptor_->options().has_ctype()) {
|
||||
printer->Outdent();
|
||||
|
@ -277,18 +305,31 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
|
|||
"inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
|
||||
" $name$_.Mutable(index)->assign(value);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(int index, const char* value) {\n"
|
||||
" $name$_.Mutable(index)->assign(value);\n"
|
||||
"}\n"
|
||||
"inline ::std::string* $classname$::add_$name$() {\n"
|
||||
" return $name$_.Add();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$(const ::std::string& value) {\n"
|
||||
" $name$_.Add()->assign(value);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$(const char* value) {\n"
|
||||
" $name$_.Add()->assign(value);\n"
|
||||
"}\n");
|
||||
|
||||
if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
|
||||
printer->Print(variables_,
|
||||
"inline void "
|
||||
"$classname$::set_$name$(int index, const char* value, size_t size) {\n"
|
||||
" $name$_.Mutable(index)->assign(value, size);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$(const char* value, size_t size) {\n"
|
||||
" $name$_.Add()->assign(value, size);\n"
|
||||
"}\n");
|
||||
} else {
|
||||
printer->Print(variables_,
|
||||
"inline void $classname$::set_$name$(int index, const char* value) {\n"
|
||||
" $name$_.Mutable(index)->assign(value);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$(const char* value) {\n"
|
||||
" $name$_.Add()->assign(value);\n"
|
||||
"}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::
|
||||
|
|
|
@ -172,6 +172,19 @@ TEST(GeneratedMessageTest, Clear) {
|
|||
&message.optional_import_message());
|
||||
}
|
||||
|
||||
TEST(GeneratedMessageTest, EmbeddedNullsInBytesCharStar) {
|
||||
unittest::TestAllTypes message;
|
||||
|
||||
const char* value = "\0lalala\0\0";
|
||||
message.set_optional_bytes(value, 9);
|
||||
ASSERT_EQ(9, message.optional_bytes().size());
|
||||
EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9));
|
||||
|
||||
message.add_repeated_bytes(value, 9);
|
||||
ASSERT_EQ(9, message.repeated_bytes(0).size());
|
||||
EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9));
|
||||
}
|
||||
|
||||
TEST(GeneratedMessageTest, ClearOneField) {
|
||||
// Set every field to a unique value, then clear one value and insure that
|
||||
// only that one value is cleared.
|
||||
|
|
|
@ -174,9 +174,9 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
|
|||
inline const ::std::string& dependency(int index) const;
|
||||
inline ::std::string* mutable_dependency(int index);
|
||||
inline void set_dependency(int index, const ::std::string& value);
|
||||
inline void set_dependency(int index, const char* value);
|
||||
inline ::std::string* add_dependency();
|
||||
inline void add_dependency(const ::std::string& value);
|
||||
inline void set_dependency(int index, const char* value);
|
||||
inline void add_dependency(const char* value);
|
||||
|
||||
// repeated .google.protobuf.DescriptorProto message_type = 4;
|
||||
|
@ -1835,15 +1835,15 @@ inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
|
|||
inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
|
||||
dependency_.Mutable(index)->assign(value);
|
||||
}
|
||||
inline void FileDescriptorProto::set_dependency(int index, const char* value) {
|
||||
dependency_.Mutable(index)->assign(value);
|
||||
}
|
||||
inline ::std::string* FileDescriptorProto::add_dependency() {
|
||||
return dependency_.Add();
|
||||
}
|
||||
inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
|
||||
dependency_.Add()->assign(value);
|
||||
}
|
||||
inline void FileDescriptorProto::set_dependency(int index, const char* value) {
|
||||
dependency_.Mutable(index)->assign(value);
|
||||
}
|
||||
inline void FileDescriptorProto::add_dependency(const char* value) {
|
||||
dependency_.Add()->assign(value);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue