/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Support/BinaryStreamReader.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- BinaryStreamReader.cpp - Reads objects from a binary stream --------===// |
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/BinaryStreamReader.h" |
11 | | |
12 | | #include "llvm/Support/BinaryStreamError.h" |
13 | | #include "llvm/Support/BinaryStreamRef.h" |
14 | | |
15 | | using namespace llvm; |
16 | | using endianness = llvm::support::endianness; |
17 | | |
18 | 15.1k | BinaryStreamReader::BinaryStreamReader(BinaryStreamRef Ref) : Stream(Ref) {} |
19 | | |
20 | 9.53k | BinaryStreamReader::BinaryStreamReader(BinaryStream &Stream) : Stream(Stream) {} |
21 | | |
22 | | BinaryStreamReader::BinaryStreamReader(ArrayRef<uint8_t> Data, |
23 | | endianness Endian) |
24 | 502 | : Stream(Data, Endian) {} |
25 | | |
26 | | BinaryStreamReader::BinaryStreamReader(StringRef Data, endianness Endian) |
27 | 364 | : Stream(Data, Endian) {} |
28 | | |
29 | | Error BinaryStreamReader::readLongestContiguousChunk( |
30 | 17.2k | ArrayRef<uint8_t> &Buffer) { |
31 | 17.2k | if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer)) |
32 | 156 | return EC; |
33 | 17.1k | Offset += Buffer.size(); |
34 | 17.1k | return Error::success(); |
35 | 17.1k | } |
36 | | |
37 | 98.4k | Error BinaryStreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) { |
38 | 98.4k | if (auto EC = Stream.readBytes(Offset, Size, Buffer)) |
39 | 17 | return EC; |
40 | 98.4k | Offset += Size; |
41 | 98.4k | return Error::success(); |
42 | 98.4k | } |
43 | | |
44 | 15.5k | Error BinaryStreamReader::readCString(StringRef &Dest) { |
45 | 15.5k | uint32_t OriginalOffset = getOffset(); |
46 | 15.5k | uint32_t FoundOffset = 0; |
47 | 15.6k | while (true15.6k ) { |
48 | 15.6k | uint32_t ThisOffset = getOffset(); |
49 | 15.6k | ArrayRef<uint8_t> Buffer; |
50 | 15.6k | if (auto EC = readLongestContiguousChunk(Buffer)) |
51 | 0 | return EC; |
52 | 15.6k | StringRef S(reinterpret_cast<const char *>(Buffer.begin()), Buffer.size()); |
53 | 15.6k | size_t Pos = S.find_first_of('\0'); |
54 | 15.6k | if (LLVM_LIKELY15.6k (Pos != StringRef::npos)) { |
55 | 15.5k | FoundOffset = Pos + ThisOffset; |
56 | 15.5k | break; |
57 | 15.5k | } |
58 | 15.6k | } |
59 | 15.5k | assert(FoundOffset >= OriginalOffset); |
60 | 15.5k | |
61 | 15.5k | setOffset(OriginalOffset); |
62 | 15.5k | size_t Length = FoundOffset - OriginalOffset; |
63 | 15.5k | |
64 | 15.5k | if (auto EC = readFixedString(Dest, Length)) |
65 | 0 | return EC; |
66 | 15.5k | |
67 | 15.5k | // Now set the offset back to after the null terminator. |
68 | 15.5k | setOffset(FoundOffset + 1); |
69 | 15.5k | return Error::success(); |
70 | 15.5k | } |
71 | | |
72 | 101 | Error BinaryStreamReader::readWideString(ArrayRef<UTF16> &Dest) { |
73 | 101 | uint32_t Length = 0; |
74 | 101 | uint32_t OriginalOffset = getOffset(); |
75 | 101 | const UTF16 *C; |
76 | 983 | while (true983 ) { |
77 | 983 | if (auto EC = readObject(C)) |
78 | 0 | return EC; |
79 | 983 | if (983 *C == 0x0000983 ) |
80 | 101 | break; |
81 | 882 | ++Length; |
82 | 882 | } |
83 | 101 | uint32_t NewOffset = getOffset(); |
84 | 101 | setOffset(OriginalOffset); |
85 | 101 | |
86 | 101 | if (auto EC = readArray(Dest, Length)) |
87 | 0 | return EC; |
88 | 101 | setOffset(NewOffset); |
89 | 101 | return Error::success(); |
90 | 101 | } |
91 | | |
92 | 16.1k | Error BinaryStreamReader::readFixedString(StringRef &Dest, uint32_t Length) { |
93 | 16.1k | ArrayRef<uint8_t> Bytes; |
94 | 16.1k | if (auto EC = readBytes(Bytes, Length)) |
95 | 15 | return EC; |
96 | 16.1k | Dest = StringRef(reinterpret_cast<const char *>(Bytes.begin()), Bytes.size()); |
97 | 16.1k | return Error::success(); |
98 | 16.1k | } |
99 | | |
100 | 170 | Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref) { |
101 | 170 | return readStreamRef(Ref, bytesRemaining()); |
102 | 170 | } |
103 | | |
104 | 5.73k | Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref, uint32_t Length) { |
105 | 5.73k | if (bytesRemaining() < Length) |
106 | 0 | return make_error<BinaryStreamError>(stream_error_code::stream_too_short); |
107 | 5.73k | Ref = Stream.slice(Offset, Length); |
108 | 5.73k | Offset += Length; |
109 | 5.73k | return Error::success(); |
110 | 5.73k | } |
111 | | |
112 | | Error BinaryStreamReader::readSubstream(BinarySubstreamRef &Stream, |
113 | 1.77k | uint32_t Size) { |
114 | 1.77k | Stream.Offset = getOffset(); |
115 | 1.77k | return readStreamRef(Stream.StreamData, Size); |
116 | 1.77k | } |
117 | | |
118 | 4.46k | Error BinaryStreamReader::skip(uint32_t Amount) { |
119 | 4.46k | if (Amount > bytesRemaining()) |
120 | 0 | return make_error<BinaryStreamError>(stream_error_code::stream_too_short); |
121 | 4.46k | Offset += Amount; |
122 | 4.46k | return Error::success(); |
123 | 4.46k | } |
124 | | |
125 | 1.65k | Error BinaryStreamReader::padToAlignment(uint32_t Align) { |
126 | 1.65k | uint32_t NewOffset = alignTo(Offset, Align); |
127 | 1.65k | return skip(NewOffset - Offset); |
128 | 1.65k | } |
129 | | |
130 | 7.75k | uint8_t BinaryStreamReader::peek() const { |
131 | 7.75k | ArrayRef<uint8_t> Buffer; |
132 | 7.75k | auto EC = Stream.readBytes(Offset, 1, Buffer); |
133 | 7.75k | assert(!EC && "Cannot peek an empty buffer!"); |
134 | 7.75k | llvm::consumeError(std::move(EC)); |
135 | 7.75k | return Buffer[0]; |
136 | 7.75k | } |
137 | | |
138 | | std::pair<BinaryStreamReader, BinaryStreamReader> |
139 | 309 | BinaryStreamReader::split(uint32_t Off) const { |
140 | 309 | assert(getLength() >= Off); |
141 | 309 | |
142 | 309 | BinaryStreamRef First = Stream.drop_front(Offset); |
143 | 309 | |
144 | 309 | BinaryStreamRef Second = First.drop_front(Off); |
145 | 309 | First = First.keep_front(Off); |
146 | 309 | BinaryStreamReader W1{First}; |
147 | 309 | BinaryStreamReader W2{Second}; |
148 | 309 | return std::make_pair(W1, W2); |
149 | 309 | } |