memory_range.h revision c89e2798e27cc57e1d543e49b6303fda80fc6c7b
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 41namespace 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. 48class MemoryRange { 49 public: 50 MemoryRange() : data_(NULL), length_(0) {} 51 52 MemoryRange(const void* data, size_t length) { 53 Set(data, length); 54 } 55 56 // Returns true if this memory range contains no data. 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. 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|. 69 void Set(const void* data, size_t length) { 70 data_ = reinterpret_cast<const u_int8_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. 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. 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> 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. 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> 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. 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. 130 const u_int8_t* data() const { return data_; } 131 132 // Returns the length, in bytes, of this memory range. 133 size_t length() const { return length_; } 134 135 private: 136 // Pointer to the beginning of this memory range. 137 const u_int8_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