1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 30 31 // Author: kenton (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 35 #include <google/protobuf/wire_format_lite_inl.h> 36 37 #include <stack> 38 #include <string> 39 #include <vector> 40 #include <google/protobuf/stubs/common.h> 41 #include <google/protobuf/io/coded_stream_inl.h> 42 #include <google/protobuf/io/zero_copy_stream.h> 43 #include <google/protobuf/io/zero_copy_stream_impl_lite.h> 44 #include <google/protobuf/unknown_field_set.h> 45 46 namespace google { 47 namespace protobuf { 48 namespace internal { 49 50 #ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC 51 // requires them. 52 const int WireFormatLite::kMessageSetItemStartTag; 53 const int WireFormatLite::kMessageSetItemEndTag; 54 const int WireFormatLite::kMessageSetTypeIdTag; 55 const int WireFormatLite::kMessageSetMessageTag; 56 57 #endif 58 59 // =================================================================== 60 61 bool FieldSkipper::SkipField( 62 io::CodedInputStream* input, uint32 tag) { 63 return WireFormatLite::SkipField(input, tag, unknown_fields_); 64 } 65 66 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { 67 return WireFormatLite::SkipMessage(input, unknown_fields_); 68 } 69 70 void FieldSkipper::SkipUnknownEnum( 71 int field_number, int value) { 72 unknown_fields_->AddVarint(field_number, value); 73 } 74 75 // =================================================================== 76 77 const int WireFormatLite::kMessageSetItemTagsSize = 78 io::CodedOutputStream::StaticVarintSize32<kMessageSetItemStartTag>::value + 79 io::CodedOutputStream::StaticVarintSize32<kMessageSetItemEndTag>::value + 80 io::CodedOutputStream::StaticVarintSize32<kMessageSetTypeIdTag>::value + 81 io::CodedOutputStream::StaticVarintSize32<kMessageSetMessageTag>::value; 82 83 const WireFormatLite::CppType 84 WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = { 85 static_cast<CppType>(0), // 0 is reserved for errors 86 87 CPPTYPE_DOUBLE, // TYPE_DOUBLE 88 CPPTYPE_FLOAT, // TYPE_FLOAT 89 CPPTYPE_INT64, // TYPE_INT64 90 CPPTYPE_UINT64, // TYPE_UINT64 91 CPPTYPE_INT32, // TYPE_INT32 92 CPPTYPE_UINT64, // TYPE_FIXED64 93 CPPTYPE_UINT32, // TYPE_FIXED32 94 CPPTYPE_BOOL, // TYPE_BOOL 95 CPPTYPE_STRING, // TYPE_STRING 96 CPPTYPE_MESSAGE, // TYPE_GROUP 97 CPPTYPE_MESSAGE, // TYPE_MESSAGE 98 CPPTYPE_STRING, // TYPE_BYTES 99 CPPTYPE_UINT32, // TYPE_UINT32 100 CPPTYPE_ENUM, // TYPE_ENUM 101 CPPTYPE_INT32, // TYPE_SFIXED32 102 CPPTYPE_INT64, // TYPE_SFIXED64 103 CPPTYPE_INT32, // TYPE_SINT32 104 CPPTYPE_INT64, // TYPE_SINT64 105 }; 106 107 const WireFormatLite::WireType 108 WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = { 109 static_cast<WireFormatLite::WireType>(-1), // invalid 110 WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE 111 WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT 112 WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64 113 WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64 114 WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32 115 WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64 116 WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32 117 WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL 118 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING 119 WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP 120 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE 121 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES 122 WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32 123 WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM 124 WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32 125 WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64 126 WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32 127 WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64 128 }; 129 130 bool WireFormatLite::SkipField(io::CodedInputStream* input, uint32 tag, 131 UnknownFieldSet* unknown_fields) { 132 int number = WireFormatLite::GetTagFieldNumber(tag); 133 134 switch (WireFormatLite::GetTagWireType(tag)) { 135 case WireFormatLite::WIRETYPE_VARINT: { 136 uint64 value; 137 if (!input->ReadVarint64(&value)) return false; 138 if (unknown_fields != NULL) unknown_fields->AddVarint(number, value); 139 return true; 140 } 141 case WireFormatLite::WIRETYPE_FIXED64: { 142 uint64 value; 143 if (!input->ReadLittleEndian64(&value)) return false; 144 if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value); 145 return true; 146 } 147 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { 148 uint32 length; 149 if (!input->ReadVarint32(&length)) return false; 150 if (unknown_fields == NULL) { 151 if (!input->Skip(length)) return false; 152 } else { 153 if (!input->ReadString(unknown_fields->AddLengthDelimited(number), 154 length)) { 155 return false; 156 } 157 } 158 return true; 159 } 160 case WireFormatLite::WIRETYPE_START_GROUP: { 161 if (!input->IncrementRecursionDepth()) return false; 162 if (!SkipMessage(input, (unknown_fields == NULL) ? 163 NULL : unknown_fields->AddGroup(number))) { 164 return false; 165 } 166 input->DecrementRecursionDepth(); 167 // Check that the ending tag matched the starting tag. 168 if (!input->LastTagWas(WireFormatLite::MakeTag( 169 WireFormatLite::GetTagFieldNumber(tag), 170 WireFormatLite::WIRETYPE_END_GROUP))) { 171 return false; 172 } 173 return true; 174 } 175 case WireFormatLite::WIRETYPE_END_GROUP: { 176 return false; 177 } 178 case WireFormatLite::WIRETYPE_FIXED32: { 179 uint32 value; 180 if (!input->ReadLittleEndian32(&value)) return false; 181 if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value); 182 return true; 183 } 184 default: { 185 return false; 186 } 187 } 188 } 189 190 bool WireFormatLite::SkipMessage(io::CodedInputStream* input, 191 UnknownFieldSet* unknown_fields) { 192 while(true) { 193 uint32 tag = input->ReadTag(); 194 if (tag == 0) { 195 // End of input. This is a valid place to end, so return true. 196 return true; 197 } 198 199 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); 200 201 if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { 202 // Must be the end of the message. 203 return true; 204 } 205 206 if (!SkipField(input, tag, unknown_fields)) return false; 207 } 208 } 209 210 void WireFormatLite::SerializeUnknownFields(const UnknownFieldSet& unknown_fields, 211 io::CodedOutputStream* output) { 212 for (int i = 0; i < unknown_fields.field_count(); i++) { 213 const UnknownField& field = unknown_fields.field(i); 214 switch (field.type()) { 215 case UnknownField::TYPE_VARINT: 216 output->WriteVarint32(WireFormatLite::MakeTag(field.number(), 217 WireFormatLite::WIRETYPE_VARINT)); 218 output->WriteVarint64(field.varint()); 219 break; 220 case UnknownField::TYPE_FIXED32: 221 output->WriteVarint32(WireFormatLite::MakeTag(field.number(), 222 WireFormatLite::WIRETYPE_FIXED32)); 223 output->WriteLittleEndian32(field.fixed32()); 224 break; 225 case UnknownField::TYPE_FIXED64: 226 output->WriteVarint32(WireFormatLite::MakeTag(field.number(), 227 WireFormatLite::WIRETYPE_FIXED64)); 228 output->WriteLittleEndian64(field.fixed64()); 229 break; 230 case UnknownField::TYPE_LENGTH_DELIMITED: 231 output->WriteVarint32(WireFormatLite::MakeTag(field.number(), 232 WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); 233 output->WriteVarint32(field.length_delimited().size()); 234 output->WriteString(field.length_delimited()); 235 break; 236 case UnknownField::TYPE_GROUP: 237 output->WriteVarint32(WireFormatLite::MakeTag(field.number(), 238 WireFormatLite::WIRETYPE_START_GROUP)); 239 SerializeUnknownFields(field.group(), output); 240 output->WriteVarint32(WireFormatLite::MakeTag(field.number(), 241 WireFormatLite::WIRETYPE_END_GROUP)); 242 break; 243 } 244 } 245 } 246 247 uint8* WireFormatLite::SerializeUnknownFieldsToArray( 248 const UnknownFieldSet& unknown_fields, 249 uint8* target) { 250 for (int i = 0; i < unknown_fields.field_count(); i++) { 251 const UnknownField& field = unknown_fields.field(i); 252 253 switch (field.type()) { 254 case UnknownField::TYPE_VARINT: 255 target = WireFormatLite::WriteInt64ToArray( 256 field.number(), field.varint(), target); 257 break; 258 case UnknownField::TYPE_FIXED32: 259 target = WireFormatLite::WriteFixed32ToArray( 260 field.number(), field.fixed32(), target); 261 break; 262 case UnknownField::TYPE_FIXED64: 263 target = WireFormatLite::WriteFixed64ToArray( 264 field.number(), field.fixed64(), target); 265 break; 266 case UnknownField::TYPE_LENGTH_DELIMITED: 267 target = WireFormatLite::WriteBytesToArray( 268 field.number(), field.length_delimited(), target); 269 break; 270 case UnknownField::TYPE_GROUP: 271 target = WireFormatLite::WriteTagToArray( 272 field.number(), WireFormatLite::WIRETYPE_START_GROUP, target); 273 target = SerializeUnknownFieldsToArray(field.group(), target); 274 target = WireFormatLite::WriteTagToArray( 275 field.number(), WireFormatLite::WIRETYPE_END_GROUP, target); 276 break; 277 } 278 } 279 return target; 280 } 281 282 void WireFormatLite::SerializeUnknownMessageSetItems( 283 const UnknownFieldSet& unknown_fields, 284 io::CodedOutputStream* output) { 285 for (int i = 0; i < unknown_fields.field_count(); i++) { 286 const UnknownField& field = unknown_fields.field(i); 287 // The only unknown fields that are allowed to exist in a MessageSet are 288 // messages, which are length-delimited. 289 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { 290 const string& data = field.length_delimited(); 291 292 // Start group. 293 output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); 294 295 // Write type ID. 296 output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); 297 output->WriteVarint32(field.number()); 298 299 // Write message. 300 output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); 301 output->WriteVarint32(data.size()); 302 output->WriteString(data); 303 304 // End group. 305 output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); 306 } 307 } 308 } 309 310 uint8* WireFormatLite::SerializeUnknownMessageSetItemsToArray( 311 const UnknownFieldSet& unknown_fields, 312 uint8* target) { 313 for (int i = 0; i < unknown_fields.field_count(); i++) { 314 const UnknownField& field = unknown_fields.field(i); 315 316 // The only unknown fields that are allowed to exist in a MessageSet are 317 // messages, which are length-delimited. 318 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { 319 const string& data = field.length_delimited(); 320 321 // Start group. 322 target = io::CodedOutputStream::WriteTagToArray( 323 WireFormatLite::kMessageSetItemStartTag, target); 324 325 // Write type ID. 326 target = io::CodedOutputStream::WriteTagToArray( 327 WireFormatLite::kMessageSetTypeIdTag, target); 328 target = io::CodedOutputStream::WriteVarint32ToArray( 329 field.number(), target); 330 331 // Write message. 332 target = io::CodedOutputStream::WriteTagToArray( 333 WireFormatLite::kMessageSetMessageTag, target); 334 target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); 335 target = io::CodedOutputStream::WriteStringToArray(data, target); 336 337 // End group. 338 target = io::CodedOutputStream::WriteTagToArray( 339 WireFormatLite::kMessageSetItemEndTag, target); 340 } 341 } 342 343 return target; 344 } 345 346 int WireFormatLite::ComputeUnknownFieldsSize( 347 const UnknownFieldSet& unknown_fields) { 348 int size = 0; 349 for (int i = 0; i < unknown_fields.field_count(); i++) { 350 const UnknownField& field = unknown_fields.field(i); 351 352 switch (field.type()) { 353 case UnknownField::TYPE_VARINT: 354 size += io::CodedOutputStream::VarintSize32( 355 WireFormatLite::MakeTag(field.number(), 356 WireFormatLite::WIRETYPE_VARINT)); 357 size += io::CodedOutputStream::VarintSize64(field.varint()); 358 break; 359 case UnknownField::TYPE_FIXED32: 360 size += io::CodedOutputStream::VarintSize32( 361 WireFormatLite::MakeTag(field.number(), 362 WireFormatLite::WIRETYPE_FIXED32)); 363 size += sizeof(int32); 364 break; 365 case UnknownField::TYPE_FIXED64: 366 size += io::CodedOutputStream::VarintSize32( 367 WireFormatLite::MakeTag(field.number(), 368 WireFormatLite::WIRETYPE_FIXED64)); 369 size += sizeof(int64); 370 break; 371 case UnknownField::TYPE_LENGTH_DELIMITED: 372 size += io::CodedOutputStream::VarintSize32( 373 WireFormatLite::MakeTag(field.number(), 374 WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); 375 size += io::CodedOutputStream::VarintSize32( 376 field.length_delimited().size()); 377 size += field.length_delimited().size(); 378 break; 379 case UnknownField::TYPE_GROUP: 380 size += io::CodedOutputStream::VarintSize32( 381 WireFormatLite::MakeTag(field.number(), 382 WireFormatLite::WIRETYPE_START_GROUP)); 383 size += ComputeUnknownFieldsSize(field.group()); 384 size += io::CodedOutputStream::VarintSize32( 385 WireFormatLite::MakeTag(field.number(), 386 WireFormatLite::WIRETYPE_END_GROUP)); 387 break; 388 } 389 } 390 391 return size; 392 } 393 394 int WireFormatLite::ComputeUnknownMessageSetItemsSize( 395 const UnknownFieldSet& unknown_fields) { 396 int size = 0; 397 for (int i = 0; i < unknown_fields.field_count(); i++) { 398 const UnknownField& field = unknown_fields.field(i); 399 400 // The only unknown fields that are allowed to exist in a MessageSet are 401 // messages, which are length-delimited. 402 if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { 403 size += WireFormatLite::kMessageSetItemTagsSize; 404 size += io::CodedOutputStream::VarintSize32(field.number()); 405 size += io::CodedOutputStream::VarintSize32( 406 field.length_delimited().size()); 407 size += field.length_delimited().size(); 408 } 409 } 410 411 return size; 412 } 413 414 bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input, 415 bool (*is_valid)(int), 416 RepeatedField<int>* values) { 417 uint32 length; 418 if (!input->ReadVarint32(&length)) return false; 419 io::CodedInputStream::Limit limit = input->PushLimit(length); 420 while (input->BytesUntilLimit() > 0) { 421 int value; 422 if (!google::protobuf::internal::WireFormatLite::ReadPrimitive< 423 int, WireFormatLite::TYPE_ENUM>(input, &value)) { 424 return false; 425 } 426 if (is_valid(value)) { 427 values->Add(value); 428 } 429 } 430 input->PopLimit(limit); 431 return true; 432 } 433 434 void WireFormatLite::WriteInt32(int field_number, int32 value, 435 io::CodedOutputStream* output) { 436 WriteTag(field_number, WIRETYPE_VARINT, output); 437 WriteInt32NoTag(value, output); 438 } 439 void WireFormatLite::WriteInt64(int field_number, int64 value, 440 io::CodedOutputStream* output) { 441 WriteTag(field_number, WIRETYPE_VARINT, output); 442 WriteInt64NoTag(value, output); 443 } 444 void WireFormatLite::WriteUInt32(int field_number, uint32 value, 445 io::CodedOutputStream* output) { 446 WriteTag(field_number, WIRETYPE_VARINT, output); 447 WriteUInt32NoTag(value, output); 448 } 449 void WireFormatLite::WriteUInt64(int field_number, uint64 value, 450 io::CodedOutputStream* output) { 451 WriteTag(field_number, WIRETYPE_VARINT, output); 452 WriteUInt64NoTag(value, output); 453 } 454 void WireFormatLite::WriteSInt32(int field_number, int32 value, 455 io::CodedOutputStream* output) { 456 WriteTag(field_number, WIRETYPE_VARINT, output); 457 WriteSInt32NoTag(value, output); 458 } 459 void WireFormatLite::WriteSInt64(int field_number, int64 value, 460 io::CodedOutputStream* output) { 461 WriteTag(field_number, WIRETYPE_VARINT, output); 462 WriteSInt64NoTag(value, output); 463 } 464 void WireFormatLite::WriteFixed32(int field_number, uint32 value, 465 io::CodedOutputStream* output) { 466 WriteTag(field_number, WIRETYPE_FIXED32, output); 467 WriteFixed32NoTag(value, output); 468 } 469 void WireFormatLite::WriteFixed64(int field_number, uint64 value, 470 io::CodedOutputStream* output) { 471 WriteTag(field_number, WIRETYPE_FIXED64, output); 472 WriteFixed64NoTag(value, output); 473 } 474 void WireFormatLite::WriteSFixed32(int field_number, int32 value, 475 io::CodedOutputStream* output) { 476 WriteTag(field_number, WIRETYPE_FIXED32, output); 477 WriteSFixed32NoTag(value, output); 478 } 479 void WireFormatLite::WriteSFixed64(int field_number, int64 value, 480 io::CodedOutputStream* output) { 481 WriteTag(field_number, WIRETYPE_FIXED64, output); 482 WriteSFixed64NoTag(value, output); 483 } 484 void WireFormatLite::WriteFloat(int field_number, float value, 485 io::CodedOutputStream* output) { 486 WriteTag(field_number, WIRETYPE_FIXED32, output); 487 WriteFloatNoTag(value, output); 488 } 489 void WireFormatLite::WriteDouble(int field_number, double value, 490 io::CodedOutputStream* output) { 491 WriteTag(field_number, WIRETYPE_FIXED64, output); 492 WriteDoubleNoTag(value, output); 493 } 494 void WireFormatLite::WriteBool(int field_number, bool value, 495 io::CodedOutputStream* output) { 496 WriteTag(field_number, WIRETYPE_VARINT, output); 497 WriteBoolNoTag(value, output); 498 } 499 void WireFormatLite::WriteEnum(int field_number, int value, 500 io::CodedOutputStream* output) { 501 WriteTag(field_number, WIRETYPE_VARINT, output); 502 WriteEnumNoTag(value, output); 503 } 504 505 void WireFormatLite::WriteString(int field_number, const string& value, 506 io::CodedOutputStream* output) { 507 // String is for UTF-8 text only 508 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 509 GOOGLE_CHECK(value.size() <= kint32max); 510 output->WriteVarint32(value.size()); 511 output->WriteString(value); 512 } 513 void WireFormatLite::WriteBytes(int field_number, const string& value, 514 io::CodedOutputStream* output) { 515 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 516 GOOGLE_CHECK(value.size() <= kint32max); 517 output->WriteVarint32(value.size()); 518 output->WriteString(value); 519 } 520 521 522 void WireFormatLite::WriteGroup(int field_number, 523 const MessageLite& value, 524 io::CodedOutputStream* output) { 525 WriteTag(field_number, WIRETYPE_START_GROUP, output); 526 value.SerializeWithCachedSizes(output); 527 WriteTag(field_number, WIRETYPE_END_GROUP, output); 528 } 529 530 void WireFormatLite::WriteMessage(int field_number, 531 const MessageLite& value, 532 io::CodedOutputStream* output) { 533 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 534 const int size = value.GetCachedSize(); 535 output->WriteVarint32(size); 536 value.SerializeWithCachedSizes(output); 537 } 538 539 void WireFormatLite::WriteGroupMaybeToArray(int field_number, 540 const MessageLite& value, 541 io::CodedOutputStream* output) { 542 WriteTag(field_number, WIRETYPE_START_GROUP, output); 543 const int size = value.GetCachedSize(); 544 uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); 545 if (target != NULL) { 546 uint8* end = value.SerializeWithCachedSizesToArray(target); 547 GOOGLE_DCHECK_EQ(end - target, size); 548 } else { 549 value.SerializeWithCachedSizes(output); 550 } 551 WriteTag(field_number, WIRETYPE_END_GROUP, output); 552 } 553 554 void WireFormatLite::WriteMessageMaybeToArray(int field_number, 555 const MessageLite& value, 556 io::CodedOutputStream* output) { 557 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 558 const int size = value.GetCachedSize(); 559 output->WriteVarint32(size); 560 uint8* target = output->GetDirectBufferForNBytesAndAdvance(size); 561 if (target != NULL) { 562 uint8* end = value.SerializeWithCachedSizesToArray(target); 563 GOOGLE_DCHECK_EQ(end - target, size); 564 } else { 565 value.SerializeWithCachedSizes(output); 566 } 567 } 568 569 bool WireFormatLite::ReadString(io::CodedInputStream* input, 570 string* value) { 571 // String is for UTF-8 text only 572 uint32 length; 573 if (!input->ReadVarint32(&length)) return false; 574 if (!input->InternalReadStringInline(value, length)) return false; 575 return true; 576 } 577 bool WireFormatLite::ReadBytes(io::CodedInputStream* input, 578 string* value) { 579 uint32 length; 580 if (!input->ReadVarint32(&length)) return false; 581 return input->InternalReadStringInline(value, length); 582 } 583 584 } // namespace internal 585 } // namespace protobuf 586 } // namespace google 587