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