BinaryStreamRef.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. 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(makeArrayRef(Data.bytes_begin(), Data.bytes_end()),
  66. Endian) {}
  67. Error BinaryStreamRef::readBytes(uint64_t Offset, uint64_t Size,
  68. ArrayRef<uint8_t> &Buffer) const {
  69. if (auto EC = checkOffsetForRead(Offset, Size))
  70. return EC;
  71. return BorrowedImpl->readBytes(ViewOffset + Offset, Size, Buffer);
  72. }
  73. Error BinaryStreamRef::readLongestContiguousChunk(
  74. uint64_t Offset, ArrayRef<uint8_t> &Buffer) const {
  75. if (auto EC = checkOffsetForRead(Offset, 1))
  76. return EC;
  77. if (auto EC =
  78. BorrowedImpl->readLongestContiguousChunk(ViewOffset + Offset, Buffer))
  79. return EC;
  80. // This StreamRef might refer to a smaller window over a larger stream. In
  81. // that case we will have read out more bytes than we should return, because
  82. // we should not read past the end of the current view.
  83. uint64_t MaxLength = getLength() - Offset;
  84. if (Buffer.size() > MaxLength)
  85. Buffer = Buffer.slice(0, MaxLength);
  86. return Error::success();
  87. }
  88. WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream)
  89. : BinaryStreamRefBase(Stream) {}
  90. WritableBinaryStreamRef::WritableBinaryStreamRef(WritableBinaryStream &Stream,
  91. uint64_t Offset,
  92. Optional<uint64_t> Length)
  93. : BinaryStreamRefBase(Stream, Offset, Length) {}
  94. WritableBinaryStreamRef::WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
  95. endianness Endian)
  96. : BinaryStreamRefBase(std::make_shared<MutableArrayRefImpl>(Data, Endian),
  97. 0, Data.size()) {}
  98. Error WritableBinaryStreamRef::writeBytes(uint64_t Offset,
  99. ArrayRef<uint8_t> Data) const {
  100. if (auto EC = checkOffsetForWrite(Offset, Data.size()))
  101. return EC;
  102. return BorrowedImpl->writeBytes(ViewOffset + Offset, Data);
  103. }
  104. WritableBinaryStreamRef::operator BinaryStreamRef() const {
  105. return BinaryStreamRef(*BorrowedImpl, ViewOffset, Length);
  106. }
  107. /// For buffered streams, commits changes to the backing store.
  108. Error WritableBinaryStreamRef::commit() { return BorrowedImpl->commit(); }