mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
2c68c634a9
After several smaller patches to get most of the core improvements finished up, this patch is a straight move and header fixup of the source. Differential Revision: https://reviews.llvm.org/D30266 llvm-svn: 296810
193 lines
6.3 KiB
C++
193 lines
6.3 KiB
C++
//===- BinaryByteStream.h ---------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//===----------------------------------------------------------------------===//
|
|
// A BinaryStream which stores data in a single continguous memory buffer.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_SUPPORT_BINARYBYTESTREAM_H
|
|
#define LLVM_SUPPORT_BINARYBYTESTREAM_H
|
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/BinaryStream.h"
|
|
#include "llvm/Support/BinaryStreamError.h"
|
|
#include "llvm/Support/Error.h"
|
|
#include "llvm/Support/FileOutputBuffer.h"
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <memory>
|
|
|
|
namespace llvm {
|
|
|
|
/// \brief An implementation of BinaryStream which holds its entire data set
|
|
/// in a single contiguous buffer. BinaryByteStream guarantees that no read
|
|
/// operation will ever incur a copy. Note that BinaryByteStream does not
|
|
/// own the underlying buffer.
|
|
class BinaryByteStream : public BinaryStream {
|
|
public:
|
|
BinaryByteStream() = default;
|
|
BinaryByteStream(ArrayRef<uint8_t> Data, llvm::support::endianness Endian)
|
|
: Endian(Endian), Data(Data) {}
|
|
BinaryByteStream(StringRef Data, llvm::support::endianness Endian)
|
|
: Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
|
|
|
|
llvm::support::endianness getEndian() const override { return Endian; }
|
|
|
|
Error readBytes(uint32_t Offset, uint32_t Size,
|
|
ArrayRef<uint8_t> &Buffer) override {
|
|
if (auto EC = checkOffset(Offset, Size))
|
|
return EC;
|
|
Buffer = Data.slice(Offset, Size);
|
|
return Error::success();
|
|
}
|
|
|
|
Error readLongestContiguousChunk(uint32_t Offset,
|
|
ArrayRef<uint8_t> &Buffer) override {
|
|
if (auto EC = checkOffset(Offset, 1))
|
|
return EC;
|
|
Buffer = Data.slice(Offset);
|
|
return Error::success();
|
|
}
|
|
|
|
uint32_t getLength() override { return Data.size(); }
|
|
|
|
ArrayRef<uint8_t> data() const { return Data; }
|
|
|
|
StringRef str() const {
|
|
const char *CharData = reinterpret_cast<const char *>(Data.data());
|
|
return StringRef(CharData, Data.size());
|
|
}
|
|
|
|
protected:
|
|
llvm::support::endianness Endian;
|
|
ArrayRef<uint8_t> Data;
|
|
};
|
|
|
|
/// \brief An implementation of BinaryStream whose data is backed by an llvm
|
|
/// MemoryBuffer object. MemoryBufferByteStream owns the MemoryBuffer in
|
|
/// question. As with BinaryByteStream, reading from a MemoryBufferByteStream
|
|
/// will never cause a copy.
|
|
class MemoryBufferByteStream : public BinaryByteStream {
|
|
public:
|
|
MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer,
|
|
llvm::support::endianness Endian)
|
|
: BinaryByteStream(Buffer->getBuffer(), Endian),
|
|
MemBuffer(std::move(Buffer)) {}
|
|
|
|
std::unique_ptr<MemoryBuffer> MemBuffer;
|
|
};
|
|
|
|
/// \brief An implementation of BinaryStream which holds its entire data set
|
|
/// in a single contiguous buffer. As with BinaryByteStream, the mutable
|
|
/// version also guarantees that no read operation will ever incur a copy,
|
|
/// and similarly it does not own the underlying buffer.
|
|
class MutableBinaryByteStream : public WritableBinaryStream {
|
|
public:
|
|
MutableBinaryByteStream() = default;
|
|
MutableBinaryByteStream(MutableArrayRef<uint8_t> Data,
|
|
llvm::support::endianness Endian)
|
|
: Data(Data), ImmutableStream(Data, Endian) {}
|
|
|
|
llvm::support::endianness getEndian() const override {
|
|
return ImmutableStream.getEndian();
|
|
}
|
|
|
|
Error readBytes(uint32_t Offset, uint32_t Size,
|
|
ArrayRef<uint8_t> &Buffer) override {
|
|
return ImmutableStream.readBytes(Offset, Size, Buffer);
|
|
}
|
|
|
|
Error readLongestContiguousChunk(uint32_t Offset,
|
|
ArrayRef<uint8_t> &Buffer) override {
|
|
return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
|
|
}
|
|
|
|
uint32_t getLength() override { return ImmutableStream.getLength(); }
|
|
|
|
Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override {
|
|
if (Buffer.empty())
|
|
return Error::success();
|
|
|
|
if (auto EC = checkOffset(Offset, Buffer.size()))
|
|
return EC;
|
|
|
|
uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
|
|
::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
|
|
return Error::success();
|
|
}
|
|
|
|
Error commit() override { return Error::success(); }
|
|
|
|
MutableArrayRef<uint8_t> data() const { return Data; }
|
|
|
|
private:
|
|
MutableArrayRef<uint8_t> Data;
|
|
BinaryByteStream ImmutableStream;
|
|
};
|
|
|
|
/// \brief An implementation of WritableBinaryStream backed by an llvm
|
|
/// FileOutputBuffer.
|
|
class FileBufferByteStream : public WritableBinaryStream {
|
|
private:
|
|
class StreamImpl : public MutableBinaryByteStream {
|
|
public:
|
|
StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer,
|
|
llvm::support::endianness Endian)
|
|
: MutableBinaryByteStream(
|
|
MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
|
|
Buffer->getBufferEnd()),
|
|
Endian),
|
|
FileBuffer(std::move(Buffer)) {}
|
|
|
|
Error commit() override {
|
|
if (FileBuffer->commit())
|
|
return make_error<BinaryStreamError>(
|
|
stream_error_code::filesystem_error);
|
|
return Error::success();
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<FileOutputBuffer> FileBuffer;
|
|
};
|
|
|
|
public:
|
|
FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer,
|
|
llvm::support::endianness Endian)
|
|
: Impl(std::move(Buffer), Endian) {}
|
|
|
|
llvm::support::endianness getEndian() const override {
|
|
return Impl.getEndian();
|
|
}
|
|
|
|
Error readBytes(uint32_t Offset, uint32_t Size,
|
|
ArrayRef<uint8_t> &Buffer) override {
|
|
return Impl.readBytes(Offset, Size, Buffer);
|
|
}
|
|
|
|
Error readLongestContiguousChunk(uint32_t Offset,
|
|
ArrayRef<uint8_t> &Buffer) override {
|
|
return Impl.readLongestContiguousChunk(Offset, Buffer);
|
|
}
|
|
|
|
uint32_t getLength() override { return Impl.getLength(); }
|
|
|
|
Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) override {
|
|
return Impl.writeBytes(Offset, Data);
|
|
}
|
|
|
|
Error commit() override { return Impl.commit(); }
|
|
|
|
private:
|
|
StreamImpl Impl;
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_SUPPORT_BYTESTREAM_H
|