Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / base / pickle.h
1 // Copyright (c) 2012 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/base_export.h"
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/logging.h"
15 #include "base/strings/string16.h"
16
17 class Pickle;
18
19 // PickleIterator reads data from a Pickle. The Pickle object must remain valid
20 // while the PickleIterator object is in use.
21 class BASE_EXPORT PickleIterator {
22  public:
23   PickleIterator() : payload_(NULL), read_index_(0), end_index_(0) {}
24   explicit PickleIterator(const Pickle& pickle);
25
26   // Methods for reading the payload of the Pickle. To read from the start of
27   // the Pickle, create a PickleIterator from a Pickle. If successful, these
28   // methods return true. Otherwise, false is returned to indicate that the
29   // result could not be extracted. It is not possible to read from iterator
30   // after that.
31   bool ReadBool(bool* result) WARN_UNUSED_RESULT;
32   bool ReadInt(int* result) WARN_UNUSED_RESULT;
33   bool ReadLong(long* result) WARN_UNUSED_RESULT;
34   bool ReadUInt16(uint16* result) WARN_UNUSED_RESULT;
35   bool ReadUInt32(uint32* result) WARN_UNUSED_RESULT;
36   bool ReadInt64(int64* result) WARN_UNUSED_RESULT;
37   bool ReadUInt64(uint64* result) WARN_UNUSED_RESULT;
38   bool ReadFloat(float* result) WARN_UNUSED_RESULT;
39   bool ReadDouble(double* result) WARN_UNUSED_RESULT;
40   bool ReadString(std::string* result) WARN_UNUSED_RESULT;
41   bool ReadWString(std::wstring* result) WARN_UNUSED_RESULT;
42   bool ReadString16(base::string16* result) WARN_UNUSED_RESULT;
43   bool ReadData(const char** data, int* length) WARN_UNUSED_RESULT;
44   bool ReadBytes(const char** data, int length) WARN_UNUSED_RESULT;
45
46   // Safer version of ReadInt() checks for the result not being negative.
47   // Use it for reading the object sizes.
48   bool ReadLength(int* result) WARN_UNUSED_RESULT {
49     return ReadInt(result) && *result >= 0;
50   }
51
52   // Skips bytes in the read buffer and returns true if there are at least
53   // num_bytes available. Otherwise, does nothing and returns false.
54   bool SkipBytes(int num_bytes) WARN_UNUSED_RESULT {
55     return !!GetReadPointerAndAdvance(num_bytes);
56   }
57
58  private:
59   // Aligns 'i' by rounding it up to the next multiple of 'alignment'
60   static size_t AlignInt(size_t i, int alignment) {
61     return i + (alignment - (i % alignment)) % alignment;
62   }
63
64   // Read Type from Pickle.
65   template <typename Type>
66   bool ReadBuiltinType(Type* result);
67
68   // Advance read_index_ but do not allow it to exceed end_index_.
69   // Keeps read_index_ aligned.
70   void Advance(size_t size);
71
72   // Get read pointer for Type and advance read pointer.
73   template<typename Type>
74   const char* GetReadPointerAndAdvance();
75
76   // Get read pointer for |num_bytes| and advance read pointer. This method
77   // checks num_bytes for negativity and wrapping.
78   const char* GetReadPointerAndAdvance(int num_bytes);
79
80   // Get read pointer for (num_elements * size_element) bytes and advance read
81   // pointer. This method checks for int overflow, negativity and wrapping.
82   const char* GetReadPointerAndAdvance(int num_elements,
83                                        size_t size_element);
84
85   const char* payload_;  // Start of our pickle's payload.
86   size_t read_index_;  // Offset of the next readable byte in payload.
87   size_t end_index_;  // Payload size.
88
89   FRIEND_TEST_ALL_PREFIXES(PickleTest, GetReadPointerAndAdvance);
90 };
91
92 // This class provides facilities for basic binary value packing and unpacking.
93 //
94 // The Pickle class supports appending primitive values (ints, strings, etc.)
95 // to a pickle instance.  The Pickle instance grows its internal memory buffer
96 // dynamically to hold the sequence of primitive values.   The internal memory
97 // buffer is exposed as the "data" of the Pickle.  This "data" can be passed
98 // to a Pickle object to initialize it for reading.
99 //
100 // When reading from a Pickle object, it is important for the consumer to know
101 // what value types to read and in what order to read them as the Pickle does
102 // not keep track of the type of data written to it.
103 //
104 // The Pickle's data has a header which contains the size of the Pickle's
105 // payload.  It can optionally support additional space in the header.  That
106 // space is controlled by the header_size parameter passed to the Pickle
107 // constructor.
108 //
109 class BASE_EXPORT Pickle {
110  public:
111   // Initialize a Pickle object using the default header size.
112   Pickle();
113
114   // Initialize a Pickle object with the specified header size in bytes, which
115   // must be greater-than-or-equal-to sizeof(Pickle::Header).  The header size
116   // will be rounded up to ensure that the header size is 32bit-aligned.
117   explicit Pickle(int header_size);
118
119   // Initializes a Pickle from a const block of data.  The data is not copied;
120   // instead the data is merely referenced by this Pickle.  Only const methods
121   // should be used on the Pickle when initialized this way.  The header
122   // padding size is deduced from the data length.
123   Pickle(const char* data, int data_len);
124
125   // Initializes a Pickle as a deep copy of another Pickle.
126   Pickle(const Pickle& other);
127
128   // Note: There are no virtual methods in this class.  This destructor is
129   // virtual as an element of defensive coding.  Other classes have derived from
130   // this class, and there is a *chance* that they will cast into this base
131   // class before destruction.  At least one such class does have a virtual
132   // destructor, suggesting at least some need to call more derived destructors.
133   virtual ~Pickle();
134
135   // Performs a deep copy.
136   Pickle& operator=(const Pickle& other);
137
138   // Returns the size of the Pickle's data.
139   size_t size() const { return header_size_ + header_->payload_size; }
140
141   // Returns the data for this Pickle.
142   const void* data() const { return header_; }
143
144   // For compatibility, these older style read methods pass through to the
145   // PickleIterator methods.
146   // TODO(jbates) Remove these methods.
147   bool ReadBool(PickleIterator* iter,
148                 bool* result) const WARN_UNUSED_RESULT {
149     return iter->ReadBool(result);
150   }
151   bool ReadInt(PickleIterator* iter,
152                int* result) const WARN_UNUSED_RESULT {
153     return iter->ReadInt(result);
154   }
155   bool ReadLong(PickleIterator* iter,
156                 long* result) const WARN_UNUSED_RESULT {
157     return iter->ReadLong(result);
158   }
159   bool ReadUInt16(PickleIterator* iter,
160                   uint16* result) const WARN_UNUSED_RESULT {
161     return iter->ReadUInt16(result);
162   }
163   bool ReadUInt32(PickleIterator* iter,
164                   uint32* result) const WARN_UNUSED_RESULT {
165     return iter->ReadUInt32(result);
166   }
167   bool ReadInt64(PickleIterator* iter,
168                  int64* result) const WARN_UNUSED_RESULT {
169     return iter->ReadInt64(result);
170   }
171   bool ReadUInt64(PickleIterator* iter,
172                   uint64* result) const WARN_UNUSED_RESULT {
173     return iter->ReadUInt64(result);
174   }
175   bool ReadFloat(PickleIterator* iter,
176                  float* result) const WARN_UNUSED_RESULT {
177     return iter->ReadFloat(result);
178   }
179   bool ReadDouble(PickleIterator* iter,
180                   double* result) const WARN_UNUSED_RESULT {
181     return iter->ReadDouble(result);
182   }
183   bool ReadString(PickleIterator* iter,
184                   std::string* result) const WARN_UNUSED_RESULT {
185     return iter->ReadString(result);
186   }
187   bool ReadWString(PickleIterator* iter,
188                    std::wstring* result) const WARN_UNUSED_RESULT {
189     return iter->ReadWString(result);
190   }
191   bool ReadString16(PickleIterator* iter,
192                     base::string16* result) const WARN_UNUSED_RESULT {
193     return iter->ReadString16(result);
194   }
195   // A pointer to the data will be placed in *data, and the length will be
196   // placed in *length. This buffer will be into the message's buffer so will
197   // be scoped to the lifetime of the message (or until the message data is
198   // mutated).
199   bool ReadData(PickleIterator* iter,
200                 const char** data,
201                 int* length) const WARN_UNUSED_RESULT {
202     return iter->ReadData(data, length);
203   }
204   // A pointer to the data will be placed in *data. The caller specifies the
205   // number of bytes to read, and ReadBytes will validate this length. The
206   // returned buffer will be into the message's buffer so will be scoped to the
207   // lifetime of the message (or until the message data is mutated).
208   bool ReadBytes(PickleIterator* iter,
209                  const char** data,
210                  int length) const WARN_UNUSED_RESULT {
211     return iter->ReadBytes(data, length);
212   }
213
214   // Safer version of ReadInt() checks for the result not being negative.
215   // Use it for reading the object sizes.
216   bool ReadLength(PickleIterator* iter,
217                   int* result) const  WARN_UNUSED_RESULT {
218     return iter->ReadLength(result);
219   }
220
221   // Methods for adding to the payload of the Pickle.  These values are
222   // appended to the end of the Pickle's payload.  When reading values from a
223   // Pickle, it is important to read them in the order in which they were added
224   // to the Pickle.
225   bool WriteBool(bool value) {
226     return WriteInt(value ? 1 : 0);
227   }
228   bool WriteInt(int value) {
229     return WritePOD(value);
230   }
231   // WARNING: DO NOT USE THIS METHOD IF PICKLES ARE PERSISTED IN ANY WAY.
232   // It will write whatever a "long" is on this architecture. On 32-bit
233   // platforms, it is 32 bits. On 64-bit platforms, it is 64 bits. If persisted
234   // pickles are still around after upgrading to 64-bit, or if they are copied
235   // between dissimilar systems, YOUR PICKLES WILL HAVE GONE BAD.
236   bool WriteLongUsingDangerousNonPortableLessPersistableForm(long value) {
237     return WritePOD(value);
238   }
239   bool WriteUInt16(uint16 value) {
240     return WritePOD(value);
241   }
242   bool WriteUInt32(uint32 value) {
243     return WritePOD(value);
244   }
245   bool WriteInt64(int64 value) {
246     return WritePOD(value);
247   }
248   bool WriteUInt64(uint64 value) {
249     return WritePOD(value);
250   }
251   bool WriteFloat(float value) {
252     return WritePOD(value);
253   }
254   bool WriteDouble(double value) {
255     return WritePOD(value);
256   }
257   bool WriteString(const std::string& value);
258   bool WriteWString(const std::wstring& value);
259   bool WriteString16(const base::string16& value);
260   // "Data" is a blob with a length. When you read it out you will be given the
261   // length. See also WriteBytes.
262   bool WriteData(const char* data, int length);
263   // "Bytes" is a blob with no length. The caller must specify the length both
264   // when reading and writing. It is normally used to serialize PoD types of a
265   // known size. See also WriteData.
266   bool WriteBytes(const void* data, int length);
267
268   // Reserves space for upcoming writes when multiple writes will be made and
269   // their sizes are computed in advance. It can be significantly faster to call
270   // Reserve() before calling WriteFoo() multiple times.
271   void Reserve(size_t additional_capacity);
272
273   // Payload follows after allocation of Header (header size is customizable).
274   struct Header {
275     uint32 payload_size;  // Specifies the size of the payload.
276   };
277
278   // Returns the header, cast to a user-specified type T.  The type T must be a
279   // subclass of Header and its size must correspond to the header_size passed
280   // to the Pickle constructor.
281   template <class T>
282   T* headerT() {
283     DCHECK_EQ(header_size_, sizeof(T));
284     return static_cast<T*>(header_);
285   }
286   template <class T>
287   const T* headerT() const {
288     DCHECK_EQ(header_size_, sizeof(T));
289     return static_cast<const T*>(header_);
290   }
291
292   // The payload is the pickle data immediately following the header.
293   size_t payload_size() const {
294     return header_ ? header_->payload_size : 0;
295   }
296
297   const char* payload() const {
298     return reinterpret_cast<const char*>(header_) + header_size_;
299   }
300
301   // Returns the address of the byte immediately following the currently valid
302   // header + payload.
303   const char* end_of_payload() const {
304     // This object may be invalid.
305     return header_ ? payload() + payload_size() : NULL;
306   }
307
308  protected:
309   char* mutable_payload() {
310     return reinterpret_cast<char*>(header_) + header_size_;
311   }
312
313   size_t capacity_after_header() const {
314     return capacity_after_header_;
315   }
316
317   // Resize the capacity, note that the input value should not include the size
318   // of the header.
319   void Resize(size_t new_capacity);
320
321   // Aligns 'i' by rounding it up to the next multiple of 'alignment'
322   static size_t AlignInt(size_t i, int alignment) {
323     return i + (alignment - (i % alignment)) % alignment;
324   }
325
326   // Find the end of the pickled data that starts at range_start.  Returns NULL
327   // if the entire Pickle is not found in the given data range.
328   static const char* FindNext(size_t header_size,
329                               const char* range_start,
330                               const char* range_end);
331
332   // The allocation granularity of the payload.
333   static const int kPayloadUnit;
334
335  private:
336   friend class PickleIterator;
337
338   Header* header_;
339   size_t header_size_;  // Supports extra data between header and payload.
340   // Allocation size of payload (or -1 if allocation is const). Note: this
341   // doesn't count the header.
342   size_t capacity_after_header_;
343   // The offset at which we will write the next field. Note: this doesn't count
344   // the header.
345   size_t write_offset_;
346
347   // Just like WriteBytes, but with a compile-time size, for performance.
348   template<size_t length> void BASE_EXPORT WriteBytesStatic(const void* data);
349
350   // Writes a POD by copying its bytes.
351   template <typename T> bool WritePOD(const T& data) {
352     WriteBytesStatic<sizeof(data)>(&data);
353     return true;
354   }
355   inline void WriteBytesCommon(const void* data, size_t length);
356
357   FRIEND_TEST_ALL_PREFIXES(PickleTest, Resize);
358   FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNext);
359   FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextWithIncompleteHeader);
360   FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextOverflow);
361 };
362
363 #endif  // BASE_PICKLE_H__