pickle.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> // for max() 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int Pickle::kPayloadUnit = 64; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kCapacityReadOnly = static_cast<size_t>(-1); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PickleIterator::PickleIterator(const Pickle& pickle) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : read_ptr_(pickle.payload()), 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_end_ptr_(pickle.end_of_payload()) { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool PickleIterator::ReadBuiltinType(Type* result) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance<Type>(); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizeof(Type) > sizeof(uint32)) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(result, read_from, sizeof(*result)); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = *reinterpret_cast<const Type*>(read_from); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename Type> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const char* PickleIterator::GetReadPointerAndAdvance() { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* current_read_ptr = read_ptr_; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_ptr_ + sizeof(Type) > read_end_ptr_) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizeof(Type) < sizeof(uint32)) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_ptr_ += AlignInt(sizeof(Type), sizeof(uint32)); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_ptr_ += sizeof(Type); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_read_ptr; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* PickleIterator::GetReadPointerAndAdvance(int num_bytes) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_bytes < 0 || read_end_ptr_ - read_ptr_ < num_bytes) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* current_read_ptr = read_ptr_; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_ptr_ += AlignInt(num_bytes, sizeof(uint32)); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_read_ptr; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const char* PickleIterator::GetReadPointerAndAdvance(int num_elements, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size_element) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for int32 overflow. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_bytes = static_cast<int64>(num_elements) * size_element; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_bytes32 = static_cast<int>(num_bytes); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_bytes != static_cast<int64>(num_bytes32)) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetReadPointerAndAdvance(num_bytes32); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadBool(bool* result) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadInt(int* result) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadLong(long* result) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadUInt16(uint16* result) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadUInt32(uint32* result) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadInt64(int64* result) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadUInt64(uint64* result) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PickleIterator::ReadFloat(float* result) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ReadBuiltinType(result); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadString(std::string* result) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(read_from, len); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadWString(std::wstring* result) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len, sizeof(wchar_t)); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const wchar_t*>(read_from), len); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadString16(string16* result) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16)); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const char16*>(read_from), len); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadData(const char** data, int* length) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *length = 0; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = 0; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(length)) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBytes(data, *length); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadBytes(const char** data, int length) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(length); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = read_from; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Payload is uint32 aligned. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle() 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(sizeof(Header)), 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(kPayloadUnit); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_->payload_size = 0; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle(int header_size) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(AlignInt(header_size, sizeof(uint32))), 1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(header_size, kPayloadUnit); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(kPayloadUnit); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_->payload_size = 0; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)Pickle::Pickle(const char* data, size_t data_len) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(reinterpret_cast<Header*>(const_cast<char*>(data))), 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(0), 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(kCapacityReadOnly), 1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (data_len >= sizeof(Header)) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = data_len - header_->payload_size; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (header_size_ > data_len) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = 0; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_size_ != AlignInt(header_size_, sizeof(uint32))) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = 0; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is anything wrong with the data, we're not going to use it. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_size_) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle(const Pickle& other) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(other.header_size_), 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(other.write_offset_) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t payload_size = header_size_ + other.header_->payload_size; 1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(payload_size); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(header_, other.header_, payload_size); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::~Pickle() { 2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (capacity_after_header_ != kCapacityReadOnly) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(header_); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle& Pickle::operator=(const Pickle& other) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this == &other) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (capacity_after_header_ == kCapacityReadOnly) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_ = 0; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_size_ != other.header_size_) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(header_); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = other.header_size_; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(other.header_->payload_size); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(header_, other.header_, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other.header_size_ + other.header_->payload_size); 2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_ = other.write_offset_; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteString(const std::string& value) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), static_cast<int>(value.size())); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteWString(const std::wstring& value) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(value.size() * sizeof(wchar_t))); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteString16(const string16& value) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(value.size()) * sizeof(char16)); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteData(const char* data, int length) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return length >= 0 && WriteInt(length) && WriteBytes(data, length); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool Pickle::WriteBytes(const void* data, int length) { 2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesCommon(data, length); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Pickle::Reserve(size_t length) { 2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t data_len = AlignInt(length, sizeof(uint32)); 2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(data_len, length); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef ARCH_CPU_64_BITS 2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(data_len, kuint32max); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(write_offset_, kuint32max - data_len); 2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t new_size = write_offset_ + data_len; 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (new_size > capacity_after_header_) 2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(capacity_after_header_ * 2 + new_size); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Pickle::Resize(size_t new_capacity) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_capacity = AlignInt(new_capacity, kPayloadUnit); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK_NE(capacity_after_header_, kCapacityReadOnly); 2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void* p = realloc(header_, header_size_ + new_capacity); 2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK(p); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = reinterpret_cast<Header*>(p); 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_ = new_capacity; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* Pickle::FindNext(size_t header_size, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* start, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(header_size, AlignInt(header_size, sizeof(uint32))); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(header_size, static_cast<size_t>(kPayloadUnit)); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (static_cast<size_t>(end - start) < sizeof(Header)) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Header* hdr = reinterpret_cast<const Header*>(start); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* payload_base = start + header_size; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* payload_end = payload_base + hdr->payload_size; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (payload_end < payload_base) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (payload_end > end) ? NULL : payload_end; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template <size_t length> void Pickle::WriteBytesStatic(const void* data) { 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesCommon(data, length); 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<2>(const void* data); 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<4>(const void* data); 3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<8>(const void* data); 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)inline void Pickle::WriteBytesCommon(const void* data, size_t length) { 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_NE(kCapacityReadOnly, capacity_after_header_) 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << "oops: pickle is readonly"; 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t data_len = AlignInt(length, sizeof(uint32)); 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(data_len, length); 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifdef ARCH_CPU_64_BITS 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(data_len, kuint32max); 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(write_offset_, kuint32max - data_len); 3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t new_size = write_offset_ + data_len; 3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (new_size > capacity_after_header_) { 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(std::max(capacity_after_header_ * 2, new_size)); 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) char* write = mutable_payload() + write_offset_; 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memcpy(write, data, length); 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memset(write + length, 0, data_len - length); 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) header_->payload_size = static_cast<uint32>(write_offset_ + length); 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_ = new_size; 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 329