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_mapping.h"
18 #include "base/strings/string16.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   // Alias for front() to make it possible for RefCountedMemory to implicitly
46   // convert to span.
data()47   const unsigned char* data() const { return front(); }
48 
49  protected:
50   friend class RefCountedThreadSafe<RefCountedMemory>;
51   RefCountedMemory();
52   virtual ~RefCountedMemory();
53 };
54 
55 // An implementation of RefCountedMemory, where the ref counting does not
56 // matter.
57 class BASE_EXPORT RefCountedStaticMemory : public RefCountedMemory {
58  public:
RefCountedStaticMemory()59   RefCountedStaticMemory() : data_(nullptr), length_(0) {}
RefCountedStaticMemory(const void * data,size_t length)60   RefCountedStaticMemory(const void* data, size_t length)
61       : data_(static_cast<const unsigned char*>(length ? data : nullptr)),
62         length_(length) {}
63 
64   // RefCountedMemory:
65   const unsigned char* front() const override;
66   size_t size() const override;
67 
68  private:
69   ~RefCountedStaticMemory() override;
70 
71   const unsigned char* data_;
72   size_t length_;
73 
74   DISALLOW_COPY_AND_ASSIGN(RefCountedStaticMemory);
75 };
76 
77 // An implementation of RefCountedMemory, where the data is stored in a STL
78 // vector.
79 class BASE_EXPORT RefCountedBytes : public RefCountedMemory {
80  public:
81   RefCountedBytes();
82 
83   // Constructs a RefCountedBytes object by copying from |initializer|.
84   explicit RefCountedBytes(const std::vector<unsigned char>& initializer);
85 
86   // Constructs a RefCountedBytes object by copying |size| bytes from |p|.
87   RefCountedBytes(const unsigned char* p, size_t size);
88 
89   // Constructs a RefCountedBytes object by zero-initializing a new vector of
90   // |size| bytes.
91   explicit RefCountedBytes(size_t size);
92 
93   // Constructs a RefCountedBytes object by performing a swap. (To non
94   // destructively build a RefCountedBytes, use the constructor that takes a
95   // vector.)
96   static scoped_refptr<RefCountedBytes> TakeVector(
97       std::vector<unsigned char>* to_destroy);
98 
99   // RefCountedMemory:
100   const unsigned char* front() const override;
101   size_t size() const override;
102 
data()103   const std::vector<unsigned char>& data() const { return data_; }
data()104   std::vector<unsigned char>& data() { return data_; }
105 
106   // Non-const versions of front() and front_as() that are simply shorthand for
107   // data().data().
front()108   unsigned char* front() { return data_.data(); }
109   template <typename T>
front_as()110   T* front_as() {
111     return reinterpret_cast<T*>(front());
112   }
113 
114  private:
115   ~RefCountedBytes() override;
116 
117   std::vector<unsigned char> data_;
118 
119   DISALLOW_COPY_AND_ASSIGN(RefCountedBytes);
120 };
121 
122 // An implementation of RefCountedMemory, where the bytes are stored in a STL
123 // string. Use this if your data naturally arrives in that format.
124 class BASE_EXPORT RefCountedString : public RefCountedMemory {
125  public:
126   RefCountedString();
127 
128   // Constructs a RefCountedString object by performing a swap. (To non
129   // destructively build a RefCountedString, use the default constructor and
130   // copy into object->data()).
131   static scoped_refptr<RefCountedString> TakeString(std::string* to_destroy);
132 
133   // RefCountedMemory:
134   const unsigned char* front() const override;
135   size_t size() const override;
136 
data()137   const std::string& data() const { return data_; }
data()138   std::string& data() { return data_; }
139 
140  private:
141   ~RefCountedString() override;
142 
143   std::string data_;
144 
145   DISALLOW_COPY_AND_ASSIGN(RefCountedString);
146 };
147 
148 // An implementation of RefCountedMemory, where the bytes are stored in a
149 // string16.
150 class BASE_EXPORT RefCountedString16 : public base::RefCountedMemory {
151  public:
152   RefCountedString16();
153 
154   // Constructs a RefCountedString16 object by performing a swap.
155   static scoped_refptr<RefCountedString16> TakeString(string16* to_destroy);
156 
157   // RefCountedMemory:
158   const unsigned char* front() const override;
159   size_t size() const override;
160 
161  protected:
162   ~RefCountedString16() override;
163 
164  private:
165   string16 data_;
166 
167   DISALLOW_COPY_AND_ASSIGN(RefCountedString16);
168 };
169 
170 // An implementation of RefCountedMemory, where the bytes are stored in
171 // ReadOnlySharedMemoryMapping.
172 class BASE_EXPORT RefCountedSharedMemoryMapping : public RefCountedMemory {
173  public:
174   // Constructs a RefCountedMemory object by taking ownership of an already
175   // mapped ReadOnlySharedMemoryMapping object.
176   explicit RefCountedSharedMemoryMapping(ReadOnlySharedMemoryMapping mapping);
177 
178   // Convenience method to map all of |region| and take ownership of the
179   // mapping. Returns an empty scoped_refptr if the map operation fails.
180   static scoped_refptr<RefCountedSharedMemoryMapping> CreateFromWholeRegion(
181       const ReadOnlySharedMemoryRegion& region);
182 
183   // RefCountedMemory:
184   const unsigned char* front() const override;
185   size_t size() const override;
186 
187  private:
188   ~RefCountedSharedMemoryMapping() override;
189 
190   const ReadOnlySharedMemoryMapping mapping_;
191   const size_t size_;
192 
193   DISALLOW_COPY_AND_ASSIGN(RefCountedSharedMemoryMapping);
194 };
195 
196 }  // namespace base
197 
198 #endif  // BASE_MEMORY_REF_COUNTED_MEMORY_H_
199