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