| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // http://code.google.com/p/protobuf/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| 11 // * Redistributions in binary form must reproduce the above | 11 // * Redistributions in binary form must reproduce the above |
| 12 // copyright notice, this list of conditions and the following disclaimer | 12 // copyright notice, this list of conditions and the following disclaimer |
| 13 // in the documentation and/or other materials provided with the | 13 // in the documentation and/or other materials provided with the |
| (...skipping 13 matching lines...) Expand all Loading... |
| 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | 30 |
| 31 // Author: kenton@google.com (Kenton Varda) | 31 // Author: kenton@google.com (Kenton Varda) |
| 32 // Based on original Protocol Buffers design by | 32 // Based on original Protocol Buffers design by |
| 33 // Sanjay Ghemawat, Jeff Dean, and others. | 33 // Sanjay Ghemawat, Jeff Dean, and others. |
| 34 | 34 |
| 35 #include <google/protobuf/unknown_field_set.h> | 35 #include <google/protobuf/unknown_field_set.h> |
| 36 | 36 |
| 37 #include <google/protobuf/stubs/logging.h> |
| 37 #include <google/protobuf/stubs/common.h> | 38 #include <google/protobuf/stubs/common.h> |
| 38 #include <google/protobuf/io/coded_stream.h> | 39 #include <google/protobuf/io/coded_stream.h> |
| 39 #include <google/protobuf/io/zero_copy_stream.h> | 40 #include <google/protobuf/io/zero_copy_stream.h> |
| 40 #include <google/protobuf/io/zero_copy_stream_impl_lite.h> | 41 #include <google/protobuf/io/zero_copy_stream_impl.h> |
| 41 #include <google/protobuf/wire_format_lite.h> | 42 #include <google/protobuf/wire_format.h> |
| 42 #include <google/protobuf/stubs/stl_util.h> | 43 #include <google/protobuf/stubs/stl_util.h> |
| 43 | 44 |
| 44 namespace google { | 45 namespace google { |
| 45 namespace protobuf { | 46 namespace protobuf { |
| 46 | 47 |
| 47 namespace internal { | 48 namespace { |
| 49 // This global instance is returned by unknown_fields() on any message class |
| 50 // when the object has no unknown fields. This is necessary because we now |
| 51 // instantiate the UnknownFieldSet dynamically only when required. |
| 52 UnknownFieldSet* default_unknown_field_set_instance_ = NULL; |
| 48 | 53 |
| 49 int StringSpaceUsedExcludingSelf(const string& str) { | 54 void DeleteDefaultUnknownFieldSet() { |
| 50 const void* start = &str; | 55 delete default_unknown_field_set_instance_; |
| 51 const void* end = &str + 1; | |
| 52 | |
| 53 if (start <= str.data() && str.data() <= end) { | |
| 54 // The string's data is stored inside the string object itself. | |
| 55 return 0; | |
| 56 } else { | |
| 57 return str.capacity(); | |
| 58 } | |
| 59 } | 56 } |
| 60 | 57 |
| 58 void InitDefaultUnknownFieldSet() { |
| 59 default_unknown_field_set_instance_ = new UnknownFieldSet(); |
| 60 internal::OnShutdown(&DeleteDefaultUnknownFieldSet); |
| 61 } |
| 62 |
| 63 GOOGLE_PROTOBUF_DECLARE_ONCE(default_unknown_field_set_once_init_); |
| 64 } |
| 65 |
| 66 const UnknownFieldSet* UnknownFieldSet::default_instance() { |
| 67 ::google::protobuf::GoogleOnceInit(&default_unknown_field_set_once_init_, |
| 68 &InitDefaultUnknownFieldSet); |
| 69 return default_unknown_field_set_instance_; |
| 61 } | 70 } |
| 62 | 71 |
| 63 UnknownFieldSet::UnknownFieldSet() | 72 UnknownFieldSet::UnknownFieldSet() |
| 64 : fields_(NULL) {} | 73 : fields_(NULL) {} |
| 65 | 74 |
| 66 UnknownFieldSet::~UnknownFieldSet() { | 75 UnknownFieldSet::~UnknownFieldSet() { |
| 67 Clear(); | 76 Clear(); |
| 68 delete fields_; | 77 delete fields_; |
| 69 } | 78 } |
| 70 | 79 |
| 71 void UnknownFieldSet::ClearFallback() { | 80 void UnknownFieldSet::ClearFallback() { |
| 72 GOOGLE_DCHECK(fields_ != NULL); | 81 if (fields_ != NULL) { |
| 73 for (int i = 0; i < fields_->size(); i++) { | 82 for (int i = 0; i < fields_->size(); i++) { |
| 74 (*fields_)[i].Delete(); | 83 (*fields_)[i].Delete(); |
| 84 } |
| 85 delete fields_; |
| 86 fields_ = NULL; |
| 75 } | 87 } |
| 76 fields_->clear(); | |
| 77 } | 88 } |
| 78 | 89 |
| 79 void UnknownFieldSet::ClearAndFreeMemory() { | 90 void UnknownFieldSet::ClearAndFreeMemory() { |
| 80 if (fields_ != NULL) { | 91 if (fields_ != NULL) { |
| 81 Clear(); | 92 Clear(); |
| 82 delete fields_; | 93 } |
| 83 fields_ = NULL; | 94 } |
| 95 |
| 96 void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) { |
| 97 int other_field_count = other.field_count(); |
| 98 if (other_field_count > 0) { |
| 99 fields_ = new vector<UnknownField>(); |
| 100 for (int i = 0; i < other_field_count; i++) { |
| 101 fields_->push_back((*other.fields_)[i]); |
| 102 fields_->back().DeepCopy((*other.fields_)[i]); |
| 103 } |
| 84 } | 104 } |
| 85 } | 105 } |
| 86 | 106 |
| 87 void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { | 107 void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { |
| 88 for (int i = 0; i < other.field_count(); i++) { | 108 int other_field_count = other.field_count(); |
| 89 AddField(other.field(i)); | 109 if (other_field_count > 0) { |
| 110 if (fields_ == NULL) fields_ = new vector<UnknownField>(); |
| 111 for (int i = 0; i < other_field_count; i++) { |
| 112 fields_->push_back((*other.fields_)[i]); |
| 113 fields_->back().DeepCopy((*other.fields_)[i]); |
| 114 } |
| 90 } | 115 } |
| 91 } | 116 } |
| 92 | 117 |
| 118 // A specialized MergeFrom for performance when we are merging from an UFS that |
| 119 // is temporary and can be destroyed in the process. |
| 120 void UnknownFieldSet::MergeFromAndDestroy(UnknownFieldSet* other) { |
| 121 int other_field_count = other->field_count(); |
| 122 if (other_field_count > 0) { |
| 123 if (fields_ == NULL) fields_ = new vector<UnknownField>(); |
| 124 for (int i = 0; i < other_field_count; i++) { |
| 125 fields_->push_back((*other->fields_)[i]); |
| 126 (*other->fields_)[i].Reset(); |
| 127 } |
| 128 } |
| 129 delete other->fields_; |
| 130 other->fields_ = NULL; |
| 131 } |
| 132 |
| 93 int UnknownFieldSet::SpaceUsedExcludingSelf() const { | 133 int UnknownFieldSet::SpaceUsedExcludingSelf() const { |
| 94 if (fields_ == NULL) return 0; | 134 if (fields_ == NULL) return 0; |
| 95 | 135 |
| 96 int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size(); | 136 int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size(); |
| 137 |
| 97 for (int i = 0; i < fields_->size(); i++) { | 138 for (int i = 0; i < fields_->size(); i++) { |
| 98 const UnknownField& field = (*fields_)[i]; | 139 const UnknownField& field = (*fields_)[i]; |
| 99 switch (field.type()) { | 140 switch (field.type()) { |
| 100 case UnknownField::TYPE_LENGTH_DELIMITED: | 141 case UnknownField::TYPE_LENGTH_DELIMITED: |
| 101 total_size += sizeof(*field.length_delimited_.string_value_) + | 142 total_size += sizeof(*field.length_delimited_.string_value_) + |
| 102 internal::StringSpaceUsedExcludingSelf( | 143 internal::StringSpaceUsedExcludingSelf( |
| 103 *field.length_delimited_.string_value_); | 144 *field.length_delimited_.string_value_); |
| 104 break; | 145 break; |
| 105 case UnknownField::TYPE_GROUP: | 146 case UnknownField::TYPE_GROUP: |
| 106 total_size += field.group_->SpaceUsed(); | 147 total_size += field.group_->SpaceUsed(); |
| 107 break; | 148 break; |
| 108 default: | 149 default: |
| 109 break; | 150 break; |
| 110 } | 151 } |
| 111 } | 152 } |
| 112 return total_size; | 153 return total_size; |
| 113 } | 154 } |
| 114 | 155 |
| 115 int UnknownFieldSet::SpaceUsed() const { | 156 int UnknownFieldSet::SpaceUsed() const { |
| 116 return sizeof(*this) + SpaceUsedExcludingSelf(); | 157 return sizeof(*this) + SpaceUsedExcludingSelf(); |
| 117 } | 158 } |
| 118 | 159 |
| 119 void UnknownFieldSet::AddVarint(int number, uint64 value) { | 160 void UnknownFieldSet::AddVarint(int number, uint64 value) { |
| 120 if (fields_ == NULL) fields_ = new vector<UnknownField>; | |
| 121 UnknownField field; | 161 UnknownField field; |
| 122 field.number_ = number; | 162 field.number_ = number; |
| 123 field.type_ = UnknownField::TYPE_VARINT; | 163 field.SetType(UnknownField::TYPE_VARINT); |
| 124 field.varint_ = value; | 164 field.varint_ = value; |
| 165 if (fields_ == NULL) fields_ = new vector<UnknownField>(); |
| 125 fields_->push_back(field); | 166 fields_->push_back(field); |
| 126 } | 167 } |
| 127 | 168 |
| 128 void UnknownFieldSet::AddFixed32(int number, uint32 value) { | 169 void UnknownFieldSet::AddFixed32(int number, uint32 value) { |
| 129 if (fields_ == NULL) fields_ = new vector<UnknownField>; | |
| 130 UnknownField field; | 170 UnknownField field; |
| 131 field.number_ = number; | 171 field.number_ = number; |
| 132 field.type_ = UnknownField::TYPE_FIXED32; | 172 field.SetType(UnknownField::TYPE_FIXED32); |
| 133 field.fixed32_ = value; | 173 field.fixed32_ = value; |
| 174 if (fields_ == NULL) fields_ = new vector<UnknownField>(); |
| 134 fields_->push_back(field); | 175 fields_->push_back(field); |
| 135 } | 176 } |
| 136 | 177 |
| 137 void UnknownFieldSet::AddFixed64(int number, uint64 value) { | 178 void UnknownFieldSet::AddFixed64(int number, uint64 value) { |
| 138 if (fields_ == NULL) fields_ = new vector<UnknownField>; | |
| 139 UnknownField field; | 179 UnknownField field; |
| 140 field.number_ = number; | 180 field.number_ = number; |
| 141 field.type_ = UnknownField::TYPE_FIXED64; | 181 field.SetType(UnknownField::TYPE_FIXED64); |
| 142 field.fixed64_ = value; | 182 field.fixed64_ = value; |
| 183 if (fields_ == NULL) fields_ = new vector<UnknownField>(); |
| 143 fields_->push_back(field); | 184 fields_->push_back(field); |
| 144 } | 185 } |
| 145 | 186 |
| 146 string* UnknownFieldSet::AddLengthDelimited(int number) { | 187 string* UnknownFieldSet::AddLengthDelimited(int number) { |
| 147 if (fields_ == NULL) fields_ = new vector<UnknownField>; | |
| 148 UnknownField field; | 188 UnknownField field; |
| 149 field.number_ = number; | 189 field.number_ = number; |
| 150 field.type_ = UnknownField::TYPE_LENGTH_DELIMITED; | 190 field.SetType(UnknownField::TYPE_LENGTH_DELIMITED); |
| 151 field.length_delimited_.string_value_ = new string; | 191 field.length_delimited_.string_value_ = new string; |
| 192 if (fields_ == NULL) fields_ = new vector<UnknownField>(); |
| 152 fields_->push_back(field); | 193 fields_->push_back(field); |
| 153 return field.length_delimited_.string_value_; | 194 return field.length_delimited_.string_value_; |
| 154 } | 195 } |
| 155 | 196 |
| 156 | 197 |
| 157 UnknownFieldSet* UnknownFieldSet::AddGroup(int number) { | 198 UnknownFieldSet* UnknownFieldSet::AddGroup(int number) { |
| 158 if (fields_ == NULL) fields_ = new vector<UnknownField>; | |
| 159 UnknownField field; | 199 UnknownField field; |
| 160 field.number_ = number; | 200 field.number_ = number; |
| 161 field.type_ = UnknownField::TYPE_GROUP; | 201 field.SetType(UnknownField::TYPE_GROUP); |
| 162 field.group_ = new UnknownFieldSet; | 202 field.group_ = new UnknownFieldSet; |
| 203 if (fields_ == NULL) fields_ = new vector<UnknownField>(); |
| 163 fields_->push_back(field); | 204 fields_->push_back(field); |
| 164 return field.group_; | 205 return field.group_; |
| 165 } | 206 } |
| 166 | 207 |
| 167 void UnknownFieldSet::AddField(const UnknownField& field) { | 208 void UnknownFieldSet::AddField(const UnknownField& field) { |
| 168 if (fields_ == NULL) fields_ = new vector<UnknownField>; | 209 if (fields_ == NULL) fields_ = new vector<UnknownField>(); |
| 169 fields_->push_back(field); | 210 fields_->push_back(field); |
| 170 fields_->back().DeepCopy(); | 211 fields_->back().DeepCopy(field); |
| 171 } | 212 } |
| 172 | 213 |
| 173 void UnknownFieldSet::DeleteSubrange(int start, int num) { | 214 void UnknownFieldSet::DeleteSubrange(int start, int num) { |
| 174 GOOGLE_DCHECK(fields_ != NULL); | |
| 175 // Delete the specified fields. | 215 // Delete the specified fields. |
| 176 for (int i = 0; i < num; ++i) { | 216 for (int i = 0; i < num; ++i) { |
| 177 (*fields_)[i + start].Delete(); | 217 (*fields_)[i + start].Delete(); |
| 178 } | 218 } |
| 179 // Slide down the remaining fields. | 219 // Slide down the remaining fields. |
| 180 for (int i = start + num; i < fields_->size(); ++i) { | 220 for (int i = start + num; i < fields_->size(); ++i) { |
| 181 (*fields_)[i - num] = (*fields_)[i]; | 221 (*fields_)[i - num] = (*fields_)[i]; |
| 182 } | 222 } |
| 183 // Pop off the # of deleted fields. | 223 // Pop off the # of deleted fields. |
| 184 for (int i = 0; i < num; ++i) { | 224 for (int i = 0; i < num; ++i) { |
| 185 fields_->pop_back(); | 225 fields_->pop_back(); |
| 186 } | 226 } |
| 227 if (fields_ && fields_->size() == 0) { |
| 228 // maintain invariant: never hold fields_ if empty. |
| 229 delete fields_; |
| 230 fields_ = NULL; |
| 231 } |
| 187 } | 232 } |
| 188 | 233 |
| 189 void UnknownFieldSet::DeleteByNumber(int number) { | 234 void UnknownFieldSet::DeleteByNumber(int number) { |
| 190 if (fields_ == NULL) return; | 235 if (fields_ == NULL) return; |
| 191 int left = 0; // The number of fields left after deletion. | 236 int left = 0; // The number of fields left after deletion. |
| 192 for (int i = 0; i < fields_->size(); ++i) { | 237 for (int i = 0; i < fields_->size(); ++i) { |
| 193 UnknownField* field = &(*fields_)[i]; | 238 UnknownField* field = &(*fields_)[i]; |
| 194 if (field->number() == number) { | 239 if (field->number() == number) { |
| 195 field->Delete(); | 240 field->Delete(); |
| 196 } else { | 241 } else { |
| 197 if (i != left) { | 242 if (i != left) { |
| 198 (*fields_)[left] = (*fields_)[i]; | 243 (*fields_)[left] = (*fields_)[i]; |
| 199 } | 244 } |
| 200 ++left; | 245 ++left; |
| 201 } | 246 } |
| 202 } | 247 } |
| 203 fields_->resize(left); | 248 fields_->resize(left); |
| 249 if (left == 0) { |
| 250 // maintain invariant: never hold fields_ if empty. |
| 251 delete fields_; |
| 252 fields_ = NULL; |
| 253 } |
| 204 } | 254 } |
| 205 | 255 |
| 206 bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) { | 256 bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) { |
| 207 | |
| 208 UnknownFieldSet other; | 257 UnknownFieldSet other; |
| 209 if (internal::WireFormatLite::SkipMessage(input, &other) && | 258 if (internal::WireFormat::SkipMessage(input, &other) && |
| 210 input->ConsumedEntireMessage()) { | 259 input->ConsumedEntireMessage()) { |
| 211 MergeFrom(other); | 260 MergeFromAndDestroy(&other); |
| 212 return true; | 261 return true; |
| 213 } else { | 262 } else { |
| 214 return false; | 263 return false; |
| 215 } | 264 } |
| 216 } | 265 } |
| 217 | 266 |
| 218 bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) { | 267 bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) { |
| 219 Clear(); | 268 Clear(); |
| 220 return MergeFromCodedStream(input); | 269 return MergeFromCodedStream(input); |
| 221 } | 270 } |
| 222 | 271 |
| 223 bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { | 272 bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { |
| 224 io::CodedInputStream coded_input(input); | 273 io::CodedInputStream coded_input(input); |
| 225 return ParseFromCodedStream(&coded_input) && | 274 return (ParseFromCodedStream(&coded_input) && |
| 226 coded_input.ConsumedEntireMessage(); | 275 coded_input.ConsumedEntireMessage()); |
| 227 } | 276 } |
| 228 | 277 |
| 229 bool UnknownFieldSet::ParseFromArray(const void* data, int size) { | 278 bool UnknownFieldSet::ParseFromArray(const void* data, int size) { |
| 230 io::ArrayInputStream input(data, size); | 279 io::ArrayInputStream input(data, size); |
| 231 return ParseFromZeroCopyStream(&input); | 280 return ParseFromZeroCopyStream(&input); |
| 232 } | 281 } |
| 233 | 282 |
| 234 void UnknownField::Delete() { | 283 void UnknownField::Delete() { |
| 235 switch (type()) { | 284 switch (type()) { |
| 236 case UnknownField::TYPE_LENGTH_DELIMITED: | 285 case UnknownField::TYPE_LENGTH_DELIMITED: |
| 237 delete length_delimited_.string_value_; | 286 delete length_delimited_.string_value_; |
| 238 break; | 287 break; |
| 239 case UnknownField::TYPE_GROUP: | 288 case UnknownField::TYPE_GROUP: |
| 240 delete group_; | 289 delete group_; |
| 241 break; | 290 break; |
| 242 default: | 291 default: |
| 243 break; | 292 break; |
| 244 } | 293 } |
| 245 } | 294 } |
| 246 | 295 |
| 247 void UnknownField::DeepCopy() { | 296 // Reset all owned ptrs, a special function for performance, to avoid double |
| 297 // owning the ptrs, when we merge from a temporary UnknownFieldSet objects. |
| 298 void UnknownField::Reset() { |
| 299 switch (type()) { |
| 300 case UnknownField::TYPE_LENGTH_DELIMITED: |
| 301 length_delimited_.string_value_ = NULL; |
| 302 break; |
| 303 case UnknownField::TYPE_GROUP: { |
| 304 group_ = NULL; |
| 305 break; |
| 306 } |
| 307 default: |
| 308 break; |
| 309 } |
| 310 } |
| 311 |
| 312 void UnknownField::DeepCopy(const UnknownField& other) { |
| 248 switch (type()) { | 313 switch (type()) { |
| 249 case UnknownField::TYPE_LENGTH_DELIMITED: | 314 case UnknownField::TYPE_LENGTH_DELIMITED: |
| 250 length_delimited_.string_value_ = new string( | 315 length_delimited_.string_value_ = new string( |
| 251 *length_delimited_.string_value_); | 316 *length_delimited_.string_value_); |
| 252 break; | 317 break; |
| 253 case UnknownField::TYPE_GROUP: { | 318 case UnknownField::TYPE_GROUP: { |
| 254 UnknownFieldSet* group = new UnknownFieldSet; | 319 UnknownFieldSet* group = new UnknownFieldSet(); |
| 255 group->MergeFrom(*group_); | 320 group->InternalMergeFrom(*group_); |
| 256 group_ = group; | 321 group_ = group; |
| 257 break; | 322 break; |
| 258 } | 323 } |
| 259 default: | 324 default: |
| 260 break; | 325 break; |
| 261 } | 326 } |
| 262 } | 327 } |
| 263 | 328 |
| 264 | 329 |
| 265 void UnknownField::SerializeLengthDelimitedNoTag( | 330 void UnknownField::SerializeLengthDelimitedNoTag( |
| 266 io::CodedOutputStream* output) const { | 331 io::CodedOutputStream* output) const { |
| 267 GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type_); | 332 GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); |
| 268 const string& data = *length_delimited_.string_value_; | 333 const string& data = *length_delimited_.string_value_; |
| 269 output->WriteVarint32(data.size()); | 334 output->WriteVarint32(data.size()); |
| 270 output->WriteString(data); | 335 output->WriteRawMaybeAliased(data.data(), data.size()); |
| 271 } | 336 } |
| 272 | 337 |
| 273 uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const { | 338 uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const { |
| 274 GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type_); | 339 GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); |
| 275 const string& data = *length_delimited_.string_value_; | 340 const string& data = *length_delimited_.string_value_; |
| 276 target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); | 341 target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); |
| 277 target = io::CodedOutputStream::WriteStringToArray(data, target); | 342 target = io::CodedOutputStream::WriteStringToArray(data, target); |
| 278 return target; | 343 return target; |
| 279 } | 344 } |
| 280 | 345 |
| 281 } // namespace protobuf | 346 } // namespace protobuf |
| 282 } // namespace google | 347 } // namespace google |
| OLD | NEW |