Commit 928ebb6b authored by temporal's avatar temporal

Fix bytes type setter to work with byte sequences with embedded NULLs.

Patch from Alkis Evlogimenos <alkis@evlogimenos.com>.
parent 40ee5517
...@@ -96,8 +96,14 @@ GenerateAccessorDeclarations(io::Printer* printer) const { ...@@ -96,8 +96,14 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_, printer->Print(variables_,
"inline const ::std::string& $name$() const;\n" "inline const ::std::string& $name$() const;\n"
"inline void set_$name$(const ::std::string& 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"); "inline void set_$name$(const char* value);\n");
}
printer->Print(variables_, printer->Print(variables_,
"inline ::std::string* mutable_$name$();\n"); "inline ::std::string* mutable_$name$();\n");
...@@ -121,7 +127,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { ...@@ -121,7 +127,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" $name$_ = new ::std::string;\n" " $name$_ = new ::std::string;\n"
" }\n" " }\n"
" $name$_->assign(value);\n" " $name$_->assign(value);\n"
"}\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" "inline void $classname$::set_$name$(const char* value) {\n"
" _set_bit($index$);\n" " _set_bit($index$);\n"
" if ($name$_ == &_default_$name$_) {\n" " if ($name$_ == &_default_$name$_) {\n"
...@@ -129,6 +147,8 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { ...@@ -129,6 +147,8 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" }\n" " }\n"
" $name$_->assign(value);\n" " $name$_->assign(value);\n"
"}\n"); "}\n");
}
printer->Print(variables_, printer->Print(variables_,
"inline ::std::string* $classname$::mutable_$name$() {\n" "inline ::std::string* $classname$::mutable_$name$() {\n"
" _set_bit($index$);\n" " _set_bit($index$);\n"
...@@ -245,10 +265,18 @@ GenerateAccessorDeclarations(io::Printer* printer) const { ...@@ -245,10 +265,18 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"inline const ::std::string& $name$(int index) const;\n" "inline const ::std::string& $name$(int index) const;\n"
"inline ::std::string* mutable_$name$(int index);\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 ::std::string& value);\n"
"inline void set_$name$(int index, const char* value);\n"
"inline ::std::string* add_$name$();\n" "inline ::std::string* add_$name$();\n"
"inline void add_$name$(const ::std::string& 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"); "inline void add_$name$(const char* value);\n");
}
if (descriptor_->options().has_ctype()) { if (descriptor_->options().has_ctype()) {
printer->Outdent(); printer->Outdent();
...@@ -277,18 +305,31 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { ...@@ -277,18 +305,31 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
"inline void $classname$::set_$name$(int index, const ::std::string& value) {\n" "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
" $name$_.Mutable(index)->assign(value);\n" " $name$_.Mutable(index)->assign(value);\n"
"}\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" "inline ::std::string* $classname$::add_$name$() {\n"
" return $name$_.Add();\n" " return $name$_.Add();\n"
"}\n" "}\n"
"inline void $classname$::add_$name$(const ::std::string& value) {\n" "inline void $classname$::add_$name$(const ::std::string& value) {\n"
" $name$_.Add()->assign(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" "}\n"
"inline void $classname$::add_$name$(const char* value) {\n" "inline void $classname$::add_$name$(const char* value) {\n"
" $name$_.Add()->assign(value);\n" " $name$_.Add()->assign(value);\n"
"}\n"); "}\n");
}
} }
void RepeatedStringFieldGenerator:: void RepeatedStringFieldGenerator::
......
...@@ -172,6 +172,19 @@ TEST(GeneratedMessageTest, Clear) { ...@@ -172,6 +172,19 @@ TEST(GeneratedMessageTest, Clear) {
&message.optional_import_message()); &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) { TEST(GeneratedMessageTest, ClearOneField) {
// Set every field to a unique value, then clear one value and insure that // Set every field to a unique value, then clear one value and insure that
// only that one value is cleared. // only that one value is cleared.
......
...@@ -174,9 +174,9 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag ...@@ -174,9 +174,9 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
inline const ::std::string& dependency(int index) const; inline const ::std::string& dependency(int index) const;
inline ::std::string* mutable_dependency(int index); inline ::std::string* mutable_dependency(int index);
inline void set_dependency(int index, const ::std::string& value); 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 ::std::string* add_dependency();
inline void add_dependency(const ::std::string& value); inline void add_dependency(const ::std::string& value);
inline void set_dependency(int index, const char* value);
inline void add_dependency(const char* value); inline void add_dependency(const char* value);
// repeated .google.protobuf.DescriptorProto message_type = 4; // repeated .google.protobuf.DescriptorProto message_type = 4;
...@@ -1835,15 +1835,15 @@ inline ::std::string* FileDescriptorProto::mutable_dependency(int index) { ...@@ -1835,15 +1835,15 @@ inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) { inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
dependency_.Mutable(index)->assign(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() { inline ::std::string* FileDescriptorProto::add_dependency() {
return dependency_.Add(); return dependency_.Add();
} }
inline void FileDescriptorProto::add_dependency(const ::std::string& value) { inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
dependency_.Add()->assign(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) { inline void FileDescriptorProto::add_dependency(const char* value) {
dependency_.Add()->assign(value); dependency_.Add()->assign(value);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment