summaryrefslogtreecommitdiff
path: root/include/llvm/Support/BinaryStreamRef.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support/BinaryStreamRef.h')
-rw-r--r--include/llvm/Support/BinaryStreamRef.h92
1 files changed, 69 insertions, 23 deletions
diff --git a/include/llvm/Support/BinaryStreamRef.h b/include/llvm/Support/BinaryStreamRef.h
index 6d5135cb258dd..5cf355be6fe9c 100644
--- a/include/llvm/Support/BinaryStreamRef.h
+++ b/include/llvm/Support/BinaryStreamRef.h
@@ -11,6 +11,7 @@
#define LLVM_SUPPORT_BINARYSTREAMREF_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/BinaryStream.h"
#include "llvm/Support/BinaryStreamError.h"
#include "llvm/Support/Error.h"
@@ -24,47 +25,74 @@ namespace llvm {
template <class RefType, class StreamType> class BinaryStreamRefBase {
protected:
BinaryStreamRefBase() = default;
+ explicit BinaryStreamRefBase(StreamType &BorrowedImpl)
+ : BorrowedImpl(&BorrowedImpl), ViewOffset(0) {
+ if (!(BorrowedImpl.getFlags() & BSF_Append))
+ Length = BorrowedImpl.getLength();
+ }
+
BinaryStreamRefBase(std::shared_ptr<StreamType> SharedImpl, uint32_t Offset,
- uint32_t Length)
+ Optional<uint32_t> Length)
: SharedImpl(SharedImpl), BorrowedImpl(SharedImpl.get()),
ViewOffset(Offset), Length(Length) {}
BinaryStreamRefBase(StreamType &BorrowedImpl, uint32_t Offset,
- uint32_t Length)
+ Optional<uint32_t> Length)
: BorrowedImpl(&BorrowedImpl), ViewOffset(Offset), Length(Length) {}
- BinaryStreamRefBase(const BinaryStreamRefBase &Other) {
- SharedImpl = Other.SharedImpl;
- BorrowedImpl = Other.BorrowedImpl;
- ViewOffset = Other.ViewOffset;
- Length = Other.Length;
- }
+ BinaryStreamRefBase(const BinaryStreamRefBase &Other) = default;
+ BinaryStreamRefBase &operator=(const BinaryStreamRefBase &Other) = default;
+
+ BinaryStreamRefBase &operator=(BinaryStreamRefBase &&Other) = default;
+ BinaryStreamRefBase(BinaryStreamRefBase &&Other) = default;
public:
llvm::support::endianness getEndian() const {
return BorrowedImpl->getEndian();
}
- uint32_t getLength() const { return Length; }
+ uint32_t getLength() const {
+ if (Length.hasValue())
+ return *Length;
- /// Return a new BinaryStreamRef with the first \p N elements removed.
+ return BorrowedImpl ? (BorrowedImpl->getLength() - ViewOffset) : 0;
+ }
+
+ /// Return a new BinaryStreamRef with the first \p N elements removed. If
+ /// this BinaryStreamRef is length-tracking, then the resulting one will be
+ /// too.
RefType drop_front(uint32_t N) const {
if (!BorrowedImpl)
return RefType();
- N = std::min(N, Length);
+ N = std::min(N, getLength());
RefType Result(static_cast<const RefType &>(*this));
+ if (N == 0)
+ return Result;
+
Result.ViewOffset += N;
- Result.Length -= N;
+ if (Result.Length.hasValue())
+ *Result.Length -= N;
return Result;
}
- /// Return a new BinaryStreamRef with the first \p N elements removed.
+ /// Return a new BinaryStreamRef with the last \p N elements removed. If
+ /// this BinaryStreamRef is length-tracking and \p N is greater than 0, then
+ /// this BinaryStreamRef will no longer length-track.
RefType drop_back(uint32_t N) const {
if (!BorrowedImpl)
return RefType();
- N = std::min(N, Length);
RefType Result(static_cast<const RefType &>(*this));
- Result.Length -= N;
+ N = std::min(N, getLength());
+
+ if (N == 0)
+ return Result;
+
+ // Since we're dropping non-zero bytes from the end, stop length-tracking
+ // by setting the length of the resulting StreamRef to an explicit value.
+ if (!Result.Length.hasValue())
+ Result.Length = getLength();
+
+ *Result.Length -= N;
return Result;
}
@@ -105,7 +133,7 @@ public:
}
protected:
- Error checkOffset(uint32_t Offset, uint32_t DataSize) const {
+ Error checkOffsetForRead(uint32_t Offset, uint32_t DataSize) const {
if (Offset > getLength())
return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
if (getLength() < DataSize + Offset)
@@ -116,7 +144,7 @@ protected:
std::shared_ptr<StreamType> SharedImpl;
StreamType *BorrowedImpl = nullptr;
uint32_t ViewOffset = 0;
- uint32_t Length = 0;
+ Optional<uint32_t> Length;
};
/// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array. It
@@ -131,18 +159,22 @@ class BinaryStreamRef
friend BinaryStreamRefBase<BinaryStreamRef, BinaryStream>;
friend class WritableBinaryStreamRef;
BinaryStreamRef(std::shared_ptr<BinaryStream> Impl, uint32_t ViewOffset,
- uint32_t Length)
+ Optional<uint32_t> Length)
: BinaryStreamRefBase(Impl, ViewOffset, Length) {}
public:
BinaryStreamRef() = default;
BinaryStreamRef(BinaryStream &Stream);
- BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, uint32_t Length);
+ BinaryStreamRef(BinaryStream &Stream, uint32_t Offset,
+ Optional<uint32_t> Length);
explicit BinaryStreamRef(ArrayRef<uint8_t> Data,
llvm::support::endianness Endian);
explicit BinaryStreamRef(StringRef Data, llvm::support::endianness Endian);
- BinaryStreamRef(const BinaryStreamRef &Other);
+ BinaryStreamRef(const BinaryStreamRef &Other) = default;
+ BinaryStreamRef &operator=(const BinaryStreamRef &Other) = default;
+ BinaryStreamRef(BinaryStreamRef &&Other) = default;
+ BinaryStreamRef &operator=(BinaryStreamRef &&Other) = default;
// Use BinaryStreamRef.slice() instead.
BinaryStreamRef(BinaryStreamRef &S, uint32_t Offset,
@@ -193,17 +225,31 @@ class WritableBinaryStreamRef
WritableBinaryStream> {
friend BinaryStreamRefBase<WritableBinaryStreamRef, WritableBinaryStream>;
WritableBinaryStreamRef(std::shared_ptr<WritableBinaryStream> Impl,
- uint32_t ViewOffset, uint32_t Length)
+ uint32_t ViewOffset, Optional<uint32_t> Length)
: BinaryStreamRefBase(Impl, ViewOffset, Length) {}
+ Error checkOffsetForWrite(uint32_t Offset, uint32_t DataSize) const {
+ if (!(BorrowedImpl->getFlags() & BSF_Append))
+ return checkOffsetForRead(Offset, DataSize);
+
+ if (Offset > getLength())
+ return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
+ return Error::success();
+ }
+
public:
WritableBinaryStreamRef() = default;
WritableBinaryStreamRef(WritableBinaryStream &Stream);
WritableBinaryStreamRef(WritableBinaryStream &Stream, uint32_t Offset,
- uint32_t Length);
+ Optional<uint32_t> Length);
explicit WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
llvm::support::endianness Endian);
- WritableBinaryStreamRef(const WritableBinaryStreamRef &Other);
+ WritableBinaryStreamRef(const WritableBinaryStreamRef &Other) = default;
+ WritableBinaryStreamRef &
+ operator=(const WritableBinaryStreamRef &Other) = default;
+
+ WritableBinaryStreamRef(WritableBinaryStreamRef &&Other) = default;
+ WritableBinaryStreamRef &operator=(WritableBinaryStreamRef &&Other) = default;
// Use WritableBinaryStreamRef.slice() instead.
WritableBinaryStreamRef(WritableBinaryStreamRef &S, uint32_t Offset,