WPILibC++ 2024.3.2
MemoryBuffer.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5//===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- C++ -*-===//
6//
7// The LLVM Compiler Infrastructure
8//
9// This file is distributed under the University of Illinois Open Source
10// License. See LICENSE.TXT for details.
11//
12//===----------------------------------------------------------------------===//
13//
14// This file defines the MemoryBuffer interface.
15//
16//===----------------------------------------------------------------------===//
17
18#pragma once
19
20#include <stdint.h>
21
22#include <cstddef>
23#include <memory>
24#include <span>
25#include <string_view>
26#include <system_error>
27
28// Duplicated from fs.h to avoid a dependency
29namespace fs {
30#if defined(_WIN32)
31// A Win32 HANDLE is a typedef of void*
32using file_t = void*;
33#else
34using file_t = int;
35#endif
36} // namespace fs
37
38namespace wpi {
39
40class MemoryBufferRef;
41
42/// This interface provides simple read-only access to a block of memory, and
43/// provides simple methods for reading files and standard input into a memory
44/// buffer.
46 const uint8_t* m_bufferStart; // Start of the buffer.
47 const uint8_t* m_bufferEnd; // End of the buffer.
48
49 protected:
50 MemoryBuffer() = default;
51
52 void Init(const uint8_t* bufStart, const uint8_t* bufEnd);
53
54 public:
55 MemoryBuffer(const MemoryBuffer&) = delete;
57 virtual ~MemoryBuffer();
58
59 const uint8_t* begin() const { return m_bufferStart; }
60 const uint8_t* end() const { return m_bufferEnd; }
61 size_t size() const { return m_bufferEnd - m_bufferStart; }
62
63 std::span<const uint8_t> GetBuffer() const { return {begin(), end()}; }
64
65 std::span<const char> GetCharBuffer() const {
66 return {reinterpret_cast<const char*>(begin()),
67 reinterpret_cast<const char*>(end())};
68 }
69
70 /// Return an identifier for this buffer, typically the filename it was read
71 /// from.
73 return "Unknown buffer";
74 }
75
76 /// Open the specified file as a MemoryBuffer, returning a new MemoryBuffer
77 /// if successful, otherwise returning null. If FileSize is specified, this
78 /// means that the client knows that the file exists and that it has the
79 /// specified size.
80 static std::unique_ptr<MemoryBuffer> GetFile(std::string_view filename,
81 std::error_code& ec,
82 int64_t fileSize = -1);
83
84 /// Read all of the specified file into a MemoryBuffer as a stream
85 /// (i.e. until EOF reached). This is useful for special files that
86 /// look like a regular file but have 0 size (e.g. /proc/cpuinfo on Linux).
87 static std::unique_ptr<MemoryBuffer> GetFileAsStream(
88 std::string_view filename, std::error_code& ec);
89
90 /// Given an already-open file descriptor, map some slice of it into a
91 /// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize.
92 static std::unique_ptr<MemoryBuffer> GetOpenFileSlice(
93 fs::file_t f, std::string_view filename, std::error_code& ec,
94 uint64_t mapSize, int64_t offset);
95
96 /// Given an already-open file descriptor, read the file and return a
97 /// MemoryBuffer.
98 static std::unique_ptr<MemoryBuffer> GetOpenFile(fs::file_t f,
99 std::string_view filename,
100 std::error_code& ec,
101 uint64_t fileSize);
102
103 /// Open the specified memory range as a MemoryBuffer.
104 static std::unique_ptr<MemoryBuffer> GetMemBuffer(
105 std::span<const uint8_t> inputData, std::string_view bufferName = "");
106
107 static std::unique_ptr<MemoryBuffer> GetMemBuffer(MemoryBufferRef ref);
108
109 /// Open the specified memory range as a MemoryBuffer, copying the contents
110 /// and taking ownership of it.
111 static std::unique_ptr<MemoryBuffer> GetMemBufferCopy(
112 std::span<const uint8_t> inputData, std::string_view bufferName = "");
113
114 /// Map a subrange of the specified file as a MemoryBuffer.
115 static std::unique_ptr<MemoryBuffer> GetFileSlice(std::string_view filename,
116 std::error_code& ec,
117 uint64_t mapSize,
118 uint64_t offset);
119
120 //===--------------------------------------------------------------------===//
121 // Provided for performance analysis.
122 //===--------------------------------------------------------------------===//
123
124 /// The kind of memory backing used to support the MemoryBuffer.
126
127 /// Return information on the memory mechanism used to support the
128 /// MemoryBuffer.
129 virtual BufferKind GetBufferKind() const = 0;
130
132};
133
134/// This class is an extension of MemoryBuffer, which allows copy-on-write
135/// access to the underlying contents. It only supports creation methods that
136/// are guaranteed to produce a writable buffer. For example, mapping a file
137/// read-only is not supported.
139 protected:
141
142 public:
144 using MemoryBuffer::end;
146 using MemoryBuffer::size;
147
148 // const_cast is well-defined here, because the underlying buffer is
149 // guaranteed to have been initialized with a mutable buffer.
150 uint8_t* begin() { return const_cast<uint8_t*>(MemoryBuffer::begin()); }
151 uint8_t* end() { return const_cast<uint8_t*>(MemoryBuffer::end()); }
152 std::span<uint8_t> GetBuffer() { return {begin(), end()}; }
153 std::span<char> GetCharBuffer() const {
154 return {reinterpret_cast<char*>(const_cast<uint8_t*>(begin())),
155 reinterpret_cast<char*>(const_cast<uint8_t*>(end()))};
156 }
157
158 static std::unique_ptr<WritableMemoryBuffer> GetFile(
159 std::string_view filename, std::error_code& ec, int64_t fileSize = -1);
160
161 /// Map a subrange of the specified file as a WritableMemoryBuffer.
162 static std::unique_ptr<WritableMemoryBuffer> GetFileSlice(
163 std::string_view filename, std::error_code& ec, uint64_t mapSize,
164 uint64_t offset);
165
166 /// Allocate a new MemoryBuffer of the specified size that is not initialized.
167 /// Note that the caller should initialize the memory allocated by this
168 /// method. The memory is owned by the MemoryBuffer object.
169 static std::unique_ptr<WritableMemoryBuffer> GetNewUninitMemBuffer(
170 size_t size, std::string_view bufferName = "");
171
172 /// Allocate a new zero-initialized MemoryBuffer of the specified size. Note
173 /// that the caller need not initialize the memory allocated by this method.
174 /// The memory is owned by the MemoryBuffer object.
175 static std::unique_ptr<WritableMemoryBuffer> GetNewMemBuffer(
176 size_t size, std::string_view bufferName = "");
177
178 private:
179 // Hide these base class factory function so one can't write
180 // WritableMemoryBuffer::getXXX()
181 // and be surprised that they got a read-only Buffer.
187};
188
189/// This class is an extension of MemoryBuffer, which allows write access to
190/// the underlying contents and committing those changes to the original source.
191/// It only supports creation methods that are guaranteed to produce a writable
192/// buffer. For example, mapping a file read-only is not supported.
194 protected:
196
197 public:
199 using MemoryBuffer::end;
201 using MemoryBuffer::size;
202
203 // const_cast is well-defined here, because the underlying buffer is
204 // guaranteed to have been initialized with a mutable buffer.
205 uint8_t* begin() { return const_cast<uint8_t*>(MemoryBuffer::begin()); }
206 uint8_t* end() { return const_cast<uint8_t*>(MemoryBuffer::end()); }
207 std::span<uint8_t> GetBuffer() { return {begin(), end()}; }
208 std::span<char> GetCharBuffer() const {
209 return {reinterpret_cast<char*>(const_cast<uint8_t*>(begin())),
210 reinterpret_cast<char*>(const_cast<uint8_t*>(end()))};
211 }
212
213 static std::unique_ptr<WriteThroughMemoryBuffer> GetFile(
214 std::string_view filename, std::error_code& ec, int64_t fileSize = -1);
215
216 /// Map a subrange of the specified file as a ReadWriteMemoryBuffer.
217 static std::unique_ptr<WriteThroughMemoryBuffer> GetFileSlice(
218 std::string_view filename, std::error_code& ec, uint64_t mapSize,
219 uint64_t offset);
220
221 private:
222 // Hide these base class factory function so one can't write
223 // WritableMemoryBuffer::getXXX()
224 // and be surprised that they got a read-only Buffer.
230};
231
233 std::span<const uint8_t> m_buffer;
234 std::string_view m_id;
235
236 public:
237 MemoryBufferRef() = default;
238 MemoryBufferRef(MemoryBuffer& buffer) // NOLINT
239 : m_buffer(buffer.GetBuffer()), m_id(buffer.GetBufferIdentifier()) {}
240 MemoryBufferRef(std::span<const uint8_t> buffer, std::string_view id)
241 : m_buffer(buffer), m_id(id) {}
242
243 std::span<const uint8_t> GetBuffer() const { return m_buffer; }
244
245 std::string_view GetBufferIdentifier() const { return m_id; }
246
247 const uint8_t* begin() const { return &*m_buffer.begin(); }
248 const uint8_t* end() const { return &*m_buffer.end(); }
249 size_t size() const { return m_buffer.size(); }
250};
251
252} // namespace wpi
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:45
static std::unique_ptr< MemoryBuffer > GetOpenFileSlice(fs::file_t f, std::string_view filename, std::error_code &ec, uint64_t mapSize, int64_t offset)
Given an already-open file descriptor, map some slice of it into a MemoryBuffer.
static std::unique_ptr< MemoryBuffer > GetFile(std::string_view filename, std::error_code &ec, int64_t fileSize=-1)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
BufferKind
The kind of memory backing used to support the MemoryBuffer.
Definition: MemoryBuffer.h:125
@ MemoryBuffer_Malloc
Definition: MemoryBuffer.h:125
@ MemoryBuffer_MMap
Definition: MemoryBuffer.h:125
virtual std::string_view GetBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
Definition: MemoryBuffer.h:72
static std::unique_ptr< MemoryBuffer > GetOpenFile(fs::file_t f, std::string_view filename, std::error_code &ec, uint64_t fileSize)
Given an already-open file descriptor, read the file and return a MemoryBuffer.
static std::unique_ptr< MemoryBuffer > GetMemBuffer(std::span< const uint8_t > inputData, std::string_view bufferName="")
Open the specified memory range as a MemoryBuffer.
static std::unique_ptr< MemoryBuffer > GetMemBufferCopy(std::span< const uint8_t > inputData, std::string_view bufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
const uint8_t * begin() const
Definition: MemoryBuffer.h:59
std::span< const uint8_t > GetBuffer() const
Definition: MemoryBuffer.h:63
virtual ~MemoryBuffer()
virtual BufferKind GetBufferKind() const =0
Return information on the memory mechanism used to support the MemoryBuffer.
static std::unique_ptr< MemoryBuffer > GetFileSlice(std::string_view filename, std::error_code &ec, uint64_t mapSize, uint64_t offset)
Map a subrange of the specified file as a MemoryBuffer.
static std::unique_ptr< MemoryBuffer > GetFileAsStream(std::string_view filename, std::error_code &ec)
Read all of the specified file into a MemoryBuffer as a stream (i.e.
MemoryBuffer(const MemoryBuffer &)=delete
MemoryBuffer()=default
MemoryBuffer & operator=(const MemoryBuffer &)=delete
const uint8_t * end() const
Definition: MemoryBuffer.h:60
void Init(const uint8_t *bufStart, const uint8_t *bufEnd)
MemoryBufferRef GetMemBufferRef() const
static std::unique_ptr< MemoryBuffer > GetMemBuffer(MemoryBufferRef ref)
std::span< const char > GetCharBuffer() const
Definition: MemoryBuffer.h:65
size_t size() const
Definition: MemoryBuffer.h:61
Definition: MemoryBuffer.h:232
std::string_view GetBufferIdentifier() const
Definition: MemoryBuffer.h:245
MemoryBufferRef(MemoryBuffer &buffer)
Definition: MemoryBuffer.h:238
std::span< const uint8_t > GetBuffer() const
Definition: MemoryBuffer.h:243
MemoryBufferRef(std::span< const uint8_t > buffer, std::string_view id)
Definition: MemoryBuffer.h:240
const uint8_t * begin() const
Definition: MemoryBuffer.h:247
MemoryBufferRef()=default
size_t size() const
Definition: MemoryBuffer.h:249
const uint8_t * end() const
Definition: MemoryBuffer.h:248
This class is an extension of MemoryBuffer, which allows copy-on-write access to the underlying conte...
Definition: MemoryBuffer.h:138
static std::unique_ptr< WritableMemoryBuffer > GetFile(std::string_view filename, std::error_code &ec, int64_t fileSize=-1)
static std::unique_ptr< WritableMemoryBuffer > GetFileSlice(std::string_view filename, std::error_code &ec, uint64_t mapSize, uint64_t offset)
Map a subrange of the specified file as a WritableMemoryBuffer.
uint8_t * end()
Definition: MemoryBuffer.h:151
std::span< uint8_t > GetBuffer()
Definition: MemoryBuffer.h:152
uint8_t * begin()
Definition: MemoryBuffer.h:150
static std::unique_ptr< WritableMemoryBuffer > GetNewMemBuffer(size_t size, std::string_view bufferName="")
Allocate a new zero-initialized MemoryBuffer of the specified size.
static std::unique_ptr< WritableMemoryBuffer > GetNewUninitMemBuffer(size_t size, std::string_view bufferName="")
Allocate a new MemoryBuffer of the specified size that is not initialized.
std::span< char > GetCharBuffer() const
Definition: MemoryBuffer.h:153
size_t size() const
Definition: MemoryBuffer.h:61
This class is an extension of MemoryBuffer, which allows write access to the underlying contents and ...
Definition: MemoryBuffer.h:193
static std::unique_ptr< WriteThroughMemoryBuffer > GetFileSlice(std::string_view filename, std::error_code &ec, uint64_t mapSize, uint64_t offset)
Map a subrange of the specified file as a ReadWriteMemoryBuffer.
static std::unique_ptr< WriteThroughMemoryBuffer > GetFile(std::string_view filename, std::error_code &ec, int64_t fileSize=-1)
std::span< char > GetCharBuffer() const
Definition: MemoryBuffer.h:208
std::span< uint8_t > GetBuffer()
Definition: MemoryBuffer.h:207
uint8_t * begin()
Definition: MemoryBuffer.h:205
uint8_t * end()
Definition: MemoryBuffer.h:206
basic_string_view< char > string_view
Definition: core.h:501
Definition: fs.h:21
int file_t
Definition: fs.h:32
Definition: ntcore_cpp.h:26