Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Unified Diff: third_party/protobuf/src/google/protobuf/io/coded_stream.cc

Issue 1322483002: Revert https://codereview.chromium.org/1291903002 (protobuf roll). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/protobuf/src/google/protobuf/io/coded_stream.cc
diff --git a/third_party/protobuf/src/google/protobuf/io/coded_stream.cc b/third_party/protobuf/src/google/protobuf/io/coded_stream.cc
index 3b8650d627c33c3790fe5a2494cf4529ecc2837b..36add8c3e4ea5d62cac71b7d3ce60fcbc6ca706c 100644
--- a/third_party/protobuf/src/google/protobuf/io/coded_stream.cc
+++ b/third_party/protobuf/src/google/protobuf/io/coded_stream.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
+// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -40,10 +40,8 @@
#include <google/protobuf/io/coded_stream_inl.h>
#include <algorithm>
-#include <utility>
#include <limits.h>
#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/arena.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stl_util.h>
@@ -85,10 +83,6 @@ CodedInputStream::~CodedInputStream() {
int CodedInputStream::default_recursion_limit_ = 100;
-void CodedOutputStream::EnableAliasing(bool enabled) {
- aliasing_enabled_ = enabled && output_->AllowsAliasing();
-}
-
void CodedInputStream::BackUpInputToCurrentPosition() {
int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
if (backup_bytes > 0) {
@@ -151,30 +145,6 @@ void CodedInputStream::PopLimit(Limit limit) {
legitimate_message_end_ = false;
}
-std::pair<CodedInputStream::Limit, int>
-CodedInputStream::IncrementRecursionDepthAndPushLimit(int byte_limit) {
- return std::make_pair(PushLimit(byte_limit), --recursion_budget_);
-}
-
-CodedInputStream::Limit CodedInputStream::ReadLengthAndPushLimit() {
- uint32 length;
- return PushLimit(ReadVarint32(&length) ? length : 0);
-}
-
-bool CodedInputStream::DecrementRecursionDepthAndPopLimit(Limit limit) {
- bool result = ConsumedEntireMessage();
- PopLimit(limit);
- GOOGLE_DCHECK_LT(recursion_budget_, recursion_limit_);
- ++recursion_budget_;
- return result;
-}
-
-bool CodedInputStream::CheckEntireMessageConsumedAndPopLimit(Limit limit) {
- bool result = ConsumedEntireMessage();
- PopLimit(limit);
- return result;
-}
-
int CodedInputStream::BytesUntilLimit() const {
if (current_limit_ == INT_MAX) return -1;
int current_position = CurrentPosition();
@@ -197,11 +167,6 @@ void CodedInputStream::SetTotalBytesLimit(
RecomputeBufferLimits();
}
-int CodedInputStream::BytesUntilTotalBytesLimit() const {
- if (total_bytes_limit_ == INT_MAX) return -1;
- return total_bytes_limit_ - CurrentPosition();
-}
-
void CodedInputStream::PrintTotalBytesLimitError() {
GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
"big (more than " << total_bytes_limit_
@@ -256,7 +221,20 @@ bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
}
bool CodedInputStream::ReadRaw(void* buffer, int size) {
- return InternalReadRawInline(buffer, size);
+ int current_buffer_size;
+ while ((current_buffer_size = BufferSize()) < size) {
+ // Reading past end of buffer. Copy what we have, then refresh.
+ memcpy(buffer, buffer_, current_buffer_size);
+ buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size;
+ size -= current_buffer_size;
+ Advance(current_buffer_size);
+ if (!Refresh()) return false;
+ }
+
+ memcpy(buffer, buffer_, size);
+ Advance(size);
+
+ return true;
}
bool CodedInputStream::ReadString(string* buffer, int size) {
@@ -269,14 +247,6 @@ bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
buffer->clear();
}
- int closest_limit = min(current_limit_, total_bytes_limit_);
- if (closest_limit != INT_MAX) {
- int bytes_to_limit = closest_limit - CurrentPosition();
- if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) {
- buffer->reserve(size);
- }
- }
-
int current_buffer_size;
while ((current_buffer_size = BufferSize()) < size) {
// Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
@@ -334,31 +304,20 @@ bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
namespace {
-// Read a varint from the given buffer, write it to *value, and return a pair.
-// The first part of the pair is true iff the read was successful. The second
-// part is buffer + (number of bytes read). This function is always inlined,
-// so returning a pair is costless.
-inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
- uint32 first_byte, const uint8* buffer,
- uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
-inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
- uint32 first_byte, const uint8* buffer, uint32* value) {
+inline const uint8* ReadVarint32FromArray(
+ const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this read won't cross the end, so we can skip the checks.
- GOOGLE_DCHECK_EQ(*buffer, first_byte);
- GOOGLE_DCHECK_EQ(first_byte & 0x80, 0x80) << first_byte;
const uint8* ptr = buffer;
uint32 b;
- uint32 result = first_byte - 0x80;
- ++ptr; // We just processed the first byte. Move on to the second.
- b = *(ptr++); result += b << 7; if (!(b & 0x80)) goto done;
- result -= 0x80 << 7;
- b = *(ptr++); result += b << 14; if (!(b & 0x80)) goto done;
- result -= 0x80 << 14;
- b = *(ptr++); result += b << 21; if (!(b & 0x80)) goto done;
- result -= 0x80 << 21;
- b = *(ptr++); result += b << 28; if (!(b & 0x80)) goto done;
- // "result -= 0x80 << 28" is irrevelant.
+ uint32 result;
+
+ b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done;
// If the input is larger than 32 bits, we still need to read it all
// and discard the high-order bits.
@@ -368,42 +327,38 @@ inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
// We have overrun the maximum size of a varint (10 bytes). Assume
// the data is corrupt.
- return std::make_pair(false, ptr);
+ return NULL;
done:
*value = result;
- return std::make_pair(true, ptr);
+ return ptr;
}
} // namespace
bool CodedInputStream::ReadVarint32Slow(uint32* value) {
+ uint64 result;
// Directly invoke ReadVarint64Fallback, since we already tried to optimize
// for one-byte varints.
- std::pair<uint64, bool> p = ReadVarint64Fallback();
- *value = static_cast<uint32>(p.first);
- return p.second;
+ if (!ReadVarint64Fallback(&result)) return false;
+ *value = (uint32)result;
+ return true;
}
-int64 CodedInputStream::ReadVarint32Fallback(uint32 first_byte_or_zero) {
+bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
if (BufferSize() >= kMaxVarintBytes ||
- // Optimization: We're also safe if the buffer is non-empty and it ends
- // with a byte that would terminate a varint.
+ // Optimization: If the varint ends at exactly the end of the buffer,
+ // we can detect that and still use the fast path.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
- GOOGLE_DCHECK_NE(first_byte_or_zero, 0)
- << "Caller should provide us with *buffer_ when buffer is non-empty";
- uint32 temp;
- ::std::pair<bool, const uint8*> p =
- ReadVarint32FromArray(first_byte_or_zero, buffer_, &temp);
- if (!p.first) return -1;
- buffer_ = p.second;
- return temp;
+ const uint8* end = ReadVarint32FromArray(buffer_, value);
+ if (end == NULL) return false;
+ buffer_ = end;
+ return true;
} else {
// Really slow case: we will incur the cost of an extra function call here,
// but moving this out of line reduces the size of this function, which
// improves the common case. In micro benchmarks, this is worth about 10-15%
- uint32 temp;
- return ReadVarint32Slow(&temp) ? static_cast<int64>(temp) : -1;
+ return ReadVarint32Slow(value);
}
}
@@ -433,24 +388,18 @@ uint32 CodedInputStream::ReadTagSlow() {
return static_cast<uint32>(result);
}
-uint32 CodedInputStream::ReadTagFallback(uint32 first_byte_or_zero) {
+uint32 CodedInputStream::ReadTagFallback() {
const int buf_size = BufferSize();
if (buf_size >= kMaxVarintBytes ||
- // Optimization: We're also safe if the buffer is non-empty and it ends
- // with a byte that would terminate a varint.
+ // Optimization: If the varint ends at exactly the end of the buffer,
+ // we can detect that and still use the fast path.
(buf_size > 0 && !(buffer_end_[-1] & 0x80))) {
- GOOGLE_DCHECK_EQ(first_byte_or_zero, buffer_[0]);
- if (first_byte_or_zero == 0) {
- ++buffer_;
- return 0;
- }
uint32 tag;
- ::std::pair<bool, const uint8*> p =
- ReadVarint32FromArray(first_byte_or_zero, buffer_, &tag);
- if (!p.first) {
+ const uint8* end = ReadVarint32FromArray(buffer_, &tag);
+ if (end == NULL) {
return 0;
}
- buffer_ = p.second;
+ buffer_ = end;
return tag;
} else {
// We are commonly at a limit when attempting to read tags. Try to quickly
@@ -493,10 +442,10 @@ bool CodedInputStream::ReadVarint64Slow(uint64* value) {
return true;
}
-std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() {
+bool CodedInputStream::ReadVarint64Fallback(uint64* value) {
if (BufferSize() >= kMaxVarintBytes ||
- // Optimization: We're also safe if the buffer is non-empty and it ends
- // with a byte that would terminate a varint.
+ // Optimization: If the varint ends at exactly the end of the buffer,
+ // we can detect that and still use the fast path.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this read won't cross the end, so we can skip the checks.
@@ -508,41 +457,29 @@ std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() {
// processors.
uint32 part0 = 0, part1 = 0, part2 = 0;
- b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done;
- part0 -= 0x80;
- b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done;
- part0 -= 0x80 << 7;
- b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
- part0 -= 0x80 << 14;
- b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
- part0 -= 0x80 << 21;
- b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done;
- part1 -= 0x80;
- b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done;
- part1 -= 0x80 << 7;
- b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
- part1 -= 0x80 << 14;
- b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
- part1 -= 0x80 << 21;
- b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done;
- part2 -= 0x80;
- b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done;
- // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
+ b = *(ptr++); part0 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part0 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part1 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part1 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part2 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part2 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
// We have overrun the maximum size of a varint (10 bytes). The data
// must be corrupt.
- return std::make_pair(0, false);
+ return false;
done:
Advance(ptr - buffer_);
- return std::make_pair((static_cast<uint64>(part0)) |
- (static_cast<uint64>(part1) << 28) |
- (static_cast<uint64>(part2) << 56),
- true);
+ *value = (static_cast<uint64>(part0) ) |
+ (static_cast<uint64>(part1) << 28) |
+ (static_cast<uint64>(part2) << 56);
+ return true;
} else {
- uint64 temp;
- bool success = ReadVarint64Slow(&temp);
- return std::make_pair(temp, success);
+ return ReadVarint64Slow(value);
}
}
@@ -618,8 +555,7 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
- had_error_(false),
- aliasing_enabled_(false) {
+ had_error_(false) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
@@ -629,15 +565,8 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
}
CodedOutputStream::~CodedOutputStream() {
- Trim();
-}
-
-void CodedOutputStream::Trim() {
if (buffer_size_ > 0) {
output_->BackUp(buffer_size_);
- total_bytes_ -= buffer_size_;
- buffer_size_ = 0;
- buffer_ = NULL;
}
}
@@ -680,18 +609,6 @@ uint8* CodedOutputStream::WriteRawToArray(
}
-void CodedOutputStream::WriteAliasedRaw(const void* data, int size) {
- if (size < buffer_size_
- ) {
- WriteRaw(data, size);
- } else {
- Trim();
-
- total_bytes_ += size;
- had_error_ |= !output_->WriteAliasedRaw(data, size);
- }
-}
-
void CodedOutputStream::WriteLittleEndian32(uint32 value) {
uint8 bytes[sizeof(value)];
@@ -722,12 +639,61 @@ void CodedOutputStream::WriteLittleEndian64(uint64 value) {
}
}
-void CodedOutputStream::WriteVarint32SlowPath(uint32 value) {
- uint8 bytes[kMaxVarint32Bytes];
- uint8* target = &bytes[0];
- uint8* end = WriteVarint32ToArray(value, target);
- int size = end - target;
- WriteRaw(bytes, size);
+inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
+ uint32 value, uint8* target) {
+ target[0] = static_cast<uint8>(value | 0x80);
+ if (value >= (1 << 7)) {
+ target[1] = static_cast<uint8>((value >> 7) | 0x80);
+ if (value >= (1 << 14)) {
+ target[2] = static_cast<uint8>((value >> 14) | 0x80);
+ if (value >= (1 << 21)) {
+ target[3] = static_cast<uint8>((value >> 21) | 0x80);
+ if (value >= (1 << 28)) {
+ target[4] = static_cast<uint8>(value >> 28);
+ return target + 5;
+ } else {
+ target[3] &= 0x7F;
+ return target + 4;
+ }
+ } else {
+ target[2] &= 0x7F;
+ return target + 3;
+ }
+ } else {
+ target[1] &= 0x7F;
+ return target + 2;
+ }
+ } else {
+ target[0] &= 0x7F;
+ return target + 1;
+ }
+}
+
+void CodedOutputStream::WriteVarint32(uint32 value) {
+ if (buffer_size_ >= kMaxVarint32Bytes) {
+ // Fast path: We have enough bytes left in the buffer to guarantee that
+ // this write won't cross the end, so we can skip the checks.
+ uint8* target = buffer_;
+ uint8* end = WriteVarint32FallbackToArrayInline(value, target);
+ int size = end - target;
+ Advance(size);
+ } else {
+ // Slow path: This write might cross the end of the buffer, so we
+ // compose the bytes first then use WriteRaw().
+ uint8 bytes[kMaxVarint32Bytes];
+ int size = 0;
+ while (value > 0x7F) {
+ bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
+ value >>= 7;
+ }
+ bytes[size++] = static_cast<uint8>(value) & 0x7F;
+ WriteRaw(bytes, size);
+ }
+}
+
+uint8* CodedOutputStream::WriteVarint32FallbackToArray(
+ uint32 value, uint8* target) {
+ return WriteVarint32FallbackToArrayInline(value, target);
}
inline uint8* CodedOutputStream::WriteVarint64ToArrayInline(
@@ -886,13 +852,6 @@ int CodedOutputStream::VarintSize64(uint64 value) {
}
}
-uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str,
- uint8* target) {
- GOOGLE_DCHECK_LE(str.size(), kuint32max);
- target = WriteVarint32ToArray(str.size(), target);
- return WriteStringToArray(str, target);
-}
-
} // namespace io
} // namespace protobuf
} // namespace google

Powered by Google App Engine
This is Rietveld 408576698