/ipc/chromium/src/base/pickle.h

http://github.com/zpao/v8monkey · C Header · 278 lines · 150 code · 33 blank · 95 comment · 7 complexity · c48aba81abf9ad6df48d4ce4370b4e7c MD5 · raw file

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