15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_PICKLE_H__ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_PICKLE_H__ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Pickle; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PickleIterator reads data from a Pickle. The Pickle object must remain valid 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while the PickleIterator object is in use. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT PickleIterator { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator() : read_ptr_(NULL), read_end_ptr_(NULL) {} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit PickleIterator(const Pickle& pickle); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Methods for reading the payload of the Pickle. To read from the start of 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the Pickle, create a PickleIterator from a Pickle. If successful, these 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // methods return true. Otherwise, false is returned to indicate that the 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result could not be extracted. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadBool(bool* result) WARN_UNUSED_RESULT; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadInt(int* result) WARN_UNUSED_RESULT; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadLong(long* result) WARN_UNUSED_RESULT; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadUInt16(uint16* result) WARN_UNUSED_RESULT; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadUInt32(uint32* result) WARN_UNUSED_RESULT; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadInt64(int64* result) WARN_UNUSED_RESULT; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadUInt64(uint64* result) WARN_UNUSED_RESULT; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ReadFloat(float* result) WARN_UNUSED_RESULT; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadString(std::string* result) WARN_UNUSED_RESULT; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadWString(std::wstring* result) WARN_UNUSED_RESULT; 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool ReadString16(base::string16* result) WARN_UNUSED_RESULT; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadData(const char** data, int* length) WARN_UNUSED_RESULT; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadBytes(const char** data, int length) WARN_UNUSED_RESULT; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Safer version of ReadInt() checks for the result not being negative. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use it for reading the object sizes. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadLength(int* result) WARN_UNUSED_RESULT { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadInt(result) && *result >= 0; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skips bytes in the read buffer and returns true if there are at least 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // num_bytes available. Otherwise, does nothing and returns false. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SkipBytes(int num_bytes) WARN_UNUSED_RESULT { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!GetReadPointerAndAdvance(num_bytes); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Aligns 'i' by rounding it up to the next multiple of 'alignment' 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static size_t AlignInt(size_t i, int alignment) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i + (alignment - (i % alignment)) % alignment; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read Type from Pickle. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Type> 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool ReadBuiltinType(Type* result); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get read pointer for Type and advance read pointer. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<typename Type> 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const char* GetReadPointerAndAdvance(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get read pointer for |num_bytes| and advance read pointer. This method 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // checks num_bytes for negativity and wrapping. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* GetReadPointerAndAdvance(int num_bytes); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get read pointer for (num_elements * size_element) bytes and advance read 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointer. This method checks for int overflow, negativity and wrapping. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const char* GetReadPointerAndAdvance(int num_elements, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size_element); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pointers to the Pickle data. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_ptr_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* read_end_ptr_; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, GetReadPointerAndAdvance); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides facilities for basic binary value packing and unpacking. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Pickle class supports appending primitive values (ints, strings, etc.) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a pickle instance. The Pickle instance grows its internal memory buffer 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dynamically to hold the sequence of primitive values. The internal memory 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// buffer is exposed as the "data" of the Pickle. This "data" can be passed 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a Pickle object to initialize it for reading. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When reading from a Pickle object, it is important for the consumer to know 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// what value types to read and in what order to read them as the Pickle does 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not keep track of the type of data written to it. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Pickle's data has a header which contains the size of the Pickle's 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// payload. It can optionally support additional space in the header. That 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// space is controlled by the header_size parameter passed to the Pickle 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constructor. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT Pickle { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize a Pickle object using the default header size. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize a Pickle object with the specified header size in bytes, which 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must be greater-than-or-equal-to sizeof(Pickle::Header). The header size 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be rounded up to ensure that the header size is 32bit-aligned. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit Pickle(int header_size); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes a Pickle from a const block of data. The data is not copied; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instead the data is merely referenced by this Pickle. Only const methods 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be used on the Pickle when initialized this way. The header 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // padding size is deduced from the data length. 1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Pickle(const char* data, int data_len); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes a Pickle as a deep copy of another Pickle. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle(const Pickle& other); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: There are no virtual methods in this class. This destructor is 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // virtual as an element of defensive coding. Other classes have derived from 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this class, and there is a *chance* that they will cast into this base 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // class before destruction. At least one such class does have a virtual 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destructor, suggesting at least some need to call more derived destructors. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Pickle(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs a deep copy. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle& operator=(const Pickle& other); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the size of the Pickle's data. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size() const { return header_size_ + header_->payload_size; } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the data for this Pickle. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* data() const { return header_; } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For compatibility, these older style read methods pass through to the 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PickleIterator methods. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jbates) Remove these methods. 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadBool(PickleIterator* iter, 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool* result) const WARN_UNUSED_RESULT { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadBool(result); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadInt(PickleIterator* iter, 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* result) const WARN_UNUSED_RESULT { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadInt(result); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadLong(PickleIterator* iter, 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) long* result) const WARN_UNUSED_RESULT { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadLong(result); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadUInt16(PickleIterator* iter, 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint16* result) const WARN_UNUSED_RESULT { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadUInt16(result); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadUInt32(PickleIterator* iter, 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32* result) const WARN_UNUSED_RESULT { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadUInt32(result); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadInt64(PickleIterator* iter, 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int64* result) const WARN_UNUSED_RESULT { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadInt64(result); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadUInt64(PickleIterator* iter, 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint64* result) const WARN_UNUSED_RESULT { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadUInt64(result); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadFloat(PickleIterator* iter, 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) float* result) const WARN_UNUSED_RESULT { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return iter->ReadFloat(result); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadString(PickleIterator* iter, 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string* result) const WARN_UNUSED_RESULT { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadString(result); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadWString(PickleIterator* iter, 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::wstring* result) const WARN_UNUSED_RESULT { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadWString(result); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadString16(PickleIterator* iter, 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* result) const WARN_UNUSED_RESULT { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadString16(result); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A pointer to the data will be placed in *data, and the length will be 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // placed in *length. This buffer will be into the message's buffer so will 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be scoped to the lifetime of the message (or until the message data is 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mutated). 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadData(PickleIterator* iter, 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char** data, 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* length) const WARN_UNUSED_RESULT { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadData(data, length); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A pointer to the data will be placed in *data. The caller specifies the 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of bytes to read, and ReadBytes will validate this length. The 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returned buffer will be into the message's buffer so will be scoped to the 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lifetime of the message (or until the message data is mutated). 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadBytes(PickleIterator* iter, 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char** data, 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int length) const WARN_UNUSED_RESULT { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadBytes(data, length); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Safer version of ReadInt() checks for the result not being negative. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use it for reading the object sizes. 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadLength(PickleIterator* iter, 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* result) const WARN_UNUSED_RESULT { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadLength(result); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Methods for adding to the payload of the Pickle. These values are 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appended to the end of the Pickle's payload. When reading values from a 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pickle, it is important to read them in the order in which they were added 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the Pickle. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteBool(bool value) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteInt(value ? 1 : 0); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteInt(int value) { 2191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WARNING: DO NOT USE THIS METHOD IF PICKLES ARE PERSISTED IN ANY WAY. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It will write whatever a "long" is on this architecture. On 32-bit 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // platforms, it is 32 bits. On 64-bit platforms, it is 64 bits. If persisted 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pickles are still around after upgrading to 64-bit, or if they are copied 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // between dissimilar systems, YOUR PICKLES WILL HAVE GONE BAD. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteLongUsingDangerousNonPortableLessPersistableForm(long value) { 2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteUInt16(uint16 value) { 2301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteUInt32(uint32 value) { 2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteInt64(int64 value) { 2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteUInt64(uint64 value) { 2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool WriteFloat(float value) { 2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteString(const std::string& value); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteWString(const std::wstring& value); 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool WriteString16(const base::string16& value); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Data" is a blob with a length. When you read it out you will be given the 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // length. See also WriteBytes. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteData(const char* data, int length); 2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // "Bytes" is a blob with no length. The caller must specify the length both 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when reading and writing. It is normally used to serialize PoD types of a 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // known size. See also WriteData. 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool WriteBytes(const void* data, int length); 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Reserves space for upcoming writes when multiple writes will be made and 2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // their sizes are computed in advance. It can be significantly faster to call 2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Reserve() before calling WriteFoo() multiple times. 2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void Reserve(size_t additional_capacity); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Payload follows after allocation of Header (header size is customizable). 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Header { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 payload_size; // Specifies the size of the payload. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the header, cast to a user-specified type T. The type T must be a 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subclass of Header and its size must correspond to the header_size passed 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the Pickle constructor. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class T> 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* headerT() { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(header_size_, sizeof(T)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<T*>(header_); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class T> 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const T* headerT() const { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(header_size_, sizeof(T)); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<const T*>(header_); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The payload is the pickle data immediately following the header. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t payload_size() const { return header_->payload_size; } 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* payload() const { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<const char*>(header_) + header_size_; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the address of the byte immediately following the currently valid 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // header + payload. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end_of_payload() const { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This object may be invalid. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return header_ ? payload() + payload_size() : NULL; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* mutable_payload() { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return reinterpret_cast<char*>(header_) + header_size_; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t capacity_after_header() const { 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return capacity_after_header_; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Resize the capacity, note that the input value should not include the size 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // of the header. 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void Resize(size_t new_capacity); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Aligns 'i' by rounding it up to the next multiple of 'alignment' 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static size_t AlignInt(size_t i, int alignment) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i + (alignment - (i % alignment)) % alignment; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the end of the pickled data that starts at range_start. Returns NULL 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the entire Pickle is not found in the given data range. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* FindNext(size_t header_size, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* range_start, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* range_end); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The allocation granularity of the payload. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kPayloadUnit; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class PickleIterator; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Header* header_; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t header_size_; // Supports extra data between header and payload. 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Allocation size of payload (or -1 if allocation is const). Note: this 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // doesn't count the header. 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t capacity_after_header_; 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The offset at which we will write the next field. Note: this doesn't count 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the header. 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t write_offset_; 3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Just like WriteBytes, but with a compile-time size, for performance. 3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) template<size_t length> void WriteBytesStatic(const void* data); 3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Writes a POD by copying its bytes. 3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) template <typename T> bool WritePOD(const T& data) { 3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesStatic<sizeof(data)>(&data); 3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) inline void WriteBytesCommon(const void* data, size_t length); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, Resize); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNext); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextWithIncompleteHeader); 3450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextOverflow); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_PICKLE_H__ 349