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: 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) PickleIterator() : payload_(NULL), read_index_(0), end_index_(0) {} 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 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // result could not be extracted. It is not possible to read from iterator 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // after that. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadBool(bool* result) WARN_UNUSED_RESULT; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadInt(int* result) WARN_UNUSED_RESULT; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadLong(long* result) WARN_UNUSED_RESULT; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadUInt16(uint16* result) WARN_UNUSED_RESULT; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadUInt32(uint32* result) WARN_UNUSED_RESULT; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadInt64(int64* result) WARN_UNUSED_RESULT; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadUInt64(uint64* result) WARN_UNUSED_RESULT; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ReadFloat(float* result) WARN_UNUSED_RESULT; 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool ReadDouble(double* result) WARN_UNUSED_RESULT; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadString(std::string* result) WARN_UNUSED_RESULT; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadWString(std::wstring* result) WARN_UNUSED_RESULT; 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool ReadString16(base::string16* result) WARN_UNUSED_RESULT; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadData(const char** data, int* length) WARN_UNUSED_RESULT; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadBytes(const char** data, int length) WARN_UNUSED_RESULT; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Safer version of ReadInt() checks for the result not being negative. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use it for reading the object sizes. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadLength(int* result) WARN_UNUSED_RESULT { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ReadInt(result) && *result >= 0; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skips bytes in the read buffer and returns true if there are at least 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // num_bytes available. Otherwise, does nothing and returns false. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SkipBytes(int num_bytes) WARN_UNUSED_RESULT { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!GetReadPointerAndAdvance(num_bytes); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Aligns 'i' by rounding it up to the next multiple of 'alignment' 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static size_t AlignInt(size_t i, int alignment) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i + (alignment - (i % alignment)) % alignment; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read Type from Pickle. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Type> 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool ReadBuiltinType(Type* result); 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Advance read_index_ but do not allow it to exceed end_index_. 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Keeps read_index_ aligned. 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void Advance(size_t size); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get read pointer for Type and advance read pointer. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<typename Type> 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const char* GetReadPointerAndAdvance(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get read pointer for |num_bytes| and advance read pointer. This method 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // checks num_bytes for negativity and wrapping. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* GetReadPointerAndAdvance(int num_bytes); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get read pointer for (num_elements * size_element) bytes and advance read 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointer. This method checks for int overflow, negativity and wrapping. 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const char* GetReadPointerAndAdvance(int num_elements, 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t size_element); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const char* payload_; // Start of our pickle's payload. 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t read_index_; // Offset of the next readable byte in payload. 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t end_index_; // Payload size. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, GetReadPointerAndAdvance); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides facilities for basic binary value packing and unpacking. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Pickle class supports appending primitive values (ints, strings, etc.) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a pickle instance. The Pickle instance grows its internal memory buffer 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dynamically to hold the sequence of primitive values. The internal memory 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// buffer is exposed as the "data" of the Pickle. This "data" can be passed 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a Pickle object to initialize it for reading. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When reading from a Pickle object, it is important for the consumer to know 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// what value types to read and in what order to read them as the Pickle does 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not keep track of the type of data written to it. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Pickle's data has a header which contains the size of the Pickle's 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// payload. It can optionally support additional space in the header. That 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// space is controlled by the header_size parameter passed to the Pickle 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constructor. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT Pickle { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize a Pickle object using the default header size. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize a Pickle object with the specified header size in bytes, which 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must be greater-than-or-equal-to sizeof(Pickle::Header). The header size 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be rounded up to ensure that the header size is 32bit-aligned. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit Pickle(int header_size); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes a Pickle from a const block of data. The data is not copied; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instead the data is merely referenced by this Pickle. Only const methods 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be used on the Pickle when initialized this way. The header 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // padding size is deduced from the data length. 1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Pickle(const char* data, int data_len); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes a Pickle as a deep copy of another Pickle. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle(const Pickle& other); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: There are no virtual methods in this class. This destructor is 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // virtual as an element of defensive coding. Other classes have derived from 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this class, and there is a *chance* that they will cast into this base 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // class before destruction. At least one such class does have a virtual 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destructor, suggesting at least some need to call more derived destructors. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Pickle(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs a deep copy. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle& operator=(const Pickle& other); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the size of the Pickle's data. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size() const { return header_size_ + header_->payload_size; } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the data for this Pickle. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* data() const { return header_; } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For compatibility, these older style read methods pass through to the 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PickleIterator methods. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jbates) Remove these methods. 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadBool(PickleIterator* iter, 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool* result) const WARN_UNUSED_RESULT { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadBool(result); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadInt(PickleIterator* iter, 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* result) const WARN_UNUSED_RESULT { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadInt(result); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadLong(PickleIterator* iter, 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) long* result) const WARN_UNUSED_RESULT { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadLong(result); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadUInt16(PickleIterator* iter, 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint16* result) const WARN_UNUSED_RESULT { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadUInt16(result); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadUInt32(PickleIterator* iter, 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32* result) const WARN_UNUSED_RESULT { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadUInt32(result); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadInt64(PickleIterator* iter, 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int64* result) const WARN_UNUSED_RESULT { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadInt64(result); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadUInt64(PickleIterator* iter, 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint64* result) const WARN_UNUSED_RESULT { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadUInt64(result); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadFloat(PickleIterator* iter, 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) float* result) const WARN_UNUSED_RESULT { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return iter->ReadFloat(result); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool ReadDouble(PickleIterator* iter, 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch double* result) const WARN_UNUSED_RESULT { 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return iter->ReadDouble(result); 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadString(PickleIterator* iter, 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string* result) const WARN_UNUSED_RESULT { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadString(result); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadWString(PickleIterator* iter, 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::wstring* result) const WARN_UNUSED_RESULT { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadWString(result); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadString16(PickleIterator* iter, 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* result) const WARN_UNUSED_RESULT { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadString16(result); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A pointer to the data will be placed in *data, and the length will be 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // placed in *length. This buffer will be into the message's buffer so will 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be scoped to the lifetime of the message (or until the message data is 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mutated). 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadData(PickleIterator* iter, 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char** data, 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* length) const WARN_UNUSED_RESULT { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadData(data, length); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A pointer to the data will be placed in *data. The caller specifies the 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of bytes to read, and ReadBytes will validate this length. The 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returned buffer will be into the message's buffer so will be scoped to the 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lifetime of the message (or until the message data is mutated). 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadBytes(PickleIterator* iter, 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char** data, 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int length) const WARN_UNUSED_RESULT { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadBytes(data, length); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Safer version of ReadInt() checks for the result not being negative. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use it for reading the object sizes. 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool ReadLength(PickleIterator* iter, 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int* result) const WARN_UNUSED_RESULT { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->ReadLength(result); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Methods for adding to the payload of the Pickle. These values are 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appended to the end of the Pickle's payload. When reading values from a 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pickle, it is important to read them in the order in which they were added 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the Pickle. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteBool(bool value) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteInt(value ? 1 : 0); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteInt(int value) { 2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WARNING: DO NOT USE THIS METHOD IF PICKLES ARE PERSISTED IN ANY WAY. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It will write whatever a "long" is on this architecture. On 32-bit 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // platforms, it is 32 bits. On 64-bit platforms, it is 64 bits. If persisted 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pickles are still around after upgrading to 64-bit, or if they are copied 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // between dissimilar systems, YOUR PICKLES WILL HAVE GONE BAD. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteLongUsingDangerousNonPortableLessPersistableForm(long value) { 2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteUInt16(uint16 value) { 2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteUInt32(uint32 value) { 2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteInt64(int64 value) { 2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteUInt64(uint64 value) { 2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool WriteFloat(float value) { 2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return WritePOD(value); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool WriteDouble(double value) { 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return WritePOD(value); 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteString(const std::string& value); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteWString(const std::wstring& value); 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool WriteString16(const base::string16& value); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Data" is a blob with a length. When you read it out you will be given the 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // length. See also WriteBytes. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteData(const char* data, int length); 2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // "Bytes" is a blob with no length. The caller must specify the length both 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when reading and writing. It is normally used to serialize PoD types of a 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // known size. See also WriteData. 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool WriteBytes(const void* data, int length); 2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Reserves space for upcoming writes when multiple writes will be made and 2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // their sizes are computed in advance. It can be significantly faster to call 2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Reserve() before calling WriteFoo() multiple times. 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void Reserve(size_t additional_capacity); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Payload follows after allocation of Header (header size is customizable). 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Header { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 payload_size; // Specifies the size of the payload. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the header, cast to a user-specified type T. The type T must be a 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // subclass of Header and its size must correspond to the header_size passed 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the Pickle constructor. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class T> 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* headerT() { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(header_size_, sizeof(T)); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<T*>(header_); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class T> 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const T* headerT() const { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(header_size_, sizeof(T)); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<const T*>(header_); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The payload is the pickle data immediately following the header. 29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) size_t payload_size() const { 29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return header_ ? header_->payload_size : 0; 29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* payload() const { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<const char*>(header_) + header_size_; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the address of the byte immediately following the currently valid 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // header + payload. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end_of_payload() const { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This object may be invalid. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return header_ ? payload() + payload_size() : NULL; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* mutable_payload() { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return reinterpret_cast<char*>(header_) + header_size_; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t capacity_after_header() const { 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return capacity_after_header_; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Resize the capacity, note that the input value should not include the size 3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // of the header. 3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void Resize(size_t new_capacity); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Aligns 'i' by rounding it up to the next multiple of 'alignment' 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static size_t AlignInt(size_t i, int alignment) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i + (alignment - (i % alignment)) % alignment; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the end of the pickled data that starts at range_start. Returns NULL 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the entire Pickle is not found in the given data range. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* FindNext(size_t header_size, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* range_start, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* range_end); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The allocation granularity of the payload. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kPayloadUnit; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class PickleIterator; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Header* header_; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t header_size_; // Supports extra data between header and payload. 3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Allocation size of payload (or -1 if allocation is const). Note: this 3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // doesn't count the header. 3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t capacity_after_header_; 3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The offset at which we will write the next field. Note: this doesn't count 3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the header. 3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t write_offset_; 3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Just like WriteBytes, but with a compile-time size, for performance. 348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) template<size_t length> void BASE_EXPORT WriteBytesStatic(const void* data); 3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Writes a POD by copying its bytes. 3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) template <typename T> bool WritePOD(const T& data) { 3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) WriteBytesStatic<sizeof(data)>(&data); 3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) inline void WriteBytesCommon(const void* data, size_t length); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, Resize); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNext); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextWithIncompleteHeader); 3600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextOverflow); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_PICKLE_H__ 364