10b57cec5SDimitry Andric //===- BinaryStreamRef.cpp - ----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "llvm/Support/BinaryStreamRef.h"
100b57cec5SDimitry Andric #include "llvm/Support/BinaryByteStream.h"
110b57cec5SDimitry Andric
120b57cec5SDimitry Andric using namespace llvm;
130b57cec5SDimitry Andric using namespace llvm::support;
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric namespace {
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric class ArrayRefImpl : public BinaryStream {
180b57cec5SDimitry Andric public:
ArrayRefImpl(ArrayRef<uint8_t> Data,endianness Endian)190b57cec5SDimitry Andric ArrayRefImpl(ArrayRef<uint8_t> Data, endianness Endian) : BBS(Data, Endian) {}
200b57cec5SDimitry Andric
getEndian() const210b57cec5SDimitry Andric llvm::support::endianness getEndian() const override {
220b57cec5SDimitry Andric return BBS.getEndian();
230b57cec5SDimitry Andric }
readBytes(uint32_t Offset,uint32_t Size,ArrayRef<uint8_t> & Buffer)240b57cec5SDimitry Andric Error readBytes(uint32_t Offset, uint32_t Size,
250b57cec5SDimitry Andric ArrayRef<uint8_t> &Buffer) override {
260b57cec5SDimitry Andric return BBS.readBytes(Offset, Size, Buffer);
270b57cec5SDimitry Andric }
readLongestContiguousChunk(uint32_t Offset,ArrayRef<uint8_t> & Buffer)280b57cec5SDimitry Andric Error readLongestContiguousChunk(uint32_t Offset,
290b57cec5SDimitry Andric ArrayRef<uint8_t> &Buffer) override {
300b57cec5SDimitry Andric return BBS.readLongestContiguousChunk(Offset, Buffer);
310b57cec5SDimitry Andric }
getLength()320b57cec5SDimitry Andric uint32_t getLength() override { return BBS.getLength(); }
330b57cec5SDimitry Andric
340b57cec5SDimitry Andric private:
350b57cec5SDimitry Andric BinaryByteStream BBS;
360b57cec5SDimitry Andric };
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric class MutableArrayRefImpl : public WritableBinaryStream {
390b57cec5SDimitry Andric public:
MutableArrayRefImpl(MutableArrayRef<uint8_t> Data,endianness Endian)400b57cec5SDimitry Andric MutableArrayRefImpl(MutableArrayRef<uint8_t> Data, endianness Endian)
410b57cec5SDimitry Andric : BBS(Data, Endian) {}
420b57cec5SDimitry Andric
430b57cec5SDimitry Andric // Inherited via WritableBinaryStream
getEndian() const440b57cec5SDimitry Andric llvm::support::endianness getEndian() const override {
450b57cec5SDimitry Andric return BBS.getEndian();
460b57cec5SDimitry Andric }
readBytes(uint32_t Offset,uint32_t Size,ArrayRef<uint8_t> & Buffer)470b57cec5SDimitry Andric Error readBytes(uint32_t Offset, uint32_t Size,
480b57cec5SDimitry Andric ArrayRef<uint8_t> &Buffer) override {
490b57cec5SDimitry Andric return BBS.readBytes(Offset, Size, Buffer);
500b57cec5SDimitry Andric }
readLongestContiguousChunk(uint32_t Offset,ArrayRef<uint8_t> & Buffer)510b57cec5SDimitry Andric Error readLongestContiguousChunk(uint32_t Offset,
520b57cec5SDimitry Andric ArrayRef<uint8_t> &Buffer) override {
530b57cec5SDimitry Andric return BBS.readLongestContiguousChunk(Offset, Buffer);
540b57cec5SDimitry Andric }
getLength()550b57cec5SDimitry Andric uint32_t getLength() override { return BBS.getLength(); }
560b57cec5SDimitry Andric
writeBytes(uint32_t Offset,ArrayRef<uint8_t> Data)570b57cec5SDimitry Andric Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override {
580b57cec5SDimitry Andric return BBS.writeBytes(Offset, Data);
590b57cec5SDimitry Andric }
commit()600b57cec5SDimitry Andric Error commit() override { return BBS.commit(); }
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric private:
630b57cec5SDimitry Andric MutableBinaryByteStream BBS;
640b57cec5SDimitry Andric };
65*5f7ddb14SDimitry Andric } // namespace
660b57cec5SDimitry Andric
BinaryStreamRef(BinaryStream & Stream)670b57cec5SDimitry Andric BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream)
680b57cec5SDimitry Andric : BinaryStreamRefBase(Stream) {}
BinaryStreamRef(BinaryStream & Stream,uint32_t Offset,Optional<uint32_t> Length)690b57cec5SDimitry Andric BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream, uint32_t Offset,
700b57cec5SDimitry Andric Optional<uint32_t> Length)
710b57cec5SDimitry Andric : BinaryStreamRefBase(Stream, Offset, Length) {}
BinaryStreamRef(ArrayRef<uint8_t> Data,endianness Endian)720b57cec5SDimitry Andric BinaryStreamRef::BinaryStreamRef(ArrayRef<uint8_t> Data, endianness Endian)
730b57cec5SDimitry Andric : BinaryStreamRefBase(std::make_shared<ArrayRefImpl>(Data, Endian), 0,
740b57cec5SDimitry Andric Data.size()) {}
BinaryStreamRef(StringRef Data,endianness Endian)750b57cec5SDimitry Andric BinaryStreamRef::BinaryStreamRef(StringRef Data, endianness Endian)
760b57cec5SDimitry Andric : BinaryStreamRef(makeArrayRef(Data.bytes_begin(), Data.bytes_end()),
770b57cec5SDimitry Andric Endian) {}
780b57cec5SDimitry Andric
readBytes(uint32_t Offset,uint32_t Size,ArrayRef<uint8_t> & Buffer) const790b57cec5SDimitry Andric Error BinaryStreamRef::readBytes(uint32_t Offset, uint32_t Size,
800b57cec5SDimitry Andric ArrayRef<uint8_t> &Buffer) const {
810b57cec5SDimitry Andric if (auto EC = checkOffsetForRead(Offset, Size))
820b57cec5SDimitry Andric return EC;
830b57cec5SDimitry Andric return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer);
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric
readLongestContiguousChunk(uint32_t Offset,ArrayRef<uint8_t> & Buffer) const860b57cec5SDimitry Andric Error BinaryStreamRef::readLongestContiguousChunk(
870b57cec5SDimitry Andric uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
880b57cec5SDimitry Andric if (auto EC = checkOffsetForRead(Offset, 1))
890b57cec5SDimitry Andric return EC;
900b57cec5SDimitry Andric
910b57cec5SDimitry Andric if (auto EC =
920b57cec5SDimitry Andric BorrowedImpl->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
930b57cec5SDimitry Andric return EC;
940b57cec5SDimitry Andric // This StreamRef might refer to a smaller window over a larger stream. In
950b57cec5SDimitry Andric // that case we will have read out more bytes than we should return, because
960b57cec5SDimitry Andric // we should not read past the end of the current view.
970b57cec5SDimitry Andric uint32_t MaxLength = getLength() - Offset;
980b57cec5SDimitry Andric if (Buffer.size() > MaxLength)
990b57cec5SDimitry Andric Buffer = Buffer.slice(0, MaxLength);
1000b57cec5SDimitry Andric return Error::success();
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric
WritableBinaryStreamRef(WritableBinaryStream & Stream)1030b57cec5SDimitry Andric WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream)
1040b57cec5SDimitry Andric : BinaryStreamRefBase(Stream) {}
1050b57cec5SDimitry Andric
WritableBinaryStreamRef(WritableBinaryStream & Stream,uint32_t Offset,Optional<uint32_t> Length)1060b57cec5SDimitry Andric WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream,
1070b57cec5SDimitry Andric uint32_t Offset,
1080b57cec5SDimitry Andric Optional<uint32_t> Length)
1090b57cec5SDimitry Andric : BinaryStreamRefBase(Stream, Offset, Length) {}
1100b57cec5SDimitry Andric
WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,endianness Endian)1110b57cec5SDimitry Andric WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
1120b57cec5SDimitry Andric endianness Endian)
1130b57cec5SDimitry Andric : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
1140b57cec5SDimitry Andric 0, Data.size()) {}
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andric
writeBytes(uint32_t Offset,ArrayRef<uint8_t> Data) const1170b57cec5SDimitry Andric Error WritableBinaryStreamRef::writeBytes(uint32_t Offset,
1180b57cec5SDimitry Andric ArrayRef<uint8_t> Data) const {
1190b57cec5SDimitry Andric if (auto EC = checkOffsetForWrite(Offset, Data.size()))
1200b57cec5SDimitry Andric return EC;
1210b57cec5SDimitry Andric
1220b57cec5SDimitry Andric return BorrowedImpl->writeBytes(ViewOffset + Offset, Data);
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric
operator BinaryStreamRef() const1250b57cec5SDimitry Andric WritableBinaryStreamRef::operator BinaryStreamRef() const {
1260b57cec5SDimitry Andric return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length);
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric
1290b57cec5SDimitry Andric /// For buffered streams, commits changes to the backing store.
commit()1300b57cec5SDimitry Andric Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); }
131