109467b48Spatrick //===- BinaryStreamRef.cpp - ----------------------------------------------===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick 909467b48Spatrick #include "llvm/Support/BinaryStreamRef.h" 1009467b48Spatrick #include "llvm/Support/BinaryByteStream.h" 1109467b48Spatrick 1209467b48Spatrick using namespace llvm; 1309467b48Spatrick using namespace llvm::support; 1409467b48Spatrick 1509467b48Spatrick namespace { 1609467b48Spatrick 1709467b48Spatrick class ArrayRefImpl : public BinaryStream { 1809467b48Spatrick public: 1909467b48Spatrick ArrayRefImpl(ArrayRef<uint8_t> Data, endianness Endian) : BBS(Data, Endian) {} 2009467b48Spatrick 2109467b48Spatrick llvm::support::endianness getEndian() const override { 2209467b48Spatrick return BBS.getEndian(); 2309467b48Spatrick } 2409467b48Spatrick Error readBytes(uint32_t Offset, uint32_t Size, 2509467b48Spatrick ArrayRef<uint8_t> &Buffer) override { 2609467b48Spatrick return BBS.readBytes(Offset, Size, Buffer); 2709467b48Spatrick } 2809467b48Spatrick Error readLongestContiguousChunk(uint32_t Offset, 2909467b48Spatrick ArrayRef<uint8_t> &Buffer) override { 3009467b48Spatrick return BBS.readLongestContiguousChunk(Offset, Buffer); 3109467b48Spatrick } 3209467b48Spatrick uint32_t getLength() override { return BBS.getLength(); } 3309467b48Spatrick 3409467b48Spatrick private: 3509467b48Spatrick BinaryByteStream BBS; 3609467b48Spatrick }; 3709467b48Spatrick 3809467b48Spatrick class MutableArrayRefImpl : public WritableBinaryStream { 3909467b48Spatrick public: 4009467b48Spatrick MutableArrayRefImpl(MutableArrayRef<uint8_t> Data, endianness Endian) 4109467b48Spatrick : BBS(Data, Endian) {} 4209467b48Spatrick 4309467b48Spatrick // Inherited via WritableBinaryStream 4409467b48Spatrick llvm::support::endianness getEndian() const override { 4509467b48Spatrick return BBS.getEndian(); 4609467b48Spatrick } 4709467b48Spatrick Error readBytes(uint32_t Offset, uint32_t Size, 4809467b48Spatrick ArrayRef<uint8_t> &Buffer) override { 4909467b48Spatrick return BBS.readBytes(Offset, Size, Buffer); 5009467b48Spatrick } 5109467b48Spatrick Error readLongestContiguousChunk(uint32_t Offset, 5209467b48Spatrick ArrayRef<uint8_t> &Buffer) override { 5309467b48Spatrick return BBS.readLongestContiguousChunk(Offset, Buffer); 5409467b48Spatrick } 5509467b48Spatrick uint32_t getLength() override { return BBS.getLength(); } 5609467b48Spatrick 5709467b48Spatrick Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override { 5809467b48Spatrick return BBS.writeBytes(Offset, Data); 5909467b48Spatrick } 6009467b48Spatrick Error commit() override { return BBS.commit(); } 6109467b48Spatrick 6209467b48Spatrick private: 6309467b48Spatrick MutableBinaryByteStream BBS; 6409467b48Spatrick }; 65*73471bf0Spatrick } // namespace 6609467b48Spatrick 6709467b48Spatrick BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream) 6809467b48Spatrick : BinaryStreamRefBase(Stream) {} 6909467b48Spatrick BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, 7009467b48Spatrick Optional<uint32_t> Length) 7109467b48Spatrick : BinaryStreamRefBase(Stream, Offset, Length) {} 7209467b48Spatrick BinaryStreamRef::BinaryStreamRef(ArrayRef<uint8_t> Data, endianness Endian) 7309467b48Spatrick : BinaryStreamRefBase(std::make_shared<ArrayRefImpl>(Data, Endian), 0, 7409467b48Spatrick Data.size()) {} 7509467b48Spatrick BinaryStreamRef::BinaryStreamRef(StringRef Data, endianness Endian) 7609467b48Spatrick : BinaryStreamRef(makeArrayRef(Data.bytes_begin(), Data.bytes_end()), 7709467b48Spatrick Endian) {} 7809467b48Spatrick 7909467b48Spatrick Error BinaryStreamRef::readBytes(uint32_t Offset, uint32_t Size, 8009467b48Spatrick ArrayRef<uint8_t> &Buffer) const { 8109467b48Spatrick if (auto EC = checkOffsetForRead(Offset, Size)) 8209467b48Spatrick return EC; 8309467b48Spatrick return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer); 8409467b48Spatrick } 8509467b48Spatrick 8609467b48Spatrick Error BinaryStreamRef::readLongestContiguousChunk( 8709467b48Spatrick uint32_t Offset, ArrayRef<uint8_t> &Buffer) const { 8809467b48Spatrick if (auto EC = checkOffsetForRead(Offset, 1)) 8909467b48Spatrick return EC; 9009467b48Spatrick 9109467b48Spatrick if (auto EC = 9209467b48Spatrick BorrowedImpl->readLongestContiguousChunk(ViewOffset + Offset, Buffer)) 9309467b48Spatrick return EC; 9409467b48Spatrick // This StreamRef might refer to a smaller window over a larger stream. In 9509467b48Spatrick // that case we will have read out more bytes than we should return, because 9609467b48Spatrick // we should not read past the end of the current view. 9709467b48Spatrick uint32_t MaxLength = getLength() - Offset; 9809467b48Spatrick if (Buffer.size() > MaxLength) 9909467b48Spatrick Buffer = Buffer.slice(0, MaxLength); 10009467b48Spatrick return Error::success(); 10109467b48Spatrick } 10209467b48Spatrick 10309467b48Spatrick WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream) 10409467b48Spatrick : BinaryStreamRefBase(Stream) {} 10509467b48Spatrick 10609467b48Spatrick WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream, 10709467b48Spatrick uint32_t Offset, 10809467b48Spatrick Optional<uint32_t> Length) 10909467b48Spatrick : BinaryStreamRefBase(Stream, Offset, Length) {} 11009467b48Spatrick 11109467b48Spatrick WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data, 11209467b48Spatrick endianness Endian) 11309467b48Spatrick : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian), 11409467b48Spatrick 0, Data.size()) {} 11509467b48Spatrick 11609467b48Spatrick 11709467b48Spatrick Error WritableBinaryStreamRef::writeBytes(uint32_t Offset, 11809467b48Spatrick ArrayRef<uint8_t> Data) const { 11909467b48Spatrick if (auto EC = checkOffsetForWrite(Offset, Data.size())) 12009467b48Spatrick return EC; 12109467b48Spatrick 12209467b48Spatrick return BorrowedImpl->writeBytes(ViewOffset + Offset, Data); 12309467b48Spatrick } 12409467b48Spatrick 12509467b48Spatrick WritableBinaryStreamRef::operator BinaryStreamRef() const { 12609467b48Spatrick return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length); 12709467b48Spatrick } 12809467b48Spatrick 12909467b48Spatrick /// For buffered streams, commits changes to the backing store. 13009467b48Spatrick Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); } 131