LLVM  4.0.0
ByteStream.h
Go to the documentation of this file.
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"
17 #include "llvm/Support/Error.h"
20 #include <algorithm>
21 #include <cstdint>
22 #include <cstring>
23 #include <memory>
24 
25 namespace llvm {
26 namespace msf {
27 
28 class ByteStream : public ReadableStream {
29 public:
30  ByteStream() = default;
31  explicit ByteStream(ArrayRef<uint8_t> Data) : Data(Data) {}
33  : Data(Data.bytes_begin(), Data.bytes_end()) {}
34 
36  ArrayRef<uint8_t> &Buffer) const override {
37  if (Offset > Data.size())
38  return make_error<MSFError>(msf_error_code::insufficient_buffer);
39  if (Data.size() < Size + Offset)
40  return make_error<MSFError>(msf_error_code::insufficient_buffer);
41  Buffer = Data.slice(Offset, Size);
42  return Error::success();
43  }
44 
46  ArrayRef<uint8_t> &Buffer) const override {
47  if (Offset >= Data.size())
48  return make_error<MSFError>(msf_error_code::insufficient_buffer);
49  Buffer = Data.slice(Offset);
50  return Error::success();
51  }
52 
53  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:
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.
69 public:
70  explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer)
71  : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
72  Buffer->getBuffer().bytes_end())),
73  MemBuffer(std::move(Buffer)) {}
74 
75  std::unique_ptr<MemoryBuffer> MemBuffer;
76 };
77 
79 public:
80  MutableByteStream() = default;
82  : Data(Data), ImmutableStream(Data) {}
83 
85  ArrayRef<uint8_t> &Buffer) const override {
86  return ImmutableStream.readBytes(Offset, Size, Buffer);
87  }
88 
90  ArrayRef<uint8_t> &Buffer) const override {
91  return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
92  }
93 
94  uint32_t getLength() const override { return ImmutableStream.getLength(); }
95 
96  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override {
97  if (Buffer.empty())
98  return Error::success();
99 
100  if (Data.size() < Buffer.size())
101  return make_error<MSFError>(msf_error_code::insufficient_buffer);
102  if (Offset > Buffer.size() - Data.size())
103  return make_error<MSFError>(msf_error_code::insufficient_buffer);
104 
105  uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
106  ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
107  return Error::success();
108  }
109 
110  Error commit() const override { return Error::success(); }
111 
112  MutableArrayRef<uint8_t> data() const { return Data; }
113 
114 private:
116  ByteStream ImmutableStream;
117 };
118 
119 // A simple adapter that acts like a ByteStream but holds ownership over
120 // and underlying FileOutputBuffer.
122 private:
123  class StreamImpl : public MutableByteStream {
124  public:
125  StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer)
126  : MutableByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
127  Buffer->getBufferEnd())),
128  FileBuffer(std::move(Buffer)) {}
129 
130  Error commit() const override {
131  if (FileBuffer->commit())
132  return llvm::make_error<MSFError>(msf_error_code::not_writable);
133  return Error::success();
134  }
135 
136  private:
137  std::unique_ptr<FileOutputBuffer> FileBuffer;
138  };
139 
140 public:
141  explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer)
142  : Impl(std::move(Buffer)) {}
143 
145  ArrayRef<uint8_t> &Buffer) const override {
146  return Impl.readBytes(Offset, Size, Buffer);
147  }
148 
150  ArrayRef<uint8_t> &Buffer) const override {
151  return Impl.readLongestContiguousChunk(Offset, Buffer);
152  }
153 
154  uint32_t getLength() const override { return Impl.getLength(); }
155 
157  return Impl.writeBytes(Offset, Data);
158  }
159 
160  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
StringRef str() const
Definition: ByteStream.h:57
Error commit() const override
Definition: ByteStream.h:160
Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef< uint8_t > &Buffer) const override
Definition: ByteStream.h:35
Error readLongestContiguousChunk(uint32_t Offset, ArrayRef< uint8_t > &Buffer) const override
Definition: ByteStream.h:149
T * data() const
Definition: ArrayRef.h:322
ArrayRef< uint8_t > data() const
Definition: ByteStream.h:55
MemoryBufferByteStream(std::unique_ptr< MemoryBuffer > Buffer)
Definition: ByteStream.h:70
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
Definition: ArrayRef.h:171
uint32_t getLength() const override
Definition: ByteStream.h:154
ByteStream(ArrayRef< uint8_t > Data)
Definition: ByteStream.h:31
uint32_t getLength() const override
Definition: ByteStream.h:94
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
ByteStream(StringRef Data)
Definition: ByteStream.h:32
Error writeBytes(uint32_t Offset, ArrayRef< uint8_t > Buffer) const override
Definition: ByteStream.h:96
uint32_t Offset
MutableArrayRef< uint8_t > data() const
Definition: ByteStream.h:112
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:136
ArrayRef< uint8_t > Data
Definition: ByteStream.h:63
Error commit() const override
Definition: ByteStream.h:110
MutableByteStream(MutableArrayRef< uint8_t > Data)
Definition: ByteStream.h:81
Error readLongestContiguousChunk(uint32_t Offset, ArrayRef< uint8_t > &Buffer) const override
Definition: ByteStream.h:45
static ErrorSuccess success()
Create a success value.
Error readLongestContiguousChunk(uint32_t Offset, ArrayRef< uint8_t > &Buffer) const override
Definition: ByteStream.h:89
uint32_t getLength() const override
Definition: ByteStream.h:53
Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef< uint8_t > &Buffer) const override
Definition: ByteStream.h:84
FileBufferByteStream(std::unique_ptr< FileOutputBuffer > Buffer)
Definition: ByteStream.h:141
std::unique_ptr< MemoryBuffer > MemBuffer
Definition: ByteStream.h:75
Lightweight error class with error context and mandatory checking.
Error writeBytes(uint32_t Offset, ArrayRef< uint8_t > Data) const override
Definition: ByteStream.h:156
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
const T * data() const
Definition: ArrayRef.h:138
Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef< uint8_t > &Buffer) const override
Definition: ByteStream.h:144