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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 // bytes as "10101011 00101100". | 103 // bytes as "10101011 00101100". |
104 // | 104 // |
105 // In theory, varint could be used to encode integers of any length. | 105 // In theory, varint could be used to encode integers of any length. |
106 // However, for practicality we set a limit at 64 bits. The maximum encoded | 106 // However, for practicality we set a limit at 64 bits. The maximum encoded |
107 // length of a number is thus 10 bytes. | 107 // length of a number is thus 10 bytes. |
108 | 108 |
109 #ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ | 109 #ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ |
110 #define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ | 110 #define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ |
111 | 111 |
112 #include <assert.h> | 112 #include <assert.h> |
| 113 #include <climits> |
113 #include <string> | 114 #include <string> |
114 #include <utility> | 115 #include <utility> |
115 #ifdef _MSC_VER | 116 #ifdef _MSC_VER |
116 // Assuming windows is always little-endian. | 117 // Assuming windows is always little-endian. |
117 #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) | 118 #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) |
118 #define PROTOBUF_LITTLE_ENDIAN 1 | 119 #define PROTOBUF_LITTLE_ENDIAN 1 |
119 #endif | 120 #endif |
120 #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) | 121 #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) |
121 // If MSVC has "/RTCc" set, it will complain about truncating casts at | 122 // If MSVC has "/RTCc" set, it will complain about truncating casts at |
122 // runtime. This file contains some intentional truncating casts. | 123 // runtime. This file contains some intentional truncating casts. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, | 231 static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, |
231 uint64* value); | 232 uint64* value); |
232 | 233 |
233 // Read an unsigned integer with Varint encoding, truncating to 32 bits. | 234 // Read an unsigned integer with Varint encoding, truncating to 32 bits. |
234 // Reading a 32-bit value is equivalent to reading a 64-bit one and casting | 235 // Reading a 32-bit value is equivalent to reading a 64-bit one and casting |
235 // it to uint32, but may be more efficient. | 236 // it to uint32, but may be more efficient. |
236 bool ReadVarint32(uint32* value); | 237 bool ReadVarint32(uint32* value); |
237 // Read an unsigned integer with Varint encoding. | 238 // Read an unsigned integer with Varint encoding. |
238 bool ReadVarint64(uint64* value); | 239 bool ReadVarint64(uint64* value); |
239 | 240 |
| 241 // Reads a varint off the wire into an "int". This should be used for reading |
| 242 // sizes off the wire (sizes of strings, submessages, bytes fields, etc). |
| 243 // |
| 244 // The value from the wire is interpreted as unsigned. If its value exceeds |
| 245 // the representable value of an integer on this platform, instead of |
| 246 // truncating we return false. Truncating (as performed by ReadVarint32() |
| 247 // above) is an acceptable approach for fields representing an integer, but |
| 248 // when we are parsing a size from the wire, truncating the value would result |
| 249 // in us misparsing the payload. |
| 250 bool ReadVarintSizeAsInt(int* value); |
| 251 |
240 // Read a tag. This calls ReadVarint32() and returns the result, or returns | 252 // Read a tag. This calls ReadVarint32() and returns the result, or returns |
241 // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates | 253 // zero (which is not a valid tag) if ReadVarint32() fails. Also, ReadTag |
242 // the last tag value, which can be checked with LastTagWas(). | 254 // (but not ReadTagNoLastTag) updates the last tag value, which can be checked |
| 255 // with LastTagWas(). |
| 256 // |
243 // Always inline because this is only called in one place per parse loop | 257 // Always inline because this is only called in one place per parse loop |
244 // but it is called for every iteration of said loop, so it should be fast. | 258 // but it is called for every iteration of said loop, so it should be fast. |
245 // GCC doesn't want to inline this by default. | 259 // GCC doesn't want to inline this by default. |
246 GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag(); | 260 GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag(); |
| 261 GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTagNoLastTag(); |
| 262 |
247 | 263 |
248 // This usually a faster alternative to ReadTag() when cutoff is a manifest | 264 // This usually a faster alternative to ReadTag() when cutoff is a manifest |
249 // constant. It does particularly well for cutoff >= 127. The first part | 265 // constant. It does particularly well for cutoff >= 127. The first part |
250 // of the return value is the tag that was read, though it can also be 0 in | 266 // of the return value is the tag that was read, though it can also be 0 in |
251 // the cases where ReadTag() would return 0. If the second part is true | 267 // the cases where ReadTag() would return 0. If the second part is true |
252 // then the tag is known to be in [0, cutoff]. If not, the tag either is | 268 // then the tag is known to be in [0, cutoff]. If not, the tag either is |
253 // above cutoff or is 0. (There's intentional wiggle room when tag is 0, | 269 // above cutoff or is 0. (There's intentional wiggle room when tag is 0, |
254 // because that can arise in several ways, and for best performance we want | 270 // because that can arise in several ways, and for best performance we want |
255 // to avoid an extra "is tag == 0?" check here.) | 271 // to avoid an extra "is tag == 0?" check here.) |
256 GOOGLE_ATTRIBUTE_ALWAYS_INLINE std::pair<uint32, bool> ReadTagWithCutoff( | 272 GOOGLE_ATTRIBUTE_ALWAYS_INLINE std::pair<uint32, bool> ReadTagWithCutoff( |
257 uint32 cutoff); | 273 uint32 cutoff); |
| 274 GOOGLE_ATTRIBUTE_ALWAYS_INLINE std::pair<uint32, bool> ReadTagWithCutoffNoLast
Tag( |
| 275 uint32 cutoff); |
258 | 276 |
259 // Usually returns true if calling ReadVarint32() now would produce the given | 277 // Usually returns true if calling ReadVarint32() now would produce the given |
260 // value. Will always return false if ReadVarint32() would not return the | 278 // value. Will always return false if ReadVarint32() would not return the |
261 // given value. If ExpectTag() returns true, it also advances past | 279 // given value. If ExpectTag() returns true, it also advances past |
262 // the varint. For best performance, use a compile-time constant as the | 280 // the varint. For best performance, use a compile-time constant as the |
263 // parameter. | 281 // parameter. |
264 // Always inline because this collapses to a small number of instructions | 282 // Always inline because this collapses to a small number of instructions |
265 // when given a constant parameter, but GCC doesn't want to inline by default. | 283 // when given a constant parameter, but GCC doesn't want to inline by default. |
266 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool ExpectTag(uint32 expected); | 284 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool ExpectTag(uint32 expected); |
267 | 285 |
268 // Like above, except this reads from the specified buffer. The caller is | 286 // Like above, except this reads from the specified buffer. The caller is |
269 // responsible for ensuring that the buffer is large enough to read a varint | 287 // responsible for ensuring that the buffer is large enough to read a varint |
270 // of the expected size. For best performance, use a compile-time constant as | 288 // of the expected size. For best performance, use a compile-time constant as |
271 // the expected tag parameter. | 289 // the expected tag parameter. |
272 // | 290 // |
273 // Returns a pointer beyond the expected tag if it was found, or NULL if it | 291 // Returns a pointer beyond the expected tag if it was found, or NULL if it |
274 // was not. | 292 // was not. |
275 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static const uint8* ExpectTagFromArray( | 293 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static const uint8* ExpectTagFromArray( |
276 const uint8* buffer, | 294 const uint8* buffer, |
277 uint32 expected); | 295 uint32 expected); |
278 | 296 |
279 // Usually returns true if no more bytes can be read. Always returns false | 297 // Usually returns true if no more bytes can be read. Always returns false |
280 // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent | 298 // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent |
281 // call to LastTagWas() will act as if ReadTag() had been called and returned | 299 // call to LastTagWas() will act as if ReadTag() had been called and returned |
282 // zero, and ConsumedEntireMessage() will return true. | 300 // zero, and ConsumedEntireMessage() will return true. |
283 bool ExpectAtEnd(); | 301 bool ExpectAtEnd(); |
284 | 302 |
285 // If the last call to ReadTag() or ReadTagWithCutoff() returned the | 303 // If the last call to ReadTag() or ReadTagWithCutoff() returned the given |
286 // given value, returns true. Otherwise, returns false; | 304 // value, returns true. Otherwise, returns false. |
| 305 // ReadTagNoLastTag/ReadTagWithCutoffNoLastTag do not preserve the last |
| 306 // returned value. |
287 // | 307 // |
288 // This is needed because parsers for some types of embedded messages | 308 // This is needed because parsers for some types of embedded messages |
289 // (with field type TYPE_GROUP) don't actually know that they've reached the | 309 // (with field type TYPE_GROUP) don't actually know that they've reached the |
290 // end of a message until they see an ENDGROUP tag, which was actually part | 310 // end of a message until they see an ENDGROUP tag, which was actually part |
291 // of the enclosing message. The enclosing message would like to check that | 311 // of the enclosing message. The enclosing message would like to check that |
292 // tag to make sure it had the right number, so it calls LastTagWas() on | 312 // tag to make sure it had the right number, so it calls LastTagWas() on |
293 // return from the embedded parser to check. | 313 // return from the embedded parser to check. |
294 bool LastTagWas(uint32 expected); | 314 bool LastTagWas(uint32 expected); |
295 | 315 |
296 // When parsing message (but NOT a group), this method must be called | 316 // When parsing message (but NOT a group), this method must be called |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 // piece. The Fallback method is used when we can't use the one-byte | 607 // piece. The Fallback method is used when we can't use the one-byte |
588 // optimization. The Slow method is yet another fallback when the buffer is | 608 // optimization. The Slow method is yet another fallback when the buffer is |
589 // not large enough. Making the slow path out-of-line speeds up the common | 609 // not large enough. Making the slow path out-of-line speeds up the common |
590 // case by 10-15%. The slow path is fairly uncommon: it only triggers when a | 610 // case by 10-15%. The slow path is fairly uncommon: it only triggers when a |
591 // message crosses multiple buffers. Note: ReadVarint32Fallback() and | 611 // message crosses multiple buffers. Note: ReadVarint32Fallback() and |
592 // ReadVarint64Fallback() are called frequently and generally not inlined, so | 612 // ReadVarint64Fallback() are called frequently and generally not inlined, so |
593 // they have been optimized to avoid "out" parameters. The former returns -1 | 613 // they have been optimized to avoid "out" parameters. The former returns -1 |
594 // if it fails and the uint32 it read otherwise. The latter has a bool | 614 // if it fails and the uint32 it read otherwise. The latter has a bool |
595 // indicating success or failure as part of its return type. | 615 // indicating success or failure as part of its return type. |
596 int64 ReadVarint32Fallback(uint32 first_byte_or_zero); | 616 int64 ReadVarint32Fallback(uint32 first_byte_or_zero); |
| 617 int ReadVarintSizeAsIntFallback(); |
597 std::pair<uint64, bool> ReadVarint64Fallback(); | 618 std::pair<uint64, bool> ReadVarint64Fallback(); |
598 bool ReadVarint32Slow(uint32* value); | 619 bool ReadVarint32Slow(uint32* value); |
599 bool ReadVarint64Slow(uint64* value); | 620 bool ReadVarint64Slow(uint64* value); |
| 621 int ReadVarintSizeAsIntSlow(); |
600 bool ReadLittleEndian32Fallback(uint32* value); | 622 bool ReadLittleEndian32Fallback(uint32* value); |
601 bool ReadLittleEndian64Fallback(uint64* value); | 623 bool ReadLittleEndian64Fallback(uint64* value); |
| 624 |
| 625 template<bool update_last_tag> |
| 626 GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTagImplementation(); |
| 627 template<bool update_last_tag> |
| 628 GOOGLE_ATTRIBUTE_ALWAYS_INLINE |
| 629 std::pair<uint32, bool> ReadTagWithCutoffImplementation(uint32 cutoff); |
| 630 |
602 // Fallback/slow methods for reading tags. These do not update last_tag_, | 631 // Fallback/slow methods for reading tags. These do not update last_tag_, |
603 // but will set legitimate_message_end_ if we are at the end of the input | 632 // but will set legitimate_message_end_ if we are at the end of the input |
604 // stream. | 633 // stream. |
605 uint32 ReadTagFallback(uint32 first_byte_or_zero); | 634 uint32 ReadTagFallback(uint32 first_byte_or_zero); |
606 uint32 ReadTagSlow(); | 635 uint32 ReadTagSlow(); |
607 bool ReadStringFallback(string* buffer, int size); | 636 bool ReadStringFallback(string* buffer, int size); |
608 | 637 |
609 // Return the size of the buffer. | 638 // Return the size of the buffer. |
610 int BufferSize() const; | 639 int BufferSize() const; |
611 | 640 |
612 static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB | 641 static const int kDefaultTotalBytesLimit = INT_MAX; |
613 | 642 |
614 static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB | 643 static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB |
615 | 644 |
616 static int default_recursion_limit_; // 100 by default. | 645 static int default_recursion_limit_; // 100 by default. |
617 }; | 646 }; |
618 | 647 |
619 // Class which encodes and writes binary data which is composed of varint- | 648 // Class which encodes and writes binary data which is composed of varint- |
620 // encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. | 649 // encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. |
621 // Most users will not need to deal with CodedOutputStream. | 650 // Most users will not need to deal with CodedOutputStream. |
622 // | 651 // |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 // In particular, if the input is a compile-time constant, this method | 793 // In particular, if the input is a compile-time constant, this method |
765 // compiles down to a couple instructions. | 794 // compiles down to a couple instructions. |
766 // Always inline because otherwise the aformentioned optimization can't work, | 795 // Always inline because otherwise the aformentioned optimization can't work, |
767 // but GCC by default doesn't want to inline this. | 796 // but GCC by default doesn't want to inline this. |
768 void WriteTag(uint32 value); | 797 void WriteTag(uint32 value); |
769 // Like WriteTag() but writing directly to the target array. | 798 // Like WriteTag() but writing directly to the target array. |
770 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteTagToArray(uint32 value, | 799 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteTagToArray(uint32 value, |
771 uint8* target); | 800 uint8* target); |
772 | 801 |
773 // Returns the number of bytes needed to encode the given value as a varint. | 802 // Returns the number of bytes needed to encode the given value as a varint. |
774 static int VarintSize32(uint32 value); | 803 static size_t VarintSize32(uint32 value); |
775 // Returns the number of bytes needed to encode the given value as a varint. | 804 // Returns the number of bytes needed to encode the given value as a varint. |
776 static int VarintSize64(uint64 value); | 805 static size_t VarintSize64(uint64 value); |
777 | 806 |
778 // If negative, 10 bytes. Otheriwse, same as VarintSize32(). | 807 // If negative, 10 bytes. Otheriwse, same as VarintSize32(). |
779 static int VarintSize32SignExtended(int32 value); | 808 static size_t VarintSize32SignExtended(int32 value); |
780 | 809 |
781 // Compile-time equivalent of VarintSize32(). | 810 // Compile-time equivalent of VarintSize32(). |
782 template <uint32 Value> | 811 template <uint32 Value> |
783 struct StaticVarintSize32 { | 812 struct StaticVarintSize32 { |
784 static const int value = | 813 static const size_t value = |
785 (Value < (1 << 7)) | 814 (Value < (1 << 7)) |
786 ? 1 | 815 ? 1 |
787 : (Value < (1 << 14)) | 816 : (Value < (1 << 14)) |
788 ? 2 | 817 ? 2 |
789 : (Value < (1 << 21)) | 818 : (Value < (1 << 21)) |
790 ? 3 | 819 ? 3 |
791 : (Value < (1 << 28)) | 820 : (Value < (1 << 28)) |
792 ? 4 | 821 ? 4 |
793 : 5; | 822 : 5; |
794 }; | 823 }; |
795 | 824 |
796 // Returns the total number of bytes written since this object was created. | 825 // Returns the total number of bytes written since this object was created. |
797 inline int ByteCount() const; | 826 inline int ByteCount() const; |
798 | 827 |
799 // Returns true if there was an underlying I/O error since this object was | 828 // Returns true if there was an underlying I/O error since this object was |
800 // created. | 829 // created. |
801 bool HadError() const { return had_error_; } | 830 bool HadError() const { return had_error_; } |
802 | 831 |
| 832 // Deterministic serialization, if requested, guarantees that for a given |
| 833 // binary, equal messages will always be serialized to the same bytes. This |
| 834 // implies: |
| 835 // . repeated serialization of a message will return the same bytes |
| 836 // . different processes of the same binary (which may be executing on |
| 837 // different machines) will serialize equal messages to the same bytes. |
| 838 // |
| 839 // Note the deterministic serialization is NOT canonical across languages; it |
| 840 // is also unstable across different builds with schema changes due to unknown |
| 841 // fields. Users who need canonical serialization, e.g., persistent storage in |
| 842 // a canonical form, fingerprinting, etc., should define their own |
| 843 // canonicalization specification and implement the serializer using |
| 844 // reflection APIs rather than relying on this API. |
| 845 // |
| 846 // If determinisitc serialization is requested, the serializer will |
| 847 // sort map entries by keys in lexicographical order or numerical order. |
| 848 // (This is an implementation detail and may subject to change.) |
| 849 // |
| 850 // There are two ways to determine whether serialization should be |
| 851 // deterministic for this CodedOutputStream. If SetSerializationDeterministic |
| 852 // has not yet been called, then the default comes from the global default, |
| 853 // which is false, until SetDefaultSerializationDeterministic has been called. |
| 854 // Otherwise, SetSerializationDeterministic has been called, and the last |
| 855 // value passed to it is all that matters. |
| 856 void SetSerializationDeterministic(bool value) { |
| 857 serialization_deterministic_is_overridden_ = true; |
| 858 serialization_deterministic_override_ = value; |
| 859 } |
| 860 // See above. Also, note that users of this CodedOutputStream may need to |
| 861 // call IsSerializationDeterministic() to serialize in the intended way. This |
| 862 // CodedOutputStream cannot enforce a desire for deterministic serialization |
| 863 // by itself. |
| 864 bool IsSerializationDeterministic() const { |
| 865 return serialization_deterministic_is_overridden_ ? |
| 866 serialization_deterministic_override_ : |
| 867 default_serialization_deterministic_; |
| 868 } |
| 869 |
803 private: | 870 private: |
804 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); | 871 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); |
805 | 872 |
806 ZeroCopyOutputStream* output_; | 873 ZeroCopyOutputStream* output_; |
807 uint8* buffer_; | 874 uint8* buffer_; |
808 int buffer_size_; | 875 int buffer_size_; |
809 int total_bytes_; // Sum of sizes of all buffers seen so far. | 876 int total_bytes_; // Sum of sizes of all buffers seen so far. |
810 bool had_error_; // Whether an error occurred during output. | 877 bool had_error_; // Whether an error occurred during output. |
811 bool aliasing_enabled_; // See EnableAliasing(). | 878 bool aliasing_enabled_; // See EnableAliasing(). |
| 879 // See SetSerializationDeterministic() regarding these three fields. |
| 880 bool serialization_deterministic_is_overridden_; |
| 881 bool serialization_deterministic_override_; |
| 882 static bool default_serialization_deterministic_; |
812 | 883 |
813 // Advance the buffer by a given number of bytes. | 884 // Advance the buffer by a given number of bytes. |
814 void Advance(int amount); | 885 void Advance(int amount); |
815 | 886 |
816 // Called when the buffer runs out to request more data. Implies an | 887 // Called when the buffer runs out to request more data. Implies an |
817 // Advance(buffer_size_). | 888 // Advance(buffer_size_). |
818 bool Refresh(); | 889 bool Refresh(); |
819 | 890 |
820 // Like WriteRaw() but may avoid copying if the underlying | 891 // Like WriteRaw() but may avoid copying if the underlying |
821 // ZeroCopyOutputStream supports it. | 892 // ZeroCopyOutputStream supports it. |
822 void WriteAliasedRaw(const void* buffer, int size); | 893 void WriteAliasedRaw(const void* buffer, int size); |
823 | 894 |
824 // If this write might cross the end of the buffer, we compose the bytes first | 895 // If this write might cross the end of the buffer, we compose the bytes first |
825 // then use WriteRaw(). | 896 // then use WriteRaw(). |
826 void WriteVarint32SlowPath(uint32 value); | 897 void WriteVarint32SlowPath(uint32 value); |
| 898 void WriteVarint64SlowPath(uint64 value); |
827 | 899 |
828 // Always-inlined versions of WriteVarint* functions so that code can be | 900 static size_t VarintSize32Fallback(uint32 value); |
829 // reused, while still controlling size. For instance, WriteVarint32ToArray() | |
830 // should not directly call this: since it is inlined itself, doing so | |
831 // would greatly increase the size of generated code. Instead, it should call | |
832 // WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already | |
833 // out-of-line, so it should just invoke this directly to avoid any extra | |
834 // function call overhead. | |
835 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteVarint64ToArrayInline( | |
836 uint64 value, uint8* target); | |
837 | 901 |
838 static int VarintSize32Fallback(uint32 value); | 902 // See above. Other projects may use "friend" to allow them to call this. |
| 903 static void SetDefaultSerializationDeterministic() { |
| 904 default_serialization_deterministic_ = true; |
| 905 } |
839 }; | 906 }; |
840 | 907 |
841 // inline methods ==================================================== | 908 // inline methods ==================================================== |
842 // The vast majority of varints are only one byte. These inline | 909 // The vast majority of varints are only one byte. These inline |
843 // methods optimize for that case. | 910 // methods optimize for that case. |
844 | 911 |
845 inline bool CodedInputStream::ReadVarint32(uint32* value) { | 912 inline bool CodedInputStream::ReadVarint32(uint32* value) { |
846 uint32 v = 0; | 913 uint32 v = 0; |
847 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { | 914 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { |
848 v = *buffer_; | 915 v = *buffer_; |
(...skipping 12 matching lines...) Expand all Loading... |
861 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { | 928 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { |
862 *value = *buffer_; | 929 *value = *buffer_; |
863 Advance(1); | 930 Advance(1); |
864 return true; | 931 return true; |
865 } | 932 } |
866 std::pair<uint64, bool> p = ReadVarint64Fallback(); | 933 std::pair<uint64, bool> p = ReadVarint64Fallback(); |
867 *value = p.first; | 934 *value = p.first; |
868 return p.second; | 935 return p.second; |
869 } | 936 } |
870 | 937 |
| 938 inline bool CodedInputStream::ReadVarintSizeAsInt(int* value) { |
| 939 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { |
| 940 int v = *buffer_; |
| 941 if (v < 0x80) { |
| 942 *value = v; |
| 943 Advance(1); |
| 944 return true; |
| 945 } |
| 946 } |
| 947 *value = ReadVarintSizeAsIntFallback(); |
| 948 return *value >= 0; |
| 949 } |
| 950 |
871 // static | 951 // static |
872 inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( | 952 inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( |
873 const uint8* buffer, | 953 const uint8* buffer, |
874 uint32* value) { | 954 uint32* value) { |
875 #if defined(PROTOBUF_LITTLE_ENDIAN) | 955 #if defined(PROTOBUF_LITTLE_ENDIAN) |
876 memcpy(value, buffer, sizeof(*value)); | 956 memcpy(value, buffer, sizeof(*value)); |
877 return buffer + sizeof(*value); | 957 return buffer + sizeof(*value); |
878 #else | 958 #else |
879 *value = (static_cast<uint32>(buffer[0]) ) | | 959 *value = (static_cast<uint32>(buffer[0]) ) | |
880 (static_cast<uint32>(buffer[1]) << 8) | | 960 (static_cast<uint32>(buffer[1]) << 8) | |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 return true; | 1007 return true; |
928 } else { | 1008 } else { |
929 return ReadLittleEndian64Fallback(value); | 1009 return ReadLittleEndian64Fallback(value); |
930 } | 1010 } |
931 #else | 1011 #else |
932 return ReadLittleEndian64Fallback(value); | 1012 return ReadLittleEndian64Fallback(value); |
933 #endif | 1013 #endif |
934 } | 1014 } |
935 | 1015 |
936 inline uint32 CodedInputStream::ReadTag() { | 1016 inline uint32 CodedInputStream::ReadTag() { |
| 1017 return ReadTagImplementation<true>(); |
| 1018 } |
| 1019 |
| 1020 inline uint32 CodedInputStream::ReadTagNoLastTag() { |
| 1021 return ReadTagImplementation<false>(); |
| 1022 } |
| 1023 |
| 1024 template<bool update_last_tag> |
| 1025 inline uint32 CodedInputStream::ReadTagImplementation() { |
937 uint32 v = 0; | 1026 uint32 v = 0; |
938 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { | 1027 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { |
939 v = *buffer_; | 1028 v = *buffer_; |
940 if (v < 0x80) { | 1029 if (v < 0x80) { |
941 last_tag_ = v; | 1030 if (update_last_tag) { |
| 1031 last_tag_ = v; |
| 1032 } |
942 Advance(1); | 1033 Advance(1); |
943 return v; | 1034 return v; |
944 } | 1035 } |
945 } | 1036 } |
946 last_tag_ = ReadTagFallback(v); | 1037 v = ReadTagFallback(v); |
947 return last_tag_; | 1038 if (update_last_tag) { |
| 1039 last_tag_ = v; |
| 1040 } |
| 1041 return v; |
948 } | 1042 } |
949 | 1043 |
950 inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( | 1044 inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( |
951 uint32 cutoff) { | 1045 uint32 cutoff) { |
| 1046 return ReadTagWithCutoffImplementation<true>(cutoff); |
| 1047 } |
| 1048 |
| 1049 inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoffNoLastTag( |
| 1050 uint32 cutoff) { |
| 1051 return ReadTagWithCutoffImplementation<false>(cutoff); |
| 1052 } |
| 1053 |
| 1054 template<bool update_last_tag> |
| 1055 inline std::pair<uint32, bool> |
| 1056 CodedInputStream::ReadTagWithCutoffImplementation( |
| 1057 uint32 cutoff) { |
952 // In performance-sensitive code we can expect cutoff to be a compile-time | 1058 // In performance-sensitive code we can expect cutoff to be a compile-time |
953 // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at | 1059 // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at |
954 // compile time. | 1060 // compile time. |
955 uint32 first_byte_or_zero = 0; | 1061 uint32 first_byte_or_zero = 0; |
956 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { | 1062 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { |
957 // Hot case: buffer_ non_empty, buffer_[0] in [1, 128). | 1063 // Hot case: buffer_ non_empty, buffer_[0] in [1, 128). |
958 // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields | 1064 // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields |
959 // is large enough then is it better to check for the two-byte case first? | 1065 // is large enough then is it better to check for the two-byte case first? |
960 first_byte_or_zero = buffer_[0]; | 1066 first_byte_or_zero = buffer_[0]; |
961 if (static_cast<int8>(buffer_[0]) > 0) { | 1067 if (static_cast<int8>(buffer_[0]) > 0) { |
962 const uint32 kMax1ByteVarint = 0x7f; | 1068 const uint32 kMax1ByteVarint = 0x7f; |
963 uint32 tag = last_tag_ = buffer_[0]; | 1069 uint32 tag = buffer_[0]; |
| 1070 if (update_last_tag) { |
| 1071 last_tag_ = tag; |
| 1072 } |
964 Advance(1); | 1073 Advance(1); |
965 return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); | 1074 return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); |
966 } | 1075 } |
967 // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available, | 1076 // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available, |
968 // and tag is two bytes. The latter is tested by bitwise-and-not of the | 1077 // and tag is two bytes. The latter is tested by bitwise-and-not of the |
969 // first byte and the second byte. | 1078 // first byte and the second byte. |
970 if (cutoff >= 0x80 && | 1079 if (cutoff >= 0x80 && |
971 GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) && | 1080 GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) && |
972 GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) { | 1081 GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) { |
973 const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f; | 1082 const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f; |
974 uint32 tag = last_tag_ = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80); | 1083 uint32 tag = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80); |
| 1084 if (update_last_tag) { |
| 1085 last_tag_ = tag; |
| 1086 } |
975 Advance(2); | 1087 Advance(2); |
976 // It might make sense to test for tag == 0 now, but it is so rare that | 1088 // It might make sense to test for tag == 0 now, but it is so rare that |
977 // that we don't bother. A varint-encoded 0 should be one byte unless | 1089 // that we don't bother. A varint-encoded 0 should be one byte unless |
978 // the encoder lost its mind. The second part of the return value of | 1090 // the encoder lost its mind. The second part of the return value of |
979 // this function is allowed to be either true or false if the tag is 0, | 1091 // this function is allowed to be either true or false if the tag is 0, |
980 // so we don't have to check for tag == 0. We may need to check whether | 1092 // so we don't have to check for tag == 0. We may need to check whether |
981 // it exceeds cutoff. | 1093 // it exceeds cutoff. |
982 bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff; | 1094 bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff; |
983 return std::make_pair(tag, at_or_below_cutoff); | 1095 return std::make_pair(tag, at_or_below_cutoff); |
984 } | 1096 } |
985 } | 1097 } |
986 // Slow path | 1098 // Slow path |
987 last_tag_ = ReadTagFallback(first_byte_or_zero); | 1099 const uint32 tag = ReadTagFallback(first_byte_or_zero); |
988 return std::make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff); | 1100 if (update_last_tag) { |
| 1101 last_tag_ = tag; |
| 1102 } |
| 1103 return std::make_pair(tag, static_cast<uint32>(tag - 1) < cutoff); |
989 } | 1104 } |
990 | 1105 |
991 inline bool CodedInputStream::LastTagWas(uint32 expected) { | 1106 inline bool CodedInputStream::LastTagWas(uint32 expected) { |
992 return last_tag_ == expected; | 1107 return last_tag_ == expected; |
993 } | 1108 } |
994 | 1109 |
995 inline bool CodedInputStream::ConsumedEntireMessage() { | 1110 inline bool CodedInputStream::ConsumedEntireMessage() { |
996 return legitimate_message_end_; | 1111 return legitimate_message_end_; |
997 } | 1112 } |
998 | 1113 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 uint8* target) { | 1188 uint8* target) { |
1074 while (value >= 0x80) { | 1189 while (value >= 0x80) { |
1075 *target = static_cast<uint8>(value | 0x80); | 1190 *target = static_cast<uint8>(value | 0x80); |
1076 value >>= 7; | 1191 value >>= 7; |
1077 ++target; | 1192 ++target; |
1078 } | 1193 } |
1079 *target = static_cast<uint8>(value); | 1194 *target = static_cast<uint8>(value); |
1080 return target + 1; | 1195 return target + 1; |
1081 } | 1196 } |
1082 | 1197 |
| 1198 inline uint8* CodedOutputStream::WriteVarint64ToArray(uint64 value, |
| 1199 uint8* target) { |
| 1200 while (value >= 0x80) { |
| 1201 *target = static_cast<uint8>(value | 0x80); |
| 1202 value >>= 7; |
| 1203 ++target; |
| 1204 } |
| 1205 *target = static_cast<uint8>(value); |
| 1206 return target + 1; |
| 1207 } |
| 1208 |
1083 inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { | 1209 inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { |
1084 if (value < 0) { | 1210 WriteVarint64(static_cast<uint64>(value)); |
1085 WriteVarint64(static_cast<uint64>(value)); | |
1086 } else { | |
1087 WriteVarint32(static_cast<uint32>(value)); | |
1088 } | |
1089 } | 1211 } |
1090 | 1212 |
1091 inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray( | 1213 inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray( |
1092 int32 value, uint8* target) { | 1214 int32 value, uint8* target) { |
1093 if (value < 0) { | 1215 return WriteVarint64ToArray(static_cast<uint64>(value), target); |
1094 return WriteVarint64ToArray(static_cast<uint64>(value), target); | |
1095 } else { | |
1096 return WriteVarint32ToArray(static_cast<uint32>(value), target); | |
1097 } | |
1098 } | 1216 } |
1099 | 1217 |
1100 inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, | 1218 inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value, |
1101 uint8* target) { | 1219 uint8* target) { |
1102 #if defined(PROTOBUF_LITTLE_ENDIAN) | 1220 #if defined(PROTOBUF_LITTLE_ENDIAN) |
1103 memcpy(target, &value, sizeof(value)); | 1221 memcpy(target, &value, sizeof(value)); |
1104 #else | 1222 #else |
1105 target[0] = static_cast<uint8>(value); | 1223 target[0] = static_cast<uint8>(value); |
1106 target[1] = static_cast<uint8>(value >> 8); | 1224 target[1] = static_cast<uint8>(value >> 8); |
1107 target[2] = static_cast<uint8>(value >> 16); | 1225 target[2] = static_cast<uint8>(value >> 16); |
(...skipping 28 matching lines...) Expand all Loading... |
1136 // this write won't cross the end, so we can skip the checks. | 1254 // this write won't cross the end, so we can skip the checks. |
1137 uint8* target = buffer_; | 1255 uint8* target = buffer_; |
1138 uint8* end = WriteVarint32ToArray(value, target); | 1256 uint8* end = WriteVarint32ToArray(value, target); |
1139 int size = static_cast<int>(end - target); | 1257 int size = static_cast<int>(end - target); |
1140 Advance(size); | 1258 Advance(size); |
1141 } else { | 1259 } else { |
1142 WriteVarint32SlowPath(value); | 1260 WriteVarint32SlowPath(value); |
1143 } | 1261 } |
1144 } | 1262 } |
1145 | 1263 |
| 1264 inline void CodedOutputStream::WriteVarint64(uint64 value) { |
| 1265 if (buffer_size_ >= 10) { |
| 1266 // Fast path: We have enough bytes left in the buffer to guarantee that |
| 1267 // this write won't cross the end, so we can skip the checks. |
| 1268 uint8* target = buffer_; |
| 1269 uint8* end = WriteVarint64ToArray(value, target); |
| 1270 int size = static_cast<int>(end - target); |
| 1271 Advance(size); |
| 1272 } else { |
| 1273 WriteVarint64SlowPath(value); |
| 1274 } |
| 1275 } |
| 1276 |
1146 inline void CodedOutputStream::WriteTag(uint32 value) { | 1277 inline void CodedOutputStream::WriteTag(uint32 value) { |
1147 WriteVarint32(value); | 1278 WriteVarint32(value); |
1148 } | 1279 } |
1149 | 1280 |
1150 inline uint8* CodedOutputStream::WriteTagToArray( | 1281 inline uint8* CodedOutputStream::WriteTagToArray( |
1151 uint32 value, uint8* target) { | 1282 uint32 value, uint8* target) { |
1152 return WriteVarint32ToArray(value, target); | 1283 return WriteVarint32ToArray(value, target); |
1153 } | 1284 } |
1154 | 1285 |
1155 inline int CodedOutputStream::VarintSize32(uint32 value) { | 1286 inline size_t CodedOutputStream::VarintSize32(uint32 value) { |
1156 if (value < (1 << 7)) { | 1287 if (value < (1 << 7)) { |
1157 return 1; | 1288 return 1; |
1158 } else { | 1289 } else { |
1159 return VarintSize32Fallback(value); | 1290 return VarintSize32Fallback(value); |
1160 } | 1291 } |
1161 } | 1292 } |
1162 | 1293 |
1163 inline int CodedOutputStream::VarintSize32SignExtended(int32 value) { | 1294 inline size_t CodedOutputStream::VarintSize32SignExtended(int32 value) { |
1164 if (value < 0) { | 1295 if (value < 0) { |
1165 return 10; // TODO(kenton): Make this a symbolic constant. | 1296 return 10; // TODO(kenton): Make this a symbolic constant. |
1166 } else { | 1297 } else { |
1167 return VarintSize32(static_cast<uint32>(value)); | 1298 return VarintSize32(static_cast<uint32>(value)); |
1168 } | 1299 } |
1169 } | 1300 } |
1170 | 1301 |
1171 inline void CodedOutputStream::WriteString(const string& str) { | 1302 inline void CodedOutputStream::WriteString(const string& str) { |
1172 WriteRaw(str.data(), static_cast<int>(str.size())); | 1303 WriteRaw(str.data(), static_cast<int>(str.size())); |
1173 } | 1304 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 } // namespace io | 1416 } // namespace io |
1286 } // namespace protobuf | 1417 } // namespace protobuf |
1287 | 1418 |
1288 | 1419 |
1289 #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) | 1420 #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) |
1290 #pragma runtime_checks("c", restore) | 1421 #pragma runtime_checks("c", restore) |
1291 #endif // _MSC_VER && !defined(__INTEL_COMPILER) | 1422 #endif // _MSC_VER && !defined(__INTEL_COMPILER) |
1292 | 1423 |
1293 } // namespace google | 1424 } // namespace google |
1294 #endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ | 1425 #endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ |
OLD | NEW |