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