LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/Msf - StreamRef.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 22 37 59.5 %
Date: 2016-07-29 04:53:09 Functions: 3 4 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- StreamRef.h - A copyable reference to a stream -----------*- C++ -*-===//
       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             : #ifndef LLVM_DEBUGINFO_MSF_STREAMREF_H
      11             : #define LLVM_DEBUGINFO_MSF_STREAMREF_H
      12             : 
      13             : #include "llvm/DebugInfo/Msf/MsfError.h"
      14             : #include "llvm/DebugInfo/Msf/StreamInterface.h"
      15             : 
      16             : namespace llvm {
      17             : namespace msf {
      18             : template <class StreamType, class RefType> class StreamRefBase {
      19             : public:
      20        1218 :   StreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {}
      21             :   StreamRefBase(const StreamType &Stream, uint32_t Offset, uint32_t Length)
      22         402 :       : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
      23             : 
      24             :   uint32_t getLength() const { return Length; }
      25             :   const StreamType *getStream() const { return Stream; }
      26             : 
      27             :   RefType drop_front(uint32_t N) const {
      28        3760 :     if (!Stream)
      29             :       return RefType();
      30             : 
      31        7520 :     N = std::min(N, Length);
      32        7520 :     return RefType(*Stream, ViewOffset + N, Length - N);
      33             :   }
      34             : 
      35             :   RefType keep_front(uint32_t N) const {
      36         461 :     if (!Stream)
      37             :       return RefType();
      38         922 :     N = std::min(N, Length);
      39         922 :     return RefType(*Stream, ViewOffset, N);
      40             :   }
      41             : 
      42         461 :   RefType slice(uint32_t Offset, uint32_t Len) const {
      43         922 :     return drop_front(Offset).keep_front(Len);
      44             :   }
      45             : 
      46             :   bool operator==(const RefType &Other) const {
      47           0 :     if (Stream != Other.Stream)
      48             :       return false;
      49           0 :     if (ViewOffset != Other.ViewOffset)
      50             :       return false;
      51           0 :     if (Length != Other.Length)
      52             :       return false;
      53             :     return true;
      54             :   }
      55             : 
      56             : protected:
      57             :   const StreamType *Stream;
      58             :   uint32_t ViewOffset;
      59             :   uint32_t Length;
      60             : };
      61             : 
      62             : class ReadableStreamRef
      63             :     : public StreamRefBase<ReadableStream, ReadableStreamRef> {
      64             : public:
      65        2440 :   ReadableStreamRef() : StreamRefBase() {}
      66             :   ReadableStreamRef(const ReadableStream &Stream)
      67         798 :       : StreamRefBase(Stream, 0, Stream.getLength()) {}
      68             :   ReadableStreamRef(const ReadableStream &Stream, uint32_t Offset,
      69             :                     uint32_t Length)
      70        4221 :       : StreamRefBase(Stream, Offset, Length) {}
      71             : 
      72             :   // Use StreamRef.slice() instead.
      73             :   ReadableStreamRef(const ReadableStreamRef &S, uint32_t Offset,
      74             :                     uint32_t Length) = delete;
      75             : 
      76       35537 :   Error readBytes(uint32_t Offset, uint32_t Size,
      77             :                   ArrayRef<uint8_t> &Buffer) const {
      78       35537 :     if (ViewOffset + Offset < Offset)
      79           0 :       return make_error<MsfError>(msf_error_code::insufficient_buffer);
      80       35537 :     if (Size + Offset > Length)
      81           6 :       return make_error<MsfError>(msf_error_code::insufficient_buffer);
      82       35534 :     return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
      83             :   }
      84             : 
      85             :   // Given an offset into the stream, read as much as possible without copying
      86             :   // any data.
      87           0 :   Error readLongestContiguousChunk(uint32_t Offset,
      88             :                                    ArrayRef<uint8_t> &Buffer) const {
      89           0 :     if (Offset >= Length)
      90           0 :       return make_error<MsfError>(msf_error_code::insufficient_buffer);
      91             : 
      92           0 :     if (auto EC = Stream->readLongestContiguousChunk(Offset, Buffer))
      93           0 :       return EC;
      94             :     // This StreamRef might refer to a smaller window over a larger stream.  In
      95             :     // that case we will have read out more bytes than we should return, because
      96             :     // we should not read past the end of the current view.
      97           0 :     uint32_t MaxLength = Length - Offset;
      98           0 :     if (Buffer.size() > MaxLength)
      99           0 :       Buffer = Buffer.slice(0, MaxLength);
     100             :     return Error::success();
     101             :   }
     102             : };
     103             : 
     104             : class WritableStreamRef
     105             :     : public StreamRefBase<WritableStream, WritableStreamRef> {
     106             : public:
     107           0 :   WritableStreamRef() : StreamRefBase() {}
     108             :   WritableStreamRef(const WritableStream &Stream)
     109           6 :       : StreamRefBase(Stream, 0, Stream.getLength()) {}
     110             :   WritableStreamRef(const WritableStream &Stream, uint32_t Offset,
     111             :                     uint32_t Length)
     112           0 :       : StreamRefBase(Stream, Offset, Length) {}
     113             : 
     114             :   // Use StreamRef.slice() instead.
     115             :   WritableStreamRef(const WritableStreamRef &S, uint32_t Offset,
     116             :                     uint32_t Length) = delete;
     117             : 
     118          40 :   Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const {
     119          40 :     if (Data.size() + Offset > Length)
     120           0 :       return make_error<MsfError>(msf_error_code::insufficient_buffer);
     121          40 :     return Stream->writeBytes(ViewOffset + Offset, Data);
     122             :   }
     123             : 
     124             :   Error commit() const { return Stream->commit(); }
     125             : };
     126             : 
     127             : } // namespace msf
     128             : } // namespace llvm
     129             : 
     130             : #endif // LLVM_DEBUGINFO_MSF_STREAMREF_H

Generated by: LCOV version 1.12