1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_MEMORY_REF_COUNTED_MEMORY_H_ 6 #define BASE_MEMORY_REF_COUNTED_MEMORY_H_ 7 8 #include <stddef.h> 9 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 #include "base/base_export.h" 15 #include "base/compiler_specific.h" 16 #include "base/containers/span.h" 17 #include "base/memory/raw_span.h" 18 #include "base/memory/ref_counted.h" 19 #include "base/memory/shared_memory_mapping.h" 20 21 namespace base { 22 23 class ReadOnlySharedMemoryRegion; 24 25 // A generic interface to memory. This object is reference counted because most 26 // of its subclasses own the data they carry, and this interface needs to 27 // support heterogeneous containers of these different types of memory. 28 // 29 // The RefCountedMemory class provides a const view of the data it holds, as it 30 // does not require all subclassing implementations to hold mutable data. If a 31 // mutable view is required, the code must maintain awareness of the subclass 32 // type, and can access it through there, such as: 33 // - RefCountedBytes provides `as_vector()` to give mutable access to its data. 34 // - RefCountedString provides `as_string()` to give mutable access to its data. 35 class BASE_EXPORT RefCountedMemory 36 : public RefCountedThreadSafe<RefCountedMemory> { 37 public: 38 // Returns true if `other` is byte for byte equal. 39 bool Equals(const scoped_refptr<RefCountedMemory>& other) const; 40 41 // Allow explicit conversion to `base::span<const uint8_t>`. Use a span to 42 // access the data in a safe way, rather than calling `data()` explicitly. 43 // 44 // Example: 45 // ``` 46 // auto data = base::MakeRefCounted<base::RefCountedBytes>( 47 // std::vector<uint8_t>{1, 2, 3}); 48 // base::span<const uint8_t> v = base::span(data); 49 // v[2] = uint8_t{4}; 50 // ``` data()51 const uint8_t* data() const LIFETIME_BOUND { return AsSpan().data(); } size()52 size_t size() const { return AsSpan().size(); } 53 54 using iterator = base::span<const uint8_t>::iterator; begin()55 iterator begin() const LIFETIME_BOUND { return AsSpan().begin(); } end()56 iterator end() const LIFETIME_BOUND { return AsSpan().end(); } 57 58 // TODO(danakj): Remove all callers and remove this. front()59 const uint8_t* front() const LIFETIME_BOUND { return AsSpan().data(); } 60 61 // The data/size members (or begin/end) give conversion to span already, but 62 // we provide this operator as an optimization to combine two virtual method 63 // calls into one. 64 explicit operator base::span<const uint8_t>() const LIFETIME_BOUND { 65 return AsSpan(); 66 } 67 68 protected: 69 friend class RefCountedThreadSafe<RefCountedMemory>; 70 RefCountedMemory(); 71 virtual ~RefCountedMemory(); 72 73 virtual base::span<const uint8_t> AsSpan() const LIFETIME_BOUND = 0; 74 }; 75 76 // An implementation of RefCountedMemory, for pointing to memory with a static 77 // lifetime. Since the memory exists for the life of the program, the class can 78 // not and does not need to take ownership of it. 79 class BASE_EXPORT RefCountedStaticMemory : public RefCountedMemory { 80 public: 81 RefCountedStaticMemory(); 82 explicit RefCountedStaticMemory(base::span<const uint8_t> bytes); 83 84 RefCountedStaticMemory(const RefCountedStaticMemory&) = delete; 85 RefCountedStaticMemory& operator=(const RefCountedStaticMemory&) = delete; 86 87 private: 88 ~RefCountedStaticMemory() override; 89 90 // RefCountedMemory: 91 base::span<const uint8_t> AsSpan() const LIFETIME_BOUND override; 92 93 base::raw_span<const uint8_t> bytes_; 94 }; 95 96 // An implementation of RefCountedMemory, where the data is stored in a STL 97 // vector. 98 class BASE_EXPORT RefCountedBytes : public RefCountedMemory { 99 public: 100 RefCountedBytes(); 101 102 // Constructs a RefCountedBytes object by taking `initializer`. 103 explicit RefCountedBytes(std::vector<uint8_t> initializer); 104 105 // Constructs a RefCountedBytes object by copying from `initializer`. 106 explicit RefCountedBytes(base::span<const uint8_t> initializer); 107 108 // Constructs a RefCountedBytes object by zero-initializing a new vector of 109 // `size` bytes. 110 explicit RefCountedBytes(size_t size); 111 112 RefCountedBytes(const RefCountedBytes&) = delete; 113 RefCountedBytes& operator=(const RefCountedBytes&) = delete; 114 as_vector()115 const std::vector<uint8_t>& as_vector() const { return bytes_; } as_vector()116 std::vector<uint8_t>& as_vector() { return bytes_; } 117 118 private: 119 ~RefCountedBytes() override; 120 121 // RefCountedMemory: 122 base::span<const uint8_t> AsSpan() const LIFETIME_BOUND override; 123 124 std::vector<uint8_t> bytes_; 125 }; 126 127 // An implementation of RefCountedMemory, where the bytes are stored in a STL 128 // string. Use this if your data naturally arrives in that format. 129 class BASE_EXPORT RefCountedString : public RefCountedMemory { 130 public: 131 RefCountedString(); 132 explicit RefCountedString(std::string value); 133 134 RefCountedString(const RefCountedString&) = delete; 135 RefCountedString& operator=(const RefCountedString&) = delete; 136 as_string()137 const std::string& as_string() const LIFETIME_BOUND { return string_; } as_string()138 std::string& as_string() LIFETIME_BOUND { return string_; } 139 140 private: 141 ~RefCountedString() override; 142 143 // RefCountedMemory: 144 base::span<const uint8_t> AsSpan() const LIFETIME_BOUND override; 145 146 std::string string_; 147 }; 148 149 // An implementation of RefCountedMemory, where the bytes are stored in a 150 // std::u16string. 151 class BASE_EXPORT RefCountedString16 : public base::RefCountedMemory { 152 public: 153 RefCountedString16(); 154 explicit RefCountedString16(std::u16string value); 155 156 RefCountedString16(const RefCountedString16&) = delete; 157 RefCountedString16& operator=(const RefCountedString16&) = delete; 158 as_string()159 const std::u16string& as_string() const LIFETIME_BOUND { return string_; } as_string()160 std::u16string& as_string() LIFETIME_BOUND { return string_; } 161 162 private: 163 ~RefCountedString16() override; 164 165 // RefCountedMemory: 166 base::span<const uint8_t> AsSpan() const LIFETIME_BOUND override; 167 168 std::u16string string_; 169 }; 170 171 // An implementation of RefCountedMemory, where the bytes are stored in 172 // ReadOnlySharedMemoryMapping. 173 class BASE_EXPORT RefCountedSharedMemoryMapping : public RefCountedMemory { 174 public: 175 // Constructs a RefCountedMemory object by taking ownership of an already 176 // mapped ReadOnlySharedMemoryMapping object. 177 explicit RefCountedSharedMemoryMapping(ReadOnlySharedMemoryMapping mapping); 178 179 RefCountedSharedMemoryMapping(const RefCountedSharedMemoryMapping&) = delete; 180 RefCountedSharedMemoryMapping& operator=( 181 const RefCountedSharedMemoryMapping&) = delete; 182 183 // Convenience method to map all of `region` and take ownership of the 184 // mapping. Returns a null `scoped_refptr` if the map operation fails. 185 static scoped_refptr<RefCountedSharedMemoryMapping> CreateFromWholeRegion( 186 const ReadOnlySharedMemoryRegion& region); 187 188 private: 189 ~RefCountedSharedMemoryMapping() override; 190 191 // RefCountedMemory: 192 base::span<const uint8_t> AsSpan() const LIFETIME_BOUND override; 193 194 const ReadOnlySharedMemoryMapping mapping_; 195 }; 196 197 } // namespace base 198 199 #endif // BASE_MEMORY_REF_COUNTED_MEMORY_H_ 200