13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_PICKLE_H__
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_PICKLE_H__
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h"
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/gtest_prod_util.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string16.h"
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class provides facilities for basic binary value packing and unpacking.
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The Pickle class supports appending primitive values (ints, strings, etc.)
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to a pickle instance.  The Pickle instance grows its internal memory buffer
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// dynamically to hold the sequence of primitive values.   The internal memory
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// buffer is exposed as the "data" of the Pickle.  This "data" can be passed
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to a Pickle object to initialize it for reading.
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// When reading from a Pickle object, it is important for the consumer to know
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// what value types to read and in what order to read them as the Pickle does
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// not keep track of the type of data written to it.
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The Pickle's data has a header which contains the size of the Pickle's
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// payload.  It can optionally support additional space in the header.  That
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// space is controlled by the header_size parameter passed to the Pickle
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// constructor.
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API Pickle {
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize a Pickle object using the default header size.
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle();
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize a Pickle object with the specified header size in bytes, which
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // must be greater-than-or-equal-to sizeof(Pickle::Header).  The header size
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // will be rounded up to ensure that the header size is 32bit-aligned.
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit Pickle(int header_size);
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initializes a Pickle from a const block of data.  The data is not copied;
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // instead the data is merely referenced by this Pickle.  Only const methods
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // should be used on the Pickle when initialized this way.  The header
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // padding size is deduced from the data length.
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle(const char* data, int data_len);
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initializes a Pickle as a deep copy of another Pickle.
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle(const Pickle& other);
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual ~Pickle();
543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Performs a deep copy.
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Pickle& operator=(const Pickle& other);
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the size of the Pickle's data.
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  size_t size() const { return header_size_ + header_->payload_size; }
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the data for this Pickle.
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const void* data() const { return header_; }
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Methods for reading the payload of the Pickle.  To read from the start of
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the Pickle, initialize *iter to NULL.  If successful, these methods return
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // true.  Otherwise, false is returned to indicate that the result could not
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // be extracted.
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadBool(void** iter, bool* result) const;
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadInt(void** iter, int* result) const;
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadLong(void** iter, long* result) const;
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadSize(void** iter, size_t* result) const;
72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool ReadUInt16(void** iter, uint16* result) const;
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadUInt32(void** iter, uint32* result) const;
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadInt64(void** iter, int64* result) const;
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadUInt64(void** iter, uint64* result) const;
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadString(void** iter, std::string* result) const;
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadWString(void** iter, std::wstring* result) const;
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadString16(void** iter, string16* result) const;
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadData(void** iter, const char** data, int* length) const;
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadBytes(void** iter, const char** data, int length) const;
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Safer version of ReadInt() checks for the result not being negative.
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Use it for reading the object sizes.
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool ReadLength(void** iter, int* result) const;
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Methods for adding to the payload of the Pickle.  These values are
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // appended to the end of the Pickle's payload.  When reading values from a
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Pickle, it is important to read them in the order in which they were added
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to the Pickle.
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteBool(bool value) {
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return WriteInt(value ? 1 : 0);
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteInt(int value) {
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return WriteBytes(&value, sizeof(value));
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteLong(long value) {
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return WriteBytes(&value, sizeof(value));
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteSize(size_t value) {
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return WriteBytes(&value, sizeof(value));
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool WriteUInt16(uint16 value) {
103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return WriteBytes(&value, sizeof(value));
104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteUInt32(uint32 value) {
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return WriteBytes(&value, sizeof(value));
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteInt64(int64 value) {
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return WriteBytes(&value, sizeof(value));
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteUInt64(uint64 value) {
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return WriteBytes(&value, sizeof(value));
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteString(const std::string& value);
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteWString(const std::wstring& value);
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteString16(const string16& value);
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteData(const char* data, int length);
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool WriteBytes(const void* data, int data_len);
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Same as WriteData, but allows the caller to write directly into the
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Pickle. This saves a copy in cases where the data is not already
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // available in a buffer. The caller should take care to not write more
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // than the length it declares it will. Use ReadData to get the data.
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns NULL on failure.
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The returned pointer will only be valid until the next write operation
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // on this Pickle.
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* BeginWriteData(int length);
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // For Pickles which contain variable length buffers (e.g. those created
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // with BeginWriteData), the Pickle can
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // be 'trimmed' if the amount of data required is less than originally
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // requested.  For example, you may have created a buffer with 10K of data,
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // but decided to only fill 10 bytes of that data.  Use this function
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to trim the buffer so that we don't send 9990 bytes of unused data.
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // You cannot increase the size of the variable buffer; only shrink it.
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // This function assumes that the length of the variable buffer has
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // not been changed.
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void TrimWriteData(int length);
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Payload follows after allocation of Header (header size is customizable).
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  struct Header {
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32 payload_size;  // Specifies the size of the payload.
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  };
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the header, cast to a user-specified type T.  The type T must be a
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // subclass of Header and its size must correspond to the header_size passed
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to the Pickle constructor.
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class T>
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  T* headerT() {
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    DCHECK_EQ(header_size_, sizeof(T));
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<T*>(header_);
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  template <class T>
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const T* headerT() const {
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    DCHECK_EQ(header_size_, sizeof(T));
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return static_cast<const T*>(header_);
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns true if the given iterator could point to data with the given
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // length. If there is no room for the given data before the end of the
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // payload, returns false.
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool IteratorHasRoomFor(const void* iter, int len) const {
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if ((len < 0) || (iter < header_) || iter > end_of_payload())
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return false;
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Watch out for overflow in pointer calculation, which wraps.
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return (iter <= end_of_region) && (end_of_region <= end_of_payload());
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected:
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t payload_size() const { return header_->payload_size; }
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* payload() {
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return reinterpret_cast<char*>(header_) + header_size_;
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* payload() const {
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return reinterpret_cast<const char*>(header_) + header_size_;
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the address of the byte immediately following the currently valid
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // header + payload.
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* end_of_payload() {
1844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // We must have a valid header_.
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return payload() + payload_size();
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* end_of_payload() const {
1884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // This object may be invalid.
1894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return header_ ? payload() + payload_size() : NULL;
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t capacity() const {
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return capacity_;
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Resizes the buffer for use when writing the specified amount of data. The
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // location that the data should be written at is returned, or NULL if there
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // was an error. Call EndWrite with the returned offset and the given length
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // to pad out for the next write.
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* BeginWrite(size_t length);
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Completes the write operation by padding the data with NULL bytes until it
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is padded. Should be paired with BeginWrite, but it does not necessarily
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // have to be called after the data is written.
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void EndWrite(char* dest, int length);
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Resize the capacity, note that the input value should include the size of
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the header: new_capacity = sizeof(Header) + desired_payload_capacity.
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A realloc() failure will cause a Resize failure... and caller should check
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the return result for true (i.e., successful resizing).
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool Resize(size_t new_capacity);
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Aligns 'i' by rounding it up to the next multiple of 'alignment'
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static size_t AlignInt(size_t i, int alignment) {
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return i + (alignment - (i % alignment)) % alignment;
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Moves the iterator by the given number of bytes, making sure it is aligned.
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Pointer (iterator) is NOT aligned, but the change in the pointer
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // is guaranteed to be a multiple of sizeof(uint32).
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void UpdateIter(void** iter, int bytes) {
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *iter = static_cast<char*>(*iter) + AlignInt(bytes, sizeof(uint32));
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Find the end of the pickled data that starts at range_start.  Returns NULL
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // if the entire Pickle is not found in the given data range.
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const char* FindNext(size_t header_size,
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              const char* range_start,
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                              const char* range_end);
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The allocation granularity of the payload.
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static const int kPayloadUnit;
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Header* header_;
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t header_size_;  // Supports extra data between header and payload.
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Allocation size of payload (or -1 if allocation is const).
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t capacity_;
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t variable_buffer_offset_;  // IF non-zero, then offset to a buffer.
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(PickleTest, Resize);
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNext);
24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextWithIncompleteHeader);
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRIEND_TEST_ALL_PREFIXES(PickleTest, IteratorHasRoom);
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // BASE_PICKLE_H__
248