• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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