xref: /freebsd-src/contrib/llvm-project/llvm/lib/Support/BinaryStreamRef.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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 
140b57cec5SDimitry Andric namespace {
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric class ArrayRefImpl : public BinaryStream {
170b57cec5SDimitry Andric public:
ArrayRefImpl(ArrayRef<uint8_t> Data,endianness Endian)180b57cec5SDimitry Andric   ArrayRefImpl(ArrayRef<uint8_t> Data, endianness Endian) : BBS(Data, Endian) {}
190b57cec5SDimitry Andric 
getEndian() const20*5f757f3fSDimitry Andric   llvm::endianness getEndian() const override { return BBS.getEndian(); }
readBytes(uint64_t Offset,uint64_t Size,ArrayRef<uint8_t> & Buffer)21349cc55cSDimitry Andric   Error readBytes(uint64_t Offset, uint64_t Size,
220b57cec5SDimitry Andric                   ArrayRef<uint8_t> &Buffer) override {
230b57cec5SDimitry Andric     return BBS.readBytes(Offset, Size, Buffer);
240b57cec5SDimitry Andric   }
readLongestContiguousChunk(uint64_t Offset,ArrayRef<uint8_t> & Buffer)25349cc55cSDimitry Andric   Error readLongestContiguousChunk(uint64_t Offset,
260b57cec5SDimitry Andric                                    ArrayRef<uint8_t> &Buffer) override {
270b57cec5SDimitry Andric     return BBS.readLongestContiguousChunk(Offset, Buffer);
280b57cec5SDimitry Andric   }
getLength()29349cc55cSDimitry Andric   uint64_t getLength() override { return BBS.getLength(); }
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric private:
320b57cec5SDimitry Andric   BinaryByteStream BBS;
330b57cec5SDimitry Andric };
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric class MutableArrayRefImpl : public WritableBinaryStream {
360b57cec5SDimitry Andric public:
MutableArrayRefImpl(MutableArrayRef<uint8_t> Data,endianness Endian)370b57cec5SDimitry Andric   MutableArrayRefImpl(MutableArrayRef<uint8_t> Data, endianness Endian)
380b57cec5SDimitry Andric       : BBS(Data, Endian) {}
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   // Inherited via WritableBinaryStream
getEndian() const41*5f757f3fSDimitry Andric   llvm::endianness getEndian() const override { return BBS.getEndian(); }
readBytes(uint64_t Offset,uint64_t Size,ArrayRef<uint8_t> & Buffer)42349cc55cSDimitry Andric   Error readBytes(uint64_t Offset, uint64_t Size,
430b57cec5SDimitry Andric                   ArrayRef<uint8_t> &Buffer) override {
440b57cec5SDimitry Andric     return BBS.readBytes(Offset, Size, Buffer);
450b57cec5SDimitry Andric   }
readLongestContiguousChunk(uint64_t Offset,ArrayRef<uint8_t> & Buffer)46349cc55cSDimitry Andric   Error readLongestContiguousChunk(uint64_t Offset,
470b57cec5SDimitry Andric                                    ArrayRef<uint8_t> &Buffer) override {
480b57cec5SDimitry Andric     return BBS.readLongestContiguousChunk(Offset, Buffer);
490b57cec5SDimitry Andric   }
getLength()50349cc55cSDimitry Andric   uint64_t getLength() override { return BBS.getLength(); }
510b57cec5SDimitry Andric 
writeBytes(uint64_t Offset,ArrayRef<uint8_t> Data)52349cc55cSDimitry Andric   Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Data) override {
530b57cec5SDimitry Andric     return BBS.writeBytes(Offset, Data);
540b57cec5SDimitry Andric   }
commit()550b57cec5SDimitry Andric   Error commit() override { return BBS.commit(); }
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric private:
580b57cec5SDimitry Andric   MutableBinaryByteStream BBS;
590b57cec5SDimitry Andric };
60fe6060f1SDimitry Andric } // namespace
610b57cec5SDimitry Andric 
BinaryStreamRef(BinaryStream & Stream)620b57cec5SDimitry Andric BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream)
630b57cec5SDimitry Andric     : BinaryStreamRefBase(Stream) {}
BinaryStreamRef(BinaryStream & Stream,uint64_t Offset,std::optional<uint64_t> Length)64349cc55cSDimitry Andric BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream, uint64_t Offset,
65bdd1243dSDimitry Andric                                  std::optional<uint64_t> Length)
660b57cec5SDimitry Andric     : BinaryStreamRefBase(Stream, Offset, Length) {}
BinaryStreamRef(ArrayRef<uint8_t> Data,endianness Endian)670b57cec5SDimitry Andric BinaryStreamRef::BinaryStreamRef(ArrayRef<uint8_t> Data, endianness Endian)
680b57cec5SDimitry Andric     : BinaryStreamRefBase(std::make_shared<ArrayRefImpl>(Data, Endian), 0,
690b57cec5SDimitry Andric                           Data.size()) {}
BinaryStreamRef(StringRef Data,endianness Endian)700b57cec5SDimitry Andric BinaryStreamRef::BinaryStreamRef(StringRef Data, endianness Endian)
71bdd1243dSDimitry Andric     : BinaryStreamRef(ArrayRef(Data.bytes_begin(), Data.bytes_end()), Endian) {}
720b57cec5SDimitry Andric 
readBytes(uint64_t Offset,uint64_t Size,ArrayRef<uint8_t> & Buffer) const73349cc55cSDimitry Andric Error BinaryStreamRef::readBytes(uint64_t Offset, uint64_t Size,
740b57cec5SDimitry Andric                                  ArrayRef<uint8_t> &Buffer) const {
750b57cec5SDimitry Andric   if (auto EC = checkOffsetForRead(Offset, Size))
760b57cec5SDimitry Andric     return EC;
770b57cec5SDimitry Andric   return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer);
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric 
readLongestContiguousChunk(uint64_t Offset,ArrayRef<uint8_t> & Buffer) const800b57cec5SDimitry Andric Error BinaryStreamRef::readLongestContiguousChunk(
81349cc55cSDimitry Andric     uint64_t Offset, ArrayRef<uint8_t> &Buffer) const {
820b57cec5SDimitry Andric   if (auto EC = checkOffsetForRead(Offset, 1))
830b57cec5SDimitry Andric     return EC;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   if (auto EC =
860b57cec5SDimitry Andric           BorrowedImpl->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
870b57cec5SDimitry Andric     return EC;
880b57cec5SDimitry Andric   // This StreamRef might refer to a smaller window over a larger stream.  In
890b57cec5SDimitry Andric   // that case we will have read out more bytes than we should return, because
900b57cec5SDimitry Andric   // we should not read past the end of the current view.
91349cc55cSDimitry Andric   uint64_t MaxLength = getLength() - Offset;
920b57cec5SDimitry Andric   if (Buffer.size() > MaxLength)
930b57cec5SDimitry Andric     Buffer = Buffer.slice(0, MaxLength);
940b57cec5SDimitry Andric   return Error::success();
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric 
WritableBinaryStreamRef(WritableBinaryStream & Stream)970b57cec5SDimitry Andric WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream)
980b57cec5SDimitry Andric     : BinaryStreamRefBase(Stream) {}
990b57cec5SDimitry Andric 
WritableBinaryStreamRef(WritableBinaryStream & Stream,uint64_t Offset,std::optional<uint64_t> Length)1000b57cec5SDimitry Andric WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream,
101349cc55cSDimitry Andric                                                  uint64_t Offset,
102bdd1243dSDimitry Andric                                                  std::optional<uint64_t> Length)
1030b57cec5SDimitry Andric     : BinaryStreamRefBase(Stream, Offset, Length) {}
1040b57cec5SDimitry Andric 
WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,endianness Endian)1050b57cec5SDimitry Andric WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
1060b57cec5SDimitry Andric                                                  endianness Endian)
1070b57cec5SDimitry Andric     : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
1080b57cec5SDimitry Andric                           0, Data.size()) {}
1090b57cec5SDimitry Andric 
writeBytes(uint64_t Offset,ArrayRef<uint8_t> Data) const110349cc55cSDimitry Andric Error WritableBinaryStreamRef::writeBytes(uint64_t Offset,
1110b57cec5SDimitry Andric                                           ArrayRef<uint8_t> Data) const {
1120b57cec5SDimitry Andric   if (auto EC = checkOffsetForWrite(Offset, Data.size()))
1130b57cec5SDimitry Andric     return EC;
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   return BorrowedImpl->writeBytes(ViewOffset + Offset, Data);
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
operator BinaryStreamRef() const1180b57cec5SDimitry Andric WritableBinaryStreamRef::operator BinaryStreamRef() const {
1190b57cec5SDimitry Andric   return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length);
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric /// For buffered streams, commits changes to the backing store.
commit()1230b57cec5SDimitry Andric Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); }
124