BinaryStreamRef.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. //===- BinaryStreamRef.cpp - ----------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/Support/BinaryStreamRef.h"
  9. #include "llvm/Support/BinaryByteStream.h"
  10. using namespace llvm;
  11. using namespace llvm::support;
  12. namespace {
  13. class ArrayRefImpl : public BinaryStream {
  14. public:
  15. ArrayRefImpl(ArrayRef<uint8_t> Data, endianness Endian) : BBS(Data, Endian) {}
  16. llvm::support::endianness getEndian() const override {
  17. return BBS.getEndian();
  18. }
  19. Error readBytes(uint64_t Offset, uint64_t Size,
  20. ArrayRef<uint8_t> &Buffer) override {
  21. return BBS.readBytes(Offset, Size, Buffer);
  22. }
  23. Error readLongestContiguousChunk(uint64_t Offset,
  24. ArrayRef<uint8_t> &Buffer) override {
  25. return BBS.readLongestContiguousChunk(Offset, Buffer);
  26. }
  27. uint64_t getLength() override { return BBS.getLength(); }
  28. private:
  29. BinaryByteStream BBS;
  30. };
  31. class MutableArrayRefImpl : public WritableBinaryStream {
  32. public:
  33. MutableArrayRefImpl(MutableArrayRef<uint8_t> Data, endianness Endian)
  34. : BBS(Data, Endian) {}
  35. // Inherited via WritableBinaryStream
  36. llvm::support::endianness getEndian() const override {
  37. return BBS.getEndian();
  38. }
  39. Error readBytes(uint64_t Offset, uint64_t Size,
  40. ArrayRef<uint8_t> &Buffer) override {
  41. return BBS.readBytes(Offset, Size, Buffer);
  42. }
  43. Error readLongestContiguousChunk(uint64_t Offset,
  44. ArrayRef<uint8_t> &Buffer) override {
  45. return BBS.readLongestContiguousChunk(Offset, Buffer);
  46. }
  47. uint64_t getLength() override { return BBS.getLength(); }
  48. Error writeBytes(uint64_t Offset, ArrayRef<uint8_t> Data) override {
  49. return BBS.writeBytes(Offset, Data);
  50. }
  51. Error commit() override { return BBS.commit(); }
  52. private:
  53. MutableBinaryByteStream BBS;
  54. };
  55. } // namespace
  56. BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream)
  57. : BinaryStreamRefBase(Stream) {}
  58. BinaryStreamRef::BinaryStreamRef(BinaryStream &Stream, uint64_t Offset,
  59. std::optional<uint64_t> Length)
  60. : BinaryStreamRefBase(Stream, Offset, Length) {}
  61. BinaryStreamRef::BinaryStreamRef(ArrayRef<uint8_t> Data, endianness Endian)
  62. : BinaryStreamRefBase(std::make_shared<ArrayRefImpl>(Data, Endian), 0,
  63. Data.size()) {}
  64. BinaryStreamRef::BinaryStreamRef(StringRef Data, endianness Endian)
  65. : BinaryStreamRef(ArrayRef(Data.bytes_begin(), Data.bytes_end()), Endian) {}
  66. Error BinaryStreamRef::readBytes(uint64_t Offset, uint64_t Size,
  67. ArrayRef<uint8_t> &Buffer) const {
  68. if (auto EC = checkOffsetForRead(Offset, Size))
  69. return EC;
  70. return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer);
  71. }
  72. Error BinaryStreamRef::readLongestContiguousChunk(
  73. uint64_t Offset, ArrayRef<uint8_t> &Buffer) const {
  74. if (auto EC = checkOffsetForRead(Offset, 1))
  75. return EC;
  76. if (auto EC =
  77. BorrowedImpl->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
  78. return EC;
  79. // This StreamRef might refer to a smaller window over a larger stream. In
  80. // that case we will have read out more bytes than we should return, because
  81. // we should not read past the end of the current view.
  82. uint64_t MaxLength = getLength() - Offset;
  83. if (Buffer.size() > MaxLength)
  84. Buffer = Buffer.slice(0, MaxLength);
  85. return Error::success();
  86. }
  87. WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream)
  88. : BinaryStreamRefBase(Stream) {}
  89. WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream,
  90. uint64_t Offset,
  91. std::optional<uint64_t> Length)
  92. : BinaryStreamRefBase(Stream, Offset, Length) {}
  93. WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
  94. endianness Endian)
  95. : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
  96. 0, Data.size()) {}
  97. Error WritableBinaryStreamRef::writeBytes(uint64_t Offset,
  98. ArrayRef<uint8_t> Data) const {
  99. if (auto EC = checkOffsetForWrite(Offset, Data.size()))
  100. return EC;
  101. return BorrowedImpl->writeBytes(ViewOffset + Offset, Data);
  102. }
  103. WritableBinaryStreamRef::operator BinaryStreamRef() const {
  104. return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length);
  105. }
  106. /// For buffered streams, commits changes to the backing store.
  107. Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); }