aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar temporal <temporal@630680e5-0e50-0410-840e-4b1c322b438d>2008-07-16 02:00:27 +0000
committerGravatar temporal <temporal@630680e5-0e50-0410-840e-4b1c322b438d>2008-07-16 02:00:27 +0000
commit928ebb6b55a23972573328e0ca9500d9730249af (patch)
treeeb3790f12e31b919f63fc22b5bc5cc0d9f963ce5
parent40ee551715c3a784ea6132dbf604b0e665ca2def (diff)
Fix bytes type setter to work with byte sequences with embedded NULLs.
Patch from Alkis Evlogimenos <alkis@evlogimenos.com>.
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc77
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc13
-rw-r--r--src/google/protobuf/descriptor.pb.h8
3 files changed, 76 insertions, 22 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index de59ac87..e74eb432 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -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::
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index 8253242b..561a5ad1 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -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.
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 892f92d0..27994dda 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -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);
}