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 <cstdint>
21 : #include <memory>
22 : #include <type_traits>
23 :
24 : namespace llvm {
25 : namespace msf {
26 :
27 710 : class ByteStream : public ReadableStream {
28 : public:
29 0 : ByteStream() {}
30 710 : explicit ByteStream(ArrayRef<uint8_t> Data) : Data(Data) {}
31 :
32 35534 : Error readBytes(uint32_t Offset, uint32_t Size,
33 : ArrayRef<uint8_t> &Buffer) const override {
34 35534 : if (Offset > Data.size())
35 0 : return make_error<MsfError>(msf_error_code::insufficient_buffer);
36 35534 : if (Data.size() < Size + Offset)
37 0 : return make_error<MsfError>(msf_error_code::insufficient_buffer);
38 71068 : Buffer = Data.slice(Offset, Size);
39 : return Error::success();
40 : }
41 0 : Error readLongestContiguousChunk(uint32_t Offset,
42 : ArrayRef<uint8_t> &Buffer) const override {
43 0 : if (Offset >= Data.size())
44 0 : return make_error<MsfError>(msf_error_code::insufficient_buffer);
45 0 : Buffer = Data.slice(Offset);
46 : return Error::success();
47 : }
48 :
49 568 : uint32_t getLength() const override { return Data.size(); }
50 :
51 : ArrayRef<uint8_t> data() const { return Data; }
52 :
53 : StringRef str() const {
54 : const char *CharData = reinterpret_cast<const char *>(Data.data());
55 : return StringRef(CharData, Data.size());
56 : }
57 :
58 : protected:
59 : ArrayRef<uint8_t> Data;
60 : };
61 :
62 : // MemoryBufferByteStream behaves like a read-only ByteStream, but has its data
63 : // backed by an llvm::MemoryBuffer. It also owns the underlying MemoryBuffer.
64 27 : class MemoryBufferByteStream : public ByteStream {
65 : public:
66 : explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer)
67 18 : : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
68 18 : Buffer->getBuffer().bytes_end())),
69 36 : MemBuffer(std::move(Buffer)) {}
70 :
71 : std::unique_ptr<MemoryBuffer> MemBuffer;
72 : };
73 :
74 3 : class MutableByteStream : public WritableStream {
75 : public:
76 0 : MutableByteStream() {}
77 : explicit MutableByteStream(MutableArrayRef<uint8_t> Data)
78 3 : : Data(Data), ImmutableStream(Data) {}
79 :
80 0 : Error readBytes(uint32_t Offset, uint32_t Size,
81 : ArrayRef<uint8_t> &Buffer) const override {
82 0 : return ImmutableStream.readBytes(Offset, Size, Buffer);
83 : }
84 0 : Error readLongestContiguousChunk(uint32_t Offset,
85 : ArrayRef<uint8_t> &Buffer) const override {
86 0 : return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
87 : }
88 :
89 2 : uint32_t getLength() const override { return ImmutableStream.getLength(); }
90 :
91 40 : Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override {
92 40 : if (Data.size() < Buffer.size())
93 0 : return make_error<MsfError>(msf_error_code::insufficient_buffer);
94 40 : if (Offset > Buffer.size() - Data.size())
95 0 : return make_error<MsfError>(msf_error_code::insufficient_buffer);
96 :
97 80 : uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
98 40 : ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
99 : return Error::success();
100 : }
101 :
102 0 : Error commit() const override { return Error::success(); }
103 :
104 : MutableArrayRef<uint8_t> data() const { return Data; }
105 :
106 : private:
107 : MutableArrayRef<uint8_t> Data;
108 : ByteStream ImmutableStream;
109 : };
110 :
111 : // A simple adapter that acts like a ByteStream but holds ownership over
112 : // and underlying FileOutputBuffer.
113 3 : class FileBufferByteStream : public WritableStream {
114 : private:
115 2 : class StreamImpl : public MutableByteStream {
116 : public:
117 1 : StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer)
118 : : MutableByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
119 : Buffer->getBufferEnd())),
120 6 : FileBuffer(std::move(Buffer)) {}
121 :
122 1 : Error commit() const override {
123 2 : if (FileBuffer->commit())
124 0 : return llvm::make_error<MsfError>(msf_error_code::not_writable);
125 : return Error::success();
126 : }
127 :
128 : private:
129 : std::unique_ptr<FileOutputBuffer> FileBuffer;
130 : };
131 :
132 : public:
133 1 : explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer)
134 3 : : Impl(std::move(Buffer)) {}
135 :
136 0 : Error readBytes(uint32_t Offset, uint32_t Size,
137 : ArrayRef<uint8_t> &Buffer) const override {
138 0 : return Impl.readBytes(Offset, Size, Buffer);
139 : }
140 0 : Error readLongestContiguousChunk(uint32_t Offset,
141 : ArrayRef<uint8_t> &Buffer) const override {
142 0 : return Impl.readLongestContiguousChunk(Offset, Buffer);
143 : }
144 :
145 2 : uint32_t getLength() const override { return Impl.getLength(); }
146 :
147 40 : Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const override {
148 40 : return Impl.writeBytes(Offset, Data);
149 : }
150 1 : Error commit() const override { return Impl.commit(); }
151 :
152 : private:
153 : StreamImpl Impl;
154 : };
155 :
156 :
157 : } // end namespace msf
158 : } // end namespace llvm
159 :
160 : #endif // LLVM_DEBUGINFO_MSF_BYTESTREAM_H
|