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