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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/metrics/histogram.cc ('k') | base/pickle.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/pickle.h
diff --git a/base/pickle.h b/base/pickle.h
index 65353de5e0994ac4406869f7668fe302d2771e7f..47e3bf6af67cd7dec4eb24083cd5064159854722 100644
--- a/base/pickle.h
+++ b/base/pickle.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,10 +10,80 @@
#include "base/base_export.h"
#include "base/basictypes.h"
+#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "base/string16.h"
+class Pickle;
+
+// PickleIterator reads data from a Pickle. The Pickle object must remain valid
+// while the PickleIterator object is in use.
+class BASE_EXPORT PickleIterator {
+ public:
+ PickleIterator() : read_ptr_(NULL), read_end_ptr_(NULL) {}
+ explicit PickleIterator(const Pickle& pickle);
+
+ // Methods for reading the payload of the Pickle. To read from the start of
+ // the Pickle, create a PickleIterator from a Pickle. If successful, these
+ // methods return true. Otherwise, false is returned to indicate that the
+ // result could not be extracted.
+ bool ReadBool(bool* result) WARN_UNUSED_RESULT;
+ bool ReadInt(int* result) WARN_UNUSED_RESULT;
+ bool ReadLong(long* result) WARN_UNUSED_RESULT;
+ bool ReadSize(size_t* result) WARN_UNUSED_RESULT;
+ bool ReadUInt16(uint16* result) WARN_UNUSED_RESULT;
+ bool ReadUInt32(uint32* result) WARN_UNUSED_RESULT;
+ bool ReadInt64(int64* result) WARN_UNUSED_RESULT;
+ bool ReadUInt64(uint64* result) WARN_UNUSED_RESULT;
+ bool ReadString(std::string* result) WARN_UNUSED_RESULT;
+ bool ReadWString(std::wstring* result) WARN_UNUSED_RESULT;
+ bool ReadString16(string16* result) WARN_UNUSED_RESULT;
+ bool ReadData(const char** data, int* length) WARN_UNUSED_RESULT;
+ bool ReadBytes(const char** data, int length) WARN_UNUSED_RESULT;
+
+ // Safer version of ReadInt() checks for the result not being negative.
+ // Use it for reading the object sizes.
+ bool ReadLength(int* result) WARN_UNUSED_RESULT {
+ return ReadInt(result) && *result >= 0;
+ }
+
+ // Skips bytes in the read buffer and returns true if there are at least
+ // num_bytes available. Otherwise, does nothing and returns false.
+ bool SkipBytes(int num_bytes) WARN_UNUSED_RESULT {
+ return !!GetReadPointerAndAdvance(num_bytes);
+ }
+
+ private:
+ // Aligns 'i' by rounding it up to the next multiple of 'alignment'
+ static size_t AlignInt(size_t i, int alignment) {
+ return i + (alignment - (i % alignment)) % alignment;
+ }
+
+ // Read Type from Pickle.
+ template <typename Type>
+ inline bool ReadBuiltinType(Type* result);
+
+ // Get read pointer for Type and advance read pointer.
+ template<typename Type>
+ inline const char* GetReadPointerAndAdvance();
+
+ // Get read pointer for |num_bytes| and advance read pointer. This method
+ // checks num_bytes for negativity and wrapping.
+ const char* GetReadPointerAndAdvance(int num_bytes);
+
+ // Get read pointer for (num_elements * size_element) bytes and advance read
+ // pointer. This method checks for int overflow, negativity and wrapping.
+ inline const char* GetReadPointerAndAdvance(int num_elements,
+ size_t size_element);
+
+ // Pointers to the Pickle data.
+ const char* read_ptr_;
+ const char* read_end_ptr_;
+
+ FRIEND_TEST_ALL_PREFIXES(PickleTest, GetReadPointerAndAdvance);
+};
+
// This class provides facilities for basic binary value packing and unpacking.
//
// The Pickle class supports appending primitive values (ints, strings, etc.)
@@ -66,27 +136,54 @@ class BASE_EXPORT Pickle {
// Returns the data for this Pickle.
const void* data() const { return header_; }
- // Methods for reading the payload of the Pickle. To read from the start of
- // the Pickle, initialize *iter to NULL. If successful, these methods return
- // true. Otherwise, false is returned to indicate that the result could not
- // be extracted.
- bool ReadBool(void** iter, bool* result) const;
- bool ReadInt(void** iter, int* result) const;
- bool ReadLong(void** iter, long* result) const;
- bool ReadSize(void** iter, size_t* result) const;
- bool ReadUInt16(void** iter, uint16* result) const;
- bool ReadUInt32(void** iter, uint32* result) const;
- bool ReadInt64(void** iter, int64* result) const;
- bool ReadUInt64(void** iter, uint64* result) const;
- bool ReadString(void** iter, std::string* result) const;
- bool ReadWString(void** iter, std::wstring* result) const;
- bool ReadString16(void** iter, string16* result) const;
- bool ReadData(void** iter, const char** data, int* length) const;
- bool ReadBytes(void** iter, const char** data, int length) const;
+ // For compatibility, these older style read methods pass through to the
+ // PickleIterator methods.
+ // TODO(jbates) Remove these methods.
+ bool ReadBool(PickleIterator* iter, bool* result) const {
+ return iter->ReadBool(result);
+ }
+ bool ReadInt(PickleIterator* iter, int* result) const {
+ return iter->ReadInt(result);
+ }
+ bool ReadLong(PickleIterator* iter, long* result) const {
+ return iter->ReadLong(result);
+ }
+ bool ReadSize(PickleIterator* iter, size_t* result) const {
+ return iter->ReadSize(result);
+ }
+ bool ReadUInt16(PickleIterator* iter, uint16* result) const {
+ return iter->ReadUInt16(result);
+ }
+ bool ReadUInt32(PickleIterator* iter, uint32* result) const {
+ return iter->ReadUInt32(result);
+ }
+ bool ReadInt64(PickleIterator* iter, int64* result) const {
+ return iter->ReadInt64(result);
+ }
+ bool ReadUInt64(PickleIterator* iter, uint64* result) const {
+ return iter->ReadUInt64(result);
+ }
+ bool ReadString(PickleIterator* iter, std::string* result) const {
+ return iter->ReadString(result);
+ }
+ bool ReadWString(PickleIterator* iter, std::wstring* result) const {
+ return iter->ReadWString(result);
+ }
+ bool ReadString16(PickleIterator* iter, string16* result) const {
+ return iter->ReadString16(result);
+ }
+ bool ReadData(PickleIterator* iter, const char** data, int* length) const {
+ return iter->ReadData(data, length);
+ }
+ bool ReadBytes(PickleIterator* iter, const char** data, int length) const {
+ return iter->ReadBytes(data, length);
+ }
// Safer version of ReadInt() checks for the result not being negative.
// Use it for reading the object sizes.
- bool ReadLength(void** iter, int* result) const;
+ bool ReadLength(PickleIterator* iter, int* result) const {
+ return iter->ReadLength(result);
+ }
// Methods for adding to the payload of the Pickle. These values are
// appended to the end of the Pickle's payload. When reading values from a
@@ -162,17 +259,6 @@ class BASE_EXPORT Pickle {
return static_cast<const T*>(header_);
}
- // Returns true if the given iterator could point to data with the given
- // length. If there is no room for the given data before the end of the
- // payload, returns false.
- bool IteratorHasRoomFor(const void* iter, int len) const {
- if ((len < 0) || (iter < header_) || iter > end_of_payload())
- return false;
- const char* end_of_region = reinterpret_cast<const char*>(iter) + len;
- // Watch out for overflow in pointer calculation, which wraps.
- return (iter <= end_of_region) && (end_of_region <= end_of_payload());
- }
-
protected:
size_t payload_size() const { return header_->payload_size; }
@@ -220,13 +306,6 @@ class BASE_EXPORT Pickle {
return i + (alignment - (i % alignment)) % alignment;
}
- // Moves the iterator by the given number of bytes, making sure it is aligned.
- // Pointer (iterator) is NOT aligned, but the change in the pointer
- // is guaranteed to be a multiple of sizeof(uint32).
- static void UpdateIter(void** iter, int bytes) {
- *iter = static_cast<char*>(*iter) + AlignInt(bytes, sizeof(uint32));
- }
-
// Find the end of the pickled data that starts at range_start. Returns NULL
// if the entire Pickle is not found in the given data range.
static const char* FindNext(size_t header_size,
@@ -237,6 +316,8 @@ class BASE_EXPORT Pickle {
static const int kPayloadUnit;
private:
+ friend class PickleIterator;
+
Header* header_;
size_t header_size_; // Supports extra data between header and payload.
// Allocation size of payload (or -1 if allocation is const).
@@ -246,7 +327,6 @@ class BASE_EXPORT Pickle {
FRIEND_TEST_ALL_PREFIXES(PickleTest, Resize);
FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNext);
FRIEND_TEST_ALL_PREFIXES(PickleTest, FindNextWithIncompleteHeader);
- FRIEND_TEST_ALL_PREFIXES(PickleTest, IteratorHasRoom);
};
#endif // BASE_PICKLE_H__
« 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