1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 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 // wink (at) google.com (Wink Saville) (refactored from wire_format.h) 33 // Based on original Protocol Buffers design by 34 // Sanjay Ghemawat, Jeff Dean, and others. 35 36 #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ 37 #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ 38 39 #ifdef _MSC_VER 40 // This is required for min/max on VS2013 only. 41 #include <algorithm> 42 #endif 43 44 #include <string> 45 #include <google/protobuf/stubs/common.h> 46 #include <google/protobuf/stubs/logging.h> 47 #include <google/protobuf/message_lite.h> 48 #include <google/protobuf/repeated_field.h> 49 #include <google/protobuf/wire_format_lite.h> 50 #include <google/protobuf/io/coded_stream.h> 51 #include <google/protobuf/arenastring.h> 52 53 54 namespace google { 55 namespace protobuf { 56 namespace internal { 57 58 // Implementation details of ReadPrimitive. 59 60 template <> 61 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>( 62 io::CodedInputStream* input, 63 int32* value) { 64 uint32 temp; 65 if (!input->ReadVarint32(&temp)) return false; 66 *value = static_cast<int32>(temp); 67 return true; 68 } 69 template <> 70 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>( 71 io::CodedInputStream* input, 72 int64* value) { 73 uint64 temp; 74 if (!input->ReadVarint64(&temp)) return false; 75 *value = static_cast<int64>(temp); 76 return true; 77 } 78 template <> 79 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>( 80 io::CodedInputStream* input, 81 uint32* value) { 82 return input->ReadVarint32(value); 83 } 84 template <> 85 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>( 86 io::CodedInputStream* input, 87 uint64* value) { 88 return input->ReadVarint64(value); 89 } 90 template <> 91 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>( 92 io::CodedInputStream* input, 93 int32* value) { 94 uint32 temp; 95 if (!input->ReadVarint32(&temp)) return false; 96 *value = ZigZagDecode32(temp); 97 return true; 98 } 99 template <> 100 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>( 101 io::CodedInputStream* input, 102 int64* value) { 103 uint64 temp; 104 if (!input->ReadVarint64(&temp)) return false; 105 *value = ZigZagDecode64(temp); 106 return true; 107 } 108 template <> 109 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>( 110 io::CodedInputStream* input, 111 uint32* value) { 112 return input->ReadLittleEndian32(value); 113 } 114 template <> 115 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>( 116 io::CodedInputStream* input, 117 uint64* value) { 118 return input->ReadLittleEndian64(value); 119 } 120 template <> 121 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>( 122 io::CodedInputStream* input, 123 int32* value) { 124 uint32 temp; 125 if (!input->ReadLittleEndian32(&temp)) return false; 126 *value = static_cast<int32>(temp); 127 return true; 128 } 129 template <> 130 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>( 131 io::CodedInputStream* input, 132 int64* value) { 133 uint64 temp; 134 if (!input->ReadLittleEndian64(&temp)) return false; 135 *value = static_cast<int64>(temp); 136 return true; 137 } 138 template <> 139 inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>( 140 io::CodedInputStream* input, 141 float* value) { 142 uint32 temp; 143 if (!input->ReadLittleEndian32(&temp)) return false; 144 *value = DecodeFloat(temp); 145 return true; 146 } 147 template <> 148 inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>( 149 io::CodedInputStream* input, 150 double* value) { 151 uint64 temp; 152 if (!input->ReadLittleEndian64(&temp)) return false; 153 *value = DecodeDouble(temp); 154 return true; 155 } 156 template <> 157 inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>( 158 io::CodedInputStream* input, 159 bool* value) { 160 uint64 temp; 161 if (!input->ReadVarint64(&temp)) return false; 162 *value = temp != 0; 163 return true; 164 } 165 template <> 166 inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( 167 io::CodedInputStream* input, 168 int* value) { 169 uint32 temp; 170 if (!input->ReadVarint32(&temp)) return false; 171 *value = static_cast<int>(temp); 172 return true; 173 } 174 175 template <> 176 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 177 uint32, WireFormatLite::TYPE_FIXED32>( 178 const uint8* buffer, 179 uint32* value) { 180 return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value); 181 } 182 template <> 183 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 184 uint64, WireFormatLite::TYPE_FIXED64>( 185 const uint8* buffer, 186 uint64* value) { 187 return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value); 188 } 189 template <> 190 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 191 int32, WireFormatLite::TYPE_SFIXED32>( 192 const uint8* buffer, 193 int32* value) { 194 uint32 temp; 195 buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); 196 *value = static_cast<int32>(temp); 197 return buffer; 198 } 199 template <> 200 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 201 int64, WireFormatLite::TYPE_SFIXED64>( 202 const uint8* buffer, 203 int64* value) { 204 uint64 temp; 205 buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); 206 *value = static_cast<int64>(temp); 207 return buffer; 208 } 209 template <> 210 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 211 float, WireFormatLite::TYPE_FLOAT>( 212 const uint8* buffer, 213 float* value) { 214 uint32 temp; 215 buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp); 216 *value = DecodeFloat(temp); 217 return buffer; 218 } 219 template <> 220 inline const uint8* WireFormatLite::ReadPrimitiveFromArray< 221 double, WireFormatLite::TYPE_DOUBLE>( 222 const uint8* buffer, 223 double* value) { 224 uint64 temp; 225 buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp); 226 *value = DecodeDouble(temp); 227 return buffer; 228 } 229 230 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 231 inline bool WireFormatLite::ReadRepeatedPrimitive( 232 int, // tag_size, unused. 233 uint32 tag, 234 io::CodedInputStream* input, 235 RepeatedField<CType>* values) { 236 CType value; 237 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; 238 values->Add(value); 239 int elements_already_reserved = values->Capacity() - values->size(); 240 while (elements_already_reserved > 0 && input->ExpectTag(tag)) { 241 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; 242 values->AddAlreadyReserved(value); 243 elements_already_reserved--; 244 } 245 return true; 246 } 247 248 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 249 inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive( 250 int tag_size, 251 uint32 tag, 252 io::CodedInputStream* input, 253 RepeatedField<CType>* values) { 254 GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size); 255 CType value; 256 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) 257 return false; 258 values->Add(value); 259 260 // For fixed size values, repeated values can be read more quickly by 261 // reading directly from a raw array. 262 // 263 // We can get a tight loop by only reading as many elements as can be 264 // added to the RepeatedField without having to do any resizing. Additionally, 265 // we only try to read as many elements as are available from the current 266 // buffer space. Doing so avoids having to perform boundary checks when 267 // reading the value: the maximum number of elements that can be read is 268 // known outside of the loop. 269 const void* void_pointer; 270 int size; 271 input->GetDirectBufferPointerInline(&void_pointer, &size); 272 if (size > 0) { 273 const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer); 274 // The number of bytes each type occupies on the wire. 275 const int per_value_size = tag_size + sizeof(value); 276 277 int elements_available = 278 std::min(values->Capacity() - values->size(), size / per_value_size); 279 int num_read = 0; 280 while (num_read < elements_available && 281 (buffer = io::CodedInputStream::ExpectTagFromArray( 282 buffer, tag)) != NULL) { 283 buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value); 284 values->AddAlreadyReserved(value); 285 ++num_read; 286 } 287 const int read_bytes = num_read * per_value_size; 288 if (read_bytes > 0) { 289 input->Skip(read_bytes); 290 } 291 } 292 return true; 293 } 294 295 // Specializations of ReadRepeatedPrimitive for the fixed size types, which use 296 // the optimized code path. 297 #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ 298 template <> \ 299 inline bool WireFormatLite::ReadRepeatedPrimitive< \ 300 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ 301 int tag_size, \ 302 uint32 tag, \ 303 io::CodedInputStream* input, \ 304 RepeatedField<CPPTYPE>* values) { \ 305 return ReadRepeatedFixedSizePrimitive< \ 306 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ 307 tag_size, tag, input, values); \ 308 } 309 310 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) 311 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) 312 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) 313 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) 314 READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) 315 READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) 316 317 #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE 318 319 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 320 bool WireFormatLite::ReadRepeatedPrimitiveNoInline( 321 int tag_size, 322 uint32 tag, 323 io::CodedInputStream* input, 324 RepeatedField<CType>* value) { 325 return ReadRepeatedPrimitive<CType, DeclaredType>( 326 tag_size, tag, input, value); 327 } 328 329 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 330 inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input, 331 RepeatedField<CType>* values) { 332 uint32 length; 333 if (!input->ReadVarint32(&length)) return false; 334 io::CodedInputStream::Limit limit = input->PushLimit(length); 335 while (input->BytesUntilLimit() > 0) { 336 CType value; 337 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; 338 values->Add(value); 339 } 340 input->PopLimit(limit); 341 return true; 342 } 343 344 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 345 inline bool WireFormatLite::ReadPackedFixedSizePrimitive( 346 io::CodedInputStream* input, RepeatedField<CType>* values) { 347 uint32 length; 348 if (!input->ReadVarint32(&length)) return false; 349 const uint32 old_entries = values->size(); 350 const uint32 new_entries = length / sizeof(CType); 351 const uint32 new_bytes = new_entries * sizeof(CType); 352 if (new_bytes != length) return false; 353 // We would *like* to pre-allocate the buffer to write into (for 354 // speed), but *must* avoid performing a very large allocation due 355 // to a malicious user-supplied "length" above. So we have a fast 356 // path that pre-allocates when the "length" is less than a bound. 357 // We determine the bound by calling BytesUntilTotalBytesLimit() and 358 // BytesUntilLimit(). These return -1 to mean "no limit set". 359 // There are four cases: 360 // TotalBytesLimit Limit 361 // -1 -1 Use slow path. 362 // -1 >= 0 Use fast path if length <= Limit. 363 // >= 0 -1 Use slow path. 364 // >= 0 >= 0 Use fast path if length <= min(both limits). 365 int64 bytes_limit = input->BytesUntilTotalBytesLimit(); 366 if (bytes_limit == -1) { 367 bytes_limit = input->BytesUntilLimit(); 368 } else { 369 bytes_limit = 370 std::min(bytes_limit, static_cast<int64>(input->BytesUntilLimit())); 371 } 372 if (bytes_limit >= new_bytes) { 373 // Fast-path that pre-allocates *values to the final size. 374 #if defined(PROTOBUF_LITTLE_ENDIAN) 375 values->Resize(old_entries + new_entries, 0); 376 // values->mutable_data() may change after Resize(), so do this after: 377 void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries); 378 if (!input->ReadRaw(dest, new_bytes)) { 379 values->Truncate(old_entries); 380 return false; 381 } 382 #else 383 values->Reserve(old_entries + new_entries); 384 CType value; 385 for (uint32 i = 0; i < new_entries; ++i) { 386 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; 387 values->AddAlreadyReserved(value); 388 } 389 #endif 390 } else { 391 // This is the slow-path case where "length" may be too large to 392 // safely allocate. We read as much as we can into *values 393 // without pre-allocating "length" bytes. 394 CType value; 395 for (uint32 i = 0; i < new_entries; ++i) { 396 if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false; 397 values->Add(value); 398 } 399 } 400 return true; 401 } 402 403 // Specializations of ReadPackedPrimitive for the fixed size types, which use 404 // an optimized code path. 405 #define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \ 406 template <> \ 407 inline bool WireFormatLite::ReadPackedPrimitive< \ 408 CPPTYPE, WireFormatLite::DECLARED_TYPE>( \ 409 io::CodedInputStream* input, \ 410 RepeatedField<CPPTYPE>* values) { \ 411 return ReadPackedFixedSizePrimitive< \ 412 CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values); \ 413 } 414 415 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32) 416 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64) 417 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32) 418 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64) 419 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT) 420 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE) 421 422 #undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE 423 424 template <typename CType, enum WireFormatLite::FieldType DeclaredType> 425 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input, 426 RepeatedField<CType>* values) { 427 return ReadPackedPrimitive<CType, DeclaredType>(input, values); 428 } 429 430 431 432 inline bool WireFormatLite::ReadGroup(int field_number, 433 io::CodedInputStream* input, 434 MessageLite* value) { 435 if (!input->IncrementRecursionDepth()) return false; 436 if (!value->MergePartialFromCodedStream(input)) return false; 437 input->DecrementRecursionDepth(); 438 // Make sure the last thing read was an end tag for this group. 439 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { 440 return false; 441 } 442 return true; 443 } 444 inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, 445 MessageLite* value) { 446 uint32 length; 447 if (!input->ReadVarint32(&length)) return false; 448 std::pair<io::CodedInputStream::Limit, int> p = 449 input->IncrementRecursionDepthAndPushLimit(length); 450 if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false; 451 // Make sure that parsing stopped when the limit was hit, not at an endgroup 452 // tag. 453 return input->DecrementRecursionDepthAndPopLimit(p.first); 454 } 455 456 // We name the template parameter something long and extremely unlikely to occur 457 // elsewhere because a *qualified* member access expression designed to avoid 458 // virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the 459 // name of the qualifying class to be looked up both in the context of the full 460 // expression (finding the template parameter) and in the context of the object 461 // whose member we are accessing. This could potentially find a nested type 462 // within that object. The standard goes on to require these names to refer to 463 // the same entity, which this collision would violate. The lack of a safe way 464 // to avoid this collision appears to be a defect in the standard, but until it 465 // is corrected, we choose the name to avoid accidental collisions. 466 template<typename MessageType_WorkAroundCppLookupDefect> 467 inline bool WireFormatLite::ReadGroupNoVirtual( 468 int field_number, io::CodedInputStream* input, 469 MessageType_WorkAroundCppLookupDefect* value) { 470 if (!input->IncrementRecursionDepth()) return false; 471 if (!value-> 472 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) 473 return false; 474 input->UnsafeDecrementRecursionDepth(); 475 // Make sure the last thing read was an end tag for this group. 476 if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { 477 return false; 478 } 479 return true; 480 } 481 template<typename MessageType_WorkAroundCppLookupDefect> 482 inline bool WireFormatLite::ReadGroupNoVirtualNoRecursionDepth( 483 int field_number, io::CodedInputStream* input, 484 MessageType_WorkAroundCppLookupDefect* value) { 485 return value->MessageType_WorkAroundCppLookupDefect:: 486 MergePartialFromCodedStream(input) && 487 input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP)); 488 } 489 template<typename MessageType_WorkAroundCppLookupDefect> 490 inline bool WireFormatLite::ReadMessageNoVirtual( 491 io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { 492 uint32 length; 493 if (!input->ReadVarint32(&length)) return false; 494 std::pair<io::CodedInputStream::Limit, int> p = 495 input->IncrementRecursionDepthAndPushLimit(length); 496 if (p.second < 0 || !value-> 497 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) 498 return false; 499 // Make sure that parsing stopped when the limit was hit, not at an endgroup 500 // tag. 501 return input->DecrementRecursionDepthAndPopLimit(p.first); 502 } 503 template<typename MessageType_WorkAroundCppLookupDefect> 504 inline bool WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( 505 io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { 506 io::CodedInputStream::Limit old_limit = input->ReadLengthAndPushLimit(); 507 if (!value-> 508 MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) 509 return false; 510 // Make sure that parsing stopped when the limit was hit, not at an endgroup 511 // tag. 512 return input->CheckEntireMessageConsumedAndPopLimit(old_limit); 513 } 514 515 // =================================================================== 516 517 inline void WireFormatLite::WriteTag(int field_number, WireType type, 518 io::CodedOutputStream* output) { 519 output->WriteTag(MakeTag(field_number, type)); 520 } 521 522 inline void WireFormatLite::WriteInt32NoTag(int32 value, 523 io::CodedOutputStream* output) { 524 output->WriteVarint32SignExtended(value); 525 } 526 inline void WireFormatLite::WriteInt64NoTag(int64 value, 527 io::CodedOutputStream* output) { 528 output->WriteVarint64(static_cast<uint64>(value)); 529 } 530 inline void WireFormatLite::WriteUInt32NoTag(uint32 value, 531 io::CodedOutputStream* output) { 532 output->WriteVarint32(value); 533 } 534 inline void WireFormatLite::WriteUInt64NoTag(uint64 value, 535 io::CodedOutputStream* output) { 536 output->WriteVarint64(value); 537 } 538 inline void WireFormatLite::WriteSInt32NoTag(int32 value, 539 io::CodedOutputStream* output) { 540 output->WriteVarint32(ZigZagEncode32(value)); 541 } 542 inline void WireFormatLite::WriteSInt64NoTag(int64 value, 543 io::CodedOutputStream* output) { 544 output->WriteVarint64(ZigZagEncode64(value)); 545 } 546 inline void WireFormatLite::WriteFixed32NoTag(uint32 value, 547 io::CodedOutputStream* output) { 548 output->WriteLittleEndian32(value); 549 } 550 inline void WireFormatLite::WriteFixed64NoTag(uint64 value, 551 io::CodedOutputStream* output) { 552 output->WriteLittleEndian64(value); 553 } 554 inline void WireFormatLite::WriteSFixed32NoTag(int32 value, 555 io::CodedOutputStream* output) { 556 output->WriteLittleEndian32(static_cast<uint32>(value)); 557 } 558 inline void WireFormatLite::WriteSFixed64NoTag(int64 value, 559 io::CodedOutputStream* output) { 560 output->WriteLittleEndian64(static_cast<uint64>(value)); 561 } 562 inline void WireFormatLite::WriteFloatNoTag(float value, 563 io::CodedOutputStream* output) { 564 output->WriteLittleEndian32(EncodeFloat(value)); 565 } 566 inline void WireFormatLite::WriteDoubleNoTag(double value, 567 io::CodedOutputStream* output) { 568 output->WriteLittleEndian64(EncodeDouble(value)); 569 } 570 inline void WireFormatLite::WriteBoolNoTag(bool value, 571 io::CodedOutputStream* output) { 572 output->WriteVarint32(value ? 1 : 0); 573 } 574 inline void WireFormatLite::WriteEnumNoTag(int value, 575 io::CodedOutputStream* output) { 576 output->WriteVarint32SignExtended(value); 577 } 578 579 // See comment on ReadGroupNoVirtual to understand the need for this template 580 // parameter name. 581 template<typename MessageType_WorkAroundCppLookupDefect> 582 inline void WireFormatLite::WriteGroupNoVirtual( 583 int field_number, const MessageType_WorkAroundCppLookupDefect& value, 584 io::CodedOutputStream* output) { 585 WriteTag(field_number, WIRETYPE_START_GROUP, output); 586 value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); 587 WriteTag(field_number, WIRETYPE_END_GROUP, output); 588 } 589 template<typename MessageType_WorkAroundCppLookupDefect> 590 inline void WireFormatLite::WriteMessageNoVirtual( 591 int field_number, const MessageType_WorkAroundCppLookupDefect& value, 592 io::CodedOutputStream* output) { 593 WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); 594 output->WriteVarint32( 595 value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()); 596 value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); 597 } 598 599 // =================================================================== 600 601 inline uint8* WireFormatLite::WriteTagToArray(int field_number, 602 WireType type, 603 uint8* target) { 604 return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type), 605 target); 606 } 607 608 inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value, 609 uint8* target) { 610 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); 611 } 612 inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value, 613 uint8* target) { 614 return io::CodedOutputStream::WriteVarint64ToArray( 615 static_cast<uint64>(value), target); 616 } 617 inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value, 618 uint8* target) { 619 return io::CodedOutputStream::WriteVarint32ToArray(value, target); 620 } 621 inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value, 622 uint8* target) { 623 return io::CodedOutputStream::WriteVarint64ToArray(value, target); 624 } 625 inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value, 626 uint8* target) { 627 return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value), 628 target); 629 } 630 inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value, 631 uint8* target) { 632 return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value), 633 target); 634 } 635 inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value, 636 uint8* target) { 637 return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target); 638 } 639 inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value, 640 uint8* target) { 641 return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target); 642 } 643 inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value, 644 uint8* target) { 645 return io::CodedOutputStream::WriteLittleEndian32ToArray( 646 static_cast<uint32>(value), target); 647 } 648 inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value, 649 uint8* target) { 650 return io::CodedOutputStream::WriteLittleEndian64ToArray( 651 static_cast<uint64>(value), target); 652 } 653 inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value, 654 uint8* target) { 655 return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value), 656 target); 657 } 658 inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value, 659 uint8* target) { 660 return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value), 661 target); 662 } 663 inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, 664 uint8* target) { 665 return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target); 666 } 667 inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, 668 uint8* target) { 669 return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); 670 } 671 672 inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, 673 int32 value, 674 uint8* target) { 675 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 676 return WriteInt32NoTagToArray(value, target); 677 } 678 inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, 679 int64 value, 680 uint8* target) { 681 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 682 return WriteInt64NoTagToArray(value, target); 683 } 684 inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, 685 uint32 value, 686 uint8* target) { 687 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 688 return WriteUInt32NoTagToArray(value, target); 689 } 690 inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, 691 uint64 value, 692 uint8* target) { 693 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 694 return WriteUInt64NoTagToArray(value, target); 695 } 696 inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, 697 int32 value, 698 uint8* target) { 699 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 700 return WriteSInt32NoTagToArray(value, target); 701 } 702 inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, 703 int64 value, 704 uint8* target) { 705 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 706 return WriteSInt64NoTagToArray(value, target); 707 } 708 inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number, 709 uint32 value, 710 uint8* target) { 711 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); 712 return WriteFixed32NoTagToArray(value, target); 713 } 714 inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number, 715 uint64 value, 716 uint8* target) { 717 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); 718 return WriteFixed64NoTagToArray(value, target); 719 } 720 inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number, 721 int32 value, 722 uint8* target) { 723 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); 724 return WriteSFixed32NoTagToArray(value, target); 725 } 726 inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number, 727 int64 value, 728 uint8* target) { 729 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); 730 return WriteSFixed64NoTagToArray(value, target); 731 } 732 inline uint8* WireFormatLite::WriteFloatToArray(int field_number, 733 float value, 734 uint8* target) { 735 target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target); 736 return WriteFloatNoTagToArray(value, target); 737 } 738 inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, 739 double value, 740 uint8* target) { 741 target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target); 742 return WriteDoubleNoTagToArray(value, target); 743 } 744 inline uint8* WireFormatLite::WriteBoolToArray(int field_number, 745 bool value, 746 uint8* target) { 747 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 748 return WriteBoolNoTagToArray(value, target); 749 } 750 inline uint8* WireFormatLite::WriteEnumToArray(int field_number, 751 int value, 752 uint8* target) { 753 target = WriteTagToArray(field_number, WIRETYPE_VARINT, target); 754 return WriteEnumNoTagToArray(value, target); 755 } 756 757 inline uint8* WireFormatLite::WriteStringToArray(int field_number, 758 const string& value, 759 uint8* target) { 760 // String is for UTF-8 text only 761 // WARNING: In wire_format.cc, both strings and bytes are handled by 762 // WriteString() to avoid code duplication. If the implementations become 763 // different, you will need to update that usage. 764 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); 765 return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); 766 } 767 inline uint8* WireFormatLite::WriteBytesToArray(int field_number, 768 const string& value, 769 uint8* target) { 770 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); 771 return io::CodedOutputStream::WriteStringWithSizeToArray(value, target); 772 } 773 774 775 inline uint8* WireFormatLite::WriteGroupToArray(int field_number, 776 const MessageLite& value, 777 uint8* target) { 778 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); 779 target = value.SerializeWithCachedSizesToArray(target); 780 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); 781 } 782 inline uint8* WireFormatLite::WriteMessageToArray(int field_number, 783 const MessageLite& value, 784 uint8* target) { 785 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); 786 target = io::CodedOutputStream::WriteVarint32ToArray( 787 value.GetCachedSize(), target); 788 return value.SerializeWithCachedSizesToArray(target); 789 } 790 791 // See comment on ReadGroupNoVirtual to understand the need for this template 792 // parameter name. 793 template<typename MessageType_WorkAroundCppLookupDefect> 794 inline uint8* WireFormatLite::WriteGroupNoVirtualToArray( 795 int field_number, const MessageType_WorkAroundCppLookupDefect& value, 796 uint8* target) { 797 target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); 798 target = value.MessageType_WorkAroundCppLookupDefect 799 ::SerializeWithCachedSizesToArray(target); 800 return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); 801 } 802 template<typename MessageType_WorkAroundCppLookupDefect> 803 inline uint8* WireFormatLite::WriteMessageNoVirtualToArray( 804 int field_number, const MessageType_WorkAroundCppLookupDefect& value, 805 uint8* target) { 806 target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); 807 target = io::CodedOutputStream::WriteVarint32ToArray( 808 value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target); 809 return value.MessageType_WorkAroundCppLookupDefect 810 ::SerializeWithCachedSizesToArray(target); 811 } 812 813 // =================================================================== 814 815 inline int WireFormatLite::Int32Size(int32 value) { 816 return io::CodedOutputStream::VarintSize32SignExtended(value); 817 } 818 inline int WireFormatLite::Int64Size(int64 value) { 819 return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value)); 820 } 821 inline int WireFormatLite::UInt32Size(uint32 value) { 822 return io::CodedOutputStream::VarintSize32(value); 823 } 824 inline int WireFormatLite::UInt64Size(uint64 value) { 825 return io::CodedOutputStream::VarintSize64(value); 826 } 827 inline int WireFormatLite::SInt32Size(int32 value) { 828 return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); 829 } 830 inline int WireFormatLite::SInt64Size(int64 value) { 831 return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); 832 } 833 inline int WireFormatLite::EnumSize(int value) { 834 return io::CodedOutputStream::VarintSize32SignExtended(value); 835 } 836 837 inline int WireFormatLite::StringSize(const string& value) { 838 return static_cast<int>( 839 io::CodedOutputStream::VarintSize32(static_cast<uint32>(value.size())) + 840 value.size()); 841 } 842 inline int WireFormatLite::BytesSize(const string& value) { 843 return static_cast<int>( 844 io::CodedOutputStream::VarintSize32(static_cast<uint32>(value.size())) + 845 value.size()); 846 } 847 848 849 inline int WireFormatLite::GroupSize(const MessageLite& value) { 850 return value.ByteSize(); 851 } 852 inline int WireFormatLite::MessageSize(const MessageLite& value) { 853 return LengthDelimitedSize(value.ByteSize()); 854 } 855 856 // See comment on ReadGroupNoVirtual to understand the need for this template 857 // parameter name. 858 template<typename MessageType_WorkAroundCppLookupDefect> 859 inline int WireFormatLite::GroupSizeNoVirtual( 860 const MessageType_WorkAroundCppLookupDefect& value) { 861 return value.MessageType_WorkAroundCppLookupDefect::ByteSize(); 862 } 863 template<typename MessageType_WorkAroundCppLookupDefect> 864 inline int WireFormatLite::MessageSizeNoVirtual( 865 const MessageType_WorkAroundCppLookupDefect& value) { 866 return LengthDelimitedSize( 867 value.MessageType_WorkAroundCppLookupDefect::ByteSize()); 868 } 869 870 inline int WireFormatLite::LengthDelimitedSize(int length) { 871 return io::CodedOutputStream::VarintSize32(length) + length; 872 } 873 874 } // namespace internal 875 } // namespace protobuf 876 877 } // namespace google 878 #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ 879