| Index: base/pickle.cc
|
| diff --git a/base/pickle.cc b/base/pickle.cc
|
| index 1d06af350fa43c738a44bc4f21887091f1fca8c6..c88503ced08ea79df6c81b8304607cc042391f87 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_after_header_(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_after_header_(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, size_t data_len)
|
| : header_(reinterpret_cast<Header*>(const_cast<char*>(data))),
|
| header_size_(0),
|
| - capacity_(kCapacityReadOnly) {
|
| + capacity_after_header_(kCapacityReadOnly),
|
| + write_offset_(0) {
|
| if (data_len >= sizeof(Header))
|
| header_size_ = data_len - header_->payload_size;
|
|
|
| @@ -189,15 +192,15 @@ Pickle::Pickle(const char* data, size_t data_len)
|
| Pickle::Pickle(const Pickle& other)
|
| : header_(NULL),
|
| header_size_(other.header_size_),
|
| - capacity_(0) {
|
| + capacity_after_header_(0),
|
| + write_offset_(other.write_offset_) {
|
| size_t payload_size = header_size_ + other.header_->payload_size;
|
| - bool resized = Resize(payload_size);
|
| - CHECK(resized); // Realloc failed.
|
| + Resize(payload_size);
|
| memcpy(header_, other.header_, payload_size);
|
| }
|
|
|
| Pickle::~Pickle() {
|
| - if (capacity_ != kCapacityReadOnly)
|
| + if (capacity_after_header_ != kCapacityReadOnly)
|
| free(header_);
|
| }
|
|
|
| @@ -206,19 +209,19 @@ Pickle& Pickle::operator=(const Pickle& other) {
|
| NOTREACHED();
|
| return *this;
|
| }
|
| - if (capacity_ == kCapacityReadOnly) {
|
| + if (capacity_after_header_ == kCapacityReadOnly) {
|
| header_ = NULL;
|
| - capacity_ = 0;
|
| + capacity_after_header_ = 0;
|
| }
|
| if (header_size_ != other.header_size_) {
|
| free(header_);
|
| header_ = NULL;
|
| header_size_ = other.header_size_;
|
| }
|
| - bool resized = Resize(other.header_size_ + other.header_->payload_size);
|
| - CHECK(resized); // Realloc failed.
|
| + Resize(other.header_->payload_size);
|
| memcpy(header_, other.header_,
|
| other.header_size_ + other.header_->payload_size);
|
| + write_offset_ = other.write_offset_;
|
| return *this;
|
| }
|
|
|
| @@ -249,64 +252,31 @@ 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) {
|
| - DCHECK_NE(kCapacityReadOnly, capacity_) << "oops: pickle is readonly";
|
| -
|
| - char* dest = BeginWrite(data_len);
|
| - if (!dest)
|
| - return false;
|
| -
|
| - memcpy(dest, data, data_len);
|
| -
|
| - EndWrite(dest, data_len);
|
| +bool Pickle::WriteBytes(const void* data, int length) {
|
| + WriteBytesCommon(data, length);
|
| return true;
|
| }
|
|
|
| -void Pickle::Reserve(size_t additional_capacity) {
|
| - // 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 + additional_capacity;
|
| - size_t needed_size = header_size_ + new_size;
|
| - if (needed_size > capacity_)
|
| - Resize(capacity_ * 2 + needed_size);
|
| -}
|
| -
|
| -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)))
|
| - return NULL;
|
| -
|
| +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_after_header_)
|
| + Resize(capacity_after_header_ * 2 + new_size);
|
| }
|
|
|
| -bool Pickle::Resize(size_t new_capacity) {
|
| +void Pickle::Resize(size_t new_capacity) {
|
| new_capacity = AlignInt(new_capacity, kPayloadUnit);
|
|
|
| - CHECK_NE(capacity_, kCapacityReadOnly);
|
| - void* p = realloc(header_, new_capacity);
|
| - if (!p)
|
| - return false;
|
| -
|
| + CHECK_NE(capacity_after_header_, kCapacityReadOnly);
|
| + void* p = realloc(header_, header_size_ + new_capacity);
|
| + CHECK(p);
|
| header_ = reinterpret_cast<Header*>(p);
|
| - capacity_ = new_capacity;
|
| - return true;
|
| + capacity_after_header_ = new_capacity;
|
| }
|
|
|
| // static
|
| @@ -327,3 +297,32 @@ const char* Pickle::FindNext(size_t header_size,
|
|
|
| return (payload_end > end) ? NULL : payload_end;
|
| }
|
| +
|
| +template <size_t length> void Pickle::WriteBytesStatic(const void* data) {
|
| + WriteBytesCommon(data, length);
|
| +}
|
| +
|
| +template void Pickle::WriteBytesStatic<2>(const void* data);
|
| +template void Pickle::WriteBytesStatic<4>(const void* data);
|
| +template void Pickle::WriteBytesStatic<8>(const void* data);
|
| +
|
| +inline void Pickle::WriteBytesCommon(const void* data, size_t length) {
|
| + DCHECK_NE(kCapacityReadOnly, capacity_after_header_)
|
| + << "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_after_header_) {
|
| + Resize(std::max(capacity_after_header_ * 2, new_size));
|
| + }
|
| +
|
| + char* write = mutable_payload() + write_offset_;
|
| + memcpy(write, data, length);
|
| + memset(write + length, 0, data_len - length);
|
| + header_->payload_size = static_cast<uint32>(write_offset_ + length);
|
| + write_offset_ = new_size;
|
| +}
|
|
|