Chromium Code Reviews| Index: base/pickle.cc |
| diff --git a/base/pickle.cc b/base/pickle.cc |
| index 5c233475b116ea88a6f302568ce290da328dc22a..3ff63690ea498f8e5e1e9e8ea8e79ec22e1cd9f5 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,49 @@ 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) { |
|
jar (doing other things)
2013/10/24 22:36:48
Note that inline is a "hint" and is traditionally
piman
2013/10/24 23:54:29
Both clang and gcc failed to inline without it.
Wi
|
| DCHECK_NE(kCapacityReadOnly, capacity_) << "oops: pickle is readonly"; |
| +#ifdef ARCH_CPU_64_BITS |
| + DCHECK_LE(static_cast<size_t>(length), kuint32max); |
|
jar (doing other things)
2013/10/24 22:36:48
nit: length is already of type size_t
Also... if
piman
2013/10/24 23:54:29
Yep, sorry, copy-and-paste from the previous versi
piman
2013/10/25 03:11:41
Done.
|
| +#endif |
| + size_t data_len = AlignInt(length, sizeof(uint32)); |
| + size_t new_size = write_offset_ + data_len; |
|
jar (doing other things)
2013/10/24 22:36:48
How are you assured that this is not an overflow?
piman
2013/10/24 23:54:29
The previous code (in BeginWrite) didn't check for
|
| + 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); |
|
jar (doing other things)
2013/10/24 22:36:48
For all the template magic... it appears that you
piman
2013/10/24 23:54:29
It's possible to do, but then you need template in
|
| } |
| -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)); |
| +template void Pickle::WriteBytesStatic<2>(const void* data); |
| +template void Pickle::WriteBytesStatic<4>(const void* data); |
| +template void Pickle::WriteBytesStatic<8>(const void* data); |
| - 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)); |
| - |
| -#ifdef ARCH_CPU_64_BITS |
| - DCHECK_LE(length, 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))); |
| +void Pickle::Reserve(size_t length) { |
| + size_t data_len = AlignInt(length, sizeof(uint32)); |
| + 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; |
| } |