File indexing completed on 2026-05-10 08:44:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef LLVM_SUPPORT_BINARYBYTESTREAM_H
0011 #define LLVM_SUPPORT_BINARYBYTESTREAM_H
0012
0013 #include "llvm/ADT/ArrayRef.h"
0014 #include "llvm/ADT/StringRef.h"
0015 #include "llvm/Support/BinaryStream.h"
0016 #include "llvm/Support/BinaryStreamError.h"
0017 #include "llvm/Support/Error.h"
0018 #include "llvm/Support/FileOutputBuffer.h"
0019 #include "llvm/Support/MemoryBuffer.h"
0020 #include <cstdint>
0021 #include <cstring>
0022 #include <memory>
0023
0024 namespace llvm {
0025
0026
0027
0028
0029
0030 class BinaryByteStream : public BinaryStream {
0031 public:
0032 BinaryByteStream() = default;
0033 BinaryByteStream(ArrayRef<uint8_t> Data, llvm::endianness Endian)
0034 : Endian(Endian), Data(Data) {}
0035 BinaryByteStream(StringRef Data, llvm::endianness Endian)
0036 : Endian(Endian), Data(Data.bytes_begin(), Data.bytes_end()) {}
0037
0038 llvm::endianness getEndian() const override { return Endian; }
0039
0040 Error readBytes(uint64_t Offset, uint64_t Size,
0041 ArrayRef<uint8_t> &Buffer) override {
0042 if (auto EC = checkOffsetForRead(Offset, Size))
0043 return EC;
0044 Buffer = Data.slice(Offset, Size);
0045 return Error::success();
0046 }
0047
0048 Error readLongestContiguousChunk(uint64_t Offset,
0049 ArrayRef<uint8_t> &Buffer) override {
0050 if (auto EC = checkOffsetForRead(Offset, 1))
0051 return EC;
0052 Buffer = Data.slice(Offset);
0053 return Error::success();
0054 }
0055
0056 uint64_t getLength() override { return Data.size(); }
0057
0058 ArrayRef<uint8_t> data() const { return Data; }
0059
0060 StringRef str() const {
0061 const char *CharData = reinterpret_cast<const char *>(Data.data());
0062 return StringRef(CharData, Data.size());
0063 }
0064
0065 protected:
0066 llvm::endianness Endian;
0067 ArrayRef<uint8_t> Data;
0068 };
0069
0070
0071
0072
0073
0074 class MemoryBufferByteStream : public BinaryByteStream {
0075 public:
0076 MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer,
0077 llvm::endianness Endian)
0078 : BinaryByteStream(Buffer->getBuffer(), Endian),
0079 MemBuffer(std::move(Buffer)) {}
0080
0081 std::unique_ptr<MemoryBuffer> MemBuffer;
0082 };
0083
0084
0085
0086
0087
0088 class MutableBinaryByteStream : public WritableBinaryStream {
0089 public:
0090 MutableBinaryByteStream() = default;
0091 MutableBinaryByteStream(MutableArrayRef<uint8_t> Data,
0092 llvm::endianness Endian)
0093 : Data(Data), ImmutableStream(Data, Endian) {}
0094
0095 llvm::endianness getEndian() const override {
0096 return ImmutableStream.getEndian();
0097 }
0098
0099 Error readBytes(uint64_t Offset, uint64_t Size,
0100 ArrayRef<uint8_t> &Buffer) override {
0101 return ImmutableStream.readBytes(Offset, Size, Buffer);
0102 }
0103
0104 Error readLongestContiguousChunk(uint64_t Offset,
0105 ArrayRef<uint8_t> &Buffer) override {
0106 return ImmutableStream.readLongestContiguousChunk(Offset, Buffer);
0107 }
0108
0109 uint64_t getLength() override { return ImmutableStream.getLength(); }
0110
0111 Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Buffer) override {
0112 if (Buffer.empty())
0113 return Error::success();
0114
0115 if (auto EC = checkOffsetForWrite(Offset, Buffer.size()))
0116 return EC;
0117
0118 uint8_t *DataPtr = const_cast<uint8_t *>(Data.data());
0119 ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size());
0120 return Error::success();
0121 }
0122
0123 Error commit() override { return Error::success(); }
0124
0125 MutableArrayRef<uint8_t> data() const { return Data; }
0126
0127 private:
0128 MutableArrayRef<uint8_t> Data;
0129 BinaryByteStream ImmutableStream;
0130 };
0131
0132
0133
0134 class AppendingBinaryByteStream : public WritableBinaryStream {
0135 std::vector<uint8_t> Data;
0136 llvm::endianness Endian = llvm::endianness::little;
0137
0138 public:
0139 AppendingBinaryByteStream() = default;
0140 AppendingBinaryByteStream(llvm::endianness Endian) : Endian(Endian) {}
0141
0142 void clear() { Data.clear(); }
0143
0144 llvm::endianness getEndian() const override { return Endian; }
0145
0146 Error readBytes(uint64_t Offset, uint64_t Size,
0147 ArrayRef<uint8_t> &Buffer) override {
0148 if (auto EC = checkOffsetForWrite(Offset, Buffer.size()))
0149 return EC;
0150
0151 Buffer = ArrayRef(Data).slice(Offset, Size);
0152 return Error::success();
0153 }
0154
0155 void insert(uint64_t Offset, ArrayRef<uint8_t> Bytes) {
0156 Data.insert(Data.begin() + Offset, Bytes.begin(), Bytes.end());
0157 }
0158
0159 Error readLongestContiguousChunk(uint64_t Offset,
0160 ArrayRef<uint8_t> &Buffer) override {
0161 if (auto EC = checkOffsetForWrite(Offset, 1))
0162 return EC;
0163
0164 Buffer = ArrayRef(Data).slice(Offset);
0165 return Error::success();
0166 }
0167
0168 uint64_t getLength() override { return Data.size(); }
0169
0170 Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Buffer) override {
0171 if (Buffer.empty())
0172 return Error::success();
0173
0174
0175
0176
0177
0178
0179
0180 if (Offset > getLength())
0181 return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
0182
0183 uint64_t RequiredSize = Offset + Buffer.size();
0184 if (RequiredSize > Data.size())
0185 Data.resize(RequiredSize);
0186
0187 ::memcpy(Data.data() + Offset, Buffer.data(), Buffer.size());
0188 return Error::success();
0189 }
0190
0191 Error commit() override { return Error::success(); }
0192
0193
0194 BinaryStreamFlags getFlags() const override { return BSF_Write | BSF_Append; }
0195
0196 MutableArrayRef<uint8_t> data() { return Data; }
0197 };
0198
0199
0200
0201 class FileBufferByteStream : public WritableBinaryStream {
0202 private:
0203 class StreamImpl : public MutableBinaryByteStream {
0204 public:
0205 StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer,
0206 llvm::endianness Endian)
0207 : MutableBinaryByteStream(
0208 MutableArrayRef<uint8_t>(Buffer->getBufferStart(),
0209 Buffer->getBufferEnd()),
0210 Endian),
0211 FileBuffer(std::move(Buffer)) {}
0212
0213 Error commit() override {
0214 if (FileBuffer->commit())
0215 return make_error<BinaryStreamError>(
0216 stream_error_code::filesystem_error);
0217 return Error::success();
0218 }
0219
0220
0221 uint8_t *getBufferStart() const { return FileBuffer->getBufferStart(); }
0222
0223
0224 uint8_t *getBufferEnd() const { return FileBuffer->getBufferEnd(); }
0225
0226 private:
0227 std::unique_ptr<FileOutputBuffer> FileBuffer;
0228 };
0229
0230 public:
0231 FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer,
0232 llvm::endianness Endian)
0233 : Impl(std::move(Buffer), Endian) {}
0234
0235 llvm::endianness getEndian() const override { return Impl.getEndian(); }
0236
0237 Error readBytes(uint64_t Offset, uint64_t Size,
0238 ArrayRef<uint8_t> &Buffer) override {
0239 return Impl.readBytes(Offset, Size, Buffer);
0240 }
0241
0242 Error readLongestContiguousChunk(uint64_t Offset,
0243 ArrayRef<uint8_t> &Buffer) override {
0244 return Impl.readLongestContiguousChunk(Offset, Buffer);
0245 }
0246
0247 uint64_t getLength() override { return Impl.getLength(); }
0248
0249 Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Data) override {
0250 return Impl.writeBytes(Offset, Data);
0251 }
0252
0253 Error commit() override { return Impl.commit(); }
0254
0255
0256 uint8_t *getBufferStart() const { return Impl.getBufferStart(); }
0257
0258
0259 uint8_t *getBufferEnd() const { return Impl.getBufferEnd(); }
0260
0261 private:
0262 StreamImpl Impl;
0263 };
0264
0265 }
0266
0267 #endif