blob: 60a03fe9930f253077c839a623cb70c238ad2023 [file] [log] [blame]
Zachary Turnerd9a62632017-05-17 20:23:31 +00001//===- 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
13using namespace llvm;
14using namespace llvm::support;
15
16namespace {
17
18class ArrayRefImpl : public BinaryStream {
19public:
20 ArrayRefImpl(ArrayRef<uint8_t> Data, endianness Endian) : BBS(Data, Endian) {}
21
22 llvm::support::endianness getEndian() const override {
23 return BBS.getEndian();
24 }
25 Error readBytes(uint32_t Offset, uint32_t Size,
26 ArrayRef<uint8_t> &Buffer) override {
27 return BBS.readBytes(Offset, Size, Buffer);
28 }
29 Error readLongestContiguousChunk(uint32_t Offset,
30 ArrayRef<uint8_t> &Buffer) override {
31 return BBS.readLongestContiguousChunk(Offset, Buffer);
32 }
33 uint32_t getLength() override { return BBS.getLength(); }
34
35private:
36 BinaryByteStream BBS;
37};
38
39class MutableArrayRefImpl : public WritableBinaryStream {
40public:
41 MutableArrayRefImpl(MutableArrayRef<uint8_t> Data, endianness Endian)
42 : BBS(Data, Endian) {}
43
44 // Inherited via WritableBinaryStream
45 llvm::support::endianness getEndian() const override {
46 return BBS.getEndian();
47 }
48 Error readBytes(uint32_t Offset, uint32_t Size,
49 ArrayRef<uint8_t> &Buffer) override {
50 return BBS.readBytes(Offset, Size, Buffer);
51 }
52 Error readLongestContiguousChunk(uint32_t Offset,
53 ArrayRef<uint8_t> &Buffer) override {
54 return BBS.readLongestContiguousChunk(Offset, Buffer);
55 }
56 uint32_t getLength() override { return BBS.getLength(); }
57
58 Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override {
59 return BBS.writeBytes(Offset, Data);
60 }
61 Error commit() override { return BBS.commit(); }
62
63private:
64 MutableBinaryByteStream BBS;
65};
66}
67
68BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream)
Zachary Turner96c69852017-11-27 18:48:37 +000069 : BinaryStreamRefBase(Stream) {}
Zachary Turnerd9a62632017-05-17 20:23:31 +000070BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream, uint32_t Offset,
Zachary Turner96c69852017-11-27 18:48:37 +000071 Optional<uint32_t> Length)
Zachary Turnerd9a62632017-05-17 20:23:31 +000072 : BinaryStreamRefBase(Stream, Offset, Length) {}
73BinaryStreamRef::BinaryStreamRef(ArrayRef<uint8_t> Data, endianness Endian)
74 : BinaryStreamRefBase(std::make_shared<ArrayRefImpl>(Data, Endian), 0,
75 Data.size()) {}
76BinaryStreamRef::BinaryStreamRef(StringRef Data, endianness Endian)
77 : BinaryStreamRef(makeArrayRef(Data.bytes_begin(), Data.bytes_end()),
78 Endian) {}
79
Zachary Turnerd9a62632017-05-17 20:23:31 +000080Error BinaryStreamRef::readBytes(uint32_t Offset, uint32_t Size,
81 ArrayRef<uint8_t> &Buffer) const {
Zachary Turner96c69852017-11-27 18:48:37 +000082 if (auto EC = checkOffsetForRead(Offset, Size))
Zachary Turnerd9a62632017-05-17 20:23:31 +000083 return EC;
84 return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer);
85}
86
87Error BinaryStreamRef::readLongestContiguousChunk(
88 uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
Zachary Turner96c69852017-11-27 18:48:37 +000089 if (auto EC = checkOffsetForRead(Offset, 1))
Zachary Turnerd9a62632017-05-17 20:23:31 +000090 return EC;
91
92 if (auto EC =
93 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.
Zachary Turner96c69852017-11-27 18:48:37 +000098 uint32_t MaxLength = getLength() - Offset;
Zachary Turnerd9a62632017-05-17 20:23:31 +000099 if (Buffer.size() > MaxLength)
100 Buffer = Buffer.slice(0, MaxLength);
101 return Error::success();
102}
103
104WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream)
Zachary Turner96c69852017-11-27 18:48:37 +0000105 : BinaryStreamRefBase(Stream) {}
Zachary Turnerd9a62632017-05-17 20:23:31 +0000106
107WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream,
108 uint32_t Offset,
Zachary Turner96c69852017-11-27 18:48:37 +0000109 Optional<uint32_t> Length)
Zachary Turnerd9a62632017-05-17 20:23:31 +0000110 : BinaryStreamRefBase(Stream, Offset, Length) {}
111
112WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
113 endianness Endian)
114 : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
115 0, Data.size()) {}
116
Zachary Turnerd9a62632017-05-17 20:23:31 +0000117
118Error WritableBinaryStreamRef::writeBytes(uint32_t Offset,
119 ArrayRef<uint8_t> Data) const {
Zachary Turner96c69852017-11-27 18:48:37 +0000120 if (auto EC = checkOffsetForWrite(Offset, Data.size()))
Zachary Turnerd9a62632017-05-17 20:23:31 +0000121 return EC;
122
123 return BorrowedImpl->writeBytes(ViewOffset + Offset, Data);
124}
125
126WritableBinaryStreamRef::operator BinaryStreamRef() const {
127 return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length);
128}
129
130/// \brief For buffered streams, commits changes to the backing store.
131Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); }