aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/io/coded_stream.cc
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-07-29 01:13:20 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-07-29 01:13:20 +0000
commit80b1d62bfcea65c59e2160da71dad84b1bd19cef (patch)
tree5423b830c53174fec83a7ea01ff0877e11c1ddb6 /src/google/protobuf/io/coded_stream.cc
parentd2fd0638c309113ccae3731a58e30419f522269a (diff)
Submit recent changes from internal branch, including "lite mode" for
C++ and Java. See CHANGES.txt for more details.
Diffstat (limited to 'src/google/protobuf/io/coded_stream.cc')
-rw-r--r--src/google/protobuf/io/coded_stream.cc96
1 files changed, 46 insertions, 50 deletions
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 0a00d2bb..e17a4775 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -80,18 +80,49 @@ CodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
recursion_depth_(0),
recursion_limit_(kDefaultRecursionLimit) {
+ // Eagerly Refresh() so buffer space is immediately available.
+ Refresh();
+}
+
+CodedInputStream::CodedInputStream(const uint8* buffer, int size)
+ : input_(NULL),
+ buffer_(buffer),
+ buffer_size_(size),
+ total_bytes_read_(size),
+ overflow_bytes_(0),
+ last_tag_(0),
+ legitimate_message_end_(false),
+ aliasing_enabled_(false),
+ current_limit_(size),
+ buffer_size_after_limit_(0),
+ total_bytes_limit_(kDefaultTotalBytesLimit),
+ total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
+ recursion_depth_(0),
+ recursion_limit_(kDefaultRecursionLimit) {
+ // Note that setting current_limit_ == size is important to prevent some
+ // code paths from trying to access input_ and segfaulting.
}
CodedInputStream::~CodedInputStream() {
+ if (input_ != NULL) {
+ BackUpInputToCurrentPosition();
+ }
+}
+
+
+void CodedInputStream::BackUpInputToCurrentPosition() {
int backup_bytes = buffer_size_ + buffer_size_after_limit_ + overflow_bytes_;
if (backup_bytes > 0) {
- // We still have bytes left over from the last buffer. Back up over
- // them.
input_->BackUp(backup_bytes);
+
+ // total_bytes_read_ doesn't include overflow_bytes_.
+ total_bytes_read_ -= buffer_size_ + buffer_size_after_limit_;
+ buffer_size_ = 0;
+ buffer_size_after_limit_ = 0;
+ overflow_bytes_ = 0;
}
}
-
inline void CodedInputStream::RecomputeBufferLimits() {
buffer_size_ += buffer_size_after_limit_;
int closest_limit = min(current_limit_, total_bytes_limit_);
@@ -193,8 +224,10 @@ bool CodedInputStream::Skip(int count) {
int bytes_until_limit = closest_limit - total_bytes_read_;
if (bytes_until_limit < count) {
// We hit the limit. Skip up to it then fail.
- total_bytes_read_ = closest_limit;
- input_->Skip(bytes_until_limit);
+ if (bytes_until_limit > 0) {
+ total_bytes_read_ = closest_limit;
+ input_->Skip(bytes_until_limit);
+ }
return false;
}
@@ -216,6 +249,7 @@ bool CodedInputStream::ReadRaw(void* buffer, int size) {
memcpy(buffer, buffer_, buffer_size_);
buffer = reinterpret_cast<uint8*>(buffer) + buffer_size_;
size -= buffer_size_;
+ Advance(buffer_size_);
if (!Refresh()) return false;
}
@@ -247,6 +281,7 @@ bool CodedInputStream::ReadString(string* buffer, int size) {
buffer->append(reinterpret_cast<const char*>(buffer_), buffer_size_);
}
size -= buffer_size_;
+ Advance(buffer_size_);
if (!Refresh()) return false;
}
@@ -441,11 +476,11 @@ bool CodedInputStream::ReadVarint64(uint64* value) {
}
bool CodedInputStream::Refresh() {
- if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0) {
- // We've hit a limit. Stop.
- buffer_ += buffer_size_;
- buffer_size_ = 0;
+ GOOGLE_DCHECK_EQ(buffer_size_, 0);
+ if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
+ total_bytes_read_ == current_limit_) {
+ // We've hit a limit. Stop.
int current_position = total_bytes_read_ - buffer_size_after_limit_;
if (current_position >= total_bytes_limit_ &&
@@ -570,10 +605,7 @@ void CodedOutputStream::WriteLittleEndian32(uint32 value) {
bool use_fast = buffer_size_ >= sizeof(value);
uint8* ptr = use_fast ? buffer_ : bytes;
- ptr[0] = static_cast<uint8>(value );
- ptr[1] = static_cast<uint8>(value >> 8);
- ptr[2] = static_cast<uint8>(value >> 16);
- ptr[3] = static_cast<uint8>(value >> 24);
+ WriteLittleEndian32ToArray(value, ptr);
if (use_fast) {
Advance(sizeof(value));
@@ -582,32 +614,13 @@ void CodedOutputStream::WriteLittleEndian32(uint32 value) {
}
}
-uint8* CodedOutputStream::WriteLittleEndian32ToArray(
- uint32 value, uint8* target) {
- target[0] = static_cast<uint8>(value );
- target[1] = static_cast<uint8>(value >> 8);
- target[2] = static_cast<uint8>(value >> 16);
- target[3] = static_cast<uint8>(value >> 24);
- return target + sizeof(value);
-}
-
void CodedOutputStream::WriteLittleEndian64(uint64 value) {
uint8 bytes[sizeof(value)];
- uint32 part0 = static_cast<uint32>(value);
- uint32 part1 = static_cast<uint32>(value >> 32);
-
bool use_fast = buffer_size_ >= sizeof(value);
uint8* ptr = use_fast ? buffer_ : bytes;
- ptr[0] = static_cast<uint8>(part0 );
- ptr[1] = static_cast<uint8>(part0 >> 8);
- ptr[2] = static_cast<uint8>(part0 >> 16);
- ptr[3] = static_cast<uint8>(part0 >> 24);
- ptr[4] = static_cast<uint8>(part1 );
- ptr[5] = static_cast<uint8>(part1 >> 8);
- ptr[6] = static_cast<uint8>(part1 >> 16);
- ptr[7] = static_cast<uint8>(part1 >> 24);
+ WriteLittleEndian64ToArray(value, ptr);
if (use_fast) {
Advance(sizeof(value));
@@ -616,23 +629,6 @@ void CodedOutputStream::WriteLittleEndian64(uint64 value) {
}
}
-uint8* CodedOutputStream::WriteLittleEndian64ToArray(
- uint64 value, uint8* target) {
- uint32 part0 = static_cast<uint32>(value);
- uint32 part1 = static_cast<uint32>(value >> 32);
-
- target[0] = static_cast<uint8>(part0 );
- target[1] = static_cast<uint8>(part0 >> 8);
- target[2] = static_cast<uint8>(part0 >> 16);
- target[3] = static_cast<uint8>(part0 >> 24);
- target[4] = static_cast<uint8>(part1 );
- target[5] = static_cast<uint8>(part1 >> 8);
- target[6] = static_cast<uint8>(part1 >> 16);
- target[7] = static_cast<uint8>(part1 >> 24);
-
- return target + sizeof(value);
-}
-
inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
uint32 value, uint8* target) {
target[0] = static_cast<uint8>(value | 0x80);