]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Support/BinaryStreamRef.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r305575, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Support / BinaryStreamRef.cpp
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 class ArrayRefImpl : public BinaryStream {
19 public:
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
35 private:
36   BinaryByteStream BBS;
37 };
38
39 class MutableArrayRefImpl : public WritableBinaryStream {
40 public:
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
63 private:
64   MutableBinaryByteStream BBS;
65 };
66 }
67
68 BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream)
69     : BinaryStreamRef(Stream, 0, Stream.getLength()) {}
70 BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream, uint32_t Offset,
71                                  uint32_t Length)
72     : BinaryStreamRefBase(Stream, Offset, Length) {}
73 BinaryStreamRef::BinaryStreamRef(ArrayRef<uint8_t> Data, endianness Endian)
74     : BinaryStreamRefBase(std::make_shared<ArrayRefImpl>(Data, Endian), 0,
75                           Data.size()) {}
76 BinaryStreamRef::BinaryStreamRef(StringRef Data, endianness Endian)
77     : BinaryStreamRef(makeArrayRef(Data.bytes_begin(), Data.bytes_end()),
78                       Endian) {}
79
80 BinaryStreamRef::BinaryStreamRef(const BinaryStreamRef &Other)
81     : BinaryStreamRefBase(Other) {}
82
83 Error BinaryStreamRef::readBytes(uint32_t Offset, uint32_t Size,
84                                  ArrayRef<uint8_t> &Buffer) const {
85   if (auto EC = checkOffset(Offset, Size))
86     return EC;
87   return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer);
88 }
89
90 Error BinaryStreamRef::readLongestContiguousChunk(
91     uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
92   if (auto EC = checkOffset(Offset, 1))
93     return EC;
94
95   if (auto EC =
96           BorrowedImpl->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
97     return EC;
98   // This StreamRef might refer to a smaller window over a larger stream.  In
99   // that case we will have read out more bytes than we should return, because
100   // we should not read past the end of the current view.
101   uint32_t MaxLength = Length - Offset;
102   if (Buffer.size() > MaxLength)
103     Buffer = Buffer.slice(0, MaxLength);
104   return Error::success();
105 }
106
107 WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream)
108     : WritableBinaryStreamRef(Stream, 0, Stream.getLength()) {}
109
110 WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream,
111                                                  uint32_t Offset,
112                                                  uint32_t Length)
113     : BinaryStreamRefBase(Stream, Offset, Length) {}
114
115 WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
116                                                  endianness Endian)
117     : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
118                           0, Data.size()) {}
119
120 WritableBinaryStreamRef::WritableBinaryStreamRef(
121     const WritableBinaryStreamRef &Other)
122     : BinaryStreamRefBase(Other) {}
123
124 Error WritableBinaryStreamRef::writeBytes(uint32_t Offset,
125                                           ArrayRef<uint8_t> Data) const {
126   if (auto EC = checkOffset(Offset, Data.size()))
127     return EC;
128
129   return BorrowedImpl->writeBytes(ViewOffset + Offset, Data);
130 }
131
132 WritableBinaryStreamRef::operator BinaryStreamRef() const {
133   return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length);
134 }
135
136 /// \brief For buffered streams, commits changes to the backing store.
137 Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); }