1 //===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/BinaryStreamWriter.h"
11 #include "llvm/Support/BinaryStreamError.h"
12 #include "llvm/Support/BinaryStreamReader.h"
13 #include "llvm/Support/BinaryStreamRef.h"
17 BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef Ref
)
20 BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStream
&Stream
)
23 BinaryStreamWriter::BinaryStreamWriter(MutableArrayRef
<uint8_t> Data
,
24 llvm::support::endianness Endian
)
25 : Stream(Data
, Endian
) {}
27 Error
BinaryStreamWriter::writeBytes(ArrayRef
<uint8_t> Buffer
) {
28 if (auto EC
= Stream
.writeBytes(Offset
, Buffer
))
30 Offset
+= Buffer
.size();
31 return Error::success();
34 Error
BinaryStreamWriter::writeCString(StringRef Str
) {
35 if (auto EC
= writeFixedString(Str
))
37 if (auto EC
= writeObject('\0'))
40 return Error::success();
43 Error
BinaryStreamWriter::writeFixedString(StringRef Str
) {
45 return writeBytes(arrayRefFromStringRef(Str
));
48 Error
BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref
) {
49 return writeStreamRef(Ref
, Ref
.getLength());
52 Error
BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref
, uint32_t Length
) {
53 BinaryStreamReader
SrcReader(Ref
.slice(0, Length
));
54 // This is a bit tricky. If we just call readBytes, we are requiring that it
55 // return us the entire stream as a contiguous buffer. There is no guarantee
56 // this can be satisfied by returning a reference straight from the buffer, as
57 // an implementation may not store all data in a single contiguous buffer. So
58 // we iterate over each contiguous chunk, writing each one in succession.
59 while (SrcReader
.bytesRemaining() > 0) {
60 ArrayRef
<uint8_t> Chunk
;
61 if (auto EC
= SrcReader
.readLongestContiguousChunk(Chunk
))
63 if (auto EC
= writeBytes(Chunk
))
66 return Error::success();
69 std::pair
<BinaryStreamWriter
, BinaryStreamWriter
>
70 BinaryStreamWriter::split(uint32_t Off
) const {
71 assert(getLength() >= Off
);
73 WritableBinaryStreamRef First
= Stream
.drop_front(Offset
);
75 WritableBinaryStreamRef Second
= First
.drop_front(Off
);
76 First
= First
.keep_front(Off
);
77 BinaryStreamWriter W1
{First
};
78 BinaryStreamWriter W2
{Second
};
79 return std::make_pair(W1
, W2
);
82 Error
BinaryStreamWriter::padToAlignment(uint32_t Align
) {
83 uint32_t NewOffset
= alignTo(Offset
, Align
);
84 if (NewOffset
> getLength())
85 return make_error
<BinaryStreamError
>(stream_error_code::stream_too_short
);
86 while (Offset
< NewOffset
)
87 if (auto EC
= writeInteger('\0'))
89 return Error::success();