LLVM  6.0.0svn
BinaryStreamRef.h
Go to the documentation of this file.
1 //===- BinaryStreamRef.h - A copyable reference to a stream -----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_SUPPORT_BINARYSTREAMREF_H
11 #define LLVM_SUPPORT_BINARYSTREAMREF_H
12 
13 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/Support/Error.h"
17 #include <algorithm>
18 #include <cstdint>
19 #include <memory>
20 
21 namespace llvm {
22 
23 /// Common stuff for mutable and immutable StreamRefs.
24 template <class RefType, class StreamType> class BinaryStreamRefBase {
25 protected:
26  BinaryStreamRefBase() = default;
27  BinaryStreamRefBase(std::shared_ptr<StreamType> SharedImpl, uint32_t Offset,
29  : SharedImpl(SharedImpl), BorrowedImpl(SharedImpl.get()),
30  ViewOffset(Offset), Length(Length) {}
33  : BorrowedImpl(&BorrowedImpl), ViewOffset(Offset), Length(Length) {}
35  BinaryStreamRefBase &operator=(const BinaryStreamRefBase &Other) = default;
36 
38  BinaryStreamRefBase(BinaryStreamRefBase &&Other) = default;
39 
40 public:
42  return BorrowedImpl->getEndian();
43  }
44 
45  uint32_t getLength() const { return Length; }
46 
47  /// Return a new BinaryStreamRef with the first \p N elements removed.
48  RefType drop_front(uint32_t N) const {
49  if (!BorrowedImpl)
50  return RefType();
51 
52  N = std::min(N, Length);
53  RefType Result(static_cast<const RefType &>(*this));
54  Result.ViewOffset += N;
55  Result.Length -= N;
56  return Result;
57  }
58 
59  /// Return a new BinaryStreamRef with the first \p N elements removed.
60  RefType drop_back(uint32_t N) const {
61  if (!BorrowedImpl)
62  return RefType();
63 
64  N = std::min(N, Length);
65  RefType Result(static_cast<const RefType &>(*this));
66  Result.Length -= N;
67  return Result;
68  }
69 
70  /// Return a new BinaryStreamRef with only the first \p N elements remaining.
71  RefType keep_front(uint32_t N) const {
72  assert(N <= getLength());
73  return drop_back(getLength() - N);
74  }
75 
76  /// Return a new BinaryStreamRef with only the last \p N elements remaining.
77  RefType keep_back(uint32_t N) const {
78  assert(N <= getLength());
79  return drop_front(getLength() - N);
80  }
81 
82  /// Return a new BinaryStreamRef with the first and last \p N elements
83  /// removed.
84  RefType drop_symmetric(uint32_t N) const {
85  return drop_front(N).drop_back(N);
86  }
87 
88  /// Return a new BinaryStreamRef with the first \p Offset elements removed,
89  /// and retaining exactly \p Len elements.
90  RefType slice(uint32_t Offset, uint32_t Len) const {
91  return drop_front(Offset).keep_front(Len);
92  }
93 
94  bool valid() const { return BorrowedImpl != nullptr; }
95 
96  bool operator==(const RefType &Other) const {
97  if (BorrowedImpl != Other.BorrowedImpl)
98  return false;
99  if (ViewOffset != Other.ViewOffset)
100  return false;
101  if (Length != Other.Length)
102  return false;
103  return true;
104  }
105 
106 protected:
108  if (Offset > getLength())
109  return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
110  if (getLength() < DataSize + Offset)
111  return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
112  return Error::success();
113  }
114 
115  std::shared_ptr<StreamType> SharedImpl;
116  StreamType *BorrowedImpl = nullptr;
119 };
120 
121 /// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It
122 /// provides copy-semantics and read only access to a "window" of the underlying
123 /// BinaryStream. Note that BinaryStreamRef is *not* a BinaryStream. That is to
124 /// say, it does not inherit and override the methods of BinaryStream. In
125 /// general, you should not pass around pointers or references to BinaryStreams
126 /// and use inheritance to achieve polymorphism. Instead, you should pass
127 /// around BinaryStreamRefs by value and achieve polymorphism that way.
129  : public BinaryStreamRefBase<BinaryStreamRef, BinaryStream> {
132  BinaryStreamRef(std::shared_ptr<BinaryStream> Impl, uint32_t ViewOffset,
134  : BinaryStreamRefBase(Impl, ViewOffset, Length) {}
135 
136 public:
137  BinaryStreamRef() = default;
138  BinaryStreamRef(BinaryStream &Stream);
143 
144  BinaryStreamRef(const BinaryStreamRef &Other) = default;
145  BinaryStreamRef &operator=(const BinaryStreamRef &Other) = default;
148 
149  // Use BinaryStreamRef.slice() instead.
151  uint32_t Length) = delete;
152 
153  /// Given an Offset into this StreamRef and a Size, return a reference to a
154  /// buffer owned by the stream.
155  ///
156  /// \returns a success error code if the entire range of data is within the
157  /// bounds of this BinaryStreamRef's view and the implementation could read
158  /// the data, and an appropriate error code otherwise.
159  Error readBytes(uint32_t Offset, uint32_t Size,
160  ArrayRef<uint8_t> &Buffer) const;
161 
162  /// Given an Offset into this BinaryStreamRef, return a reference to the
163  /// largest buffer the stream could support without necessitating a copy.
164  ///
165  /// \returns a success error code if implementation could read the data,
166  /// and an appropriate error code otherwise.
167  Error readLongestContiguousChunk(uint32_t Offset,
168  ArrayRef<uint8_t> &Buffer) const;
169 };
170 
172  uint32_t Offset; // Offset in the parent stream
173  BinaryStreamRef StreamData; // Stream Data
174 
176  BinaryStreamRef SubSub = StreamData.slice(Off, Size);
177  return {Off + Offset, SubSub};
178  }
180  return slice(N, size() - N);
181  }
182  BinarySubstreamRef keep_front(uint32_t N) const { return slice(0, N); }
183 
184  std::pair<BinarySubstreamRef, BinarySubstreamRef>
185  split(uint32_t Offset) const {
186  return std::make_pair(keep_front(Offset), drop_front(Offset));
187  }
188 
189  uint32_t size() const { return StreamData.getLength(); }
190  bool empty() const { return size() == 0; }
191 };
192 
194  : public BinaryStreamRefBase<WritableBinaryStreamRef,
195  WritableBinaryStream> {
197  WritableBinaryStreamRef(std::shared_ptr<WritableBinaryStream> Impl,
199  : BinaryStreamRefBase(Impl, ViewOffset, Length) {}
200 
201 public:
202  WritableBinaryStreamRef() = default;
205  uint32_t Length);
210  operator=(const WritableBinaryStreamRef &Other) = default;
211 
214 
215  // Use WritableBinaryStreamRef.slice() instead.
217  uint32_t Length) = delete;
218 
219  /// Given an Offset into this WritableBinaryStreamRef and some input data,
220  /// writes the data to the underlying stream.
221  ///
222  /// \returns a success error code if the data could fit within the underlying
223  /// stream at the specified location and the implementation could write the
224  /// data, and an appropriate error code otherwise.
225  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const;
226 
227  /// Conver this WritableBinaryStreamRef to a read-only BinaryStreamRef.
228  operator BinaryStreamRef() const;
229 
230  /// \brief For buffered streams, commits changes to the backing store.
231  Error commit();
232 };
233 
234 } // end namespace llvm
235 
236 #endif // LLVM_SUPPORT_BINARYSTREAMREF_H
BinarySubstreamRef slice(uint32_t Off, uint32_t Size) const
bool operator==(const RefType &Other) const
RefType slice(uint32_t Offset, uint32_t Len) const
Return a new BinaryStreamRef with the first Offset elements removed, and retaining exactly Len elemen...
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
BinaryStreamRefBase & operator=(const BinaryStreamRefBase &Other)=default
Error checkOffset(uint32_t Offset, uint32_t DataSize) const
std::shared_ptr< StreamType > SharedImpl
llvm::support::endianness getEndian() const
Common stuff for mutable and immutable StreamRefs.
RefType keep_back(uint32_t N) const
Return a new BinaryStreamRef with only the last N elements remaining.
BinaryStreamRefBase(StreamType &BorrowedImpl, uint32_t Offset, uint32_t Length)
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:736
An interface for accessing data in a stream-like format, but which discourages copying.
Definition: BinaryStream.h:28
RefType drop_back(uint32_t N) const
Return a new BinaryStreamRef with the first N elements removed.
BinarySubstreamRef drop_front(uint32_t N) const
RefType drop_front(uint32_t N) const
Return a new BinaryStreamRef with the first N elements removed.
BinaryStreamRef StreamData
uint32_t getLength() const
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
std::pair< BinarySubstreamRef, BinarySubstreamRef > split(uint32_t Offset) const
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
BinaryStreamRefBase(std::shared_ptr< StreamType > SharedImpl, uint32_t Offset, uint32_t Length)
#define N
RefType drop_symmetric(uint32_t N) const
Return a new BinaryStreamRef with the first and last N elements removed.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BinarySubstreamRef keep_front(uint32_t N) const
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
RefType keep_front(uint32_t N) const
Return a new BinaryStreamRef with only the first N elements remaining.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
A BinaryStream which can be read from as well as written to.
Definition: BinaryStream.h:63