1 //===- StreamReader.cpp - Reads bytes and objects from a 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/DebugInfo/CodeView/StreamReader.h" 11 12 #include "llvm/DebugInfo/CodeView/CodeViewError.h" 13 #include "llvm/DebugInfo/CodeView/StreamRef.h" 14 15 using namespace llvm; 16 using namespace llvm::codeview; 17 18 StreamReader::StreamReader(StreamRef S) : Stream(S), Offset(0) {} 19 20 Error StreamReader::readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer) { 21 if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer)) 22 return EC; 23 Offset += Buffer.size(); 24 return Error::success(); 25 } 26 27 Error StreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) { 28 if (auto EC = Stream.readBytes(Offset, Size, Buffer)) 29 return EC; 30 Offset += Size; 31 return Error::success(); 32 } 33 34 Error StreamReader::readInteger(uint16_t &Dest) { 35 const support::ulittle16_t *P; 36 if (auto EC = readObject(P)) 37 return EC; 38 Dest = *P; 39 return Error::success(); 40 } 41 42 Error StreamReader::readInteger(uint32_t &Dest) { 43 const support::ulittle32_t *P; 44 if (auto EC = readObject(P)) 45 return EC; 46 Dest = *P; 47 return Error::success(); 48 } 49 50 Error StreamReader::readZeroString(StringRef &Dest) { 51 uint32_t Length = 0; 52 // First compute the length of the string by reading 1 byte at a time. 53 uint32_t OriginalOffset = getOffset(); 54 const char *C; 55 do { 56 if (auto EC = readObject(C)) 57 return EC; 58 if (*C != '\0') 59 ++Length; 60 } while (*C != '\0'); 61 // Now go back and request a reference for that many bytes. 62 uint32_t NewOffset = getOffset(); 63 setOffset(OriginalOffset); 64 65 ArrayRef<uint8_t> Data; 66 if (auto EC = readBytes(Data, Length)) 67 return EC; 68 Dest = StringRef(reinterpret_cast<const char *>(Data.begin()), Data.size()); 69 70 // Now set the offset back to where it was after we calculated the length. 71 setOffset(NewOffset); 72 return Error::success(); 73 } 74 75 Error StreamReader::readFixedString(StringRef &Dest, uint32_t Length) { 76 ArrayRef<uint8_t> Bytes; 77 if (auto EC = readBytes(Bytes, Length)) 78 return EC; 79 Dest = StringRef(reinterpret_cast<const char *>(Bytes.begin()), Bytes.size()); 80 return Error::success(); 81 } 82 83 Error StreamReader::readStreamRef(StreamRef &Ref) { 84 return readStreamRef(Ref, bytesRemaining()); 85 } 86 87 Error StreamReader::readStreamRef(StreamRef &Ref, uint32_t Length) { 88 if (bytesRemaining() < Length) 89 return make_error<CodeViewError>(cv_error_code::insufficient_buffer); 90 Ref = Stream.slice(Offset, Length); 91 Offset += Length; 92 return Error::success(); 93 } 94