1 // Copyright (c) 2011, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // memory_range.h: Define the google_breakpad::MemoryRange class, which 31 // is a lightweight wrapper with a pointer and a length to encapsulate 32 // a contiguous range of memory. 33 34 #ifndef COMMON_MEMORY_RANGE_H_ 35 #define COMMON_MEMORY_RANGE_H_ 36 37 #include <stddef.h> 38 39 #include "google_breakpad/common/breakpad_types.h" 40 41 namespace google_breakpad { 42 43 // A lightweight wrapper with a pointer and a length to encapsulate a 44 // contiguous range of memory. It provides helper methods for checked 45 // access of a subrange of the memory. Its implemementation does not 46 // allocate memory or call into libc functions, and is thus safer to use 47 // in a crashed environment. 48 class MemoryRange { 49 public: MemoryRange()50 MemoryRange() : data_(NULL), length_(0) {} 51 MemoryRange(const void * data,size_t length)52 MemoryRange(const void* data, size_t length) { 53 Set(data, length); 54 } 55 56 // Returns true if this memory range contains no data. IsEmpty()57 bool IsEmpty() const { 58 // Set() guarantees that |length_| is zero if |data_| is NULL. 59 return length_ == 0; 60 } 61 62 // Resets to an empty range. Reset()63 void Reset() { 64 data_ = NULL; 65 length_ = 0; 66 } 67 68 // Sets this memory range to point to |data| and its length to |length|. Set(const void * data,size_t length)69 void Set(const void* data, size_t length) { 70 data_ = reinterpret_cast<const uint8_t*>(data); 71 // Always set |length_| to zero if |data_| is NULL. 72 length_ = data ? length : 0; 73 } 74 75 // Returns true if this range covers a subrange of |sub_length| bytes 76 // at |sub_offset| bytes of this memory range, or false otherwise. Covers(size_t sub_offset,size_t sub_length)77 bool Covers(size_t sub_offset, size_t sub_length) const { 78 // The following checks verify that: 79 // 1. sub_offset is within [ 0 .. length_ - 1 ] 80 // 2. sub_offset + sub_length is within 81 // [ sub_offset .. length_ ] 82 return sub_offset < length_ && 83 sub_offset + sub_length >= sub_offset && 84 sub_offset + sub_length <= length_; 85 } 86 87 // Returns a raw data pointer to a subrange of |sub_length| bytes at 88 // |sub_offset| bytes of this memory range, or NULL if the subrange 89 // is out of bounds. GetData(size_t sub_offset,size_t sub_length)90 const void* GetData(size_t sub_offset, size_t sub_length) const { 91 return Covers(sub_offset, sub_length) ? (data_ + sub_offset) : NULL; 92 } 93 94 // Same as the two-argument version of GetData() but uses sizeof(DataType) 95 // as the subrange length and returns an |DataType| pointer for convenience. 96 template <typename DataType> GetData(size_t sub_offset)97 const DataType* GetData(size_t sub_offset) const { 98 return reinterpret_cast<const DataType*>( 99 GetData(sub_offset, sizeof(DataType))); 100 } 101 102 // Returns a raw pointer to the |element_index|-th element of an array 103 // of elements of length |element_size| starting at |sub_offset| bytes 104 // of this memory range, or NULL if the element is out of bounds. GetArrayElement(size_t element_offset,size_t element_size,unsigned element_index)105 const void* GetArrayElement(size_t element_offset, 106 size_t element_size, 107 unsigned element_index) const { 108 size_t sub_offset = element_offset + element_index * element_size; 109 return GetData(sub_offset, element_size); 110 } 111 112 // Same as the three-argument version of GetArrayElement() but deduces 113 // the element size using sizeof(ElementType) and returns an |ElementType| 114 // pointer for convenience. 115 template <typename ElementType> GetArrayElement(size_t element_offset,unsigned element_index)116 const ElementType* GetArrayElement(size_t element_offset, 117 unsigned element_index) const { 118 return reinterpret_cast<const ElementType*>( 119 GetArrayElement(element_offset, sizeof(ElementType), element_index)); 120 } 121 122 // Returns a subrange of |sub_length| bytes at |sub_offset| bytes of 123 // this memory range, or an empty range if the subrange is out of bounds. Subrange(size_t sub_offset,size_t sub_length)124 MemoryRange Subrange(size_t sub_offset, size_t sub_length) const { 125 return Covers(sub_offset, sub_length) ? 126 MemoryRange(data_ + sub_offset, sub_length) : MemoryRange(); 127 } 128 129 // Returns a pointer to the beginning of this memory range. data()130 const uint8_t* data() const { return data_; } 131 132 // Returns the length, in bytes, of this memory range. length()133 size_t length() const { return length_; } 134 135 private: 136 // Pointer to the beginning of this memory range. 137 const uint8_t* data_; 138 139 // Length, in bytes, of this memory range. 140 size_t length_; 141 }; 142 143 } // namespace google_breakpad 144 145 #endif // COMMON_MEMORY_RANGE_H_ 146