pickle.cc revision f2477e01787aa58f445919b809d89e252beef54f
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) { 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // crbug.com/315213 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The source data may not be properly aligned, and unaligned float reads 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // cause SIGBUS on some ARM platforms, so force using memcpy to copy the data 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // into the result. 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* read_from = GetReadPointerAndAdvance<float>(); 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!read_from) 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memcpy(result, read_from, sizeof(*result)); 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadString(std::string* result) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(read_from, len); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadWString(std::wstring* result) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len, sizeof(wchar_t)); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const wchar_t*>(read_from), len); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadString16(string16* result) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const char16*>(read_from), len); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadData(const char** data, int* length) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *length = 0; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = 0; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(length)) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBytes(data, *length); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadBytes(const char** data, int length) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(length); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = read_from; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Payload is uint32 aligned. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle() 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(sizeof(Header)), 1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(kPayloadUnit); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_->payload_size = 0; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle(int header_size) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(AlignInt(header_size, sizeof(uint32))), 1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header)); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(header_size, kPayloadUnit); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(kPayloadUnit); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_->payload_size = 0; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)Pickle::Pickle(const char* data, int data_len) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(reinterpret_cast<Header*>(const_cast<char*>(data))), 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(0), 1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(kCapacityReadOnly), 1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (data_len >= static_cast<int>(sizeof(Header))) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = data_len - header_->payload_size; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (header_size_ > static_cast<unsigned int>(data_len)) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = 0; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_size_ != AlignInt(header_size_, sizeof(uint32))) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = 0; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is anything wrong with the data, we're not going to use it. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_size_) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle(const Pickle& other) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(other.header_size_), 2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(other.write_offset_) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t payload_size = header_size_ + other.header_->payload_size; 2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(payload_size); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(header_, other.header_, payload_size); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::~Pickle() { 2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (capacity_after_header_ != kCapacityReadOnly) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(header_); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle& Pickle::operator=(const Pickle& other) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this == &other) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (capacity_after_header_ == kCapacityReadOnly) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_ = 0; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_size_ != other.header_size_) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(header_); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = other.header_size_; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(other.header_->payload_size); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(header_, other.header_, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other.header_size_ + other.header_->payload_size); 2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_ = other.write_offset_; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteString(const std::string& value) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), static_cast<int>(value.size())); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteWString(const std::wstring& 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(wchar_t))); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteString16(const string16& value) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(value.size()) * sizeof(char16)); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteData(const char* data, int length) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return length >= 0 && WriteInt(length) && WriteBytes(data, length); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool Pickle::WriteBytes(const void* data, int length) { 2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesCommon(data, length); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Pickle::Reserve(size_t length) { 2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t data_len = AlignInt(length, sizeof(uint32)); 2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(data_len, length); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef ARCH_CPU_64_BITS 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(data_len, kuint32max); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(write_offset_, kuint32max - data_len); 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t new_size = write_offset_ + data_len; 2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (new_size > capacity_after_header_) 2771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(capacity_after_header_ * 2 + new_size); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Pickle::Resize(size_t new_capacity) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_capacity = AlignInt(new_capacity, kPayloadUnit); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK_NE(capacity_after_header_, kCapacityReadOnly); 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void* p = realloc(header_, header_size_ + new_capacity); 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK(p); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = reinterpret_cast<Header*>(p); 2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_ = new_capacity; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* Pickle::FindNext(size_t header_size, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* start, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(header_size, AlignInt(header_size, sizeof(uint32))); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(header_size, static_cast<size_t>(kPayloadUnit)); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) size_t length = static_cast<size_t>(end - start); 2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (length < sizeof(Header)) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Header* hdr = reinterpret_cast<const Header*>(start); 3020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (length < header_size || length - header_size < hdr->payload_size) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return start + header_size + hdr->payload_size; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template <size_t length> void Pickle::WriteBytesStatic(const void* data) { 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesCommon(data, length); 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<2>(const void* data); 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<4>(const void* data); 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<8>(const void* data); 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)inline void Pickle::WriteBytesCommon(const void* data, size_t length) { 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_NE(kCapacityReadOnly, capacity_after_header_) 3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << "oops: pickle is readonly"; 3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t data_len = AlignInt(length, sizeof(uint32)); 3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(data_len, length); 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifdef ARCH_CPU_64_BITS 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(data_len, kuint32max); 3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(write_offset_, kuint32max - data_len); 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t new_size = write_offset_ + data_len; 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (new_size > capacity_after_header_) { 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(std::max(capacity_after_header_ * 2, new_size)); 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) char* write = mutable_payload() + write_offset_; 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memcpy(write, data, length); 3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memset(write + length, 0, data_len - length); 3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) header_->payload_size = static_cast<uint32>(write_offset_ + length); 3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_ = new_size; 3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 335