Line data Source code
1 : //===- ByteStream.h - Reads stream data from a byte sequence ----*- 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 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_DEBUGINFO_MSF_BYTESTREAM_H
11 : #define LLVM_DEBUGINFO_MSF_BYTESTREAM_H
12 :
13 : #include "llvm/ADT/ArrayRef.h"
14 : #include "llvm/ADT/StringRef.h"
15 : #include "llvm/DebugInfo/MSF/MSFError.h"
16 : #include "llvm/DebugInfo/MSF/StreamInterface.h"
17 : #include "llvm/Support/Error.h"
18 : #include "llvm/Support/FileOutputBuffer.h"
19 : #include "llvm/Support/MemoryBuffer.h"
20 : #include <algorithm>
21 : #include <cstdint>
22 : #include <cstring>
23 : #include <memory>
24 :
25 : namespace llvm {
26 : namespace msf {
27 :
28 10958 : class ByteStream : public ReadableStream {
29 : public:
30 20 : ByteStream() = default;
31 10847 : explicit ByteStream(ArrayRef<uint8_t> Data) : Data(Data) {}
32 : explicit ByteStream(StringRef Data)
33 368 : : Data(Data.bytes_begin(), Data.bytes_end()) {}
34 :
35 776685 : Error readBytes(uint32_t Offset, uint32_t Size,
36 : ArrayRef<uint8_t> &Buffer) const override {
37 776685 : if (Offset > Data.size())
38 0 : return make_error<MSFError>(msf_error_code::insufficient_buffer);
39 776685 : if (Data.size() < Size + Offset)
40 0 : return make_error<MSFError>(msf_error_code::insufficient_buffer);
41 1553370 : Buffer = Data.slice(Offset, Size);
42 2330055 : return Error::success();
43 : }
44 :
45 673 : Error readLongestContiguousChunk(uint32_t Offset,
46 : ArrayRef<uint8_t> &Buffer) const override {
47 684 : if (Offset >= Data.size())
48 0 : return make_error<MSFError>(msf_error_code::insufficient_buffer);
49 1368 : Buffer = Data.slice(Offset);
50 2052 : return Error::success();
51 : }
52 :
53 11326 : uint32_t getLength() const override { return Data.size(); }
54 :
55 : ArrayRef<uint8_t> data() const { return Data; }
56 :
57 : StringRef str() const {
58 : const char *CharData = reinterpret_cast<const char *>(Data.data());
59 : return StringRef(CharData, Data.size());
60 : }
61 :
62 : protected:
63 : ArrayRef<uint8_t> Data;
64 : };
65 :
66 : // MemoryBufferByteStream behaves like a read-only ByteStream, but has its data
67 : // backed by an llvm::MemoryBuffer. It also owns the underlying MemoryBuffer.
68 57 : class MemoryBufferByteStream : public ByteStream {
69 : public:
70 : explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer)
71 60 : : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
72 40 : Buffer->getBuffer().bytes_end())),
73 80 : MemBuffer(std::move(Buffer)) {}
74 :
75 : std::unique_ptr<MemoryBuffer> MemBuffer;
76 : };
77 :
78 7698 : class MutableByteStream : public WritableStream {
79 : public:
80 40 : MutableByteStream() = default;
81 : explicit MutableByteStream(MutableArrayRef<uint8_t> Data)
82 7638 : : Data(Data), ImmutableStream(Data) {}
83 :
84 23 : Error readBytes(uint32_t Offset, uint32_t Size,
85 : ArrayRef<uint8_t> &Buffer) const override {
86 23 : return ImmutableStream.readBytes(Offset, Size, Buffer);
87 : }
88 :
89 11 : Error readLongestContiguousChunk(uint32_t Offset,
90 : ArrayRef<uint8_t> &Buffer) const override {
91 22 : return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
92 : }
93 :
94 5146 : uint32_t getLength() const override { return ImmutableStream.getLength(); }
95 :
96 41906 : Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override {
97 41906 : if (Buffer.empty())
98 159 : return Error::success();
99 :
100 41853 : if (Data.size() < Buffer.size())
101 0 : return make_error<MSFError>(msf_error_code::insufficient_buffer);
102 41853 : if (Offset > Buffer.size() - Data.size())
103 0 : return make_error<MSFError>(msf_error_code::insufficient_buffer);
104 :
105 83706 : uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
106 41853 : ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
107 125559 : return Error::success();
108 : }
109 :
110 0 : Error commit() const override { return Error::success(); }
111 :
112 : MutableArrayRef<uint8_t> data() const { return Data; }
113 :
114 : private:
115 : MutableArrayRef<uint8_t> Data;
116 : ByteStream ImmutableStream;
117 : };
118 :
119 : // A simple adapter that acts like a ByteStream but holds ownership over
120 : // and underlying FileOutputBuffer.
121 18 : class FileBufferByteStream : public WritableStream {
122 : private:
123 12 : class StreamImpl : public MutableByteStream {
124 : public:
125 6 : StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer)
126 6 : : MutableByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
127 : Buffer->getBufferEnd())),
128 36 : FileBuffer(std::move(Buffer)) {}
129 :
130 6 : Error commit() const override {
131 12 : if (FileBuffer->commit())
132 0 : return llvm::make_error<MSFError>(msf_error_code::not_writable);
133 18 : return Error::success();
134 : }
135 :
136 : private:
137 : std::unique_ptr<FileOutputBuffer> FileBuffer;
138 : };
139 :
140 : public:
141 6 : explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer)
142 18 : : Impl(std::move(Buffer)) {}
143 :
144 0 : Error readBytes(uint32_t Offset, uint32_t Size,
145 : ArrayRef<uint8_t> &Buffer) const override {
146 0 : return Impl.readBytes(Offset, Size, Buffer);
147 : }
148 :
149 0 : Error readLongestContiguousChunk(uint32_t Offset,
150 : ArrayRef<uint8_t> &Buffer) const override {
151 0 : return Impl.readLongestContiguousChunk(Offset, Buffer);
152 : }
153 :
154 12 : uint32_t getLength() const override { return Impl.getLength(); }
155 :
156 502 : Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const override {
157 502 : return Impl.writeBytes(Offset, Data);
158 : }
159 :
160 6 : Error commit() const override { return Impl.commit(); }
161 :
162 : private:
163 : StreamImpl Impl;
164 : };
165 :
166 : } // end namespace msf
167 : } // end namespace llvm
168 :
169 : #endif // LLVM_DEBUGINFO_MSF_BYTESTREAM_H
|