Line data Source code
1 : //===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "llvm/Support/BinaryStreamWriter.h"
11 :
12 : #include "llvm/Support/BinaryStreamError.h"
13 : #include "llvm/Support/BinaryStreamReader.h"
14 : #include "llvm/Support/BinaryStreamRef.h"
15 :
16 : using namespace llvm;
17 :
18 2459 : BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef Ref)
19 2459 : : Stream(Ref) {}
20 :
21 2835 : BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStream &Stream)
22 2835 : : Stream(Stream) {}
23 :
24 3277 : BinaryStreamWriter::BinaryStreamWriter(MutableArrayRef<uint8_t> Data,
25 3277 : llvm::support::endianness Endian)
26 3277 : : Stream(Data, Endian) {}
27 :
28 85037 : Error BinaryStreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
29 170074 : if (auto EC = Stream.writeBytes(Offset, Buffer))
30 : return EC;
31 85025 : Offset += Buffer.size();
32 : return Error::success();
33 : }
34 :
35 11218 : Error BinaryStreamWriter::writeCString(StringRef Str) {
36 22436 : if (auto EC = writeFixedString(Str))
37 : return EC;
38 11218 : if (auto EC = writeObject('\0'))
39 : return EC;
40 :
41 : return Error::success();
42 : }
43 :
44 11359 : Error BinaryStreamWriter::writeFixedString(StringRef Str) {
45 :
46 11359 : return writeBytes(arrayRefFromStringRef(Str));
47 : }
48 :
49 641 : Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref) {
50 641 : return writeStreamRef(Ref, Ref.getLength());
51 : }
52 :
53 641 : Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint32_t Length) {
54 1282 : BinaryStreamReader SrcReader(Ref.slice(0, Length));
55 : // This is a bit tricky. If we just call readBytes, we are requiring that it
56 : // return us the entire stream as a contiguous buffer. There is no guarantee
57 : // this can be satisfied by returning a reference straight from the buffer, as
58 : // an implementation may not store all data in a single contiguous buffer. So
59 : // we iterate over each contiguous chunk, writing each one in succession.
60 2169 : while (SrcReader.bytesRemaining() > 0) {
61 1528 : ArrayRef<uint8_t> Chunk;
62 3056 : if (auto EC = SrcReader.readLongestContiguousChunk(Chunk))
63 : return EC;
64 3056 : if (auto EC = writeBytes(Chunk))
65 : return EC;
66 : }
67 : return Error::success();
68 : }
69 :
70 : std::pair<BinaryStreamWriter, BinaryStreamWriter>
71 880 : BinaryStreamWriter::split(uint32_t Off) const {
72 : assert(getLength() >= Off);
73 :
74 880 : WritableBinaryStreamRef First = Stream.drop_front(Offset);
75 :
76 880 : WritableBinaryStreamRef Second = First.drop_front(Off);
77 1760 : First = First.keep_front(Off);
78 1760 : BinaryStreamWriter W1{First};
79 1760 : BinaryStreamWriter W2{Second};
80 880 : return std::make_pair(W1, W2);
81 : }
82 :
83 2296 : Error BinaryStreamWriter::padToAlignment(uint32_t Align) {
84 4592 : uint32_t NewOffset = alignTo(Offset, Align);
85 2296 : if (NewOffset > getLength())
86 0 : return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
87 4023 : while (Offset < NewOffset)
88 3454 : if (auto EC = writeInteger('\0'))
89 : return EC;
90 : return Error::success();
91 : }
|