ipc/chromium/src/base/pickle.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
     2 // Use of this source code is governed by a BSD-style license that can be
     3 // found in the LICENSE file.
     5 #ifndef BASE_PICKLE_H__
     6 #define BASE_PICKLE_H__
     8 #include <string>
    10 #include "base/basictypes.h"
    11 #include "base/logging.h"
    12 #include "base/string16.h"
    14 // This class provides facilities for basic binary value packing and unpacking.
    15 //
    16 // The Pickle class supports appending primitive values (ints, strings, etc.)
    17 // to a pickle instance.  The Pickle instance grows its internal memory buffer
    18 // dynamically to hold the sequence of primitive values.   The internal memory
    19 // buffer is exposed as the "data" of the Pickle.  This "data" can be passed
    20 // to a Pickle object to initialize it for reading.
    21 //
    22 // When reading from a Pickle object, it is important for the consumer to know
    23 // what value types to read and in what order to read them as the Pickle does
    24 // not keep track of the type of data written to it.
    25 //
    26 // The Pickle's data has a header which contains the size of the Pickle's
    27 // payload.  It can optionally support additional space in the header.  That
    28 // space is controlled by the header_size parameter passed to the Pickle
    29 // constructor.
    30 //
    31 class Pickle {
    32  public:
    33   ~Pickle();
    35   // Initialize a Pickle object using the default header size.
    36   Pickle();
    38   // Initialize a Pickle object with the specified header size in bytes, which
    39   // must be greater-than-or-equal-to sizeof(Pickle::Header).  The header size
    40   // will be rounded up to ensure that the header size is 32bit-aligned.
    41   explicit Pickle(int header_size);
    43   // Initializes a Pickle from a const block of data.  The data is not copied;
    44   // instead the data is merely referenced by this Pickle.  Only const methods
    45   // should be used on the Pickle when initialized this way.  The header
    46   // padding size is deduced from the data length.
    47   Pickle(const char* data, int data_len);
    49   // Initializes a Pickle as a deep copy of another Pickle.
    50   Pickle(const Pickle& other);
    52   // Performs a deep copy.
    53   Pickle& operator=(const Pickle& other);
    55   // Returns the size of the Pickle's data.
    56   int size() const { return static_cast<int>(header_size_ +
    57                                              header_->payload_size); }
    59   // Returns the data for this Pickle.
    60   const void* data() const { return header_; }
    62   // Methods for reading the payload of the Pickle.  To read from the start of
    63   // the Pickle, initialize *iter to NULL.  If successful, these methods return
    64   // true.  Otherwise, false is returned to indicate that the result could not
    65   // be extracted.
    66   bool ReadBool(void** iter, bool* result) const;
    67   bool ReadInt16(void** iter, int16_t* result) const;
    68   bool ReadUInt16(void** iter, uint16_t* result) const;
    69   bool ReadShort(void** iter, short* result) const;
    70   bool ReadInt(void** iter, int* result) const;
    71   bool ReadLong(void** iter, long* result) const;
    72   bool ReadULong(void** iter, unsigned long* result) const;
    73   bool ReadSize(void** iter, size_t* result) const;
    74   bool ReadInt32(void** iter, int32_t* result) const;
    75   bool ReadUInt32(void** iter, uint32_t* result) const;
    76   bool ReadInt64(void** iter, int64_t* result) const;
    77   bool ReadUInt64(void** iter, uint64_t* result) const;
    78   bool ReadDouble(void** iter, double* result) const;
    79   bool ReadIntPtr(void** iter, intptr_t* result) const;
    80   bool ReadUnsignedChar(void** iter, unsigned char* result) const;
    81   bool ReadString(void** iter, std::string* result) const;
    82   bool ReadWString(void** iter, std::wstring* result) const;
    83   bool ReadString16(void** iter, string16* result) const;
    84   bool ReadData(void** iter, const char** data, int* length) const;
    85   bool ReadBytes(void** iter, const char** data, int length,
    86                  uint32_t alignment = sizeof(memberAlignmentType)) const;
    88   // Safer version of ReadInt() checks for the result not being negative.
    89   // Use it for reading the object sizes.
    90   bool ReadLength(void** iter, int* result) const;
    92   // Methods for adding to the payload of the Pickle.  These values are
    93   // appended to the end of the Pickle's payload.  When reading values from a
    94   // Pickle, it is important to read them in the order in which they were added
    95   // to the Pickle.
    96   bool WriteBool(bool value) {
    97     return WriteInt(value ? 1 : 0);
    98   }
    99   bool WriteInt16(int16_t value) {
   100     return WriteBytes(&value, sizeof(value));
   101   }
   102   bool WriteUInt16(uint16_t value) {
   103     return WriteBytes(&value, sizeof(value));
   104   }
   105   bool WriteInt(int value) {
   106     return WriteBytes(&value, sizeof(value));
   107   }
   108   bool WriteLong(long value) {
   109     // Always written as a 64-bit value since the size for this type can
   110     // differ between architectures.
   111     return WriteInt64(int64_t(value));
   112   }
   113   bool WriteULong(unsigned long value) {
   114     // Always written as a 64-bit value since the size for this type can
   115     // differ between architectures.
   116     return WriteUInt64(uint64_t(value));
   117   }
   118   bool WriteSize(size_t value) {
   119     // Always written as a 64-bit value since the size for this type can
   120     // differ between architectures.
   121     return WriteUInt64(uint64_t(value));
   122   }
   123   bool WriteInt32(int32_t value) {
   124     return WriteBytes(&value, sizeof(value));
   125   }
   126   bool WriteUInt32(uint32_t value) {
   127     return WriteBytes(&value, sizeof(value));
   128   }
   129   bool WriteInt64(int64_t value) {
   130     return WriteBytes(&value, sizeof(value));
   131   }
   132   bool WriteUInt64(uint64_t value) {
   133     return WriteBytes(&value, sizeof(value));
   134   }
   135   bool WriteDouble(double value) {
   136     return WriteBytes(&value, sizeof(value));
   137   }
   138   bool WriteIntPtr(intptr_t value) {
   139     // Always written as a 64-bit value since the size for this type can
   140     // differ between architectures.
   141     return WriteInt64(int64_t(value));
   142   }
   143   bool WriteUnsignedChar(unsigned char value) {
   144     return WriteBytes(&value, sizeof(value));
   145   }
   146   bool WriteString(const std::string& value);
   147   bool WriteWString(const std::wstring& value);
   148   bool WriteString16(const string16& value);
   149   bool WriteData(const char* data, int length);
   150   bool WriteBytes(const void* data, int data_len,
   151                   uint32_t alignment = sizeof(memberAlignmentType));
   153   // Same as WriteData, but allows the caller to write directly into the
   154   // Pickle. This saves a copy in cases where the data is not already
   155   // available in a buffer. The caller should take care to not write more
   156   // than the length it declares it will. Use ReadData to get the data.
   157   // Returns NULL on failure.
   158   //
   159   // The returned pointer will only be valid until the next write operation
   160   // on this Pickle.
   161   char* BeginWriteData(int length);
   163   // For Pickles which contain variable length buffers (e.g. those created
   164   // with BeginWriteData), the Pickle can
   165   // be 'trimmed' if the amount of data required is less than originally
   166   // requested.  For example, you may have created a buffer with 10K of data,
   167   // but decided to only fill 10 bytes of that data.  Use this function
   168   // to trim the buffer so that we don't send 9990 bytes of unused data.
   169   // You cannot increase the size of the variable buffer; only shrink it.
   170   // This function assumes that the length of the variable buffer has
   171   // not been changed.
   172   void TrimWriteData(int length);
   174   void EndRead(void* iter) const {
   175     DCHECK(iter == end_of_payload());
   176   }
   178   // Payload follows after allocation of Header (header size is customizable).
   179   struct Header {
   180     uint32_t payload_size;  // Specifies the size of the payload.
   181   };
   183   // Returns the header, cast to a user-specified type T.  The type T must be a
   184   // subclass of Header and its size must correspond to the header_size passed
   185   // to the Pickle constructor.
   186   template <class T>
   187   T* headerT() {
   188     DCHECK(sizeof(T) == header_size_);
   189     return static_cast<T*>(header_);
   190   }
   191   template <class T>
   192   const T* headerT() const {
   193     DCHECK(sizeof(T) == header_size_);
   194     return static_cast<const T*>(header_);
   195   }
   197   // Returns true if the given iterator could point to data with the given
   198   // length. If there is no room for the given data before the end of the
   199   // payload, returns false.
   200   bool IteratorHasRoomFor(const void* iter, int len) const {
   201     if ((len < 0) || (iter < header_) || iter > end_of_payload())
   202       return false;
   203     const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
   204     // Watch out for overflow in pointer calculation, which wraps.
   205     return (iter <= end_of_region) && (end_of_region <= end_of_payload());
   206   }
   208   typedef uint32_t memberAlignmentType;
   210  protected:
   211   uint32_t payload_size() const { return header_->payload_size; }
   213   char* payload() {
   214     return reinterpret_cast<char*>(header_) + header_size_;
   215   }
   216   const char* payload() const {
   217     return reinterpret_cast<const char*>(header_) + header_size_;
   218   }
   220   // Returns the address of the byte immediately following the currently valid
   221   // header + payload.
   222   char* end_of_payload() {
   223     return payload() + payload_size();
   224   }
   225   const char* end_of_payload() const {
   226     return payload() + payload_size();
   227   }
   229   uint32_t capacity() const {
   230     return capacity_;
   231   }
   233   // Resizes the buffer for use when writing the specified amount of data. The
   234   // location that the data should be written at is returned, or NULL if there
   235   // was an error. Call EndWrite with the returned offset and the given length
   236   // to pad out for the next write.
   237   char* BeginWrite(uint32_t length, uint32_t alignment);
   239   // Completes the write operation by padding the data with NULL bytes until it
   240   // is padded. Should be paired with BeginWrite, but it does not necessarily
   241   // have to be called after the data is written.
   242   void EndWrite(char* dest, int length);
   244   // Resize the capacity, note that the input value should include the size of
   245   // the header: new_capacity = sizeof(Header) + desired_payload_capacity.
   246   // A realloc() failure will cause a Resize failure... and caller should check
   247   // the return result for true (i.e., successful resizing).
   248   bool Resize(uint32_t new_capacity);
   250   // Round 'bytes' up to the next multiple of 'alignment'.  'alignment' must be
   251   // a power of 2.
   252   template<uint32_t alignment> struct ConstantAligner {
   253     static uint32_t align(int bytes) {
   254       static_assert((alignment & (alignment - 1)) == 0,
   255 			"alignment must be a power of two");
   256       return (bytes + (alignment - 1)) & ~static_cast<uint32_t>(alignment - 1);
   257     }
   258   };
   260   static uint32_t AlignInt(int bytes) {
   261     return ConstantAligner<sizeof(memberAlignmentType)>::align(bytes);
   262   }
   264   // Moves the iterator by the given number of bytes, making sure it is aligned.
   265   // Pointer (iterator) is NOT aligned, but the change in the pointer
   266   // is guaranteed to be a multiple of sizeof(memberAlignmentType).
   267   static void UpdateIter(void** iter, int bytes) {
   268     *iter = static_cast<char*>(*iter) + AlignInt(bytes);
   269   }
   271   // Find the end of the pickled data that starts at range_start.  Returns NULL
   272   // if the entire Pickle is not found in the given data range.
   273   static const char* FindNext(uint32_t header_size,
   274                               const char* range_start,
   275                               const char* range_end);
   277   // The allocation granularity of the payload.
   278   static const int kPayloadUnit;
   280  private:
   281   Header* header_;
   282   uint32_t header_size_;
   283   uint32_t capacity_;
   284   uint32_t variable_buffer_offset_;
   285 };
   287 #endif  // BASE_PICKLE_H__

mercurial