Home | History | Annotate | Download | only in CodeView
      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