Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: base/pickle.h

Issue 9447084: Refactor Pickle Read methods to use higher performance PickleIterator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: compile (racing with incoming CLs) Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/metrics/histogram.cc ('k') | base/pickle.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_PICKLE_H__ 5 #ifndef BASE_PICKLE_H__
6 #define BASE_PICKLE_H__ 6 #define BASE_PICKLE_H__
7 #pragma once 7 #pragma once
8 8
9 #include <string> 9 #include <string>
10 10
11 #include "base/base_export.h" 11 #include "base/base_export.h"
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
13 #include "base/gtest_prod_util.h" 14 #include "base/gtest_prod_util.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/string16.h" 16 #include "base/string16.h"
16 17
18 class Pickle;
19
20 // PickleIterator reads data from a Pickle. The Pickle object must remain valid
21 // while the PickleIterator object is in use.
22 class BASE_EXPORT PickleIterator {
23 public:
24 PickleIterator() : read_ptr_(NULL), read_end_ptr_(NULL) {}
25 explicit PickleIterator(const Pickle& pickle);
26
27 // Methods for reading the payload of the Pickle. To read from the start of
28 // the Pickle, create a PickleIterator from a Pickle. If successful, these
29 // methods return true. Otherwise, false is returned to indicate that the
30 // result could not be extracted.
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 ReadSize(size_t* result) WARN_UNUSED_RESULT;
35 bool ReadUInt16(uint16* result) WARN_UNUSED_RESULT;
36 bool ReadUInt32(uint32* result) WARN_UNUSED_RESULT;
37 bool ReadInt64(int64* result) WARN_UNUSED_RESULT;
38 bool ReadUInt64(uint64* result) WARN_UNUSED_RESULT;
39 bool ReadString(std::string* result) WARN_UNUSED_RESULT;
40 bool ReadWString(std::wstring* result) WARN_UNUSED_RESULT;
41 bool ReadString16(string16* result) WARN_UNUSED_RESULT;
42 bool ReadData(const char** data, int* length) WARN_UNUSED_RESULT;
43 bool ReadBytes(const char** data, int length) WARN_UNUSED_RESULT;
44
45 // Safer version of ReadInt() checks for the result not being negative.
46 // Use it for reading the object sizes.
47 bool ReadLength(int* result) WARN_UNUSED_RESULT {
48 return ReadInt(result) && *result >= 0;
49 }
50
51 // Skips bytes in the read buffer and returns true if there are at least
52 // num_bytes available. Otherwise, does nothing and returns false.
53 bool SkipBytes(int num_bytes) WARN_UNUSED_RESULT {
54 return !!GetReadPointerAndAdvance(num_bytes);
55 }
56
57 private:
58 // Aligns 'i' by rounding it up to the next multiple of 'alignment'
59 static size_t AlignInt(size_t i, int alignment) {
60 return i + (alignment - (i % alignment)) % alignment;
61 }
62
63 // Read Type from Pickle.
64 template <typename Type>
65 inline bool ReadBuiltinType(Type* result);
66
67 // Get read pointer for Type and advance read pointer.
68 template<typename Type>
69 inline const char* GetReadPointerAndAdvance();
70
71 // Get read pointer for |num_bytes| and advance read pointer. This method
72 // checks num_bytes for negativity and wrapping.
73 const char* GetReadPointerAndAdvance(int num_bytes);
74
75 // Get read pointer for (num_elements * size_element) bytes and advance read
76 // pointer. This method checks for int overflow, negativity and wrapping.
77 inline const char* GetReadPointerAndAdvance(int num_elements,
78 size_t size_element);
79
80 // Pointers to the Pickle data.
81 const char* read_ptr_;
82 const char* read_end_ptr_;
83
84 FRIEND_TEST_ALL_PREFIXES(PickleTest, GetReadPointerAndAdvance);
85 };
86
17 // This class provides facilities for basic binary value packing and unpacking. 87 // This class provides facilities for basic binary value packing and unpacking.
18 // 88 //
19 // The Pickle class supports appending primitive values (ints, strings, etc.) 89 // The Pickle class supports appending primitive values (ints, strings, etc.)
20 // to a pickle instance. The Pickle instance grows its internal memory buffer 90 // to a pickle instance. The Pickle instance grows its internal memory buffer
21 // dynamically to hold the sequence of primitive values. The internal memory 91 // dynamically to hold the sequence of primitive values. The internal memory
22 // buffer is exposed as the "data" of the Pickle. This "data" can be passed 92 // buffer is exposed as the "data" of the Pickle. This "data" can be passed
23 // to a Pickle object to initialize it for reading. 93 // to a Pickle object to initialize it for reading.
24 // 94 //
25 // When reading from a Pickle object, it is important for the consumer to know 95 // When reading from a Pickle object, it is important for the consumer to know
26 // what value types to read and in what order to read them as the Pickle does 96 // what value types to read and in what order to read them as the Pickle does
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 129
60 // Performs a deep copy. 130 // Performs a deep copy.
61 Pickle& operator=(const Pickle& other); 131 Pickle& operator=(const Pickle& other);
62 132
63 // Returns the size of the Pickle's data. 133 // Returns the size of the Pickle's data.
64 size_t size() const { return header_size_ + header_->payload_size; } 134 size_t size() const { return header_size_ + header_->payload_size; }
65 135
66 // Returns the data for this Pickle. 136 // Returns the data for this Pickle.
67 const void* data() const { return header_; } 137 const void* data() const { return header_; }
68 138
69 // Methods for reading the payload of the Pickle. To read from the start of 139 // For compatibility, these older style read methods pass through to the
70 // the Pickle, initialize *iter to NULL. If successful, these methods return 140 // PickleIterator methods.
71 // true. Otherwise, false is returned to indicate that the result could not 141 // TODO(jbates) Remove these methods.
72 // be extracted. 142 bool ReadBool(PickleIterator* iter, bool* result) const {
73 bool ReadBool(void** iter, bool* result) const; 143 return iter->ReadBool(result);
74 bool ReadInt(void** iter, int* result) const; 144 }
75 bool ReadLong(void** iter, long* result) const; 145 bool ReadInt(PickleIterator* iter, int* result) const {
76 bool ReadSize(void** iter, size_t* result) const; 146 return iter->ReadInt(result);
77 bool ReadUInt16(void** iter, uint16* result) const; 147 }
78 bool ReadUInt32(void** iter, uint32* result) const; 148 bool ReadLong(PickleIterator* iter, long* result) const {
79 bool ReadInt64(void** iter, int64* result) const; 149 return iter->ReadLong(result);
80 bool ReadUInt64(void** iter, uint64* result) const; 150 }
81 bool ReadString(void** iter, std::string* result) const; 151 bool ReadSize(PickleIterator* iter, size_t* result) const {
82 bool ReadWString(void** iter, std::wstring* result) const; 152 return iter->ReadSize(result);
83 bool ReadString16(void** iter, string16* result) const; 153 }
84 bool ReadData(void** iter, const char** data, int* length) const; 154 bool ReadUInt16(PickleIterator* iter, uint16* result) const {
85 bool ReadBytes(void** iter, const char** data, int length) const; 155 return iter->ReadUInt16(result);
156 }
157 bool ReadUInt32(PickleIterator* iter, uint32* result) const {
158 return iter->ReadUInt32(result);
159 }
160 bool ReadInt64(PickleIterator* iter, int64* result) const {
161 return iter->ReadInt64(result);
162 }
163 bool ReadUInt64(PickleIterator* iter, uint64* result) const {
164 return iter->ReadUInt64(result);
165 }
166 bool ReadString(PickleIterator* iter, std::string* result) const {
167 return iter->ReadString(result);
168 }
169 bool ReadWString(PickleIterator* iter, std::wstring* result) const {
170 return iter->ReadWString(result);
171 }
172 bool ReadString16(PickleIterator* iter, string16* result) const {
173 return iter->ReadString16(result);
174 }
175 bool ReadData(PickleIterator* iter, const char** data, int* length) const {
176 return iter->ReadData(data, length);
177 }
178 bool ReadBytes(PickleIterator* iter, const char** data, int length) const {
179 return iter->ReadBytes(data, length);
180 }
86 181
87 // Safer version of ReadInt() checks for the result not being negative. 182 // Safer version of ReadInt() checks for the result not being negative.
88 // Use it for reading the object sizes. 183 // Use it for reading the object sizes.
89 bool ReadLength(void** iter, int* result) const; 184 bool ReadLength(PickleIterator* iter, int* result) const {
185 return iter->ReadLength(result);
186 }
90 187
91 // Methods for adding to the payload of the Pickle. These values are 188 // Methods for adding to the payload of the Pickle. These values are
92 // appended to the end of the Pickle's payload. When reading values from a 189 // appended to the end of the Pickle's payload. When reading values from a
93 // Pickle, it is important to read them in the order in which they were added 190 // Pickle, it is important to read them in the order in which they were added
94 // to the Pickle. 191 // to the Pickle.
95 bool WriteBool(bool value) { 192 bool WriteBool(bool value) {
96 return WriteInt(value ? 1 : 0); 193 return WriteInt(value ? 1 : 0);
97 } 194 }
98 bool WriteInt(int value) { 195 bool WriteInt(int value) {
99 return WriteBytes(&value, sizeof(value)); 196 return WriteBytes(&value, sizeof(value));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 T* headerT() { 252 T* headerT() {
156 DCHECK_EQ(header_size_, sizeof(T)); 253 DCHECK_EQ(header_size_, sizeof(T));
157 return static_cast<T*>(header_); 254 return static_cast<T*>(header_);
158 } 255 }
159 template <class T> 256 template <class T>
160 const T* headerT() const { 257 const T* headerT() const {
161 DCHECK_EQ(header_size_, sizeof(T)); 258 DCHECK_EQ(header_size_, sizeof(T));
162 return static_cast<const T*>(header_); 259 return static_cast<const T*>(header_);
163 } 260 }
164 261
165 // Returns true if the given iterator could point to data with the given
166 // length. If there is no room for the given data before the end of the
167 // payload, returns false.
168 bool IteratorHasRoomFor(const void* iter, int len) const {
169 if ((len < 0) || (iter < header_) || iter > end_of_payload())
170 return false;
171 const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
172 // Watch out for overflow in pointer calculation, which wraps.
173 return (iter <= end_of_region) && (end_of_region <= end_of_payload());
174 }
175
176 protected: 262 protected:
177 size_t payload_size() const { return header_->payload_size; } 263 size_t payload_size() const { return header_->payload_size; }
178 264
179 char* payload() { 265 char* payload() {
180 return reinterpret_cast<char*>(header_) + header_size_; 266 return reinterpret_cast<char*>(header_) + header_size_;
181 } 267 }
182 const char* payload() const { 268 const char* payload() const {
183 return reinterpret_cast<const char*>(header_) + header_size_; 269 return reinterpret_cast<const char*>(header_) + header_size_;
184 } 270 }
185 271
(...skipping 27 matching lines...) Expand all
213 // the header: new_capacity = sizeof(Header) + desired_payload_capacity. 299 // the header: new_capacity = sizeof(Header) + desired_payload_capacity.
214 // A realloc() failure will cause a Resize failure... and caller should check 300 // A realloc() failure will cause a Resize failure... and caller should check
215 // the return result for true (i.e., successful resizing). 301 // the return result for true (i.e., successful resizing).
216 bool Resize(size_t new_capacity); 302 bool Resize(size_t new_capacity);
217 303
218 // Aligns 'i' by rounding it up to the next multiple of 'alignment' 304 // Aligns 'i' by rounding it up to the next multiple of 'alignment'
219 static size_t AlignInt(size_t i, int alignment) { 305 static size_t AlignInt(size_t i, int alignment) {
220 return i + (alignment - (i % alignment)) % alignment; 306 return i + (alignment - (i % alignment)) % alignment;
221 } 307 }
222 308
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
230 // Find the end of the pickled data that starts at range_start. Returns NULL 309 // Find the end of the pickled data that starts at range_start. Returns NULL
231 // if the entire Pickle is not found in the given data range. 310 // if the entire Pickle is not found in the given data range.
232 static const char* FindNext(size_t header_size, 311 static const char* FindNext(size_t header_size,
233 const char* range_start, 312 const char* range_start,
234 const char* range_end); 313 const char* range_end);
235 314
236 // The allocation granularity of the payload. 315 // The allocation granularity of the payload.
237 static const int kPayloadUnit; 316 static const int kPayloadUnit;
238 317
239 private: 318 private:
319 friend class PickleIterator;
320
240 Header* header_; 321 Header* header_;
241 size_t header_size_; // Supports extra data between header and payload. 322 size_t header_size_; // Supports extra data between header and payload.
242 // Allocation size of payload (or -1 if allocation is const). 323 // Allocation size of payload (or -1 if allocation is const).
243 size_t capacity_; 324 size_t capacity_;
244 size_t variable_buffer_offset_; // IF non-zero, then offset to a buffer. 325 size_t variable_buffer_offset_; // IF non-zero, then offset to a buffer.
245 326
246 FRIEND_TEST_ALL_PREFIXES(PickleTest, Resize); 327 FRIEND_TEST_ALL_PREFIXES(PickleTest, Resize);
247 FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNext); 328 FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNext);
248 FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextWithIncompleteHeader); 329 FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextWithIncompleteHeader);
249 FRIEND_TEST_ALL_PREFIXES(PickleTest, IteratorHasRoom);
250 }; 330 };
251 331
252 #endif // BASE_PICKLE_H__ 332 #endif // BASE_PICKLE_H__
OLDNEW
« no previous file with comments | « base/metrics/histogram.cc ('k') | base/pickle.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698