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) 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool PickleIterator::ReadDouble(double* result) { 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // crbug.com/315213 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The source data may not be properly aligned, and unaligned double reads 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // cause SIGBUS on some ARM platforms, so force using memcpy to copy the data 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // into the result. 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const char* read_from = GetReadPointerAndAdvance<double>(); 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!read_from) 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(result, read_from, sizeof(*result)); 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadString(std::string* 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); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(read_from, len); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadWString(std::wstring* 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(wchar_t)); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const wchar_t*>(read_from), len); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadString16(string16* result) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(&len)) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const char16*>(read_from), len); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadData(const char** data, int* length) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *length = 0; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = 0; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(length)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadBytes(data, *length); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PickleIterator::ReadBytes(const char** data, int length) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_from = GetReadPointerAndAdvance(length); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_from) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *data = read_from; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Payload is uint32 aligned. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle() 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(sizeof(Header)), 1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(kPayloadUnit); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_->payload_size = 0; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle(int header_size) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(AlignInt(header_size, sizeof(uint32))), 2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(header_size, kPayloadUnit); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(kPayloadUnit); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_->payload_size = 0; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)Pickle::Pickle(const char* data, int data_len) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(reinterpret_cast<Header*>(const_cast<char*>(data))), 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(0), 2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(kCapacityReadOnly), 2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(0) { 2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (data_len >= static_cast<int>(sizeof(Header))) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = data_len - header_->payload_size; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (header_size_ > static_cast<unsigned int>(data_len)) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = 0; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_size_ != AlignInt(header_size_, sizeof(uint32))) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = 0; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is anything wrong with the data, we're not going to use it. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header_size_) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::Pickle(const Pickle& other) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : header_(NULL), 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_(other.header_size_), 2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_(0), 2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_(other.write_offset_) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t payload_size = header_size_ + other.header_->payload_size; 2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(payload_size); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(header_, other.header_, payload_size); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle::~Pickle() { 2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (capacity_after_header_ != kCapacityReadOnly) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(header_); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Pickle& Pickle::operator=(const Pickle& other) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this == &other) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (capacity_after_header_ == kCapacityReadOnly) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_ = 0; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (header_size_ != other.header_size_) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(header_); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = NULL; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_size_ = other.header_size_; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(other.header_->payload_size); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(header_, other.header_, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other.header_size_ + other.header_->payload_size); 2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_ = other.write_offset_; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteString(const std::string& value) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), static_cast<int>(value.size())); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteWString(const std::wstring& value) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(value.size() * sizeof(wchar_t))); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteString16(const string16& value) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WriteInt(static_cast<int>(value.size()))) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteBytes(value.data(), 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(value.size()) * sizeof(char16)); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Pickle::WriteData(const char* data, int length) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return length >= 0 && WriteInt(length) && WriteBytes(data, length); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool Pickle::WriteBytes(const void* data, int length) { 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesCommon(data, length); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Pickle::Reserve(size_t length) { 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t data_len = AlignInt(length, sizeof(uint32)); 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(data_len, length); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef ARCH_CPU_64_BITS 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(data_len, kuint32max); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(write_offset_, kuint32max - data_len); 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t new_size = write_offset_ + data_len; 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (new_size > capacity_after_header_) 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(capacity_after_header_ * 2 + new_size); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void Pickle::Resize(size_t new_capacity) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_capacity = AlignInt(new_capacity, kPayloadUnit); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK_NE(capacity_after_header_, kCapacityReadOnly); 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void* p = realloc(header_, header_size_ + new_capacity); 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK(p); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_ = reinterpret_cast<Header*>(p); 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) capacity_after_header_ = new_capacity; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* Pickle::FindNext(size_t header_size, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* start, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(header_size, AlignInt(header_size, sizeof(uint32))); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(header_size, static_cast<size_t>(kPayloadUnit)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) size_t length = static_cast<size_t>(end - start); 3260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (length < sizeof(Header)) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Header* hdr = reinterpret_cast<const Header*>(start); 3300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (length < header_size || length - header_size < hdr->payload_size) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return start + header_size + hdr->payload_size; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template <size_t length> void Pickle::WriteBytesStatic(const void* data) { 3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesCommon(data, length); 3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<2>(const void* data); 3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<4>(const void* data); 3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template void Pickle::WriteBytesStatic<8>(const void* data); 3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)inline void Pickle::WriteBytesCommon(const void* data, size_t length) { 3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_NE(kCapacityReadOnly, capacity_after_header_) 3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << "oops: pickle is readonly"; 3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t data_len = AlignInt(length, sizeof(uint32)); 3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_GE(data_len, length); 3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifdef ARCH_CPU_64_BITS 3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(data_len, kuint32max); 3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LE(write_offset_, kuint32max - data_len); 3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t new_size = write_offset_ + data_len; 3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (new_size > capacity_after_header_) { 3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Resize(std::max(capacity_after_header_ * 2, new_size)); 3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) char* write = mutable_payload() + write_offset_; 3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memcpy(write, data, length); 3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) memset(write + length, 0, data_len - length); 36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) header_->payload_size = static_cast<uint32>(new_size); 3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) write_offset_ = new_size; 3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 363