LLVM  16.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"
13 #include "llvm/ADT/Optional.h"
16 #include "llvm/Support/Error.h"
17 #include <cstdint>
18 #include <memory>
19 
20 namespace llvm {
21 
22 /// Common stuff for mutable and immutable StreamRefs.
23 template <class RefType, class StreamType> class BinaryStreamRefBase {
24 protected:
25  BinaryStreamRefBase() = default;
28  if (!(BorrowedImpl.getFlags() & BSF_Append))
29  Length = BorrowedImpl.getLength();
30  }
31 
32  BinaryStreamRefBase(std::shared_ptr<StreamType> SharedImpl, uint64_t Offset,
35  ViewOffset(Offset), Length(Length) {}
39  BinaryStreamRefBase(const BinaryStreamRefBase &Other) = default;
40  BinaryStreamRefBase &operator=(const BinaryStreamRefBase &Other) = default;
41 
43  BinaryStreamRefBase(BinaryStreamRefBase &&Other) = default;
44 
45 public:
47  return BorrowedImpl->getEndian();
48  }
49 
50  uint64_t getLength() const {
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 
133 protected:
134  Error checkOffsetForRead(uint64_t Offset, uint64_t DataSize) const {
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;
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,
162 
163 public:
164  BinaryStreamRef() = default;
165  BinaryStreamRef(BinaryStream &Stream);
171 
172  BinaryStreamRef(const BinaryStreamRef &Other) = default;
173  BinaryStreamRef &operator=(const BinaryStreamRef &Other) = default;
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
201  BinaryStreamRef StreamData; // Stream Data
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,
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 
237 public:
238  WritableBinaryStreamRef() = default;
246  operator=(const WritableBinaryStreamRef &Other) = default;
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
llvm::BinaryStreamRef::readLongestContiguousChunk
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 ...
Definition: BinaryStreamRef.cpp:86
llvm::BinaryStream
An interface for accessing data in a stream-like format, but which discourages copying.
Definition: BinaryStream.h:35
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::WritableBinaryStreamRef::operator=
WritableBinaryStreamRef & operator=(const WritableBinaryStreamRef &Other)=default
Optional.h
BinaryStream.h
llvm::BinaryStreamRef::BinaryStreamRef
BinaryStreamRef()=default
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::BinaryStreamRefBase::operator=
BinaryStreamRefBase & operator=(const BinaryStreamRefBase &Other)=default
Error.h
llvm::BinaryStreamRefBase::checkOffsetForRead
Error checkOffsetForRead(uint64_t Offset, uint64_t DataSize) const
Definition: BinaryStreamRef.h:134
llvm::BinaryStreamRefBase::ViewOffset
uint64_t ViewOffset
Definition: BinaryStreamRef.h:144
llvm::Optional< uint64_t >
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:80
llvm::BinarySubstreamRef::drop_front
BinarySubstreamRef drop_front(uint64_t N) const
Definition: BinaryStreamRef.h:207
llvm::BinaryStreamRefBase::Length
Optional< uint64_t > Length
Definition: BinaryStreamRef.h:145
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::WritableBinaryStreamRef::commit
Error commit()
For buffered streams, commits changes to the backing store.
Definition: BinaryStreamRef.cpp:129
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::BinarySubstreamRef::size
uint64_t size() const
Definition: BinaryStreamRef.h:216
llvm::stream_error_code::invalid_offset
@ invalid_offset
llvm::BinaryStreamRefBase::drop_symmetric
RefType drop_symmetric(uint64_t N) const
Return a new BinaryStreamRef with the first and last N elements removed.
Definition: BinaryStreamRef.h:111
llvm::get
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
Definition: PointerIntPair.h:234
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::MutableArrayRef< uint8_t >
llvm::BinaryStreamRefBase::drop_back
RefType drop_back(uint64_t N) const
Return a new BinaryStreamRef with the last N elements removed.
Definition: BinaryStreamRef.h:78
llvm::BinaryStreamRefBase::SharedImpl
std::shared_ptr< StreamType > SharedImpl
Definition: BinaryStreamRef.h:142
llvm::BinarySubstreamRef
Definition: BinaryStreamRef.h:199
llvm::BinaryStreamRefBase::getLength
uint64_t getLength() const
Definition: BinaryStreamRef.h:50
BinaryStreamError.h
llvm::BinarySubstreamRef::StreamData
BinaryStreamRef StreamData
Definition: BinaryStreamRef.h:201
llvm::BinaryStreamRefBase::keep_front
RefType keep_front(uint64_t N) const
Return a new BinaryStreamRef with only the first N elements remaining.
Definition: BinaryStreamRef.h:98
llvm::minidump::StreamType
StreamType
The type of a minidump stream identifies its contents.
Definition: Minidump.h:50
uint64_t
llvm::BSF_Append
@ BSF_Append
Definition: BinaryStream.h:24
llvm::WritableBinaryStreamRef::WritableBinaryStreamRef
WritableBinaryStreamRef()=default
ArrayRef.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::BinaryStreamRefBase::BinaryStreamRefBase
BinaryStreamRefBase()=default
llvm::ArrayRef< uint8_t >
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::BinaryStreamRefBase
Common stuff for mutable and immutable StreamRefs.
Definition: BinaryStreamRef.h:23
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::BinaryStreamRefBase::getEndian
llvm::support::endianness getEndian() const
Definition: BinaryStreamRef.h:46
llvm::BinaryStreamRefBase::operator==
friend bool operator==(const RefType &LHS, const RefType &RHS)
Definition: BinaryStreamRef.h:123
llvm::BinarySubstreamRef::slice
BinarySubstreamRef slice(uint64_t Off, uint64_t Size) const
Definition: BinaryStreamRef.h:203
llvm::BinarySubstreamRef::split
std::pair< BinarySubstreamRef, BinarySubstreamRef > split(uint64_t Off) const
Definition: BinaryStreamRef.h:212
llvm::BinarySubstreamRef::keep_front
BinarySubstreamRef keep_front(uint64_t N) const
Definition: BinaryStreamRef.h:210
llvm::BinaryStreamRefBase::slice
RefType slice(uint64_t Offset, uint64_t Len) const
Return a new BinaryStreamRef with the first Offset elements removed, and retaining exactly Len elemen...
Definition: BinaryStreamRef.h:117
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::BinaryStreamRefBase::valid
bool valid() const
Definition: BinaryStreamRef.h:121
llvm::BinaryStreamRefBase::BinaryStreamRefBase
BinaryStreamRefBase(StreamType &BorrowedImpl)
Definition: BinaryStreamRef.h:26
llvm::BinaryStreamRefBase::BorrowedImpl
StreamType * BorrowedImpl
Definition: BinaryStreamRef.h:143
llvm::BinaryStreamRefBase::keep_back
RefType keep_back(uint64_t N) const
Return a new BinaryStreamRef with only the last N elements remaining.
Definition: BinaryStreamRef.h:104
llvm::WritableBinaryStreamRef::writeBytes
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...
Definition: BinaryStreamRef.cpp:116
llvm::BinaryStreamRef::readBytes
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.
Definition: BinaryStreamRef.cpp:79
Other
std::optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1252
N
#define N
llvm::BinaryStreamRef::operator=
BinaryStreamRef & operator=(const BinaryStreamRef &Other)=default
llvm::BinaryStreamRefBase::BinaryStreamRefBase
BinaryStreamRefBase(std::shared_ptr< StreamType > SharedImpl, uint64_t Offset, Optional< uint64_t > Length)
Definition: BinaryStreamRef.h:32
llvm::stream_error_code::stream_too_short
@ stream_too_short
llvm::support::endianness
endianness
Definition: Endian.h:27
llvm::BinaryStreamRefBase::BinaryStreamRefBase
BinaryStreamRefBase(StreamType &BorrowedImpl, uint64_t Offset, Optional< uint64_t > Length)
Definition: BinaryStreamRef.h:36
InlinePriorityMode::Size
@ Size
llvm::BinarySubstreamRef::Offset
uint64_t Offset
Definition: BinaryStreamRef.h:200
llvm::BinarySubstreamRef::empty
bool empty() const
Definition: BinaryStreamRef.h:217
llvm::WritableBinaryStream
A BinaryStream which can be read from as well as written to.
Definition: BinaryStream.h:73
llvm::WritableBinaryStreamRef
Definition: BinaryStreamRef.h:220
llvm::BinaryStreamRefBase::drop_front
RefType drop_front(uint64_t N) const
Return a new BinaryStreamRef with the first N elements removed.
Definition: BinaryStreamRef.h:60
llvm::BinaryStreamRef
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
Definition: BinaryStreamRef.h:155
llvm::WritableBinaryStream::getFlags
BinaryStreamFlags getFlags() const override
Return the properties of this stream.
Definition: BinaryStream.h:86