LCOV - code coverage report
Current view: directory - ipc/chromium/src/base - pickle.h (source / functions) Found Hit Coverage
Test: app.info Lines: 47 32 68.1 %
Date: 2012-06-02 Functions: 22 16 72.7 %

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

Generated by: LCOV version 1.7