| 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 |