| Index: base/pickle.cc
|
| diff --git a/base/pickle.cc b/base/pickle.cc
|
| index 28b6292290073c2759eaffc5c6a2dde7bf01493f..a095e3593147db9c7b1c574fcfe8f374daa2fc5f 100644
|
| --- a/base/pickle.cc
|
| +++ b/base/pickle.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -15,6 +15,143 @@ const int Pickle::kPayloadUnit = 64;
|
|
|
| static const size_t kCapacityReadOnly = static_cast<size_t>(-1);
|
|
|
| +PickleIterator::PickleIterator(const Pickle& pickle)
|
| + : read_ptr_(pickle.payload()),
|
| + read_end_ptr_(pickle.end_of_payload()) {
|
| +}
|
| +
|
| +template <typename Type>
|
| +inline bool PickleIterator::ReadBuiltinType(Type* result) {
|
| + const char* read_from = GetReadPointerAndAdvance<Type>();
|
| + if (!read_from)
|
| + return false;
|
| + if (sizeof(Type) > sizeof(uint32))
|
| + memcpy(result, read_from, sizeof(*result));
|
| + else
|
| + *result = *reinterpret_cast<const Type*>(read_from);
|
| + return true;
|
| +}
|
| +
|
| +template<typename Type>
|
| +inline const char* PickleIterator::GetReadPointerAndAdvance() {
|
| + const char* current_read_ptr = read_ptr_;
|
| + if (read_ptr_ + sizeof(Type) > read_end_ptr_)
|
| + return NULL;
|
| + if (sizeof(Type) < sizeof(uint32))
|
| + read_ptr_ += AlignInt(sizeof(Type), sizeof(uint32));
|
| + else
|
| + read_ptr_ += sizeof(Type);
|
| + return current_read_ptr;
|
| +}
|
| +
|
| +const char* PickleIterator::GetReadPointerAndAdvance(int num_bytes) {
|
| + const char* current_read_ptr = read_ptr_;
|
| + const char* end_data_ptr = read_ptr_ + num_bytes;
|
| + if (num_bytes < 0)
|
| + return NULL;
|
| + // Check for enough space and for wrapping.
|
| + if (end_data_ptr > read_end_ptr_ || end_data_ptr < current_read_ptr)
|
| + return NULL;
|
| + read_ptr_ += AlignInt(num_bytes, sizeof(uint32));
|
| + return current_read_ptr;
|
| +}
|
| +
|
| +inline const char* PickleIterator::GetReadPointerAndAdvance(int num_elements,
|
| + size_t size_element) {
|
| + // Check for int32 overflow.
|
| + int64 num_bytes = static_cast<int64>(num_elements) * size_element;
|
| + int num_bytes32 = static_cast<int>(num_bytes);
|
| + if (num_bytes != static_cast<int64>(num_bytes32))
|
| + return NULL;
|
| + return GetReadPointerAndAdvance(num_bytes32);
|
| +}
|
| +
|
| +bool PickleIterator::ReadBool(bool* result) {
|
| + return ReadBuiltinType(result);
|
| +}
|
| +
|
| +bool PickleIterator::ReadInt(int* result) {
|
| + return ReadBuiltinType(result);
|
| +}
|
| +
|
| +bool PickleIterator::ReadLong(long* result) {
|
| + return ReadBuiltinType(result);
|
| +}
|
| +
|
| +bool PickleIterator::ReadSize(size_t* result) {
|
| + return ReadBuiltinType(result);
|
| +}
|
| +
|
| +bool PickleIterator::ReadUInt16(uint16* result) {
|
| + return ReadBuiltinType(result);
|
| +}
|
| +
|
| +bool PickleIterator::ReadUInt32(uint32* result) {
|
| + return ReadBuiltinType(result);
|
| +}
|
| +
|
| +bool PickleIterator::ReadInt64(int64* result) {
|
| + return ReadBuiltinType(result);
|
| +}
|
| +
|
| +bool PickleIterator::ReadUInt64(uint64* result) {
|
| + return ReadBuiltinType(result);
|
| +}
|
| +
|
| +bool PickleIterator::ReadString(std::string* result) {
|
| + int len;
|
| + if (!ReadInt(&len))
|
| + return false;
|
| + const char* read_from = GetReadPointerAndAdvance(len);
|
| + if (!read_from)
|
| + return false;
|
| +
|
| + result->assign(read_from, len);
|
| + return true;
|
| +}
|
| +
|
| +bool PickleIterator::ReadWString(std::wstring* result) {
|
| + int len;
|
| + if (!ReadInt(&len))
|
| + return false;
|
| + const char* read_from = GetReadPointerAndAdvance(len, sizeof(wchar_t));
|
| + if (!read_from)
|
| + return false;
|
| +
|
| + result->assign(reinterpret_cast<const wchar_t*>(read_from), len);
|
| + return true;
|
| +}
|
| +
|
| +bool PickleIterator::ReadString16(string16* result) {
|
| + int len;
|
| + if (!ReadInt(&len))
|
| + return false;
|
| + const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16));
|
| + if (!read_from)
|
| + return false;
|
| +
|
| + result->assign(reinterpret_cast<const char16*>(read_from), len);
|
| + return true;
|
| +}
|
| +
|
| +bool PickleIterator::ReadData(const char** data, int* length) {
|
| + *length = 0;
|
| + *data = 0;
|
| +
|
| + if (!ReadInt(length))
|
| + return false;
|
| +
|
| + return ReadBytes(data, *length);
|
| +}
|
| +
|
| +bool PickleIterator::ReadBytes(const char** data, int length) {
|
| + const char* read_from = GetReadPointerAndAdvance(length);
|
| + if (!read_from)
|
| + return false;
|
| + *data = read_from;
|
| + return true;
|
| +}
|
| +
|
| // Payload is uint32 aligned.
|
|
|
| Pickle::Pickle()
|
| @@ -94,209 +231,6 @@ Pickle& Pickle::operator=(const Pickle& other) {
|
| return *this;
|
| }
|
|
|
| -bool Pickle::ReadBool(void** iter, bool* result) const {
|
| - DCHECK(iter);
|
| -
|
| - int tmp;
|
| - if (!ReadInt(iter, &tmp))
|
| - return false;
|
| - DCHECK(0 == tmp || 1 == tmp);
|
| - *result = tmp ? true : false;
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadInt(void** iter, int* result) const {
|
| - DCHECK(iter);
|
| - if (!*iter)
|
| - *iter = const_cast<char*>(payload());
|
| -
|
| - if (!IteratorHasRoomFor(*iter, sizeof(*result)))
|
| - return false;
|
| -
|
| - // TODO(jar): http://crbug.com/13108 Pickle should be cleaned up, and not
|
| - // dependent on alignment.
|
| - // Next line is otherwise the same as: memcpy(result, *iter, sizeof(*result));
|
| - *result = *reinterpret_cast<int*>(*iter);
|
| -
|
| - UpdateIter(iter, sizeof(*result));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadLong(void** iter, long* result) const {
|
| - DCHECK(iter);
|
| - if (!*iter)
|
| - *iter = const_cast<char*>(payload());
|
| -
|
| - if (!IteratorHasRoomFor(*iter, sizeof(*result)))
|
| - return false;
|
| -
|
| - // TODO(jar): http://crbug.com/13108 Pickle should be cleaned up, and not
|
| - // dependent on alignment.
|
| - memcpy(result, *iter, sizeof(*result));
|
| -
|
| - UpdateIter(iter, sizeof(*result));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadSize(void** iter, size_t* result) const {
|
| - DCHECK(iter);
|
| - if (!*iter)
|
| - *iter = const_cast<char*>(payload());
|
| -
|
| - if (!IteratorHasRoomFor(*iter, sizeof(*result)))
|
| - return false;
|
| -
|
| - // TODO(jar): http://crbug.com/13108 Pickle should be cleaned up, and not
|
| - // dependent on alignment.
|
| - // Next line is otherwise the same as: memcpy(result, *iter, sizeof(*result));
|
| - *result = *reinterpret_cast<size_t*>(*iter);
|
| -
|
| - UpdateIter(iter, sizeof(*result));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadUInt16(void** iter, uint16* result) const {
|
| - DCHECK(iter);
|
| - if (!*iter)
|
| - *iter = const_cast<char*>(payload());
|
| -
|
| - if (!IteratorHasRoomFor(*iter, sizeof(*result)))
|
| - return false;
|
| -
|
| - memcpy(result, *iter, sizeof(*result));
|
| -
|
| - UpdateIter(iter, sizeof(*result));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadUInt32(void** iter, uint32* result) const {
|
| - DCHECK(iter);
|
| - if (!*iter)
|
| - *iter = const_cast<char*>(payload());
|
| -
|
| - if (!IteratorHasRoomFor(*iter, sizeof(*result)))
|
| - return false;
|
| -
|
| - memcpy(result, *iter, sizeof(*result));
|
| -
|
| - UpdateIter(iter, sizeof(*result));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadInt64(void** iter, int64* result) const {
|
| - DCHECK(iter);
|
| - if (!*iter)
|
| - *iter = const_cast<char*>(payload());
|
| -
|
| - if (!IteratorHasRoomFor(*iter, sizeof(*result)))
|
| - return false;
|
| -
|
| - memcpy(result, *iter, sizeof(*result));
|
| -
|
| - UpdateIter(iter, sizeof(*result));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadUInt64(void** iter, uint64* result) const {
|
| - DCHECK(iter);
|
| - if (!*iter)
|
| - *iter = const_cast<char*>(payload());
|
| -
|
| - if (!IteratorHasRoomFor(*iter, sizeof(*result)))
|
| - return false;
|
| -
|
| - memcpy(result, *iter, sizeof(*result));
|
| -
|
| - UpdateIter(iter, sizeof(*result));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadString(void** iter, std::string* result) const {
|
| - DCHECK(iter);
|
| -
|
| - int len;
|
| - if (!ReadLength(iter, &len))
|
| - return false;
|
| - if (!IteratorHasRoomFor(*iter, len))
|
| - return false;
|
| -
|
| - char* chars = reinterpret_cast<char*>(*iter);
|
| - result->assign(chars, len);
|
| -
|
| - UpdateIter(iter, len);
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadWString(void** iter, std::wstring* result) const {
|
| - DCHECK(iter);
|
| -
|
| - int len;
|
| - if (!ReadLength(iter, &len))
|
| - return false;
|
| - // Avoid integer overflow.
|
| - if (len > INT_MAX / static_cast<int>(sizeof(wchar_t)))
|
| - return false;
|
| - if (!IteratorHasRoomFor(*iter, len * sizeof(wchar_t)))
|
| - return false;
|
| -
|
| - wchar_t* chars = reinterpret_cast<wchar_t*>(*iter);
|
| - result->assign(chars, len);
|
| -
|
| - UpdateIter(iter, len * sizeof(wchar_t));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadString16(void** iter, string16* result) const {
|
| - DCHECK(iter);
|
| -
|
| - int len;
|
| - if (!ReadLength(iter, &len))
|
| - return false;
|
| - if (!IteratorHasRoomFor(*iter, len * sizeof(char16)))
|
| - return false;
|
| -
|
| - char16* chars = reinterpret_cast<char16*>(*iter);
|
| - result->assign(chars, len);
|
| -
|
| - UpdateIter(iter, len * sizeof(char16));
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadData(void** iter, const char** data, int* length) const {
|
| - DCHECK(iter);
|
| - DCHECK(data);
|
| - DCHECK(length);
|
| - *length = 0;
|
| - *data = 0;
|
| -
|
| - if (!ReadLength(iter, length))
|
| - return false;
|
| -
|
| - return ReadBytes(iter, data, *length);
|
| -}
|
| -
|
| -bool Pickle::ReadBytes(void** iter, const char** data, int length) const {
|
| - DCHECK(iter);
|
| - DCHECK(data);
|
| - *data = 0;
|
| - if (!*iter)
|
| - *iter = const_cast<char*>(payload());
|
| -
|
| - if (!IteratorHasRoomFor(*iter, length))
|
| - return false;
|
| -
|
| - *data = reinterpret_cast<const char*>(*iter);
|
| -
|
| - UpdateIter(iter, length);
|
| - return true;
|
| -}
|
| -
|
| -bool Pickle::ReadLength(void** iter, int* result) const {
|
| - if (!ReadInt(iter, result))
|
| - return false;
|
| - return ((*result) >= 0);
|
| -}
|
| -
|
| bool Pickle::WriteString(const std::string& value) {
|
| if (!WriteInt(static_cast<int>(value.size())))
|
| return false;
|
|
|