xref: /openbsd-src/gnu/llvm/llvm/lib/Support/BinaryStreamRef.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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:
ArrayRefImpl(ArrayRef<uint8_t> Data,endianness Endian)1909467b48Spatrick   ArrayRefImpl(ArrayRef<uint8_t> Data, endianness Endian) : BBS(Data, Endian) {}
2009467b48Spatrick 
getEndian() const2109467b48Spatrick   llvm::support::endianness getEndian() const override {
2209467b48Spatrick     return BBS.getEndian();
2309467b48Spatrick   }
readBytes(uint64_t Offset,uint64_t Size,ArrayRef<uint8_t> & Buffer)24*d415bd75Srobert   Error readBytes(uint64_t Offset, uint64_t Size,
2509467b48Spatrick                   ArrayRef<uint8_t> &Buffer) override {
2609467b48Spatrick     return BBS.readBytes(Offset, Size, Buffer);
2709467b48Spatrick   }
readLongestContiguousChunk(uint64_t Offset,ArrayRef<uint8_t> & Buffer)28*d415bd75Srobert   Error readLongestContiguousChunk(uint64_t Offset,
2909467b48Spatrick                                    ArrayRef<uint8_t> &Buffer) override {
3009467b48Spatrick     return BBS.readLongestContiguousChunk(Offset, Buffer);
3109467b48Spatrick   }
getLength()32*d415bd75Srobert   uint64_t getLength() override { return BBS.getLength(); }
3309467b48Spatrick 
3409467b48Spatrick private:
3509467b48Spatrick   BinaryByteStream BBS;
3609467b48Spatrick };
3709467b48Spatrick 
3809467b48Spatrick class MutableArrayRefImpl : public WritableBinaryStream {
3909467b48Spatrick public:
MutableArrayRefImpl(MutableArrayRef<uint8_t> Data,endianness Endian)4009467b48Spatrick   MutableArrayRefImpl(MutableArrayRef<uint8_t> Data, endianness Endian)
4109467b48Spatrick       : BBS(Data, Endian) {}
4209467b48Spatrick 
4309467b48Spatrick   // Inherited via WritableBinaryStream
getEndian() const4409467b48Spatrick   llvm::support::endianness getEndian() const override {
4509467b48Spatrick     return BBS.getEndian();
4609467b48Spatrick   }
readBytes(uint64_t Offset,uint64_t Size,ArrayRef<uint8_t> & Buffer)47*d415bd75Srobert   Error readBytes(uint64_t Offset, uint64_t Size,
4809467b48Spatrick                   ArrayRef<uint8_t> &Buffer) override {
4909467b48Spatrick     return BBS.readBytes(Offset, Size, Buffer);
5009467b48Spatrick   }
readLongestContiguousChunk(uint64_t Offset,ArrayRef<uint8_t> & Buffer)51*d415bd75Srobert   Error readLongestContiguousChunk(uint64_t Offset,
5209467b48Spatrick                                    ArrayRef<uint8_t> &Buffer) override {
5309467b48Spatrick     return BBS.readLongestContiguousChunk(Offset, Buffer);
5409467b48Spatrick   }
getLength()55*d415bd75Srobert   uint64_t getLength() override { return BBS.getLength(); }
5609467b48Spatrick 
writeBytes(uint64_t Offset,ArrayRef<uint8_t> Data)57*d415bd75Srobert   Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Data) override {
5809467b48Spatrick     return BBS.writeBytes(Offset, Data);
5909467b48Spatrick   }
commit()6009467b48Spatrick   Error commit() override { return BBS.commit(); }
6109467b48Spatrick 
6209467b48Spatrick private:
6309467b48Spatrick   MutableBinaryByteStream BBS;
6409467b48Spatrick };
6573471bf0Spatrick } // namespace
6609467b48Spatrick 
BinaryStreamRef(BinaryStream & Stream)6709467b48Spatrick BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream)
6809467b48Spatrick     : BinaryStreamRefBase(Stream) {}
BinaryStreamRef(BinaryStream & Stream,uint64_t Offset,std::optional<uint64_t> Length)69*d415bd75Srobert BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream, uint64_t Offset,
70*d415bd75Srobert                                  std::optional<uint64_t> Length)
7109467b48Spatrick     : BinaryStreamRefBase(Stream, Offset, Length) {}
BinaryStreamRef(ArrayRef<uint8_t> Data,endianness Endian)7209467b48Spatrick BinaryStreamRef::BinaryStreamRef(ArrayRef<uint8_t> Data, endianness Endian)
7309467b48Spatrick     : BinaryStreamRefBase(std::make_shared<ArrayRefImpl>(Data, Endian), 0,
7409467b48Spatrick                           Data.size()) {}
BinaryStreamRef(StringRef Data,endianness Endian)7509467b48Spatrick BinaryStreamRef::BinaryStreamRef(StringRef Data, endianness Endian)
76*d415bd75Srobert     : BinaryStreamRef(ArrayRef(Data.bytes_begin(), Data.bytes_end()), Endian) {}
7709467b48Spatrick 
readBytes(uint64_t Offset,uint64_t Size,ArrayRef<uint8_t> & Buffer) const78*d415bd75Srobert Error BinaryStreamRef::readBytes(uint64_t Offset, uint64_t Size,
7909467b48Spatrick                                  ArrayRef<uint8_t> &Buffer) const {
8009467b48Spatrick   if (auto EC = checkOffsetForRead(Offset, Size))
8109467b48Spatrick     return EC;
8209467b48Spatrick   return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer);
8309467b48Spatrick }
8409467b48Spatrick 
readLongestContiguousChunk(uint64_t Offset,ArrayRef<uint8_t> & Buffer) const8509467b48Spatrick Error BinaryStreamRef::readLongestContiguousChunk(
86*d415bd75Srobert     uint64_t Offset, ArrayRef<uint8_t> &Buffer) const {
8709467b48Spatrick   if (auto EC = checkOffsetForRead(Offset, 1))
8809467b48Spatrick     return EC;
8909467b48Spatrick 
9009467b48Spatrick   if (auto EC =
9109467b48Spatrick           BorrowedImpl->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
9209467b48Spatrick     return EC;
9309467b48Spatrick   // This StreamRef might refer to a smaller window over a larger stream.  In
9409467b48Spatrick   // that case we will have read out more bytes than we should return, because
9509467b48Spatrick   // we should not read past the end of the current view.
96*d415bd75Srobert   uint64_t MaxLength = getLength() - Offset;
9709467b48Spatrick   if (Buffer.size() > MaxLength)
9809467b48Spatrick     Buffer = Buffer.slice(0, MaxLength);
9909467b48Spatrick   return Error::success();
10009467b48Spatrick }
10109467b48Spatrick 
WritableBinaryStreamRef(WritableBinaryStream & Stream)10209467b48Spatrick WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream)
10309467b48Spatrick     : BinaryStreamRefBase(Stream) {}
10409467b48Spatrick 
WritableBinaryStreamRef(WritableBinaryStream & Stream,uint64_t Offset,std::optional<uint64_t> Length)10509467b48Spatrick WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream,
106*d415bd75Srobert                                                  uint64_t Offset,
107*d415bd75Srobert                                                  std::optional<uint64_t> Length)
10809467b48Spatrick     : BinaryStreamRefBase(Stream, Offset, Length) {}
10909467b48Spatrick 
WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,endianness Endian)11009467b48Spatrick WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
11109467b48Spatrick                                                  endianness Endian)
11209467b48Spatrick     : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
11309467b48Spatrick                           0, Data.size()) {}
11409467b48Spatrick 
writeBytes(uint64_t Offset,ArrayRef<uint8_t> Data) const115*d415bd75Srobert Error WritableBinaryStreamRef::writeBytes(uint64_t Offset,
11609467b48Spatrick                                           ArrayRef<uint8_t> Data) const {
11709467b48Spatrick   if (auto EC = checkOffsetForWrite(Offset, Data.size()))
11809467b48Spatrick     return EC;
11909467b48Spatrick 
12009467b48Spatrick   return BorrowedImpl->writeBytes(ViewOffset + Offset, Data);
12109467b48Spatrick }
12209467b48Spatrick 
operator BinaryStreamRef() const12309467b48Spatrick WritableBinaryStreamRef::operator BinaryStreamRef() const {
12409467b48Spatrick   return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length);
12509467b48Spatrick }
12609467b48Spatrick 
12709467b48Spatrick /// For buffered streams, commits changes to the backing store.
commit()12809467b48Spatrick Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); }
129