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() 100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <limits> 110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/bits.h" 130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/macros.h" 1445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko#include "base/numerics/safe_conversions.h" 150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "build/build_config.h" 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst int Pickle::kPayloadUnit = 64; 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstatic const size_t kCapacityReadOnly = static_cast<size_t>(-1); 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickleIterator::PickleIterator(const Pickle& pickle) 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : payload_(pickle.payload()), 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_(0), 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat end_index_(pickle.payload_size()) { 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <typename Type> 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline bool PickleIterator::ReadBuiltinType(Type* result) { 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance<Type>(); 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko if (sizeof(Type) > sizeof(uint32_t)) 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(result, read_from, sizeof(*result)); 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat else 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *result = *reinterpret_cast<const Type*>(read_from); 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline void PickleIterator::Advance(size_t size) { 430d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko size_t aligned_size = bits::Align(size, sizeof(uint32_t)); 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (end_index_ - read_index_ < aligned_size) { 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_ = end_index_; 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } else { 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_ += aligned_size; 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate<typename Type> 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline const char* PickleIterator::GetReadPointerAndAdvance() { 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (sizeof(Type) > end_index_ - read_index_) { 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_ = end_index_; 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return NULL; 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* current_read_ptr = payload_ + read_index_; 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Advance(sizeof(Type)); 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return current_read_ptr; 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char* PickleIterator::GetReadPointerAndAdvance(int num_bytes) { 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (num_bytes < 0 || 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat end_index_ - read_index_ < static_cast<size_t>(num_bytes)) { 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat read_index_ = end_index_; 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return NULL; 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* current_read_ptr = payload_ + read_index_; 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Advance(num_bytes); 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return current_read_ptr; 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratinline const char* PickleIterator::GetReadPointerAndAdvance( 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int num_elements, 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t size_element) { 760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // Check for int32_t overflow. 770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko int64_t num_bytes = static_cast<int64_t>(num_elements) * size_element; 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int num_bytes32 = static_cast<int>(num_bytes); 790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko if (num_bytes != static_cast<int64_t>(num_bytes32)) 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return NULL; 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return GetReadPointerAndAdvance(num_bytes32); 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadBool(bool* result) { 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadInt(int* result) { 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadLong(long* result) { 9345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko // Always read long as a 64-bit value to ensure compatibility between 32-bit 9445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko // and 64-bit processes. 9545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko int64_t result_int64 = 0; 9645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko if (!ReadBuiltinType(&result_int64)) 9745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko return false; 9845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko // CHECK if the cast truncates the value so that we know to change this IPC 9945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko // parameter to use int64_t. 10045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko *result = base::checked_cast<long>(result_int64); 10145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko return true; 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkobool PickleIterator::ReadUInt16(uint16_t* result) { 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkobool PickleIterator::ReadUInt32(uint32_t* result) { 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkobool PickleIterator::ReadInt64(int64_t* result) { 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkobool PickleIterator::ReadUInt64(uint64_t* result) { 117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBuiltinType(result); 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadFloat(float* result) { 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // crbug.com/315213 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The source data may not be properly aligned, and unaligned float reads 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // cause SIGBUS on some ARM platforms, so force using memcpy to copy the data 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // into the result. 125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance<float>(); 126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(result, read_from, sizeof(*result)); 129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadDouble(double* result) { 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // crbug.com/315213 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // The source data may not be properly aligned, and unaligned double reads 135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // cause SIGBUS on some ARM platforms, so force using memcpy to copy the data 136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // into the result. 137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance<double>(); 138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(result, read_from, sizeof(*result)); 141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadString(std::string* result) { 145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int len; 146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(&len)) 147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(len); 149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 150b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 151b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 152b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat result->assign(read_from, len); 153b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 154b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 155b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadStringPiece(StringPiece* result) { 157b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int len; 158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(&len)) 159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 160b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(len); 161b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 162b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 163b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 164b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *result = StringPiece(read_from, len); 165b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 166b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 167b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 168b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadString16(string16* result) { 169b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int len; 170b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(&len)) 171b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 172b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16)); 173b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 174b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 175b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 176b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat result->assign(reinterpret_cast<const char16*>(read_from), len); 177b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 178b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 179b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 180b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadStringPiece16(StringPiece16* result) { 181b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat int len; 182b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(&len)) 183b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 184b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(len, sizeof(char16)); 185b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 186b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 187b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 188b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *result = StringPiece16(reinterpret_cast<const char16*>(read_from), len); 189b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 190b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 191b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 192b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadData(const char** data, int* length) { 193b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *length = 0; 194b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *data = 0; 195b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 196b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!ReadInt(length)) 197b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 198b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 199b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ReadBytes(data, *length); 200b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 201b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 202b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool PickleIterator::ReadBytes(const char** data, int length) { 203b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* read_from = GetReadPointerAndAdvance(length); 204b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!read_from) 205b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 206b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat *data = read_from; 207b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 208b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 209b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 21045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoPickleSizer::PickleSizer() {} 21145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 21245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoPickleSizer::~PickleSizer() {} 21345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 21445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkovoid PickleSizer::AddString(const StringPiece& value) { 21545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko AddInt(); 21645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko AddBytes(static_cast<int>(value.size())); 21745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 21845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 21945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkovoid PickleSizer::AddString16(const StringPiece16& value) { 22045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko AddInt(); 22145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko AddBytes(static_cast<int>(value.size() * sizeof(char16))); 22245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 22345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 22445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkovoid PickleSizer::AddData(int length) { 22545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko CHECK_GE(length, 0); 22645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko AddInt(); 22745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko AddBytes(length); 22845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 22945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 23045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkovoid PickleSizer::AddBytes(int length) { 23145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko payload_size_ += bits::Align(length, sizeof(uint32_t)); 23245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 23345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 23494ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavezvoid PickleSizer::AddAttachment() { 23594ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez // From IPC::Message::WriteAttachment 23694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez AddBool(); 23794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez AddInt(); 23894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez} 23994ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez 24045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkotemplate <size_t length> void PickleSizer::AddBytesStatic() { 24145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko DCHECK_LE(length, static_cast<size_t>(std::numeric_limits<int>::max())); 24245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko AddBytes(length); 24345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 24445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 24545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkotemplate void PickleSizer::AddBytesStatic<2>(); 24645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkotemplate void PickleSizer::AddBytesStatic<4>(); 24745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkotemplate void PickleSizer::AddBytesStatic<8>(); 24845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 24945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoPickle::Attachment::Attachment() {} 25045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 25145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoPickle::Attachment::~Attachment() {} 25245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 2530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Payload is uint32_t aligned. 254b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 255b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::Pickle() 256b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : header_(NULL), 257b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_(sizeof(Header)), 258b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_(0), 259b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_(0) { 2600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko static_assert((Pickle::kPayloadUnit & (Pickle::kPayloadUnit - 1)) == 0, 2610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko "Pickle::kPayloadUnit must be a power of two"); 262b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(kPayloadUnit); 263b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_->payload_size = 0; 264b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 265b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 266b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::Pickle(int header_size) 267b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : header_(NULL), 2680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko header_size_(bits::Align(header_size, sizeof(uint32_t))), 269b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_(0), 270b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_(0) { 271b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_GE(static_cast<size_t>(header_size), sizeof(Header)); 272b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_LE(header_size, kPayloadUnit); 273b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(kPayloadUnit); 274b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_->payload_size = 0; 275b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 276b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 277b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::Pickle(const char* data, int data_len) 278b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : header_(reinterpret_cast<Header*>(const_cast<char*>(data))), 279b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_(0), 280b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_(kCapacityReadOnly), 281b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_(0) { 282b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (data_len >= static_cast<int>(sizeof(Header))) 283b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_ = data_len - header_->payload_size; 284b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 285b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (header_size_ > static_cast<unsigned int>(data_len)) 286b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_ = 0; 287b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 2880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko if (header_size_ != bits::Align(header_size_, sizeof(uint32_t))) 289b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_ = 0; 290b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 291b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // If there is anything wrong with the data, we're not going to use it. 292b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!header_size_) 293b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_ = NULL; 294b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 295b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 296b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::Pickle(const Pickle& other) 297b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : header_(NULL), 298b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_(other.header_size_), 299b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_(0), 300b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_(other.write_offset_) { 3010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko Resize(other.header_->payload_size); 3020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko memcpy(header_, other.header_, header_size_ + other.header_->payload_size); 303b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 304b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 305b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle::~Pickle() { 306b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (capacity_after_header_ != kCapacityReadOnly) 307b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat free(header_); 308b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 309b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 310b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratPickle& Pickle::operator=(const Pickle& other) { 311b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (this == &other) { 312b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NOTREACHED(); 313b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return *this; 314b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 315b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (capacity_after_header_ == kCapacityReadOnly) { 316b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_ = NULL; 317b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat capacity_after_header_ = 0; 318b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 319b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (header_size_ != other.header_size_) { 320b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat free(header_); 321b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_ = NULL; 322b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_size_ = other.header_size_; 323b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 324b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(other.header_->payload_size); 325b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat memcpy(header_, other.header_, 326b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat other.header_size_ + other.header_->payload_size); 327b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_ = other.write_offset_; 328b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return *this; 329b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 330b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 331b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool Pickle::WriteString(const StringPiece& value) { 332b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!WriteInt(static_cast<int>(value.size()))) 333b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 334b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 335b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return WriteBytes(value.data(), static_cast<int>(value.size())); 336b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 337b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 338b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool Pickle::WriteString16(const StringPiece16& value) { 339b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (!WriteInt(static_cast<int>(value.size()))) 340b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; 341b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 342b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return WriteBytes(value.data(), 343b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat static_cast<int>(value.size()) * sizeof(char16)); 344b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 345b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 346b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool Pickle::WriteData(const char* data, int length) { 347b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return length >= 0 && WriteInt(length) && WriteBytes(data, length); 348b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 349b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 350b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool Pickle::WriteBytes(const void* data, int length) { 351b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat WriteBytesCommon(data, length); 352b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 353b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 354b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 355b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid Pickle::Reserve(size_t length) { 3560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko size_t data_len = bits::Align(length, sizeof(uint32_t)); 357b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_GE(data_len, length); 358b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifdef ARCH_CPU_64_BITS 3590d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko DCHECK_LE(data_len, std::numeric_limits<uint32_t>::max()); 360b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 3610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko DCHECK_LE(write_offset_, std::numeric_limits<uint32_t>::max() - data_len); 362b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t new_size = write_offset_ + data_len; 363b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (new_size > capacity_after_header_) 364b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Resize(capacity_after_header_ * 2 + new_size); 365b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 366b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 36794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavezbool Pickle::WriteAttachment(scoped_refptr<Attachment> /*attachment*/) { 36845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko return false; 36945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 37045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 37194ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavezbool Pickle::ReadAttachment(base::PickleIterator* /*iter*/, 37294ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez scoped_refptr<Attachment>* /*attachment*/) const { 37345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko return false; 37445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 37545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 37645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkobool Pickle::HasAttachments() const { 37745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko return false; 37845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 37945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 380b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid Pickle::Resize(size_t new_capacity) { 381b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat CHECK_NE(capacity_after_header_, kCapacityReadOnly); 3820d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko capacity_after_header_ = bits::Align(new_capacity, kPayloadUnit); 383b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat void* p = realloc(header_, GetTotalAllocatedSize()); 384b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat CHECK(p); 385b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat header_ = reinterpret_cast<Header*>(p); 386b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 387b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 3880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkovoid* Pickle::ClaimBytes(size_t num_bytes) { 3890d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko void* p = ClaimUninitializedBytesInternal(num_bytes); 3900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko CHECK(p); 3910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko memset(p, 0, num_bytes); 3920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko return p; 3930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko} 3940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 395b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratsize_t Pickle::GetTotalAllocatedSize() const { 396b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (capacity_after_header_ == kCapacityReadOnly) 397b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return 0; 398b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return header_size_ + capacity_after_header_; 399b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 400b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 401b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static 402b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char* Pickle::FindNext(size_t header_size, 403b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* start, 404b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const char* end) { 4050d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko size_t pickle_size = 0; 4060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko if (!PeekNext(header_size, start, end, &pickle_size)) 4070d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko return NULL; 4080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 4090d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko if (pickle_size > static_cast<size_t>(end - start)) 4100d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko return NULL; 4110d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 4120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko return start + pickle_size; 4130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko} 4140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 4150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// static 4160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkobool Pickle::PeekNext(size_t header_size, 4170d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const char* start, 4180d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const char* end, 4190d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko size_t* pickle_size) { 4200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko DCHECK_EQ(header_size, bits::Align(header_size, sizeof(uint32_t))); 4210d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko DCHECK_GE(header_size, sizeof(Header)); 422b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_LE(header_size, static_cast<size_t>(kPayloadUnit)); 423b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 424b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t length = static_cast<size_t>(end - start); 425b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (length < sizeof(Header)) 4260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko return false; 427b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 428b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat const Header* hdr = reinterpret_cast<const Header*>(start); 4290d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko if (length < header_size) 4300d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko return false; 4310d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 4320d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko if (hdr->payload_size > std::numeric_limits<size_t>::max() - header_size) { 4330d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // If payload_size causes an overflow, we return maximum possible 4340d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // pickle size to indicate that. 4350d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko *pickle_size = std::numeric_limits<size_t>::max(); 4360d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko } else { 4370d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko *pickle_size = header_size + hdr->payload_size; 4380d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko } 4390d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko return true; 440b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 441b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 442b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate <size_t length> void Pickle::WriteBytesStatic(const void* data) { 443b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat WriteBytesCommon(data, length); 444b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 445b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 446b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate void Pickle::WriteBytesStatic<2>(const void* data); 447b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate void Pickle::WriteBytesStatic<4>(const void* data); 448b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattemplate void Pickle::WriteBytesStatic<8>(const void* data); 449b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 4500d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoinline void* Pickle::ClaimUninitializedBytesInternal(size_t length) { 451b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_NE(kCapacityReadOnly, capacity_after_header_) 452b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat << "oops: pickle is readonly"; 4530d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko size_t data_len = bits::Align(length, sizeof(uint32_t)); 454b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_GE(data_len, length); 455b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifdef ARCH_CPU_64_BITS 4560d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko DCHECK_LE(data_len, std::numeric_limits<uint32_t>::max()); 457b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 4580d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko DCHECK_LE(write_offset_, std::numeric_limits<uint32_t>::max() - data_len); 459b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat size_t new_size = write_offset_ + data_len; 460b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (new_size > capacity_after_header_) { 4610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko size_t new_capacity = capacity_after_header_ * 2; 4620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const size_t kPickleHeapAlign = 4096; 4630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko if (new_capacity > kPickleHeapAlign) 4640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko new_capacity = bits::Align(new_capacity, kPickleHeapAlign) - kPayloadUnit; 4650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko Resize(std::max(new_capacity, new_size)); 466b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 467b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 468b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat char* write = mutable_payload() + write_offset_; 4690d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko memset(write + length, 0, data_len - length); // Always initialize padding 4700d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko header_->payload_size = static_cast<uint32_t>(new_size); 471b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat write_offset_ = new_size; 4720d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko return write; 4730d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko} 4740d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 4750d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenkoinline void Pickle::WriteBytesCommon(const void* data, size_t length) { 4760d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko DCHECK_NE(kCapacityReadOnly, capacity_after_header_) 4770d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko << "oops: pickle is readonly"; 4780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko MSAN_CHECK_MEM_IS_INITIALIZED(data, length); 4790d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko void* write = ClaimUninitializedBytesInternal(length); 4800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko memcpy(write, data, length); 481b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 482b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 483b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 484