pickle.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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) 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using base::char16; 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using base::string16; 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int Pickle::kPayloadUnit = 64; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kCapacityReadOnly = static_cast<size_t>(-1); 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PickleIterator::PickleIterator(const Pickle& pickle) 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : payload_(pickle.payload()), 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) read_index_(0), 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) end_index_(pickle.payload_size()) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool PickleIterator::ReadBuiltinType(Type* result) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance<Type>(); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizeof(Type) > sizeof(uint32)) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(result, read_from, sizeof(*result)); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = *reinterpret_cast<const Type*>(read_from); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)inline void PickleIterator::Advance(size_t size) { 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t aligned_size = AlignInt(size, sizeof(uint32_t)); 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (end_index_ - read_index_ < aligned_size) { 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) read_index_ = end_index_; 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) read_index_ += aligned_size; 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename Type> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const char* PickleIterator::GetReadPointerAndAdvance() { 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (sizeof(Type) > end_index_ - read_index_) { 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) read_index_ = end_index_; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const char* current_read_ptr = payload_ + read_index_; 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Advance(sizeof(Type)); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_read_ptr; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* PickleIterator::GetReadPointerAndAdvance(int num_bytes) { 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (num_bytes < 0 || 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) end_index_ - read_index_ < static_cast<size_t>(num_bytes)) { 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) read_index_ = end_index_; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const char* current_read_ptr = payload_ + read_index_; 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Advance(num_bytes); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_read_ptr; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)inline const char* PickleIterator::GetReadPointerAndAdvance( 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int num_elements, 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t size_element) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for int32 overflow. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_bytes = static_cast<int64>(num_elements) * size_element; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_bytes32 = static_cast<int>(num_bytes); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_bytes != static_cast<int64>(num_bytes32)) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetReadPointerAndAdvance(num_bytes32); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadBool(bool* result) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadInt(int* result) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadLong(long* result) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadUInt16(uint16* result) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadUInt32(uint32* result) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadInt64(int64* result) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadUInt64(uint64* result) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBuiltinType(result); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PickleIterator::ReadFloat(float* result) { 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // crbug.com/315213 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The source data may not be properly aligned, and unaligned float reads 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // cause SIGBUS on some ARM platforms, so force using memcpy to copy the data 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // into the result. 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* read_from = GetReadPointerAndAdvance<float>(); 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!read_from) 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memcpy(result, read_from, sizeof(*result)); 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadString(std::string* 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); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(read_from, len); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadWString(std::wstring* result) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len, sizeof(wchar_t)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const wchar_t*>(read_from), len); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadString16(string16* result) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16)); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const char16*>(read_from), len); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadData(const char** data, int* length) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *length = 0; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = 0; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(length)) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBytes(data, *length); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadBytes(const char** data, int length) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(length); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = read_from; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Payload is uint32 aligned. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle() 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(sizeof(Header)), 1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(kPayloadUnit); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_->payload_size = 0; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle(int header_size) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(AlignInt(header_size, sizeof(uint32))), 1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(header_size, kPayloadUnit); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(kPayloadUnit); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_->payload_size = 0; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)Pickle::Pickle(const char* data, int data_len) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(reinterpret_cast<Header*>(const_cast<char*>(data))), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(0), 2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(kCapacityReadOnly), 2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (data_len >= static_cast<int>(sizeof(Header))) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = data_len - header_->payload_size; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (header_size_ > static_cast<unsigned int>(data_len)) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = 0; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_size_ != AlignInt(header_size_, sizeof(uint32))) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = 0; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is anything wrong with the data, we're not going to use it. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_size_) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle(const Pickle& other) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(other.header_size_), 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(other.write_offset_) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t payload_size = header_size_ + other.header_->payload_size; 2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(payload_size); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(header_, other.header_, payload_size); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::~Pickle() { 2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (capacity_after_header_ != kCapacityReadOnly) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(header_); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle& Pickle::operator=(const Pickle& other) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this == &other) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (capacity_after_header_ == kCapacityReadOnly) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_ = 0; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_size_ != other.header_size_) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(header_); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = other.header_size_; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(other.header_->payload_size); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(header_, other.header_, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other.header_size_ + other.header_->payload_size); 2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_ = other.write_offset_; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteString(const std::string& value) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), static_cast<int>(value.size())); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteWString(const std::wstring& value) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(value.size() * sizeof(wchar_t))); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteString16(const string16& value) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(value.size()) * sizeof(char16)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteData(const char* data, int length) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return length >= 0 && WriteInt(length) && WriteBytes(data, length); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool Pickle::WriteBytes(const void* data, int length) { 2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesCommon(data, length); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Pickle::Reserve(size_t length) { 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t data_len = AlignInt(length, sizeof(uint32)); 2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(data_len, length); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef ARCH_CPU_64_BITS 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(data_len, kuint32max); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(write_offset_, kuint32max - data_len); 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t new_size = write_offset_ + data_len; 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (new_size > capacity_after_header_) 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(capacity_after_header_ * 2 + new_size); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Pickle::Resize(size_t new_capacity) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_capacity = AlignInt(new_capacity, kPayloadUnit); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK_NE(capacity_after_header_, kCapacityReadOnly); 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void* p = realloc(header_, header_size_ + new_capacity); 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK(p); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = reinterpret_cast<Header*>(p); 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_ = new_capacity; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* Pickle::FindNext(size_t header_size, 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* start, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(header_size, AlignInt(header_size, sizeof(uint32))); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(header_size, static_cast<size_t>(kPayloadUnit)); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) size_t length = static_cast<size_t>(end - start); 3140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (length < sizeof(Header)) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Header* hdr = reinterpret_cast<const Header*>(start); 3180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (length < header_size || length - header_size < hdr->payload_size) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return start + header_size + hdr->payload_size; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template <size_t length> void Pickle::WriteBytesStatic(const void* data) { 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesCommon(data, length); 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<2>(const void* data); 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<4>(const void* data); 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<8>(const void* data); 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)inline void Pickle::WriteBytesCommon(const void* data, size_t length) { 3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_NE(kCapacityReadOnly, capacity_after_header_) 3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << "oops: pickle is readonly"; 3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t data_len = AlignInt(length, sizeof(uint32)); 3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(data_len, length); 3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifdef ARCH_CPU_64_BITS 3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(data_len, kuint32max); 3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(write_offset_, kuint32max - data_len); 3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t new_size = write_offset_ + data_len; 3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (new_size > capacity_after_header_) { 3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(std::max(capacity_after_header_ * 2, new_size)); 3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) char* write = mutable_payload() + write_offset_; 3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memcpy(write, data, length); 3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memset(write + length, 0, data_len - length); 34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) header_->payload_size = static_cast<uint32>(new_size); 3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_ = new_size; 3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 351