LLVM 18.0.0git
BinaryStreamRef.h
Go to the documentation of this file.
1//===- BinaryStreamRef.h - A copyable reference to a stream -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_SUPPORT_BINARYSTREAMREF_H
10#define LLVM_SUPPORT_BINARYSTREAMREF_H
11
12#include "llvm/ADT/ArrayRef.h"
15#include "llvm/Support/Error.h"
16#include <cstdint>
17#include <memory>
18#include <optional>
19
20namespace llvm {
21
22/// Common stuff for mutable and immutable StreamRefs.
23template <class RefType, class StreamType> class BinaryStreamRefBase {
24protected:
26 explicit BinaryStreamRefBase(StreamType &BorrowedImpl)
28 if (!(BorrowedImpl.getFlags() & BSF_Append))
29 Length = BorrowedImpl.getLength();
30 }
31
32 BinaryStreamRefBase(std::shared_ptr<StreamType> SharedImpl, uint64_t Offset,
33 std::optional<uint64_t> Length)
37 std::optional<uint64_t> Length)
41
44
45public:
47 return BorrowedImpl->getEndian();
48 }
49
51 if (Length)
52 return *Length;
53
54 return BorrowedImpl ? (BorrowedImpl->getLength() - ViewOffset) : 0;
55 }
56
57 /// Return a new BinaryStreamRef with the first \p N elements removed. If
58 /// this BinaryStreamRef is length-tracking, then the resulting one will be
59 /// too.
60 RefType drop_front(uint64_t N) const {
61 if (!BorrowedImpl)
62 return RefType();
63
64 N = std::min(N, getLength());
65 RefType Result(static_cast<const RefType &>(*this));
66 if (N == 0)
67 return Result;
68
69 Result.ViewOffset += N;
70 if (Result.Length)
71 *Result.Length -= N;
72 return Result;
73 }
74
75 /// Return a new BinaryStreamRef with the last \p N elements removed. If
76 /// this BinaryStreamRef is length-tracking and \p N is greater than 0, then
77 /// this BinaryStreamRef will no longer length-track.
78 RefType drop_back(uint64_t N) const {
79 if (!BorrowedImpl)
80 return RefType();
81
82 RefType Result(static_cast<const RefType &>(*this));
83 N = std::min(N, getLength());
84
85 if (N == 0)
86 return Result;
87
88 // Since we're dropping non-zero bytes from the end, stop length-tracking
89 // by setting the length of the resulting StreamRef to an explicit value.
90 if (!Result.Length)
91 Result.Length = getLength();
92
93 *Result.Length -= N;
94 return Result;
95 }
96
97 /// Return a new BinaryStreamRef with only the first \p N elements remaining.
98 RefType keep_front(uint64_t N) const {
99 assert(N <= getLength());
100 return drop_back(getLength() - N);
101 }
102
103 /// Return a new BinaryStreamRef with only the last \p N elements remaining.
104 RefType keep_back(uint64_t N) const {
105 assert(N <= getLength());
106 return drop_front(getLength() - N);
107 }
108
109 /// Return a new BinaryStreamRef with the first and last \p N elements
110 /// removed.
111 RefType drop_symmetric(uint64_t N) const {
112 return drop_front(N).drop_back(N);
113 }
114
115 /// Return a new BinaryStreamRef with the first \p Offset elements removed,
116 /// and retaining exactly \p Len elements.
117 RefType slice(uint64_t Offset, uint64_t Len) const {
118 return drop_front(Offset).keep_front(Len);
119 }
120
121 bool valid() const { return BorrowedImpl != nullptr; }
122
123 friend bool operator==(const RefType &LHS, const RefType &RHS) {
124 if (LHS.BorrowedImpl != RHS.BorrowedImpl)
125 return false;
126 if (LHS.ViewOffset != RHS.ViewOffset)
127 return false;
128 if (LHS.Length != RHS.Length)
129 return false;
130 return true;
131 }
132
133protected:
135 if (Offset > getLength())
136 return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
137 if (getLength() < DataSize + Offset)
138 return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
139 return Error::success();
140 }
141
142 std::shared_ptr<StreamType> SharedImpl;
143 StreamType *BorrowedImpl = nullptr;
145 std::optional<uint64_t> Length;
146};
147
148/// BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It
149/// provides copy-semantics and read only access to a "window" of the underlying
150/// BinaryStream. Note that BinaryStreamRef is *not* a BinaryStream. That is to
151/// say, it does not inherit and override the methods of BinaryStream. In
152/// general, you should not pass around pointers or references to BinaryStreams
153/// and use inheritance to achieve polymorphism. Instead, you should pass
154/// around BinaryStreamRefs by value and achieve polymorphism that way.
156 : public BinaryStreamRefBase<BinaryStreamRef, BinaryStream> {
159 BinaryStreamRef(std::shared_ptr<BinaryStream> Impl, uint64_t ViewOffset,
160 std::optional<uint64_t> Length)
162
163public:
164 BinaryStreamRef() = default;
167 std::optional<uint64_t> Length);
171
176
177 // Use BinaryStreamRef.slice() instead.
179 uint64_t Length) = delete;
180
181 /// Given an Offset into this StreamRef and a Size, return a reference to a
182 /// buffer owned by the stream.
183 ///
184 /// \returns a success error code if the entire range of data is within the
185 /// bounds of this BinaryStreamRef's view and the implementation could read
186 /// the data, and an appropriate error code otherwise.
188 ArrayRef<uint8_t> &Buffer) const;
189
190 /// Given an Offset into this BinaryStreamRef, return a reference to the
191 /// largest buffer the stream could support without necessitating a copy.
192 ///
193 /// \returns a success error code if implementation could read the data,
194 /// and an appropriate error code otherwise.
196 ArrayRef<uint8_t> &Buffer) const;
197};
198
200 uint64_t Offset = 0; // Offset in the parent stream
202
204 BinaryStreamRef SubSub = StreamData.slice(Off, Size);
205 return {Off + Offset, SubSub};
206 }
208 return slice(N, size() - N);
209 }
211
212 std::pair<BinarySubstreamRef, BinarySubstreamRef> split(uint64_t Off) const {
213 return std::make_pair(keep_front(Off), drop_front(Off));
214 }
215
216 uint64_t size() const { return StreamData.getLength(); }
217 bool empty() const { return size() == 0; }
218};
219
221 : public BinaryStreamRefBase<WritableBinaryStreamRef,
222 WritableBinaryStream> {
224 WritableBinaryStreamRef(std::shared_ptr<WritableBinaryStream> Impl,
225 uint64_t ViewOffset, std::optional<uint64_t> Length)
227
228 Error checkOffsetForWrite(uint64_t Offset, uint64_t DataSize) const {
229 if (!(BorrowedImpl->getFlags() & BSF_Append))
230 return checkOffsetForRead(Offset, DataSize);
231
232 if (Offset > getLength())
233 return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
234 return Error::success();
235 }
236
237public:
241 std::optional<uint64_t> Length);
247
250
251 // Use WritableBinaryStreamRef.slice() instead.
253 uint64_t Length) = delete;
254
255 /// Given an Offset into this WritableBinaryStreamRef and some input data,
256 /// writes the data to the underlying stream.
257 ///
258 /// \returns a success error code if the data could fit within the underlying
259 /// stream at the specified location and the implementation could write the
260 /// data, and an appropriate error code otherwise.
262
263 /// Conver this WritableBinaryStreamRef to a read-only BinaryStreamRef.
264 operator BinaryStreamRef() const;
265
266 /// For buffered streams, commits changes to the backing store.
267 Error commit();
268};
269
270} // end namespace llvm
271
272#endif // LLVM_SUPPORT_BINARYSTREAMREF_H
uint64_t Size
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
endianness Endian
Value * RHS
Value * LHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Common stuff for mutable and immutable StreamRefs.
llvm::support::endianness getEndian() const
friend bool operator==(const RefType &LHS, const RefType &RHS)
std::optional< uint64_t > Length
RefType drop_back(uint64_t N) const
Return a new BinaryStreamRef with the last N elements removed.
BinaryStreamRefBase & operator=(const BinaryStreamRefBase &Other)=default
RefType drop_front(uint64_t N) const
Return a new BinaryStreamRef with the first N elements removed.
BinaryStreamRefBase & operator=(BinaryStreamRefBase &&Other)=default
BinaryStreamRefBase(StreamType &BorrowedImpl, uint64_t Offset, std::optional< uint64_t > Length)
std::shared_ptr< StreamType > SharedImpl
Error checkOffsetForRead(uint64_t Offset, uint64_t DataSize) const
RefType drop_symmetric(uint64_t N) const
Return a new BinaryStreamRef with the first and last N elements removed.
BinaryStreamRefBase(std::shared_ptr< StreamType > SharedImpl, uint64_t Offset, std::optional< uint64_t > Length)
RefType slice(uint64_t Offset, uint64_t Len) const
Return a new BinaryStreamRef with the first Offset elements removed, and retaining exactly Len elemen...
BinaryStreamRefBase(StreamType &BorrowedImpl)
RefType keep_back(uint64_t N) const
Return a new BinaryStreamRef with only the last N elements remaining.
RefType keep_front(uint64_t N) const
Return a new BinaryStreamRef with only the first N elements remaining.
BinaryStreamRefBase(BinaryStreamRefBase &&Other)=default
uint64_t getLength() const
BinaryStreamRefBase(const BinaryStreamRefBase &Other)=default
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
BinaryStreamRef(BinaryStreamRef &&Other)=default
Error readLongestContiguousChunk(uint64_t Offset, ArrayRef< uint8_t > &Buffer) const
Given an Offset into this BinaryStreamRef, return a reference to the largest buffer the stream could ...
BinaryStreamRef(const BinaryStreamRef &Other)=default
BinaryStreamRef(BinaryStreamRef &S, uint64_t Offset, uint64_t Length)=delete
Error readBytes(uint64_t Offset, uint64_t Size, ArrayRef< uint8_t > &Buffer) const
Given an Offset into this StreamRef and a Size, return a reference to a buffer owned by the stream.
BinaryStreamRef & operator=(BinaryStreamRef &&Other)=default
BinaryStreamRef & operator=(const BinaryStreamRef &Other)=default
An interface for accessing data in a stream-like format, but which discourages copying.
Definition: BinaryStream.h:35
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
WritableBinaryStreamRef & operator=(const WritableBinaryStreamRef &Other)=default
WritableBinaryStreamRef(const WritableBinaryStreamRef &Other)=default
WritableBinaryStreamRef(WritableBinaryStreamRef &&Other)=default
WritableBinaryStreamRef(WritableBinaryStreamRef &S, uint64_t Offset, uint64_t Length)=delete
Error writeBytes(uint64_t Offset, ArrayRef< uint8_t > Data) const
Given an Offset into this WritableBinaryStreamRef and some input data, writes the data to the underly...
WritableBinaryStreamRef & operator=(WritableBinaryStreamRef &&Other)=default
Error commit()
For buffered streams, commits changes to the backing store.
A BinaryStream which can be read from as well as written to.
Definition: BinaryStream.h:73
BinaryStreamFlags getFlags() const override
Return the properties of this stream.
Definition: BinaryStream.h:86
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
@ BSF_Append
Definition: BinaryStream.h:24
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
@ Other
Any other memory.
#define N
std::pair< BinarySubstreamRef, BinarySubstreamRef > split(uint64_t Off) const
BinarySubstreamRef keep_front(uint64_t N) const
BinarySubstreamRef slice(uint64_t Off, uint64_t Size) const
BinaryStreamRef StreamData
BinarySubstreamRef drop_front(uint64_t N) const