Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/Support/BinaryByteStream.h
Line
Count
Source (jump to first uncovered line)
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
433
  BinaryByteStream() = default;
35
  BinaryByteStream(ArrayRef<uint8_t> Data, llvm::support::endianness Endian)
36
15.6k
      : Endian(Endian), Data(Data) {}
37
  BinaryByteStream(StringRef Data, llvm::support::endianness Endian)
38
117
      : Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
39
40
80.9k
  llvm::support::endianness getEndian() const override { return Endian; }
41
42
  Error readBytes(uint32_t Offset, uint32_t Size,
43
114k
                  ArrayRef<uint8_t> &Buffer) override {
44
114k
    if (auto EC = checkOffset(Offset, Size))
45
3
      return EC;
46
114k
    Buffer = Data.slice(Offset, Size);
47
114k
    return Error::success();
48
114k
  }
49
50
  Error readLongestContiguousChunk(uint32_t Offset,
51
12.6k
                                   ArrayRef<uint8_t> &Buffer) override {
52
12.6k
    if (auto EC = checkOffset(Offset, 1))
53
0
      return EC;
54
12.6k
    Buffer = Data.slice(Offset);
55
12.6k
    return Error::success();
56
12.6k
  }
57
58
387k
  uint32_t getLength() override { return Data.size(); }
59
60
0
  ArrayRef<uint8_t> data() const { return Data; }
61
62
0
  StringRef str() const {
63
0
    const char *CharData = reinterpret_cast<const char *>(Data.data());
64
0
    return StringRef(CharData, Data.size());
65
0
  }
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
0
        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
5.94k
      : Data(Data), ImmutableStream(Data, Endian) {}
96
97
31.6k
  llvm::support::endianness getEndian() const override {
98
31.6k
    return ImmutableStream.getEndian();
99
31.6k
  }
100
101
  Error readBytes(uint32_t Offset, uint32_t Size,
102
57
                  ArrayRef<uint8_t> &Buffer) override {
103
57
    return ImmutableStream.readBytes(Offset, Size, Buffer);
104
57
  }
105
106
  Error readLongestContiguousChunk(uint32_t Offset,
107
58
                                   ArrayRef<uint8_t> &Buffer) override {
108
58
    return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
109
58
  }
110
111
121k
  uint32_t getLength() override { return ImmutableStream.getLength(); }
112
113
57.7k
  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override {
114
57.7k
    if (Buffer.empty())
115
62
      return Error::success();
116
57.7k
117
57.6k
    
if (auto 57.6k
EC57.6k
= checkOffset(Offset, Buffer.size()))
118
3
      return EC;
119
57.6k
120
57.6k
    uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
121
57.6k
    ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
122
57.6k
    return Error::success();
123
57.7k
  }
124
125
0
  Error commit() override { return Error::success(); }
126
127
4
  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
0
          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
0
      : Impl(std::move(Buffer), Endian) {}
163
164
0
  llvm::support::endianness getEndian() const override {
165
0
    return Impl.getEndian();
166
0
  }
167
168
  Error readBytes(uint32_t Offset, uint32_t Size,
169
0
                  ArrayRef<uint8_t> &Buffer) override {
170
0
    return Impl.readBytes(Offset, Size, Buffer);
171
0
  }
172
173
  Error readLongestContiguousChunk(uint32_t Offset,
174
0
                                   ArrayRef<uint8_t> &Buffer) override {
175
0
    return Impl.readLongestContiguousChunk(Offset, Buffer);
176
0
  }
177
178
0
  uint32_t getLength() override { return Impl.getLength(); }
179
180
0
  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override {
181
0
    return Impl.writeBytes(Offset, Data);
182
0
  }
183
184
0
  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