mirror of
https://github.com/RPCS3/llvm.git
synced 2026-01-31 01:25:19 +01:00
The existing library assumed that a stream's length would never change. This makes some things simpler, but it's not flexible enough for what we need, especially for writable streams where what you really want is for each call to write to actually append. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319070 91177308-0d34-0410-b5e6-96231b3b80d8
103 lines
3.8 KiB
C++
103 lines
3.8 KiB
C++
//===- BinaryStream.h - Base interface for a stream of data -----*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_SUPPORT_BINARYSTREAM_H
|
|
#define LLVM_SUPPORT_BINARYSTREAM_H
|
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/BitmaskEnum.h"
|
|
#include "llvm/Support/BinaryStreamError.h"
|
|
#include "llvm/Support/Endian.h"
|
|
#include "llvm/Support/Error.h"
|
|
#include <cstdint>
|
|
|
|
namespace llvm {
|
|
|
|
enum BinaryStreamFlags {
|
|
BSF_None = 0,
|
|
BSF_Write = 1, // Stream supports writing.
|
|
BSF_Append = 2, // Writing can occur at offset == length.
|
|
LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ BSF_Append)
|
|
};
|
|
|
|
/// \brief An interface for accessing data in a stream-like format, but which
|
|
/// discourages copying. Instead of specifying a buffer in which to copy
|
|
/// data on a read, the API returns an ArrayRef to data owned by the stream's
|
|
/// implementation. Since implementations may not necessarily store data in a
|
|
/// single contiguous buffer (or even in memory at all), in such cases a it may
|
|
/// be necessary for an implementation to cache such a buffer so that it can
|
|
/// return it.
|
|
class BinaryStream {
|
|
public:
|
|
virtual ~BinaryStream() = default;
|
|
|
|
virtual llvm::support::endianness getEndian() const = 0;
|
|
|
|
/// \brief Given an offset into the stream and a number of bytes, attempt to
|
|
/// read the bytes and set the output ArrayRef to point to data owned by the
|
|
/// stream.
|
|
virtual Error readBytes(uint32_t Offset, uint32_t Size,
|
|
ArrayRef<uint8_t> &Buffer) = 0;
|
|
|
|
/// \brief Given an offset into the stream, read as much as possible without
|
|
/// copying any data.
|
|
virtual Error readLongestContiguousChunk(uint32_t Offset,
|
|
ArrayRef<uint8_t> &Buffer) = 0;
|
|
|
|
/// \brief Return the number of bytes of data in this stream.
|
|
virtual uint32_t getLength() = 0;
|
|
|
|
/// \brief Return the properties of this stream.
|
|
virtual BinaryStreamFlags getFlags() const { return BSF_None; }
|
|
|
|
protected:
|
|
Error checkOffsetForRead(uint32_t Offset, uint32_t DataSize) {
|
|
if (Offset > getLength())
|
|
return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
|
|
if (getLength() < DataSize + Offset)
|
|
return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
|
|
return Error::success();
|
|
}
|
|
};
|
|
|
|
/// \brief A BinaryStream which can be read from as well as written to. Note
|
|
/// that writing to a BinaryStream always necessitates copying from the input
|
|
/// buffer to the stream's backing store. Streams are assumed to be buffered
|
|
/// so that to be portable it is necessary to call commit() on the stream when
|
|
/// all data has been written.
|
|
class WritableBinaryStream : public BinaryStream {
|
|
public:
|
|
~WritableBinaryStream() override = default;
|
|
|
|
/// \brief Attempt to write the given bytes into the stream at the desired
|
|
/// offset. This will always necessitate a copy. Cannot shrink or grow the
|
|
/// stream, only writes into existing allocated space.
|
|
virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) = 0;
|
|
|
|
/// \brief For buffered streams, commits changes to the backing store.
|
|
virtual Error commit() = 0;
|
|
|
|
/// \brief Return the properties of this stream.
|
|
BinaryStreamFlags getFlags() const override { return BSF_Write; }
|
|
|
|
protected:
|
|
Error checkOffsetForWrite(uint32_t Offset, uint32_t DataSize) {
|
|
if (!(getFlags() & BSF_Append))
|
|
return checkOffsetForRead(Offset, DataSize);
|
|
|
|
if (Offset > getLength())
|
|
return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
|
|
return Error::success();
|
|
}
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_SUPPORT_BINARYSTREAM_H
|