OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 // _inl.h) | 148 // _inl.h) |
149 // | 149 // |
150 // This is different from MakeTag(field->number(), field->type()) in the case | 150 // This is different from MakeTag(field->number(), field->type()) in the case |
151 // of packed repeated fields. | 151 // of packed repeated fields. |
152 static uint32 MakeTag(int field_number, WireType type); | 152 static uint32 MakeTag(int field_number, WireType type); |
153 static WireType GetTagWireType(uint32 tag); | 153 static WireType GetTagWireType(uint32 tag); |
154 static int GetTagFieldNumber(uint32 tag); | 154 static int GetTagFieldNumber(uint32 tag); |
155 | 155 |
156 // Compute the byte size of a tag. For groups, this includes both the start | 156 // Compute the byte size of a tag. For groups, this includes both the start |
157 // and end tags. | 157 // and end tags. |
158 static inline int TagSize(int field_number, WireFormatLite::FieldType type); | 158 static inline size_t TagSize(int field_number, |
| 159 WireFormatLite::FieldType type); |
159 | 160 |
160 // Skips a field value with the given tag. The input should start | 161 // Skips a field value with the given tag. The input should start |
161 // positioned immediately after the tag. Skipped values are simply discarded, | 162 // positioned immediately after the tag. Skipped values are simply discarded, |
162 // not recorded anywhere. See WireFormat::SkipField() for a version that | 163 // not recorded anywhere. See WireFormat::SkipField() for a version that |
163 // records to an UnknownFieldSet. | 164 // records to an UnknownFieldSet. |
164 static bool SkipField(io::CodedInputStream* input, uint32 tag); | 165 static bool SkipField(io::CodedInputStream* input, uint32 tag); |
165 | 166 |
166 // Skips a field value with the given tag. The input should start | 167 // Skips a field value with the given tag. The input should start |
167 // positioned immediately after the tag. Skipped values are recorded to a | 168 // positioned immediately after the tag. Skipped values are recorded to a |
168 // CodedOutputStream. | 169 // CodedOutputStream. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, | 206 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber, |
206 WireFormatLite::WIRETYPE_END_GROUP); | 207 WireFormatLite::WIRETYPE_END_GROUP); |
207 static const int kMessageSetTypeIdTag = | 208 static const int kMessageSetTypeIdTag = |
208 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber, | 209 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber, |
209 WireFormatLite::WIRETYPE_VARINT); | 210 WireFormatLite::WIRETYPE_VARINT); |
210 static const int kMessageSetMessageTag = | 211 static const int kMessageSetMessageTag = |
211 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber, | 212 GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber, |
212 WireFormatLite::WIRETYPE_LENGTH_DELIMITED); | 213 WireFormatLite::WIRETYPE_LENGTH_DELIMITED); |
213 | 214 |
214 // Byte size of all tags of a MessageSet::Item combined. | 215 // Byte size of all tags of a MessageSet::Item combined. |
215 static const int kMessageSetItemTagsSize; | 216 static const size_t kMessageSetItemTagsSize; |
216 | 217 |
217 // Helper functions for converting between floats/doubles and IEEE-754 | 218 // Helper functions for converting between floats/doubles and IEEE-754 |
218 // uint32s/uint64s so that they can be written. (Assumes your platform | 219 // uint32s/uint64s so that they can be written. (Assumes your platform |
219 // uses IEEE-754 floats.) | 220 // uses IEEE-754 floats.) |
220 static uint32 EncodeFloat(float value); | 221 static uint32 EncodeFloat(float value); |
221 static float DecodeFloat(uint32 value); | 222 static float DecodeFloat(uint32 value); |
222 static uint64 EncodeDouble(double value); | 223 static uint64 EncodeDouble(double value); |
223 static double DecodeDouble(uint64 value); | 224 static double DecodeDouble(uint64 value); |
224 | 225 |
225 // Helper functions for mapping signed integers to unsigned integers in | 226 // Helper functions for mapping signed integers to unsigned integers in |
226 // such a way that numbers with small magnitudes will encode to smaller | 227 // such a way that numbers with small magnitudes will encode to smaller |
227 // varints. If you simply static_cast a negative number to an unsigned | 228 // varints. If you simply static_cast a negative number to an unsigned |
228 // number and varint-encode it, it will always take 10 bytes, defeating | 229 // number and varint-encode it, it will always take 10 bytes, defeating |
229 // the purpose of varint. So, for the "sint32" and "sint64" field types, | 230 // the purpose of varint. So, for the "sint32" and "sint64" field types, |
230 // we ZigZag-encode the values. | 231 // we ZigZag-encode the values. |
231 static uint32 ZigZagEncode32(int32 n); | 232 static uint32 ZigZagEncode32(int32 n); |
232 static int32 ZigZagDecode32(uint32 n); | 233 static int32 ZigZagDecode32(uint32 n); |
233 static uint64 ZigZagEncode64(int64 n); | 234 static uint64 ZigZagEncode64(int64 n); |
234 static int64 ZigZagDecode64(uint64 n); | 235 static int64 ZigZagDecode64(uint64 n); |
235 | 236 |
236 // ================================================================= | 237 // ================================================================= |
237 // Methods for reading/writing individual field. The implementations | 238 // Methods for reading/writing individual field. The implementations |
238 // of these methods are defined in wire_format_lite_inl.h; you must #include | 239 // of these methods are defined in wire_format_lite_inl.h; you must #include |
239 // that file to use these. | 240 // that file to use these. |
240 | 241 |
241 // Avoid ugly line wrapping | 242 // Avoid ugly line wrapping |
242 #define input io::CodedInputStream* input_arg | 243 #define input io::CodedInputStream* input_arg |
243 #define output io::CodedOutputStream* output_arg | 244 #define output io::CodedOutputStream* output_arg |
244 #define field_number int field_number_arg | 245 #define field_number int field_number_arg |
| 246 #ifdef NDEBUG |
245 #define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE | 247 #define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE |
| 248 #else |
| 249 // Avoid excessive inlining in non-optimized builds. Without other optimizations |
| 250 // the inlining is not going to provide benefits anyway and the huge resulting |
| 251 // functions, especially in the proto-generated serialization functions, produce |
| 252 // stack frames so large that many tests run into stack overflows (b/32192897). |
| 253 #define INL |
| 254 #endif |
246 | 255 |
247 // Read fields, not including tags. The assumption is that you already | 256 // Read fields, not including tags. The assumption is that you already |
248 // read the tag to determine what field to read. | 257 // read the tag to determine what field to read. |
249 | 258 |
250 // For primitive fields, we just use a templatized routine parameterized by | 259 // For primitive fields, we just use a templatized routine parameterized by |
251 // the represented type and the FieldType. These are specialized with the | 260 // the represented type and the FieldType. These are specialized with the |
252 // appropriate definition for each declared type. | 261 // appropriate definition for each declared type. |
253 template <typename CType, enum FieldType DeclaredType> INL | 262 template <typename CType, enum FieldType DeclaredType> INL |
254 static bool ReadPrimitive(input, CType* value); | 263 static bool ReadPrimitive(input, CType* value); |
255 | 264 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 INL static uint8* WriteFloatToArray(field_number, float value, output); | 459 INL static uint8* WriteFloatToArray(field_number, float value, output); |
451 INL static uint8* WriteDoubleToArray(field_number, double value, output); | 460 INL static uint8* WriteDoubleToArray(field_number, double value, output); |
452 INL static uint8* WriteBoolToArray(field_number, bool value, output); | 461 INL static uint8* WriteBoolToArray(field_number, bool value, output); |
453 INL static uint8* WriteEnumToArray(field_number, int value, output); | 462 INL static uint8* WriteEnumToArray(field_number, int value, output); |
454 | 463 |
455 INL static uint8* WriteStringToArray( | 464 INL static uint8* WriteStringToArray( |
456 field_number, const string& value, output); | 465 field_number, const string& value, output); |
457 INL static uint8* WriteBytesToArray( | 466 INL static uint8* WriteBytesToArray( |
458 field_number, const string& value, output); | 467 field_number, const string& value, output); |
459 | 468 |
460 INL static uint8* WriteGroupToArray( | 469 // Whether to serialize deterministically (e.g., map keys are |
461 field_number, const MessageLite& value, output); | 470 // sorted) is a property of a CodedOutputStream, and in the process |
462 INL static uint8* WriteMessageToArray( | 471 // of serialization, the "ToArray" variants may be invoked. But they don't |
463 field_number, const MessageLite& value, output); | 472 // have a CodedOutputStream available, so they get an additional parameter |
| 473 // telling them whether to serialize deterministically. |
| 474 INL static uint8* InternalWriteGroupToArray( |
| 475 field_number, const MessageLite& value, bool deterministic, output); |
| 476 INL static uint8* InternalWriteMessageToArray( |
| 477 field_number, const MessageLite& value, bool deterministic, output); |
464 | 478 |
465 // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The | 479 // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The |
466 // pointer must point at an instance of MessageType, *not* a subclass (or | 480 // pointer must point at an instance of MessageType, *not* a subclass (or |
467 // the subclass must not override SerializeWithCachedSizes()). | 481 // the subclass must not override SerializeWithCachedSizes()). |
468 template<typename MessageType> | 482 template<typename MessageType> |
| 483 INL static uint8* InternalWriteGroupNoVirtualToArray( |
| 484 field_number, const MessageType& value, bool deterministic, output); |
| 485 template<typename MessageType> |
| 486 INL static uint8* InternalWriteMessageNoVirtualToArray( |
| 487 field_number, const MessageType& value, bool deterministic, output); |
| 488 |
| 489 // For backward-compatibility, the last four methods also have versions |
| 490 // that are non-deterministic always. |
| 491 INL static uint8* WriteGroupToArray( |
| 492 field_number, const MessageLite& value, output) { |
| 493 return InternalWriteGroupToArray(field_number_arg, value, false, target); |
| 494 } |
| 495 INL static uint8* WriteMessageToArray( |
| 496 field_number, const MessageLite& value, output) { |
| 497 return InternalWriteMessageToArray(field_number_arg, value, false, target); |
| 498 } |
| 499 template<typename MessageType> |
469 INL static uint8* WriteGroupNoVirtualToArray( | 500 INL static uint8* WriteGroupNoVirtualToArray( |
470 field_number, const MessageType& value, output); | 501 field_number, const MessageType& value, output) { |
| 502 return InternalWriteGroupNoVirtualToArray(field_number_arg, value, false, |
| 503 target); |
| 504 } |
471 template<typename MessageType> | 505 template<typename MessageType> |
472 INL static uint8* WriteMessageNoVirtualToArray( | 506 INL static uint8* WriteMessageNoVirtualToArray( |
473 field_number, const MessageType& value, output); | 507 field_number, const MessageType& value, output) { |
| 508 return InternalWriteMessageNoVirtualToArray(field_number_arg, value, false, |
| 509 target); |
| 510 } |
474 | 511 |
475 #undef output | 512 #undef output |
476 #undef input | 513 #undef input |
477 #undef INL | 514 #undef INL |
478 | 515 |
479 #undef field_number | 516 #undef field_number |
480 | 517 |
481 // Compute the byte size of a field. The XxSize() functions do NOT include | 518 // Compute the byte size of a field. The XxSize() functions do NOT include |
482 // the tag, so you must also call TagSize(). (This is because, for repeated | 519 // the tag, so you must also call TagSize(). (This is because, for repeated |
483 // fields, you should only call TagSize() once and multiply it by the element | 520 // fields, you should only call TagSize() once and multiply it by the element |
484 // count, but you may have to call XxSize() for each individual element.) | 521 // count, but you may have to call XxSize() for each individual element.) |
485 static inline int Int32Size ( int32 value); | 522 static inline size_t Int32Size ( int32 value); |
486 static inline int Int64Size ( int64 value); | 523 static inline size_t Int64Size ( int64 value); |
487 static inline int UInt32Size (uint32 value); | 524 static inline size_t UInt32Size (uint32 value); |
488 static inline int UInt64Size (uint64 value); | 525 static inline size_t UInt64Size (uint64 value); |
489 static inline int SInt32Size ( int32 value); | 526 static inline size_t SInt32Size ( int32 value); |
490 static inline int SInt64Size ( int64 value); | 527 static inline size_t SInt64Size ( int64 value); |
491 static inline int EnumSize ( int value); | 528 static inline size_t EnumSize ( int value); |
492 | 529 |
493 // These types always have the same size. | 530 // These types always have the same size. |
494 static const int kFixed32Size = 4; | 531 static const size_t kFixed32Size = 4; |
495 static const int kFixed64Size = 8; | 532 static const size_t kFixed64Size = 8; |
496 static const int kSFixed32Size = 4; | 533 static const size_t kSFixed32Size = 4; |
497 static const int kSFixed64Size = 8; | 534 static const size_t kSFixed64Size = 8; |
498 static const int kFloatSize = 4; | 535 static const size_t kFloatSize = 4; |
499 static const int kDoubleSize = 8; | 536 static const size_t kDoubleSize = 8; |
500 static const int kBoolSize = 1; | 537 static const size_t kBoolSize = 1; |
501 | 538 |
502 static inline int StringSize(const string& value); | 539 static inline size_t StringSize(const string& value); |
503 static inline int BytesSize (const string& value); | 540 static inline size_t BytesSize (const string& value); |
504 | 541 |
505 static inline int GroupSize (const MessageLite& value); | 542 static inline size_t GroupSize (const MessageLite& value); |
506 static inline int MessageSize(const MessageLite& value); | 543 static inline size_t MessageSize(const MessageLite& value); |
507 | 544 |
508 // Like above, but de-virtualize the call to ByteSize(). The | 545 // Like above, but de-virtualize the call to ByteSize(). The |
509 // pointer must point at an instance of MessageType, *not* a subclass (or | 546 // pointer must point at an instance of MessageType, *not* a subclass (or |
510 // the subclass must not override ByteSize()). | 547 // the subclass must not override ByteSize()). |
511 template<typename MessageType> | 548 template<typename MessageType> |
512 static inline int GroupSizeNoVirtual (const MessageType& value); | 549 static inline size_t GroupSizeNoVirtual (const MessageType& value); |
513 template<typename MessageType> | 550 template<typename MessageType> |
514 static inline int MessageSizeNoVirtual(const MessageType& value); | 551 static inline size_t MessageSizeNoVirtual(const MessageType& value); |
515 | 552 |
516 // Given the length of data, calculate the byte size of the data on the | 553 // Given the length of data, calculate the byte size of the data on the |
517 // wire if we encode the data as a length delimited field. | 554 // wire if we encode the data as a length delimited field. |
518 static inline int LengthDelimitedSize(int length); | 555 static inline size_t LengthDelimitedSize(size_t length); |
519 | 556 |
520 private: | 557 private: |
521 // A helper method for the repeated primitive reader. This method has | 558 // A helper method for the repeated primitive reader. This method has |
522 // optimizations for primitive types that have fixed size on the wire, and | 559 // optimizations for primitive types that have fixed size on the wire, and |
523 // can be read using potentially faster paths. | 560 // can be read using potentially faster paths. |
524 template <typename CType, enum FieldType DeclaredType> GOOGLE_ATTRIBUTE_ALWAYS
_INLINE | 561 template <typename CType, enum FieldType DeclaredType> GOOGLE_ATTRIBUTE_ALWAYS
_INLINE |
525 static bool ReadRepeatedFixedSizePrimitive( | 562 static bool ReadRepeatedFixedSizePrimitive( |
526 int tag_size, | 563 int tag_size, |
527 uint32 tag, | 564 uint32 tag, |
528 google::protobuf::io::CodedInputStream* input, | 565 google::protobuf::io::CodedInputStream* input, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 } | 628 } |
592 | 629 |
593 inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { | 630 inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) { |
594 return static_cast<WireType>(tag & kTagTypeMask); | 631 return static_cast<WireType>(tag & kTagTypeMask); |
595 } | 632 } |
596 | 633 |
597 inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { | 634 inline int WireFormatLite::GetTagFieldNumber(uint32 tag) { |
598 return static_cast<int>(tag >> kTagTypeBits); | 635 return static_cast<int>(tag >> kTagTypeBits); |
599 } | 636 } |
600 | 637 |
601 inline int WireFormatLite::TagSize(int field_number, | 638 inline size_t WireFormatLite::TagSize(int field_number, |
602 WireFormatLite::FieldType type) { | 639 WireFormatLite::FieldType type) { |
603 int result = io::CodedOutputStream::VarintSize32( | 640 size_t result = io::CodedOutputStream::VarintSize32( |
604 field_number << kTagTypeBits); | 641 field_number << kTagTypeBits); |
605 if (type == TYPE_GROUP) { | 642 if (type == TYPE_GROUP) { |
606 // Groups have both a start and an end tag. | 643 // Groups have both a start and an end tag. |
607 return result * 2; | 644 return result * 2; |
608 } else { | 645 } else { |
609 return result; | 646 return result; |
610 } | 647 } |
611 } | 648 } |
612 | 649 |
613 inline uint32 WireFormatLite::EncodeFloat(float value) { | 650 inline uint32 WireFormatLite::EncodeFloat(float value) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 inline bool WireFormatLite::ReadString(io::CodedInputStream* input, | 724 inline bool WireFormatLite::ReadString(io::CodedInputStream* input, |
688 string** p) { | 725 string** p) { |
689 return ReadBytes(input, p); | 726 return ReadBytes(input, p); |
690 } | 727 } |
691 | 728 |
692 } // namespace internal | 729 } // namespace internal |
693 } // namespace protobuf | 730 } // namespace protobuf |
694 | 731 |
695 } // namespace google | 732 } // namespace google |
696 #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ | 733 #endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__ |
OLD | NEW |