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@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 46namespace google { 47namespace protobuf { 48namespace internal { 49 50#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC 51 // requires them. 52const int WireFormatLite::kMessageSetItemStartTag; 53const int WireFormatLite::kMessageSetItemEndTag; 54const int WireFormatLite::kMessageSetTypeIdTag; 55const int WireFormatLite::kMessageSetMessageTag; 56 57#endif 58 59// =================================================================== 60 61bool FieldSkipper::SkipField( 62 io::CodedInputStream* input, uint32 tag) { 63 return WireFormatLite::SkipField(input, tag, unknown_fields_); 64} 65 66bool FieldSkipper::SkipMessage(io::CodedInputStream* input) { 67 return WireFormatLite::SkipMessage(input, unknown_fields_); 68} 69 70void FieldSkipper::SkipUnknownEnum( 71 int field_number, int value) { 72 unknown_fields_->AddVarint(field_number, value); 73} 74 75// =================================================================== 76 77const 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 83const WireFormatLite::CppType 84WireFormatLite::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 107const WireFormatLite::WireType 108WireFormatLite::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 130bool 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 190bool 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 210void 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 247uint8* 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 282void 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 310uint8* 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 346int 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 394int 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 414bool 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 434void WireFormatLite::WriteInt32(int field_number, int32 value, 435 io::CodedOutputStream* output) { 436 WriteTag(field_number, WIRETYPE_VARINT, output); 437 WriteInt32NoTag(value, output); 438} 439void WireFormatLite::WriteInt64(int field_number, int64 value, 440 io::CodedOutputStream* output) { 441 WriteTag(field_number, WIRETYPE_VARINT, output); 442 WriteInt64NoTag(value, output); 443} 444void WireFormatLite::WriteUInt32(int field_number, uint32 value, 445 io::CodedOutputStream* output) { 446 WriteTag(field_number, WIRETYPE_VARINT, output); 447 WriteUInt32NoTag(value, output); 448} 449void WireFormatLite::WriteUInt64(int field_number, uint64 value, 450 io::CodedOutputStream* output) { 451 WriteTag(field_number, WIRETYPE_VARINT, output); 452 WriteUInt64NoTag(value, output); 453} 454void WireFormatLite::WriteSInt32(int field_number, int32 value, 455 io::CodedOutputStream* output) { 456 WriteTag(field_number, WIRETYPE_VARINT, output); 457 WriteSInt32NoTag(value, output); 458} 459void WireFormatLite::WriteSInt64(int field_number, int64 value, 460 io::CodedOutputStream* output) { 461 WriteTag(field_number, WIRETYPE_VARINT, output); 462 WriteSInt64NoTag(value, output); 463} 464void WireFormatLite::WriteFixed32(int field_number, uint32 value, 465 io::CodedOutputStream* output) { 466 WriteTag(field_number, WIRETYPE_FIXED32, output); 467 WriteFixed32NoTag(value, output); 468} 469void WireFormatLite::WriteFixed64(int field_number, uint64 value, 470 io::CodedOutputStream* output) { 471 WriteTag(field_number, WIRETYPE_FIXED64, output); 472 WriteFixed64NoTag(value, output); 473} 474void WireFormatLite::WriteSFixed32(int field_number, int32 value, 475 io::CodedOutputStream* output) { 476 WriteTag(field_number, WIRETYPE_FIXED32, output); 477 WriteSFixed32NoTag(value, output); 478} 479void WireFormatLite::WriteSFixed64(int field_number, int64 value, 480 io::CodedOutputStream* output) { 481 WriteTag(field_number, WIRETYPE_FIXED64, output); 482 WriteSFixed64NoTag(value, output); 483} 484void WireFormatLite::WriteFloat(int field_number, float value, 485 io::CodedOutputStream* output) { 486 WriteTag(field_number, WIRETYPE_FIXED32, output); 487 WriteFloatNoTag(value, output); 488} 489void WireFormatLite::WriteDouble(int field_number, double value, 490 io::CodedOutputStream* output) { 491 WriteTag(field_number, WIRETYPE_FIXED64, output); 492 WriteDoubleNoTag(value, output); 493} 494void WireFormatLite::WriteBool(int field_number, bool value, 495 io::CodedOutputStream* output) { 496 WriteTag(field_number, WIRETYPE_VARINT, output); 497 WriteBoolNoTag(value, output); 498} 499void WireFormatLite::WriteEnum(int field_number, int value, 500 io::CodedOutputStream* output) { 501 WriteTag(field_number, WIRETYPE_VARINT, output); 502 WriteEnumNoTag(value, output); 503} 504 505void 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} 513void 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 522void 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 530void 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 539void 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 554void 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 569bool 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} 577bool 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