xref: /openbsd-src/gnu/llvm/llvm/lib/Support/BinaryStreamRef.cpp (revision 73471bf04ceb096474c7f0fa83b1b65c70a787a1)
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