1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
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/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/shared_memory.h"
18 #include "base/memory/shared_memory_mapping.h"
19 
20 namespace base {
21 
22 class ReadOnlySharedMemoryRegion;
23 
24 // A generic interface to memory. This object is reference counted because most
25 // of its subclasses own the data they carry, and this interface needs to
26 // support heterogeneous containers of these different types of memory.
27 class BASE_EXPORT RefCountedMemory
28     : public RefCountedThreadSafe<RefCountedMemory> {
29  public:
30   // Retrieves a pointer to the beginning of the data we point to. If the data
31   // is empty, this will return NULL.
32   virtual const unsigned char* front() const = 0;
33 
34   // Size of the memory pointed to.
35   virtual size_t size() const = 0;
36 
37   // Returns true if |other| is byte for byte equal.
38   bool Equals(const scoped_refptr<RefCountedMemory>& other) const;
39 
40   // Handy method to simplify calling front() with a reinterpret_cast.
front_as()41   template<typename T> const T* front_as() const {
42     return reinterpret_cast<const T*>(front());
43   }
44 
45  protected:
46   friend class RefCountedThreadSafe<RefCountedMemory>;
47   RefCountedMemory();
48   virtual ~RefCountedMemory();
49 };
50 
51 // An implementation of RefCountedMemory, where the ref counting does not
52 // matter.
53 class BASE_EXPORT RefCountedStaticMemory : public RefCountedMemory {
54  public:
RefCountedStaticMemory()55   RefCountedStaticMemory() : data_(nullptr), length_(0) {}
RefCountedStaticMemory(const void * data,size_t length)56   RefCountedStaticMemory(const void* data, size_t length)
57       : data_(static_cast<const unsigned char*>(length ? data : nullptr)),
58         length_(length) {}
59 
60   // RefCountedMemory:
61   const unsigned char* front() const override;
62   size_t size() const override;
63 
64  private:
65   ~RefCountedStaticMemory() override;
66 
67   const unsigned char* data_;
68   size_t length_;
69 
70   DISALLOW_COPY_AND_ASSIGN(RefCountedStaticMemory);
71 };
72 
73 // An implementation of RefCountedMemory, where the data is stored in a STL
74 // vector.
75 class BASE_EXPORT RefCountedBytes : public RefCountedMemory {
76  public:
77   RefCountedBytes();
78 
79   // Constructs a RefCountedBytes object by copying from |initializer|.
80   explicit RefCountedBytes(const std::vector<unsigned char>& initializer);
81 
82   // Constructs a RefCountedBytes object by copying |size| bytes from |p|.
83   RefCountedBytes(const unsigned char* p, size_t size);
84 
85   // Constructs a RefCountedBytes object by zero-initializing a new vector of
86   // |size| bytes.
87   explicit RefCountedBytes(size_t size);
88 
89   // Constructs a RefCountedBytes object by performing a swap. (To non
90   // destructively build a RefCountedBytes, use the constructor that takes a
91   // vector.)
92   static scoped_refptr<RefCountedBytes> TakeVector(
93       std::vector<unsigned char>* to_destroy);
94 
95   // RefCountedMemory:
96   const unsigned char* front() const override;
97   size_t size() const override;
98 
data()99   const std::vector<unsigned char>& data() const { return data_; }
data()100   std::vector<unsigned char>& data() { return data_; }
101 
102   // Non-const versions of front() and front_as() that are simply shorthand for
103   // data().data().
front()104   unsigned char* front() { return data_.data(); }
105   template <typename T>
front_as()106   T* front_as() {
107     return reinterpret_cast<T*>(front());
108   }
109 
110  private:
111   ~RefCountedBytes() override;
112 
113   std::vector<unsigned char> data_;
114 
115   DISALLOW_COPY_AND_ASSIGN(RefCountedBytes);
116 };
117 
118 // An implementation of RefCountedMemory, where the bytes are stored in a STL
119 // string. Use this if your data naturally arrives in that format.
120 class BASE_EXPORT RefCountedString : public RefCountedMemory {
121  public:
122   RefCountedString();
123 
124   // Constructs a RefCountedString object by performing a swap. (To non
125   // destructively build a RefCountedString, use the default constructor and
126   // copy into object->data()).
127   static scoped_refptr<RefCountedString> TakeString(std::string* to_destroy);
128 
129   // RefCountedMemory:
130   const unsigned char* front() const override;
131   size_t size() const override;
132 
data()133   const std::string& data() const { return data_; }
data()134   std::string& data() { return data_; }
135 
136  private:
137   ~RefCountedString() override;
138 
139   std::string data_;
140 
141   DISALLOW_COPY_AND_ASSIGN(RefCountedString);
142 };
143 
144 // An implementation of RefCountedMemory, where the bytes are stored in
145 // SharedMemory.
146 class BASE_EXPORT RefCountedSharedMemory : public RefCountedMemory {
147  public:
148   // Constructs a RefCountedMemory object by taking ownership of an already
149   // mapped SharedMemory object.
150   RefCountedSharedMemory(std::unique_ptr<SharedMemory> shm, size_t size);
151 
152   // RefCountedMemory:
153   const unsigned char* front() const override;
154   size_t size() const override;
155 
156  private:
157   ~RefCountedSharedMemory() override;
158 
159   const std::unique_ptr<SharedMemory> shm_;
160   const size_t size_;
161 
162   DISALLOW_COPY_AND_ASSIGN(RefCountedSharedMemory);
163 };
164 
165 // An implementation of RefCountedMemory, where the bytes are stored in
166 // ReadOnlySharedMemoryMapping.
167 class BASE_EXPORT RefCountedSharedMemoryMapping : public RefCountedMemory {
168  public:
169   // Constructs a RefCountedMemory object by taking ownership of an already
170   // mapped ReadOnlySharedMemoryMapping object.
171   explicit RefCountedSharedMemoryMapping(ReadOnlySharedMemoryMapping mapping);
172 
173   // Convenience method to map all of |region| and take ownership of the
174   // mapping. Returns an empty scoped_refptr if the map operation fails.
175   static scoped_refptr<RefCountedSharedMemoryMapping> CreateFromWholeRegion(
176       const ReadOnlySharedMemoryRegion& region);
177 
178   // RefCountedMemory:
179   const unsigned char* front() const override;
180   size_t size() const override;
181 
182  private:
183   ~RefCountedSharedMemoryMapping() override;
184 
185   const ReadOnlySharedMemoryMapping mapping_;
186   const size_t size_;
187 
188   DISALLOW_COPY_AND_ASSIGN(RefCountedSharedMemoryMapping);
189 };
190 
191 }  // namespace base
192 
193 #endif  // BASE_MEMORY_REF_COUNTED_MEMORY_H_
194