| //===- StreamReader.cpp - Reads bytes and objects from a stream -----------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/DebugInfo/CodeView/StreamReader.h" |
| |
| #include "llvm/DebugInfo/CodeView/CodeViewError.h" |
| #include "llvm/DebugInfo/CodeView/StreamRef.h" |
| |
| using namespace llvm; |
| using namespace llvm::codeview; |
| |
| StreamReader::StreamReader(StreamRef S) : Stream(S), Offset(0) {} |
| |
| Error StreamReader::readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer) { |
| if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer)) |
| return EC; |
| Offset += Buffer.size(); |
| return Error::success(); |
| } |
| |
| Error StreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) { |
| if (auto EC = Stream.readBytes(Offset, Size, Buffer)) |
| return EC; |
| Offset += Size; |
| return Error::success(); |
| } |
| |
| Error StreamReader::readInteger(uint16_t &Dest) { |
| const support::ulittle16_t *P; |
| if (auto EC = readObject(P)) |
| return EC; |
| Dest = *P; |
| return Error::success(); |
| } |
| |
| Error StreamReader::readInteger(uint32_t &Dest) { |
| const support::ulittle32_t *P; |
| if (auto EC = readObject(P)) |
| return EC; |
| Dest = *P; |
| return Error::success(); |
| } |
| |
| Error StreamReader::readZeroString(StringRef &Dest) { |
| uint32_t Length = 0; |
| // First compute the length of the string by reading 1 byte at a time. |
| uint32_t OriginalOffset = getOffset(); |
| const char *C; |
| do { |
| if (auto EC = readObject(C)) |
| return EC; |
| if (*C != '\0') |
| ++Length; |
| } while (*C != '\0'); |
| // Now go back and request a reference for that many bytes. |
| uint32_t NewOffset = getOffset(); |
| setOffset(OriginalOffset); |
| |
| ArrayRef<uint8_t> Data; |
| if (auto EC = readBytes(Data, Length)) |
| return EC; |
| Dest = StringRef(reinterpret_cast<const char *>(Data.begin()), Data.size()); |
| |
| // Now set the offset back to where it was after we calculated the length. |
| setOffset(NewOffset); |
| return Error::success(); |
| } |
| |
| Error StreamReader::readFixedString(StringRef &Dest, uint32_t Length) { |
| ArrayRef<uint8_t> Bytes; |
| if (auto EC = readBytes(Bytes, Length)) |
| return EC; |
| Dest = StringRef(reinterpret_cast<const char *>(Bytes.begin()), Bytes.size()); |
| return Error::success(); |
| } |
| |
| Error StreamReader::readStreamRef(StreamRef &Ref) { |
| return readStreamRef(Ref, bytesRemaining()); |
| } |
| |
| Error StreamReader::readStreamRef(StreamRef &Ref, uint32_t Length) { |
| if (bytesRemaining() < Length) |
| return make_error<CodeViewError>(cv_error_code::insufficient_buffer); |
| Ref = Stream.slice(Offset, Length); |
| Offset += Length; |
| return Error::success(); |
| } |