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