LCOV - app.info - ipc/chromium/src/base/pickle.h

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-04-21 | 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