BinaryStreamWriter.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===//
  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/BinaryStreamWriter.h"
  9. #include "llvm/Support/BinaryStreamError.h"
  10. #include "llvm/Support/BinaryStreamReader.h"
  11. #include "llvm/Support/BinaryStreamRef.h"
  12. #include "llvm/Support/LEB128.h"
  13. using namespace llvm;
  14. BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef Ref)
  15. : Stream(Ref) {}
  16. BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStream &Stream)
  17. : Stream(Stream) {}
  18. BinaryStreamWriter::BinaryStreamWriter(MutableArrayRef<uint8_t> Data,
  19. llvm::support::endianness Endian)
  20. : Stream(Data, Endian) {}
  21. Error BinaryStreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
  22. if (auto EC = Stream.writeBytes(Offset, Buffer))
  23. return EC;
  24. Offset += Buffer.size();
  25. return Error::success();
  26. }
  27. Error BinaryStreamWriter::writeULEB128(uint64_t Value) {
  28. uint8_t EncodedBytes[10] = {0};
  29. unsigned Size = encodeULEB128(Value, &EncodedBytes[0]);
  30. return writeBytes({EncodedBytes, Size});
  31. }
  32. Error BinaryStreamWriter::writeSLEB128(int64_t Value) {
  33. uint8_t EncodedBytes[10] = {0};
  34. unsigned Size = encodeSLEB128(Value, &EncodedBytes[0]);
  35. return writeBytes({EncodedBytes, Size});
  36. }
  37. Error BinaryStreamWriter::writeCString(StringRef Str) {
  38. if (auto EC = writeFixedString(Str))
  39. return EC;
  40. if (auto EC = writeObject('\0'))
  41. return EC;
  42. return Error::success();
  43. }
  44. Error BinaryStreamWriter::writeFixedString(StringRef Str) {
  45. return writeBytes(arrayRefFromStringRef(Str));
  46. }
  47. Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref) {
  48. return writeStreamRef(Ref, Ref.getLength());
  49. }
  50. Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint64_t Length) {
  51. BinaryStreamReader SrcReader(Ref.slice(0, Length));
  52. // This is a bit tricky. If we just call readBytes, we are requiring that it
  53. // return us the entire stream as a contiguous buffer. There is no guarantee
  54. // this can be satisfied by returning a reference straight from the buffer, as
  55. // an implementation may not store all data in a single contiguous buffer. So
  56. // we iterate over each contiguous chunk, writing each one in succession.
  57. while (SrcReader.bytesRemaining() > 0) {
  58. ArrayRef<uint8_t> Chunk;
  59. if (auto EC = SrcReader.readLongestContiguousChunk(Chunk))
  60. return EC;
  61. if (auto EC = writeBytes(Chunk))
  62. return EC;
  63. }
  64. return Error::success();
  65. }
  66. std::pair<BinaryStreamWriter, BinaryStreamWriter>
  67. BinaryStreamWriter::split(uint64_t Off) const {
  68. assert(getLength() >= Off);
  69. WritableBinaryStreamRef First = Stream.drop_front(Offset);
  70. WritableBinaryStreamRef Second = First.drop_front(Off);
  71. First = First.keep_front(Off);
  72. BinaryStreamWriter W1{First};
  73. BinaryStreamWriter W2{Second};
  74. return std::make_pair(W1, W2);
  75. }
  76. Error BinaryStreamWriter::padToAlignment(uint32_t Align) {
  77. uint64_t NewOffset = alignTo(Offset, Align);
  78. if (NewOffset > getLength())
  79. return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
  80. while (Offset < NewOffset)
  81. if (auto EC = writeInteger('\0'))
  82. return EC;
  83. return Error::success();
  84. }