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