aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/io/coded_stream.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/io/coded_stream.h')
-rw-r--r--src/google/protobuf/io/coded_stream.h72
1 files changed, 40 insertions, 32 deletions
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index 71a4f5fb..63631d1f 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -161,6 +161,13 @@ class CodedOutputStream;
class ZeroCopyInputStream; // zero_copy_stream.h
class ZeroCopyOutputStream; // zero_copy_stream.h
+template <typename T>
+T UnalignedLoad(const void* p) {
+ T res;
+ memcpy(&res, p, sizeof(T));
+ return res;
+}
+
// Class which reads and decodes binary data which is composed of varint-
// encoded integers and fixed-width pieces. Wraps a ZeroCopyInputStream.
// Most users will not need to deal with CodedInputStream.
@@ -168,7 +175,7 @@ class ZeroCopyOutputStream; // zero_copy_stream.h
// Most methods of CodedInputStream that return a bool return false if an
// underlying I/O error occurs or if the data is malformed. Once such a
// failure occurs, the CodedInputStream is broken and is no longer useful.
-class LIBPROTOBUF_EXPORT CodedInputStream {
+class PROTOBUF_EXPORT CodedInputStream {
public:
// Create a CodedInputStream that reads from the given ZeroCopyInputStream.
explicit CodedInputStream(ZeroCopyInputStream* input);
@@ -204,7 +211,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Like GetDirectBufferPointer, but this method is inlined, and does not
// attempt to Refresh() if the buffer is currently empty.
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
+ PROTOBUF_ALWAYS_INLINE
void GetDirectBufferPointerInline(const void** data, int* size);
// Read raw bytes, copying them into the given buffer.
@@ -212,15 +219,15 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Like the above, with inlined optimizations. This should only be used
// by the protobuf implementation.
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
+ PROTOBUF_ALWAYS_INLINE
bool InternalReadRawInline(void* buffer, int size);
// Like ReadRaw, but reads into a string.
- bool ReadString(string* buffer, int size);
+ bool ReadString(std::string* buffer, int size);
// Like the above, with inlined optimizations. This should only be used
// by the protobuf implementation.
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
- bool InternalReadStringInline(string* buffer, int size);
+ PROTOBUF_ALWAYS_INLINE
+ bool InternalReadStringInline(std::string* buffer, int size);
// Read a 32-bit little-endian integer.
@@ -263,11 +270,11 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Always inline because this is only called in one place per parse loop
// but it is called for every iteration of said loop, so it should be fast.
// GCC doesn't want to inline this by default.
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag() {
+ PROTOBUF_ALWAYS_INLINE uint32 ReadTag() {
return last_tag_ = ReadTagNoLastTag();
}
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTagNoLastTag();
+ PROTOBUF_ALWAYS_INLINE uint32 ReadTagNoLastTag();
// This usually a faster alternative to ReadTag() when cutoff is a manifest
// constant. It does particularly well for cutoff >= 127. The first part
@@ -277,14 +284,14 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// above cutoff or is 0. (There's intentional wiggle room when tag is 0,
// because that can arise in several ways, and for best performance we want
// to avoid an extra "is tag == 0?" check here.)
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
+ PROTOBUF_ALWAYS_INLINE
std::pair<uint32, bool> ReadTagWithCutoff(uint32 cutoff) {
std::pair<uint32, bool> result = ReadTagWithCutoffNoLastTag(cutoff);
last_tag_ = result.first;
return result;
}
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
+ PROTOBUF_ALWAYS_INLINE
std::pair<uint32, bool> ReadTagWithCutoffNoLastTag(uint32 cutoff);
// Usually returns true if calling ReadVarint32() now would produce the given
@@ -294,7 +301,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// parameter.
// Always inline because this collapses to a small number of instructions
// when given a constant parameter, but GCC doesn't want to inline by default.
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool ExpectTag(uint32 expected);
+ PROTOBUF_ALWAYS_INLINE bool ExpectTag(uint32 expected);
// Like above, except this reads from the specified buffer. The caller is
// responsible for ensuring that the buffer is large enough to read a varint
@@ -303,7 +310,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
//
// Returns a pointer beyond the expected tag if it was found, or NULL if it
// was not.
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
+ PROTOBUF_ALWAYS_INLINE
static const uint8* ExpectTagFromArray(const uint8* buffer, uint32 expected);
// Usually returns true if no more bytes can be read. Always returns false
@@ -390,7 +397,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// This is unrelated to PushLimit()/PopLimit().
void SetTotalBytesLimit(int total_bytes_limit);
- GOOGLE_PROTOBUF_DEPRECATED_MSG(
+ PROTOBUF_DEPRECATED_MSG(
"Please use the single parameter version of SetTotalBytesLimit(). The "
"second parameter is ignored.")
void SetTotalBytesLimit(int total_bytes_limit, int) {
@@ -409,6 +416,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Sets the maximum recursion depth. The default is 100.
void SetRecursionLimit(int limit);
+ int RecursionBudget() { return recursion_budget_; }
// Increments the current recursion depth. Returns true if the depth is
@@ -627,7 +635,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// stream.
uint32 ReadTagFallback(uint32 first_byte_or_zero);
uint32 ReadTagSlow();
- bool ReadStringFallback(string* buffer, int size);
+ bool ReadStringFallback(std::string* buffer, int size);
// Return the size of the buffer.
int BufferSize() const;
@@ -683,7 +691,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// }
//
// delete coded_output;
-class LIBPROTOBUF_EXPORT CodedOutputStream {
+class PROTOBUF_EXPORT CodedOutputStream {
public:
// Create an CodedOutputStream that writes to the given ZeroCopyOutputStream.
explicit CodedOutputStream(ZeroCopyOutputStream* output);
@@ -737,11 +745,11 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
static uint8* WriteRawToArray(const void* buffer, int size, uint8* target);
// Equivalent to WriteRaw(str.data(), str.size()).
- void WriteString(const string& str);
+ void WriteString(const std::string& str);
// Like WriteString() but writing directly to the target array.
- static uint8* WriteStringToArray(const string& str, uint8* target);
+ static uint8* WriteStringToArray(const std::string& str, uint8* target);
// Write the varint-encoded size of str followed by str.
- static uint8* WriteStringWithSizeToArray(const string& str, uint8* target);
+ static uint8* WriteStringWithSizeToArray(const std::string& str, uint8* target);
// Instructs the CodedOutputStream to allow the underlying
@@ -788,7 +796,7 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// but GCC by default doesn't want to inline this.
void WriteTag(uint32 value);
// Like WriteTag() but writing directly to the target array.
- GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
+ PROTOBUF_ALWAYS_INLINE
static uint8* WriteTagToArray(uint32 value, uint8* target);
// Returns the number of bytes needed to encode the given value as a varint.
@@ -908,7 +916,7 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
inline bool CodedInputStream::ReadVarint32(uint32* value) {
uint32 v = 0;
- if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
+ if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
v = *buffer_;
if (v < 0x80) {
*value = v;
@@ -922,7 +930,7 @@ inline bool CodedInputStream::ReadVarint32(uint32* value) {
}
inline bool CodedInputStream::ReadVarint64(uint64* value) {
- if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) {
+ if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) {
*value = *buffer_;
Advance(1);
return true;
@@ -933,7 +941,7 @@ inline bool CodedInputStream::ReadVarint64(uint64* value) {
}
inline bool CodedInputStream::ReadVarintSizeAsInt(int* value) {
- if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
+ if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
int v = *buffer_;
if (v < 0x80) {
*value = v;
@@ -984,7 +992,7 @@ inline const uint8* CodedInputStream::ReadLittleEndian64FromArray(
inline bool CodedInputStream::ReadLittleEndian32(uint32* value) {
#if defined(PROTOBUF_LITTLE_ENDIAN)
- if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
+ if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
buffer_ = ReadLittleEndian32FromArray(buffer_, value);
return true;
} else {
@@ -997,7 +1005,7 @@ inline bool CodedInputStream::ReadLittleEndian32(uint32* value) {
inline bool CodedInputStream::ReadLittleEndian64(uint64* value) {
#if defined(PROTOBUF_LITTLE_ENDIAN)
- if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
+ if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
buffer_ = ReadLittleEndian64FromArray(buffer_, value);
return true;
} else {
@@ -1010,7 +1018,7 @@ inline bool CodedInputStream::ReadLittleEndian64(uint64* value) {
inline uint32 CodedInputStream::ReadTagNoLastTag() {
uint32 v = 0;
- if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
+ if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
v = *buffer_;
if (v < 0x80) {
Advance(1);
@@ -1027,7 +1035,7 @@ inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoffNoLastTag(
// constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at
// compile time.
uint32 first_byte_or_zero = 0;
- if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
+ if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
// Hot case: buffer_ non_empty, buffer_[0] in [1, 128).
// TODO(gpike): Is it worth rearranging this? E.g., if the number of fields
// is large enough then is it better to check for the two-byte case first?
@@ -1041,8 +1049,8 @@ inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoffNoLastTag(
// Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available,
// and tag is two bytes. The latter is tested by bitwise-and-not of the
// first byte and the second byte.
- if (cutoff >= 0x80 && GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) &&
- GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) {
+ if (cutoff >= 0x80 && PROTOBUF_PREDICT_TRUE(buffer_ + 1 < buffer_end_) &&
+ PROTOBUF_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) {
const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f;
uint32 tag = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80);
Advance(2);
@@ -1071,14 +1079,14 @@ inline bool CodedInputStream::ConsumedEntireMessage() {
inline bool CodedInputStream::ExpectTag(uint32 expected) {
if (expected < (1 << 7)) {
- if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) {
+ if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) {
Advance(1);
return true;
} else {
return false;
}
} else if (expected < (1 << 14)) {
- if (GOOGLE_PREDICT_TRUE(BufferSize() >= 2) &&
+ if (PROTOBUF_PREDICT_TRUE(BufferSize() >= 2) &&
buffer_[0] == static_cast<uint8>(expected | 0x80) &&
buffer_[1] == static_cast<uint8>(expected >> 7)) {
Advance(2);
@@ -1269,7 +1277,7 @@ inline size_t CodedOutputStream::VarintSize32SignExtended(int32 value) {
}
}
-inline void CodedOutputStream::WriteString(const string& str) {
+inline void CodedOutputStream::WriteString(const std::string& str) {
WriteRaw(str.data(), static_cast<int>(str.size()));
}
@@ -1283,7 +1291,7 @@ inline void CodedOutputStream::WriteRawMaybeAliased(
}
inline uint8* CodedOutputStream::WriteStringToArray(
- const string& str, uint8* target) {
+ const std::string& str, uint8* target) {
return WriteRawToArray(str.data(), static_cast<int>(str.size()), target);
}