| Index: base/pickle.cc
|
| diff --git a/base/pickle.cc b/base/pickle.cc
|
| index 5c233475b116ea88a6f302568ce290da328dc22a..3a59177f32ff312f571917daf30c7f764ec78eac 100644
|
| --- a/base/pickle.cc
|
| +++ b/base/pickle.cc
|
| @@ -153,7 +153,8 @@ bool PickleIterator::ReadBytes(const char** data, int length) {
|
| Pickle::Pickle()
|
| : header_(NULL),
|
| header_size_(sizeof(Header)),
|
| - capacity_(0) {
|
| + capacity_(0),
|
| + write_offset_(0) {
|
| Resize(kPayloadUnit);
|
| header_->payload_size = 0;
|
| }
|
| @@ -161,7 +162,8 @@ Pickle::Pickle()
|
| Pickle::Pickle(int header_size)
|
| : header_(NULL),
|
| header_size_(AlignInt(header_size, sizeof(uint32))),
|
| - capacity_(0) {
|
| + capacity_(0),
|
| + write_offset_(0) {
|
| DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header));
|
| DCHECK_LE(header_size, kPayloadUnit);
|
| Resize(kPayloadUnit);
|
| @@ -171,7 +173,8 @@ Pickle::Pickle(int header_size)
|
| Pickle::Pickle(const char* data, int data_len)
|
| : header_(reinterpret_cast<Header*>(const_cast<char*>(data))),
|
| header_size_(0),
|
| - capacity_(kCapacityReadOnly) {
|
| + capacity_(kCapacityReadOnly),
|
| + write_offset_(0) {
|
| if (data_len >= static_cast<int>(sizeof(Header)))
|
| header_size_ = data_len - header_->payload_size;
|
|
|
| @@ -189,10 +192,10 @@ Pickle::Pickle(const char* data, int data_len)
|
| Pickle::Pickle(const Pickle& other)
|
| : header_(NULL),
|
| header_size_(other.header_size_),
|
| - capacity_(0) {
|
| - size_t payload_size = header_size_ + other.header_->payload_size;
|
| - Resize(payload_size);
|
| - memcpy(header_, other.header_, payload_size);
|
| + capacity_(0),
|
| + write_offset_(other.write_offset_) {
|
| + Resize(other.header_->payload_size);
|
| + memcpy(header_, other.header_, header_size_ + other.header_->payload_size);
|
| }
|
|
|
| Pickle::~Pickle() {
|
| @@ -214,9 +217,10 @@ Pickle& Pickle::operator=(const Pickle& other) {
|
| header_ = NULL;
|
| header_size_ = other.header_size_;
|
| }
|
| - Resize(other.header_size_ + other.header_->payload_size);
|
| + Resize(other.header_->payload_size);
|
| memcpy(header_, other.header_,
|
| other.header_size_ + other.header_->payload_size);
|
| + write_offset_ = other.write_offset_;
|
| return *this;
|
| }
|
|
|
| @@ -247,58 +251,56 @@ bool Pickle::WriteData(const char* data, int length) {
|
| return length >= 0 && WriteInt(length) && WriteBytes(data, length);
|
| }
|
|
|
| -bool Pickle::WriteBytes(const void* data, int data_len) {
|
| +inline void Pickle::WriteBytesCommon(const void* data, size_t length) {
|
| DCHECK_NE(kCapacityReadOnly, capacity_) << "oops: pickle is readonly";
|
| + size_t data_len = AlignInt(length, sizeof(uint32));
|
| + DCHECK_GE(data_len, length);
|
| +#ifdef ARCH_CPU_64_BITS
|
| + DCHECK_LE(data_len, kuint32max);
|
| +#endif
|
| + DCHECK_LE(write_offset_, kuint32max - data_len);
|
| + size_t new_size = write_offset_ + data_len;
|
| + if (new_size > capacity_) {
|
| + Resize(std::max(capacity_ * 2, new_size));
|
| + }
|
|
|
| - char* dest = BeginWrite(data_len);
|
| - if (!dest)
|
| - return false;
|
| -
|
| - memcpy(dest, data, data_len);
|
| + char* write = mutable_payload() + write_offset_;
|
| + memcpy(write, data, length);
|
| + memset(write + length, 0, data_len - length);
|
| + header_->payload_size = write_offset_ + length;
|
| + write_offset_ = new_size;
|
| +}
|
|
|
| - EndWrite(dest, data_len);
|
| +bool Pickle::WriteBytes(const void* data, int length) {
|
| + WriteBytesCommon(data, length);
|
| return true;
|
| }
|
|
|
| -void Pickle::Reserve(size_t length) {
|
| - // write at a uint32-aligned offset from the beginning of the header
|
| - size_t offset = AlignInt(header_->payload_size, sizeof(uint32));
|
| -
|
| - size_t new_size = offset + length;
|
| - size_t needed_size = header_size_ + new_size;
|
| - if (needed_size > capacity_)
|
| - Resize(capacity_ * 2 + needed_size);
|
| +template <size_t length> void Pickle::WriteBytesStatic(const void* data) {
|
| + WriteBytesCommon(data, length);
|
| }
|
|
|
| -char* Pickle::BeginWrite(size_t length) {
|
| - // write at a uint32-aligned offset from the beginning of the header
|
| - size_t offset = AlignInt(header_->payload_size, sizeof(uint32));
|
| -
|
| - size_t new_size = offset + length;
|
| - size_t needed_size = header_size_ + new_size;
|
| - if (needed_size > capacity_)
|
| - Resize(std::max(capacity_ * 2, needed_size));
|
| +template void Pickle::WriteBytesStatic<2>(const void* data);
|
| +template void Pickle::WriteBytesStatic<4>(const void* data);
|
| +template void Pickle::WriteBytesStatic<8>(const void* data);
|
|
|
| +void Pickle::Reserve(size_t length) {
|
| + size_t data_len = AlignInt(length, sizeof(uint32));
|
| + DCHECK_GE(data_len, length);
|
| #ifdef ARCH_CPU_64_BITS
|
| - DCHECK_LE(length, kuint32max);
|
| + DCHECK_LE(data_len, kuint32max);
|
| #endif
|
| -
|
| - header_->payload_size = static_cast<uint32>(new_size);
|
| - return mutable_payload() + offset;
|
| -}
|
| -
|
| -void Pickle::EndWrite(char* dest, int length) {
|
| - // Zero-pad to keep tools like valgrind from complaining about uninitialized
|
| - // memory.
|
| - if (length % sizeof(uint32))
|
| - memset(dest + length, 0, sizeof(uint32) - (length % sizeof(uint32)));
|
| + DCHECK_LE(write_offset_, kuint32max - data_len);
|
| + size_t new_size = write_offset_ + data_len;
|
| + if (new_size > capacity_)
|
| + Resize(capacity_ * 2 + new_size);
|
| }
|
|
|
| void Pickle::Resize(size_t new_capacity) {
|
| CHECK_NE(capacity_, kCapacityReadOnly);
|
|
|
| new_capacity = AlignInt(new_capacity, kPayloadUnit);
|
| - void* p = realloc(header_, new_capacity);
|
| + void* p = realloc(header_, header_size_ + new_capacity);
|
| header_ = reinterpret_cast<Header*>(p);
|
| capacity_ = new_capacity;
|
| }
|
|
|