pickle.cc revision b8cf94937c52feb53b55c39e3f82094d27de464c
1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/pickle.h" 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <stdlib.h> 8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 9b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <algorithm> // for max() 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst int Pickle::kPayloadUnit = 64; 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstatic const size_t kCapacityReadOnly = static_cast<size_t>(-1); 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickleIterator::PickleIterator(const Pickle& pickle) 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : payload_(pickle.payload()), 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_(0), 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat end_index_(pickle.payload_size()) { 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <typename Type> 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool PickleIterator::ReadBuiltinType(Type* result) { 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance<Type>(); 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (sizeof(Type) > sizeof(uint32)) 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(result, read_from, sizeof(*result)); 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat else 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *result = *reinterpret_cast<const Type*>(read_from); 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline void PickleIterator::Advance(size_t size) { 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t aligned_size = AlignInt(size, sizeof(uint32_t)); 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (end_index_ - read_index_ < aligned_size) { 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_ = end_index_; 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } else { 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_ += aligned_size; 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate<typename Type> 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline const char* PickleIterator::GetReadPointerAndAdvance() { 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (sizeof(Type) > end_index_ - read_index_) { 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_ = end_index_; 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return NULL; 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* current_read_ptr = payload_ + read_index_; 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Advance(sizeof(Type)); 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return current_read_ptr; 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char* PickleIterator::GetReadPointerAndAdvance(int num_bytes) { 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (num_bytes < 0 || 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat end_index_ - read_index_ < static_cast<size_t>(num_bytes)) { 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_ = end_index_; 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return NULL; 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* current_read_ptr = payload_ + read_index_; 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Advance(num_bytes); 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return current_read_ptr; 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline const char* PickleIterator::GetReadPointerAndAdvance( 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int num_elements, 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t size_element) { 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Check for int32 overflow. 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int64 num_bytes = static_cast<int64>(num_elements) * size_element; 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int num_bytes32 = static_cast<int>(num_bytes); 73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (num_bytes != static_cast<int64>(num_bytes32)) 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return NULL; 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return GetReadPointerAndAdvance(num_bytes32); 76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadBool(bool* result) { 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadInt(int* result) { 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadLong(long* result) { 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadUInt16(uint16* result) { 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadUInt32(uint32* result) { 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadInt64(int64* result) { 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadUInt64(uint64* result) { 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadSizeT(size_t* result) { 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Always read size_t as a 64-bit value to ensure compatibility between 32-bit 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // and 64-bit processes. 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat uint64 result_uint64 = 0; 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool success = ReadBuiltinType(&result_uint64); 111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *result = static_cast<size_t>(result_uint64); 112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Fail if the cast above truncates the value. 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return success && (*result == result_uint64); 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadFloat(float* result) { 117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // crbug.com/315213 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The source data may not be properly aligned, and unaligned float reads 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // cause SIGBUS on some ARM platforms, so force using memcpy to copy the data 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // into the result. 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance<float>(); 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(result, read_from, sizeof(*result)); 125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadDouble(double* result) { 129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // crbug.com/315213 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The source data may not be properly aligned, and unaligned double reads 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // cause SIGBUS on some ARM platforms, so force using memcpy to copy the data 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // into the result. 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance<double>(); 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(result, read_from, sizeof(*result)); 137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadString(std::string* result) { 141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int len; 142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(&len)) 143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(len); 145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat result->assign(read_from, len); 149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 150b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 151b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 152b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadStringPiece(StringPiece* result) { 153b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int len; 154b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(&len)) 155b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(len); 157b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 160b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *result = StringPiece(read_from, len); 161b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 162b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 163b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 164b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadString16(string16* result) { 165b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int len; 166b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(&len)) 167b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 168b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16)); 169b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 170b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 171b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 172b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat result->assign(reinterpret_cast<const char16*>(read_from), len); 173b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 174b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 175b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 176b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadStringPiece16(StringPiece16* result) { 177b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int len; 178b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(&len)) 179b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 180b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16)); 181b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 182b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 183b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 184b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *result = StringPiece16(reinterpret_cast<const char16*>(read_from), len); 185b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 186b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 187b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 188b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadData(const char** data, int* length) { 189b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *length = 0; 190b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *data = 0; 191b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 192b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(length)) 193b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 194b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 195b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBytes(data, *length); 196b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 197b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 198b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadBytes(const char** data, int length) { 199b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(length); 200b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 201b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 202b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *data = read_from; 203b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 204b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 205b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 206b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Payload is uint32 aligned. 207b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 208b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::Pickle() 209b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : header_(NULL), 210b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_(sizeof(Header)), 211b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_(0), 212b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_(0) { 213b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(kPayloadUnit); 214b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_->payload_size = 0; 215b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 216b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 217b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::Pickle(int header_size) 218b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : header_(NULL), 219b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_(AlignInt(header_size, sizeof(uint32))), 220b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_(0), 221b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_(0) { 222b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header)); 223b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_LE(header_size, kPayloadUnit); 224b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(kPayloadUnit); 225b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_->payload_size = 0; 226b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 227b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 228b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::Pickle(const char* data, int data_len) 229b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : header_(reinterpret_cast<Header*>(const_cast<char*>(data))), 230b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_(0), 231b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_(kCapacityReadOnly), 232b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_(0) { 233b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (data_len >= static_cast<int>(sizeof(Header))) 234b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_ = data_len - header_->payload_size; 235b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 236b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (header_size_ > static_cast<unsigned int>(data_len)) 237b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_ = 0; 238b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 239b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (header_size_ != AlignInt(header_size_, sizeof(uint32))) 240b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_ = 0; 241b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 242b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // If there is anything wrong with the data, we're not going to use it. 243b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!header_size_) 244b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_ = NULL; 245b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 246b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 247b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::Pickle(const Pickle& other) 248b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : header_(NULL), 249b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_(other.header_size_), 250b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_(0), 251b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_(other.write_offset_) { 252b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t payload_size = header_size_ + other.header_->payload_size; 253b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(payload_size); 254b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(header_, other.header_, payload_size); 255b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 256b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 257b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::~Pickle() { 258b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (capacity_after_header_ != kCapacityReadOnly) 259b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat free(header_); 260b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 261b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 262b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle& Pickle::operator=(const Pickle& other) { 263b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (this == &other) { 264b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NOTREACHED(); 265b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return *this; 266b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 267b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (capacity_after_header_ == kCapacityReadOnly) { 268b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_ = NULL; 269b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_ = 0; 270b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 271b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (header_size_ != other.header_size_) { 272b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat free(header_); 273b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_ = NULL; 274b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_ = other.header_size_; 275b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 276b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(other.header_->payload_size); 277b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(header_, other.header_, 278b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat other.header_size_ + other.header_->payload_size); 279b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_ = other.write_offset_; 280b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return *this; 281b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 282b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 283b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool Pickle::WriteString(const StringPiece& value) { 284b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!WriteInt(static_cast<int>(value.size()))) 285b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 286b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 287b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return WriteBytes(value.data(), static_cast<int>(value.size())); 288b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 289b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 290b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool Pickle::WriteString16(const StringPiece16& value) { 291b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!WriteInt(static_cast<int>(value.size()))) 292b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 293b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 294b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return WriteBytes(value.data(), 295b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat static_cast<int>(value.size()) * sizeof(char16)); 296b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 297b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 298b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool Pickle::WriteData(const char* data, int length) { 299b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return length >= 0 && WriteInt(length) && WriteBytes(data, length); 300b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 301b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 302b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool Pickle::WriteBytes(const void* data, int length) { 303b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat WriteBytesCommon(data, length); 304b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 305b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 306b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 307b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid Pickle::Reserve(size_t length) { 308b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t data_len = AlignInt(length, sizeof(uint32)); 309b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_GE(data_len, length); 310b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifdef ARCH_CPU_64_BITS 311b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_LE(data_len, kuint32max); 312b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 313b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_LE(write_offset_, kuint32max - data_len); 314b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t new_size = write_offset_ + data_len; 315b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (new_size > capacity_after_header_) 316b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(capacity_after_header_ * 2 + new_size); 317b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 318b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 319b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid Pickle::Resize(size_t new_capacity) { 320b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat CHECK_NE(capacity_after_header_, kCapacityReadOnly); 321b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_ = AlignInt(new_capacity, kPayloadUnit); 322b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void* p = realloc(header_, GetTotalAllocatedSize()); 323b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat CHECK(p); 324b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_ = reinterpret_cast<Header*>(p); 325b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 326b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 327b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratsize_t Pickle::GetTotalAllocatedSize() const { 328b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (capacity_after_header_ == kCapacityReadOnly) 329b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return 0; 330b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return header_size_ + capacity_after_header_; 331b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 332b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 333b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 334b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char* Pickle::FindNext(size_t header_size, 335b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* start, 336b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* end) { 337b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_EQ(header_size, AlignInt(header_size, sizeof(uint32))); 338b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_LE(header_size, static_cast<size_t>(kPayloadUnit)); 339b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 340b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t length = static_cast<size_t>(end - start); 341b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (length < sizeof(Header)) 342b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return NULL; 343b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 344b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const Header* hdr = reinterpret_cast<const Header*>(start); 345b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (length < header_size || length - header_size < hdr->payload_size) 346b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return NULL; 347b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return start + header_size + hdr->payload_size; 348b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 349b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 350b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <size_t length> void Pickle::WriteBytesStatic(const void* data) { 351b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat WriteBytesCommon(data, length); 352b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 353b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 354b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate void Pickle::WriteBytesStatic<2>(const void* data); 355b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate void Pickle::WriteBytesStatic<4>(const void* data); 356b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate void Pickle::WriteBytesStatic<8>(const void* data); 357b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 358b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline void Pickle::WriteBytesCommon(const void* data, size_t length) { 359b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_NE(kCapacityReadOnly, capacity_after_header_) 360b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat << "oops: pickle is readonly"; 361b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat MSAN_CHECK_MEM_IS_INITIALIZED(data, length); 362b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t data_len = AlignInt(length, sizeof(uint32)); 363b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_GE(data_len, length); 364b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifdef ARCH_CPU_64_BITS 365b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_LE(data_len, kuint32max); 366b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 367b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_LE(write_offset_, kuint32max - data_len); 368b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t new_size = write_offset_ + data_len; 369b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (new_size > capacity_after_header_) { 370b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(std::max(capacity_after_header_ * 2, new_size)); 371b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 372b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 373b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char* write = mutable_payload() + write_offset_; 374b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(write, data, length); 375b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memset(write + length, 0, data_len - length); 376b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_->payload_size = static_cast<uint32>(new_size); 377b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_ = new_size; 378b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 379b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 380b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 381