| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/pickle.h" | 5 #include "base/pickle.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include <algorithm> // for max() | 9 #include <algorithm> // for max() |
| 10 | 10 |
| 11 //------------------------------------------------------------------------------ | 11 //------------------------------------------------------------------------------ |
| 12 | 12 |
| 13 using base::char16; | 13 using base::char16; |
| 14 using base::string16; | 14 using base::string16; |
| 15 | 15 |
| 16 // static | 16 // static |
| 17 const int Pickle::kPayloadUnit = 64; | 17 const int Pickle::kPayloadUnit = 64; |
| 18 | 18 |
| 19 static const size_t kCapacityReadOnly = static_cast<size_t>(-1); | 19 static const size_t kCapacityReadOnly = static_cast<size_t>(-1); |
| 20 | 20 |
| 21 PickleIterator::PickleIterator(const Pickle& pickle) | 21 PickleIterator::PickleIterator(const Pickle& pickle) |
| 22 : read_ptr_(pickle.payload()), | 22 : read_ptr_(pickle.payload()), |
| 23 read_end_ptr_(pickle.end_of_payload()) { | 23 read_end_ptr_(pickle.end_of_payload()) { |
| 24 } | 24 } |
| 25 | 25 |
| 26 template <typename Type> | 26 template <typename Type> |
| 27 inline bool PickleIterator::ReadBuiltinType(Type* result) { | 27 bool PickleIterator::ReadBuiltinType(Type* result) { |
| 28 const char* read_from = GetReadPointerAndAdvance<Type>(); | 28 const char* read_from = GetReadPointerAndAdvance<Type>(); |
| 29 if (!read_from) | 29 if (!read_from) |
| 30 return false; | 30 return false; |
| 31 if (sizeof(Type) > sizeof(uint32)) | 31 if (sizeof(Type) > sizeof(uint32)) |
| 32 memcpy(result, read_from, sizeof(*result)); | 32 memcpy(result, read_from, sizeof(*result)); |
| 33 else | 33 else |
| 34 *result = *reinterpret_cast<const Type*>(read_from); | 34 *result = *reinterpret_cast<const Type*>(read_from); |
| 35 return true; | 35 return true; |
| 36 } | 36 } |
| 37 | 37 |
| 38 template<typename Type> | 38 template<typename Type> |
| 39 inline const char* PickleIterator::GetReadPointerAndAdvance() { | 39 const char* PickleIterator::GetReadPointerAndAdvance() { |
| 40 const char* current_read_ptr = read_ptr_; | 40 const char* current_read_ptr = read_ptr_; |
| 41 if (read_ptr_ + sizeof(Type) > read_end_ptr_) | 41 if (read_ptr_ + sizeof(Type) > read_end_ptr_) |
| 42 return NULL; | 42 return NULL; |
| 43 if (sizeof(Type) < sizeof(uint32)) | 43 if (sizeof(Type) < sizeof(uint32)) |
| 44 read_ptr_ += AlignInt(sizeof(Type), sizeof(uint32)); | 44 read_ptr_ += AlignInt(sizeof(Type), sizeof(uint32)); |
| 45 else | 45 else |
| 46 read_ptr_ += sizeof(Type); | 46 read_ptr_ += sizeof(Type); |
| 47 return current_read_ptr; | 47 return current_read_ptr; |
| 48 } | 48 } |
| 49 | 49 |
| 50 const char* PickleIterator::GetReadPointerAndAdvance(int num_bytes) { | 50 const char* PickleIterator::GetReadPointerAndAdvance(int num_bytes) { |
| 51 if (num_bytes < 0 || read_end_ptr_ - read_ptr_ < num_bytes) | 51 if (num_bytes < 0 || read_end_ptr_ - read_ptr_ < num_bytes) |
| 52 return NULL; | 52 return NULL; |
| 53 const char* current_read_ptr = read_ptr_; | 53 const char* current_read_ptr = read_ptr_; |
| 54 read_ptr_ += AlignInt(num_bytes, sizeof(uint32)); | 54 read_ptr_ += AlignInt(num_bytes, sizeof(uint32)); |
| 55 return current_read_ptr; | 55 return current_read_ptr; |
| 56 } | 56 } |
| 57 | 57 |
| 58 inline const char* PickleIterator::GetReadPointerAndAdvance(int num_elements, | 58 const char* PickleIterator::GetReadPointerAndAdvance(int num_elements, |
| 59 size_t size_element) { | 59 size_t size_element) { |
| 60 // Check for int32 overflow. | 60 // Check for int32 overflow. |
| 61 int64 num_bytes = static_cast<int64>(num_elements) * size_element; | 61 int64 num_bytes = static_cast<int64>(num_elements) * size_element; |
| 62 int num_bytes32 = static_cast<int>(num_bytes); | 62 int num_bytes32 = static_cast<int>(num_bytes); |
| 63 if (num_bytes != static_cast<int64>(num_bytes32)) | 63 if (num_bytes != static_cast<int64>(num_bytes32)) |
| 64 return NULL; | 64 return NULL; |
| 65 return GetReadPointerAndAdvance(num_bytes32); | 65 return GetReadPointerAndAdvance(num_bytes32); |
| 66 } | 66 } |
| 67 | 67 |
| 68 bool PickleIterator::ReadBool(bool* result) { | 68 bool PickleIterator::ReadBool(bool* result) { |
| 69 return ReadBuiltinType(result); | 69 return ReadBuiltinType(result); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 } | 308 } |
| 309 | 309 |
| 310 template <size_t length> void Pickle::WriteBytesStatic(const void* data) { | 310 template <size_t length> void Pickle::WriteBytesStatic(const void* data) { |
| 311 WriteBytesCommon(data, length); | 311 WriteBytesCommon(data, length); |
| 312 } | 312 } |
| 313 | 313 |
| 314 template void Pickle::WriteBytesStatic<2>(const void* data); | 314 template void Pickle::WriteBytesStatic<2>(const void* data); |
| 315 template void Pickle::WriteBytesStatic<4>(const void* data); | 315 template void Pickle::WriteBytesStatic<4>(const void* data); |
| 316 template void Pickle::WriteBytesStatic<8>(const void* data); | 316 template void Pickle::WriteBytesStatic<8>(const void* data); |
| 317 | 317 |
| 318 inline void Pickle::WriteBytesCommon(const void* data, size_t length) { | 318 void Pickle::WriteBytesCommon(const void* data, size_t length) { |
| 319 DCHECK_NE(kCapacityReadOnly, capacity_after_header_) | 319 DCHECK_NE(kCapacityReadOnly, capacity_after_header_) |
| 320 << "oops: pickle is readonly"; | 320 << "oops: pickle is readonly"; |
| 321 size_t data_len = AlignInt(length, sizeof(uint32)); | 321 size_t data_len = AlignInt(length, sizeof(uint32)); |
| 322 DCHECK_GE(data_len, length); | 322 DCHECK_GE(data_len, length); |
| 323 #ifdef ARCH_CPU_64_BITS | 323 #ifdef ARCH_CPU_64_BITS |
| 324 DCHECK_LE(data_len, kuint32max); | 324 DCHECK_LE(data_len, kuint32max); |
| 325 #endif | 325 #endif |
| 326 DCHECK_LE(write_offset_, kuint32max - data_len); | 326 DCHECK_LE(write_offset_, kuint32max - data_len); |
| 327 size_t new_size = write_offset_ + data_len; | 327 size_t new_size = write_offset_ + data_len; |
| 328 if (new_size > capacity_after_header_) { | 328 if (new_size > capacity_after_header_) { |
| 329 Resize(std::max(capacity_after_header_ * 2, new_size)); | 329 Resize(std::max(capacity_after_header_ * 2, new_size)); |
| 330 } | 330 } |
| 331 | 331 |
| 332 char* write = mutable_payload() + write_offset_; | 332 char* write = mutable_payload() + write_offset_; |
| 333 memcpy(write, data, length); | 333 memcpy(write, data, length); |
| 334 memset(write + length, 0, data_len - length); | 334 memset(write + length, 0, data_len - length); |
| 335 header_->payload_size = static_cast<uint32>(write_offset_ + length); | 335 header_->payload_size = static_cast<uint32>(write_offset_ + length); |
| 336 write_offset_ = new_size; | 336 write_offset_ = new_size; |
| 337 } | 337 } |
| OLD | NEW |