]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Support/BinaryByteStream.h
Import tzdata 2017c
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / Support / BinaryByteStream.h
1 //===- BinaryByteStream.h ---------------------------------------*- C++ -*-===//
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 // A BinaryStream which stores data in a single continguous memory buffer.
9 //===----------------------------------------------------------------------===//
10
11 #ifndef LLVM_SUPPORT_BINARYBYTESTREAM_H
12 #define LLVM_SUPPORT_BINARYBYTESTREAM_H
13
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/BinaryStream.h"
17 #include "llvm/Support/BinaryStreamError.h"
18 #include "llvm/Support/Error.h"
19 #include "llvm/Support/FileOutputBuffer.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include <algorithm>
22 #include <cstdint>
23 #include <cstring>
24 #include <memory>
25
26 namespace llvm {
27
28 /// \brief An implementation of BinaryStream which holds its entire data set
29 /// in a single contiguous buffer.  BinaryByteStream guarantees that no read
30 /// operation will ever incur a copy.  Note that BinaryByteStream does not
31 /// own the underlying buffer.
32 class BinaryByteStream : public BinaryStream {
33 public:
34   BinaryByteStream() = default;
35   BinaryByteStream(ArrayRef<uint8_t> Data, llvm::support::endianness Endian)
36       : Endian(Endian), Data(Data) {}
37   BinaryByteStream(StringRef Data, llvm::support::endianness Endian)
38       : Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
39
40   llvm::support::endianness getEndian() const override { return Endian; }
41
42   Error readBytes(uint32_t Offset, uint32_t Size,
43                   ArrayRef<uint8_t> &Buffer) override {
44     if (auto EC = checkOffset(Offset, Size))
45       return EC;
46     Buffer = Data.slice(Offset, Size);
47     return Error::success();
48   }
49
50   Error readLongestContiguousChunk(uint32_t Offset,
51                                    ArrayRef<uint8_t> &Buffer) override {
52     if (auto EC = checkOffset(Offset, 1))
53       return EC;
54     Buffer = Data.slice(Offset);
55     return Error::success();
56   }
57
58   uint32_t getLength() override { return Data.size(); }
59
60   ArrayRef<uint8_t> data() const { return Data; }
61
62   StringRef str() const {
63     const char *CharData = reinterpret_cast<const char *>(Data.data());
64     return StringRef(CharData, Data.size());
65   }
66
67 protected:
68   llvm::support::endianness Endian;
69   ArrayRef<uint8_t> Data;
70 };
71
72 /// \brief An implementation of BinaryStream whose data is backed by an llvm
73 /// MemoryBuffer object.  MemoryBufferByteStream owns the MemoryBuffer in
74 /// question.  As with BinaryByteStream, reading from a MemoryBufferByteStream
75 /// will never cause a copy.
76 class MemoryBufferByteStream : public BinaryByteStream {
77 public:
78   MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer,
79                          llvm::support::endianness Endian)
80       : BinaryByteStream(Buffer->getBuffer(), Endian),
81         MemBuffer(std::move(Buffer)) {}
82
83   std::unique_ptr<MemoryBuffer> MemBuffer;
84 };
85
86 /// \brief An implementation of BinaryStream which holds its entire data set
87 /// in a single contiguous buffer.  As with BinaryByteStream, the mutable
88 /// version also guarantees that no read operation will ever incur a copy,
89 /// and similarly it does not own the underlying buffer.
90 class MutableBinaryByteStream : public WritableBinaryStream {
91 public:
92   MutableBinaryByteStream() = default;
93   MutableBinaryByteStream(MutableArrayRef<uint8_t> Data,
94                           llvm::support::endianness Endian)
95       : Data(Data), ImmutableStream(Data, Endian) {}
96
97   llvm::support::endianness getEndian() const override {
98     return ImmutableStream.getEndian();
99   }
100
101   Error readBytes(uint32_t Offset, uint32_t Size,
102                   ArrayRef<uint8_t> &Buffer) override {
103     return ImmutableStream.readBytes(Offset, Size, Buffer);
104   }
105
106   Error readLongestContiguousChunk(uint32_t Offset,
107                                    ArrayRef<uint8_t> &Buffer) override {
108     return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
109   }
110
111   uint32_t getLength() override { return ImmutableStream.getLength(); }
112
113   Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override {
114     if (Buffer.empty())
115       return Error::success();
116
117     if (auto EC = checkOffset(Offset, Buffer.size()))
118       return EC;
119
120     uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
121     ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
122     return Error::success();
123   }
124
125   Error commit() override { return Error::success(); }
126
127   MutableArrayRef<uint8_t> data() const { return Data; }
128
129 private:
130   MutableArrayRef<uint8_t> Data;
131   BinaryByteStream ImmutableStream;
132 };
133
134 /// \brief An implementation of WritableBinaryStream backed by an llvm
135 /// FileOutputBuffer.
136 class FileBufferByteStream : public WritableBinaryStream {
137 private:
138   class StreamImpl : public MutableBinaryByteStream {
139   public:
140     StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer,
141                llvm::support::endianness Endian)
142         : MutableBinaryByteStream(
143               MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
144                                        Buffer->getBufferEnd()),
145               Endian),
146           FileBuffer(std::move(Buffer)) {}
147
148     Error commit() override {
149       if (FileBuffer->commit())
150         return make_error<BinaryStreamError>(
151             stream_error_code::filesystem_error);
152       return Error::success();
153     }
154
155   private:
156     std::unique_ptr<FileOutputBuffer> FileBuffer;
157   };
158
159 public:
160   FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer,
161                        llvm::support::endianness Endian)
162       : Impl(std::move(Buffer), Endian) {}
163
164   llvm::support::endianness getEndian() const override {
165     return Impl.getEndian();
166   }
167
168   Error readBytes(uint32_t Offset, uint32_t Size,
169                   ArrayRef<uint8_t> &Buffer) override {
170     return Impl.readBytes(Offset, Size, Buffer);
171   }
172
173   Error readLongestContiguousChunk(uint32_t Offset,
174                                    ArrayRef<uint8_t> &Buffer) override {
175     return Impl.readLongestContiguousChunk(Offset, Buffer);
176   }
177
178   uint32_t getLength() override { return Impl.getLength(); }
179
180   Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override {
181     return Impl.writeBytes(Offset, Data);
182   }
183
184   Error commit() override { return Impl.commit(); }
185
186 private:
187   StreamImpl Impl;
188 };
189
190 } // end namespace llvm
191
192 #endif // LLVM_SUPPORT_BYTESTREAM_H