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"
13 using namespace llvm::support
;
17 class ArrayRefImpl
: public BinaryStream
{
19 ArrayRefImpl(ArrayRef
<uint8_t> Data
, endianness Endian
) : BBS(Data
, Endian
) {}
21 llvm::support::endianness
getEndian() const override
{
22 return BBS
.getEndian();
24 Error
readBytes(uint32_t Offset
, uint32_t Size
,
25 ArrayRef
<uint8_t> &Buffer
) override
{
26 return BBS
.readBytes(Offset
, Size
, Buffer
);
28 Error
readLongestContiguousChunk(uint32_t Offset
,
29 ArrayRef
<uint8_t> &Buffer
) override
{
30 return BBS
.readLongestContiguousChunk(Offset
, Buffer
);
32 uint32_t getLength() override
{ return BBS
.getLength(); }
38 class MutableArrayRefImpl
: public WritableBinaryStream
{
40 MutableArrayRefImpl(MutableArrayRef
<uint8_t> Data
, endianness Endian
)
41 : BBS(Data
, Endian
) {}
43 // Inherited via WritableBinaryStream
44 llvm::support::endianness
getEndian() const override
{
45 return BBS
.getEndian();
47 Error
readBytes(uint32_t Offset
, uint32_t Size
,
48 ArrayRef
<uint8_t> &Buffer
) override
{
49 return BBS
.readBytes(Offset
, Size
, Buffer
);
51 Error
readLongestContiguousChunk(uint32_t Offset
,
52 ArrayRef
<uint8_t> &Buffer
) override
{
53 return BBS
.readLongestContiguousChunk(Offset
, Buffer
);
55 uint32_t getLength() override
{ return BBS
.getLength(); }
57 Error
writeBytes(uint32_t Offset
, ArrayRef
<uint8_t> Data
) override
{
58 return BBS
.writeBytes(Offset
, Data
);
60 Error
commit() override
{ return BBS
.commit(); }
63 MutableBinaryByteStream BBS
;
67 BinaryStreamRef::BinaryStreamRef(BinaryStream
&Stream
)
68 : BinaryStreamRefBase(Stream
) {}
69 BinaryStreamRef::BinaryStreamRef(BinaryStream
&Stream
, uint32_t Offset
,
70 Optional
<uint32_t> Length
)
71 : BinaryStreamRefBase(Stream
, Offset
, Length
) {}
72 BinaryStreamRef::BinaryStreamRef(ArrayRef
<uint8_t> Data
, endianness Endian
)
73 : BinaryStreamRefBase(std::make_shared
<ArrayRefImpl
>(Data
, Endian
), 0,
75 BinaryStreamRef::BinaryStreamRef(StringRef Data
, endianness Endian
)
76 : BinaryStreamRef(makeArrayRef(Data
.bytes_begin(), Data
.bytes_end()),
79 Error
BinaryStreamRef::readBytes(uint32_t Offset
, uint32_t Size
,
80 ArrayRef
<uint8_t> &Buffer
) const {
81 if (auto EC
= checkOffsetForRead(Offset
, Size
))
83 return BorrowedImpl
->readBytes(ViewOffset
+ Offset
, Size
, Buffer
);
86 Error
BinaryStreamRef::readLongestContiguousChunk(
87 uint32_t Offset
, ArrayRef
<uint8_t> &Buffer
) const {
88 if (auto EC
= checkOffsetForRead(Offset
, 1))
92 BorrowedImpl
->readLongestContiguousChunk(ViewOffset
+ Offset
, Buffer
))
94 // This StreamRef might refer to a smaller window over a larger stream. In
95 // that case we will have read out more bytes than we should return, because
96 // we should not read past the end of the current view.
97 uint32_t MaxLength
= getLength() - Offset
;
98 if (Buffer
.size() > MaxLength
)
99 Buffer
= Buffer
.slice(0, MaxLength
);
100 return Error::success();
103 WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream
&Stream
)
104 : BinaryStreamRefBase(Stream
) {}
106 WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream
&Stream
,
108 Optional
<uint32_t> Length
)
109 : BinaryStreamRefBase(Stream
, Offset
, Length
) {}
111 WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef
<uint8_t> Data
,
113 : BinaryStreamRefBase(std::make_shared
<MutableArrayRefImpl
>(Data
, Endian
),
117 Error
WritableBinaryStreamRef::writeBytes(uint32_t Offset
,
118 ArrayRef
<uint8_t> Data
) const {
119 if (auto EC
= checkOffsetForWrite(Offset
, Data
.size()))
122 return BorrowedImpl
->writeBytes(ViewOffset
+ Offset
, Data
);
125 WritableBinaryStreamRef::operator BinaryStreamRef() const {
126 return BinaryStreamRef(*BorrowedImpl
, ViewOffset
, Length
);
129 /// For buffered streams, commits changes to the backing store.
130 Error
WritableBinaryStreamRef::commit() { return BorrowedImpl
->commit(); }