diff options
Diffstat (limited to 'contrib/llvm/include/llvm/Support/BinaryByteStream.h')
-rw-r--r-- | contrib/llvm/include/llvm/Support/BinaryByteStream.h | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/contrib/llvm/include/llvm/Support/BinaryByteStream.h b/contrib/llvm/include/llvm/Support/BinaryByteStream.h index 694be28e07e1..db1ccba1398b 100644 --- a/contrib/llvm/include/llvm/Support/BinaryByteStream.h +++ b/contrib/llvm/include/llvm/Support/BinaryByteStream.h @@ -41,7 +41,7 @@ public: Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef<uint8_t> &Buffer) override { - if (auto EC = checkOffset(Offset, Size)) + if (auto EC = checkOffsetForRead(Offset, Size)) return EC; Buffer = Data.slice(Offset, Size); return Error::success(); @@ -49,7 +49,7 @@ public: Error readLongestContiguousChunk(uint32_t Offset, ArrayRef<uint8_t> &Buffer) override { - if (auto EC = checkOffset(Offset, 1)) + if (auto EC = checkOffsetForRead(Offset, 1)) return EC; Buffer = Data.slice(Offset); return Error::success(); @@ -114,7 +114,7 @@ public: if (Buffer.empty()) return Error::success(); - if (auto EC = checkOffset(Offset, Buffer.size())) + if (auto EC = checkOffsetForWrite(Offset, Buffer.size())) return EC; uint8_t *DataPtr = const_cast<uint8_t *>(Data.data()); @@ -131,6 +131,76 @@ private: BinaryByteStream ImmutableStream; }; +/// \brief An implementation of WritableBinaryStream which can write at its end +/// causing the underlying data to grow. This class owns the underlying data. +class AppendingBinaryByteStream : public WritableBinaryStream { + std::vector<uint8_t> Data; + llvm::support::endianness Endian = llvm::support::little; + +public: + AppendingBinaryByteStream() = default; + AppendingBinaryByteStream(llvm::support::endianness Endian) + : Endian(Endian) {} + + void clear() { Data.clear(); } + + llvm::support::endianness getEndian() const override { return Endian; } + + Error readBytes(uint32_t Offset, uint32_t Size, + ArrayRef<uint8_t> &Buffer) override { + if (auto EC = checkOffsetForWrite(Offset, Buffer.size())) + return EC; + + Buffer = makeArrayRef(Data).slice(Offset, Size); + return Error::success(); + } + + void insert(uint32_t Offset, ArrayRef<uint8_t> Bytes) { + Data.insert(Data.begin() + Offset, Bytes.begin(), Bytes.end()); + } + + Error readLongestContiguousChunk(uint32_t Offset, + ArrayRef<uint8_t> &Buffer) override { + if (auto EC = checkOffsetForWrite(Offset, 1)) + return EC; + + Buffer = makeArrayRef(Data).slice(Offset); + return Error::success(); + } + + uint32_t getLength() override { return Data.size(); } + + Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override { + if (Buffer.empty()) + return Error::success(); + + // This is well-defined for any case except where offset is strictly + // greater than the current length. If offset is equal to the current + // length, we can still grow. If offset is beyond the current length, we + // would have to decide how to deal with the intermediate uninitialized + // bytes. So we punt on that case for simplicity and just say it's an + // error. + if (Offset > getLength()) + return make_error<BinaryStreamError>(stream_error_code::invalid_offset); + + uint32_t RequiredSize = Offset + Buffer.size(); + if (RequiredSize > Data.size()) + Data.resize(RequiredSize); + + ::memcpy(Data.data() + Offset, Buffer.data(), Buffer.size()); + return Error::success(); + } + + Error commit() override { return Error::success(); } + + /// \brief Return the properties of this stream. + virtual BinaryStreamFlags getFlags() const override { + return BSF_Write | BSF_Append; + } + + MutableArrayRef<uint8_t> data() { return Data; } +}; + /// \brief An implementation of WritableBinaryStream backed by an llvm /// FileOutputBuffer. class FileBufferByteStream : public WritableBinaryStream { |