1 //===- BinaryStreamRef.cpp - ----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/BinaryStreamRef.h"
10 #include "llvm/Support/BinaryByteStream.h"
16 class ArrayRefImpl
: public BinaryStream
{
18 ArrayRefImpl(ArrayRef
<uint8_t> Data
, endianness Endian
) : BBS(Data
, Endian
) {}
20 llvm::endianness
getEndian() const override
{ return BBS
.getEndian(); }
21 Error
readBytes(uint64_t Offset
, uint64_t Size
,
22 ArrayRef
<uint8_t> &Buffer
) override
{
23 return BBS
.readBytes(Offset
, Size
, Buffer
);
25 Error
readLongestContiguousChunk(uint64_t Offset
,
26 ArrayRef
<uint8_t> &Buffer
) override
{
27 return BBS
.readLongestContiguousChunk(Offset
, Buffer
);
29 uint64_t getLength() override
{ return BBS
.getLength(); }
35 class MutableArrayRefImpl
: public WritableBinaryStream
{
37 MutableArrayRefImpl(MutableArrayRef
<uint8_t> Data
, endianness Endian
)
38 : BBS(Data
, Endian
) {}
40 // Inherited via WritableBinaryStream
41 llvm::endianness
getEndian() const override
{ return BBS
.getEndian(); }
42 Error
readBytes(uint64_t Offset
, uint64_t Size
,
43 ArrayRef
<uint8_t> &Buffer
) override
{
44 return BBS
.readBytes(Offset
, Size
, Buffer
);
46 Error
readLongestContiguousChunk(uint64_t Offset
,
47 ArrayRef
<uint8_t> &Buffer
) override
{
48 return BBS
.readLongestContiguousChunk(Offset
, Buffer
);
50 uint64_t getLength() override
{ return BBS
.getLength(); }
52 Error
writeBytes(uint64_t Offset
, ArrayRef
<uint8_t> Data
) override
{
53 return BBS
.writeBytes(Offset
, Data
);
55 Error
commit() override
{ return BBS
.commit(); }
58 MutableBinaryByteStream BBS
;
62 BinaryStreamRef::BinaryStreamRef(BinaryStream
&Stream
)
63 : BinaryStreamRefBase(Stream
) {}
64 BinaryStreamRef::BinaryStreamRef(BinaryStream
&Stream
, uint64_t Offset
,
65 std::optional
<uint64_t> Length
)
66 : BinaryStreamRefBase(Stream
, Offset
, Length
) {}
67 BinaryStreamRef::BinaryStreamRef(ArrayRef
<uint8_t> Data
, endianness Endian
)
68 : BinaryStreamRefBase(std::make_shared
<ArrayRefImpl
>(Data
, Endian
), 0,
70 BinaryStreamRef::BinaryStreamRef(StringRef Data
, endianness Endian
)
71 : BinaryStreamRef(ArrayRef(Data
.bytes_begin(), Data
.bytes_end()), Endian
) {}
73 Error
BinaryStreamRef::readBytes(uint64_t Offset
, uint64_t Size
,
74 ArrayRef
<uint8_t> &Buffer
) const {
75 if (auto EC
= checkOffsetForRead(Offset
, Size
))
77 return BorrowedImpl
->readBytes(ViewOffset
+ Offset
, Size
, Buffer
);
80 Error
BinaryStreamRef::readLongestContiguousChunk(
81 uint64_t Offset
, ArrayRef
<uint8_t> &Buffer
) const {
82 if (auto EC
= checkOffsetForRead(Offset
, 1))
86 BorrowedImpl
->readLongestContiguousChunk(ViewOffset
+ Offset
, Buffer
))
88 // This StreamRef might refer to a smaller window over a larger stream. In
89 // that case we will have read out more bytes than we should return, because
90 // we should not read past the end of the current view.
91 uint64_t MaxLength
= getLength() - Offset
;
92 if (Buffer
.size() > MaxLength
)
93 Buffer
= Buffer
.slice(0, MaxLength
);
94 return Error::success();
97 WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream
&Stream
)
98 : BinaryStreamRefBase(Stream
) {}
100 WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream
&Stream
,
102 std::optional
<uint64_t> Length
)
103 : BinaryStreamRefBase(Stream
, Offset
, Length
) {}
105 WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef
<uint8_t> Data
,
107 : BinaryStreamRefBase(std::make_shared
<MutableArrayRefImpl
>(Data
, Endian
),
110 Error
WritableBinaryStreamRef::writeBytes(uint64_t Offset
,
111 ArrayRef
<uint8_t> Data
) const {
112 if (auto EC
= checkOffsetForWrite(Offset
, Data
.size()))
115 return BorrowedImpl
->writeBytes(ViewOffset
+ Offset
, Data
);
118 WritableBinaryStreamRef::operator BinaryStreamRef() const {
119 return BinaryStreamRef(*BorrowedImpl
, ViewOffset
, Length
);
122 /// For buffered streams, commits changes to the backing store.
123 Error
WritableBinaryStreamRef::commit() { return BorrowedImpl
->commit(); }