1 // Copyright (c) 2011 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__
12 #include "base/base_export.h"
13 #include "base/basictypes.h"
14 //#include "base/gtest_prod_util.h" // jaehwa
15 //#include "base/logging.h" // jaehwa
16 #include "log.h" // jaehwa
17 //#include "base/string16.h" // jaehwa
19 // This class provides facilities for basic binary value packing and unpacking.
21 // The Pickle class supports appending primitive values (ints, strings, etc.)
22 // to a pickle instance. The Pickle instance grows its internal memory buffer
23 // dynamically to hold the sequence of primitive values. The internal memory
24 // buffer is exposed as the "data" of the Pickle. This "data" can be passed
25 // to a Pickle object to initialize it for reading.
27 // When reading from a Pickle object, it is important for the consumer to know
28 // what value types to read and in what order to read them as the Pickle does
29 // not keep track of the type of data written to it.
31 // The Pickle's data has a header which contains the size of the Pickle's
32 // payload. It can optionally support additional space in the header. That
33 // space is controlled by the header_size parameter passed to the Pickle
36 class BASE_EXPORT Pickle {
38 // Initialize a Pickle object using the default header size.
41 // Initialize a Pickle object with the specified header size in bytes, which
42 // must be greater-than-or-equal-to sizeof(Pickle::Header). The header size
43 // will be rounded up to ensure that the header size is 32bit-aligned.
44 explicit Pickle(int header_size);
46 // Initializes a Pickle from a const block of data. The data is not copied;
47 // instead the data is merely referenced by this Pickle. Only const methods
48 // should be used on the Pickle when initialized this way. The header
49 // padding size is deduced from the data length.
50 Pickle(const char* data, int data_len);
52 // Initializes a Pickle as a deep copy of another Pickle.
53 Pickle(const Pickle& other);
57 // Performs a deep copy.
58 Pickle& operator=(const Pickle& other);
60 // Returns the size of the Pickle's data.
61 size_t size() const { return header_size_ + header_->payload_size; }
63 // Returns the data for this Pickle.
64 const void* data() const { return header_; }
66 // Methods for reading the payload of the Pickle. To read from the start of
67 // the Pickle, initialize *iter to NULL. If successful, these methods return
68 // true. Otherwise, false is returned to indicate that the result could not
70 bool ReadBool(void** iter, bool* result) const;
71 bool ReadInt(void** iter, int* result) const;
72 bool ReadLong(void** iter, long* result) const;
73 bool ReadSize(void** iter, size_t* result) const;
74 bool ReadUInt16(void** iter, uint16* result) const;
75 bool ReadUInt32(void** iter, uint32* result) const;
76 bool ReadInt64(void** iter, int64* result) const;
77 bool ReadUInt64(void** iter, uint64* result) const;
78 bool ReadString(void** iter, std::string* result) const;
79 // bool ReadWString(void** iter, std::wstring* result) const;
80 // bool ReadString16(void** iter, string16* result) const;
81 bool ReadData(void** iter, const char** data, int* length) const;
82 bool ReadBytes(void** iter, const char** data, int length) const;
84 // Safer version of ReadInt() checks for the result not being negative.
85 // Use it for reading the object sizes.
86 bool ReadLength(void** iter, int* result) const;
88 // Methods for adding to the payload of the Pickle. These values are
89 // appended to the end of the Pickle's payload. When reading values from a
90 // Pickle, it is important to read them in the order in which they were added
92 bool WriteBool(bool value) {
93 return WriteInt(value ? 1 : 0);
95 bool WriteInt(int value) {
96 return WriteBytes(&value, sizeof(value));
98 bool WriteLong(long value) {
99 return WriteBytes(&value, sizeof(value));
101 bool WriteSize(size_t value) {
102 return WriteBytes(&value, sizeof(value));
104 bool WriteUInt16(uint16 value) {
105 return WriteBytes(&value, sizeof(value));
107 bool WriteUInt32(uint32 value) {
108 return WriteBytes(&value, sizeof(value));
110 bool WriteInt64(int64 value) {
111 return WriteBytes(&value, sizeof(value));
113 bool WriteUInt64(uint64 value) {
114 return WriteBytes(&value, sizeof(value));
116 bool WriteString(const std::string& value);
117 // bool WriteWString(const std::wstring& value);
118 // bool WriteString16(const string16& value);
119 bool WriteData(const char* data, int length);
120 bool WriteBytes(const void* data, int data_len);
122 // Same as WriteData, but allows the caller to write directly into the
123 // Pickle. This saves a copy in cases where the data is not already
124 // available in a buffer. The caller should take care to not write more
125 // than the length it declares it will. Use ReadData to get the data.
126 // Returns NULL on failure.
128 // The returned pointer will only be valid until the next write operation
130 char* BeginWriteData(int length);
132 // For Pickles which contain variable length buffers (e.g. those created
133 // with BeginWriteData), the Pickle can
134 // be 'trimmed' if the amount of data required is less than originally
135 // requested. For example, you may have created a buffer with 10K of data,
136 // but decided to only fill 10 bytes of that data. Use this function
137 // to trim the buffer so that we don't send 9990 bytes of unused data.
138 // You cannot increase the size of the variable buffer; only shrink it.
139 // This function assumes that the length of the variable buffer has
141 void TrimWriteData(int length);
143 // Payload follows after allocation of Header (header size is customizable).
145 uint32 payload_size; // Specifies the size of the payload.
148 // Returns the header, cast to a user-specified type T. The type T must be a
149 // subclass of Header and its size must correspond to the header_size passed
150 // to the Pickle constructor.
153 DCHECK_EQ(header_size_, sizeof(T));
154 return static_cast<T*>(header_);
157 const T* headerT() const {
158 DCHECK_EQ(header_size_, sizeof(T));
159 return static_cast<const T*>(header_);
162 // Returns true if the given iterator could point to data with the given
163 // length. If there is no room for the given data before the end of the
164 // payload, returns false.
165 bool IteratorHasRoomFor(const void* iter, int len) const {
166 if ((len < 0) || (iter < header_) || iter > end_of_payload())
168 const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
169 // Watch out for overflow in pointer calculation, which wraps.
170 return (iter <= end_of_region) && (end_of_region <= end_of_payload());
174 size_t payload_size() const { return header_->payload_size; }
177 return reinterpret_cast<char*>(header_) + header_size_;
179 const char* payload() const {
180 return reinterpret_cast<const char*>(header_) + header_size_;
183 // Returns the address of the byte immediately following the currently valid
185 char* end_of_payload() {
186 // We must have a valid header_.
187 return payload() + payload_size();
189 const char* end_of_payload() const {
190 // This object may be invalid.
191 return header_ ? payload() + payload_size() : NULL;
194 size_t capacity() const {
198 // Resizes the buffer for use when writing the specified amount of data. The
199 // location that the data should be written at is returned, or NULL if there
200 // was an error. Call EndWrite with the returned offset and the given length
201 // to pad out for the next write.
202 char* BeginWrite(size_t length);
204 // Completes the write operation by padding the data with NULL bytes until it
205 // is padded. Should be paired with BeginWrite, but it does not necessarily
206 // have to be called after the data is written.
207 void EndWrite(char* dest, int length);
209 // Resize the capacity, note that the input value should include the size of
210 // the header: new_capacity = sizeof(Header) + desired_payload_capacity.
211 // A realloc() failure will cause a Resize failure... and caller should check
212 // the return result for true (i.e., successful resizing).
213 bool Resize(size_t new_capacity);
215 // Aligns 'i' by rounding it up to the next multiple of 'alignment'
216 static size_t AlignInt(size_t i, int alignment) {
217 return i + (alignment - (i % alignment)) % alignment;
220 // Moves the iterator by the given number of bytes, making sure it is aligned.
221 // Pointer (iterator) is NOT aligned, but the change in the pointer
222 // is guaranteed to be a multiple of sizeof(uint32).
223 static void UpdateIter(void** iter, int bytes) {
224 *iter = static_cast<char*>(*iter) + AlignInt(bytes, sizeof(uint32));
227 // Find the end of the pickled data that starts at range_start. Returns NULL
228 // if the entire Pickle is not found in the given data range.
229 static const char* FindNext(size_t header_size,
230 const char* range_start,
231 const char* range_end);
233 // The allocation granularity of the payload.
234 static const int kPayloadUnit;
238 size_t header_size_; // Supports extra data between header and payload.
239 // Allocation size of payload (or -1 if allocation is const).
241 size_t variable_buffer_offset_; // IF non-zero, then offset to a buffer.
243 // FRIEND_TEST_ALL_PREFIXES(PickleTest, Resize);
244 // FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNext);
245 // FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextWithIncompleteHeader);
246 // FRIEND_TEST_ALL_PREFIXES(PickleTest, IteratorHasRoom);
249 #endif // BASE_PICKLE_H__