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