Line data Source code
1 : //===- BinaryStreamRef.cpp - ----------------------------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "llvm/Support/BinaryStreamRef.h"
11 : #include "llvm/Support/BinaryByteStream.h"
12 :
13 : using namespace llvm;
14 : using namespace llvm::support;
15 :
16 : namespace {
17 :
18 2210 : class ArrayRefImpl : public BinaryStream {
19 : public:
20 0 : ArrayRefImpl(ArrayRef<uint8_t> Data, endianness Endian) : BBS(Data, Endian) {}
21 :
22 1556 : llvm::support::endianness getEndian() const override {
23 1556 : return BBS.getEndian();
24 : }
25 22583 : Error readBytes(uint32_t Offset, uint32_t Size,
26 : ArrayRef<uint8_t> &Buffer) override {
27 22583 : return BBS.readBytes(Offset, Size, Buffer);
28 : }
29 713 : Error readLongestContiguousChunk(uint32_t Offset,
30 : ArrayRef<uint8_t> &Buffer) override {
31 713 : return BBS.readLongestContiguousChunk(Offset, Buffer);
32 : }
33 0 : uint32_t getLength() override { return BBS.getLength(); }
34 :
35 : private:
36 : BinaryByteStream BBS;
37 : };
38 :
39 3277 : class MutableArrayRefImpl : public WritableBinaryStream {
40 : public:
41 : MutableArrayRefImpl(MutableArrayRef<uint8_t> Data, endianness Endian)
42 0 : : BBS(Data, Endian) {}
43 :
44 : // Inherited via WritableBinaryStream
45 13579 : llvm::support::endianness getEndian() const override {
46 13579 : return BBS.getEndian();
47 : }
48 0 : Error readBytes(uint32_t Offset, uint32_t Size,
49 : ArrayRef<uint8_t> &Buffer) override {
50 0 : return BBS.readBytes(Offset, Size, Buffer);
51 : }
52 0 : Error readLongestContiguousChunk(uint32_t Offset,
53 : ArrayRef<uint8_t> &Buffer) override {
54 0 : return BBS.readLongestContiguousChunk(Offset, Buffer);
55 : }
56 0 : uint32_t getLength() override { return BBS.getLength(); }
57 :
58 22388 : Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override {
59 22388 : return BBS.writeBytes(Offset, Data);
60 : }
61 0 : Error commit() override { return BBS.commit(); }
62 :
63 : private:
64 : MutableBinaryByteStream BBS;
65 : };
66 : }
67 :
68 21545 : BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream)
69 21545 : : BinaryStreamRefBase(Stream) {}
70 1782 : BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream, uint32_t Offset,
71 : Optional<uint32_t> Length)
72 1782 : : BinaryStreamRefBase(Stream, Offset, Length) {}
73 2211 : BinaryStreamRef::BinaryStreamRef(ArrayRef<uint8_t> Data, endianness Endian)
74 2211 : : BinaryStreamRefBase(std::make_shared<ArrayRefImpl>(Data, Endian), 0,
75 4422 : Data.size()) {}
76 1386 : BinaryStreamRef::BinaryStreamRef(StringRef Data, endianness Endian)
77 : : BinaryStreamRef(makeArrayRef(Data.bytes_begin(), Data.bytes_end()),
78 1386 : Endian) {}
79 :
80 378104 : Error BinaryStreamRef::readBytes(uint32_t Offset, uint32_t Size,
81 : ArrayRef<uint8_t> &Buffer) const {
82 756208 : if (auto EC = checkOffsetForRead(Offset, Size))
83 : return EC;
84 378071 : return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer);
85 : }
86 :
87 26782 : Error BinaryStreamRef::readLongestContiguousChunk(
88 : uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
89 53564 : if (auto EC = checkOffsetForRead(Offset, 1))
90 : return EC;
91 :
92 26552 : if (auto EC =
93 26552 : BorrowedImpl->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
94 : return EC;
95 : // This StreamRef might refer to a smaller window over a larger stream. In
96 : // that case we will have read out more bytes than we should return, because
97 : // we should not read past the end of the current view.
98 26552 : uint32_t MaxLength = getLength() - Offset;
99 26552 : if (Buffer.size() > MaxLength)
100 4108 : Buffer = Buffer.slice(0, MaxLength);
101 : return Error::success();
102 : }
103 :
104 4517 : WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream)
105 4517 : : BinaryStreamRefBase(Stream) {}
106 :
107 0 : WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream,
108 : uint32_t Offset,
109 : Optional<uint32_t> Length)
110 0 : : BinaryStreamRefBase(Stream, Offset, Length) {}
111 :
112 3277 : WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
113 3277 : endianness Endian)
114 3277 : : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
115 6554 : 0, Data.size()) {}
116 :
117 :
118 97846 : Error WritableBinaryStreamRef::writeBytes(uint32_t Offset,
119 : ArrayRef<uint8_t> Data) const {
120 195692 : if (auto EC = checkOffsetForWrite(Offset, Data.size()))
121 : return EC;
122 :
123 97834 : return BorrowedImpl->writeBytes(ViewOffset + Offset, Data);
124 : }
125 :
126 1782 : WritableBinaryStreamRef::operator BinaryStreamRef() const {
127 1782 : return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length);
128 : }
129 :
130 : /// For buffered streams, commits changes to the backing store.
131 0 : Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); }
|