LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/MSF - StreamRef.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 35 39 89.7 %
Date: 2017-02-25 14:46:56 Functions: 4 4 100.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/ADT/ArrayRef.h"
      14             : #include "llvm/DebugInfo/MSF/MSFError.h"
      15             : #include "llvm/DebugInfo/MSF/StreamInterface.h"
      16             : #include "llvm/Support/Error.h"
      17             : #include <algorithm>
      18             : #include <cstdint>
      19             : 
      20             : namespace llvm {
      21             : namespace msf {
      22             : 
      23             : template <class StreamType, class RefType> class StreamRefBase {
      24             : public:
      25        1910 :   StreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {}
      26       11195 :   StreamRefBase(const StreamType &Stream, uint32_t Offset, uint32_t Length)
      27       11195 :       : Stream(&Stream), ViewOffset(Offset), Length(Length) {}
      28             : 
      29             :   uint32_t getLength() const { return Length; }
      30             :   const StreamType *getStream() const { return Stream; }
      31             : 
      32             :   RefType drop_front(uint32_t N) const {
      33        5653 :     if (!Stream)
      34             :       return RefType();
      35             : 
      36       11306 :     N = std::min(N, Length);
      37       11306 :     return RefType(*Stream, ViewOffset + N, Length - N);
      38             :   }
      39             : 
      40             :   RefType keep_front(uint32_t N) const {
      41         816 :     if (!Stream)
      42             :       return RefType();
      43        1632 :     N = std::min(N, Length);
      44        1632 :     return RefType(*Stream, ViewOffset, N);
      45             :   }
      46             : 
      47         811 :   RefType slice(uint32_t Offset, uint32_t Len) const {
      48        1622 :     return drop_front(Offset).keep_front(Len);
      49             :   }
      50             : 
      51             :   bool operator==(const RefType &Other) const {
      52          59 :     if (Stream != Other.Stream)
      53             :       return false;
      54          59 :     if (ViewOffset != Other.ViewOffset)
      55             :       return false;
      56          59 :     if (Length != Other.Length)
      57             :       return false;
      58             :     return true;
      59             :   }
      60             : 
      61             : protected:
      62             :   const StreamType *Stream;
      63             :   uint32_t ViewOffset;
      64             :   uint32_t Length;
      65             : };
      66             : 
      67             : class ReadableStreamRef
      68             :     : public StreamRefBase<ReadableStream, ReadableStreamRef> {
      69             : public:
      70        3814 :   ReadableStreamRef() = default;
      71             :   ReadableStreamRef(const ReadableStream &Stream)
      72       17112 :       : StreamRefBase(Stream, 0, Stream.getLength()) {}
      73             :   ReadableStreamRef(const ReadableStream &Stream, uint32_t Offset,
      74             :                     uint32_t Length)
      75        6459 :       : StreamRefBase(Stream, Offset, Length) {}
      76             : 
      77             :   // Use StreamRef.slice() instead.
      78             :   ReadableStreamRef(const ReadableStreamRef &S, uint32_t Offset,
      79             :                     uint32_t Length) = delete;
      80             : 
      81      776748 :   Error readBytes(uint32_t Offset, uint32_t Size,
      82             :                   ArrayRef<uint8_t> &Buffer) const {
      83      776748 :     if (ViewOffset + Offset < Offset)
      84           0 :       return make_error<MSFError>(msf_error_code::insufficient_buffer);
      85      776748 :     if (Size + Offset > Length)
      86           8 :       return make_error<MSFError>(msf_error_code::insufficient_buffer);
      87      776740 :     return Stream->readBytes(ViewOffset + Offset, Size, Buffer);
      88             :   }
      89             : 
      90             :   // Given an offset into the stream, read as much as possible without copying
      91             :   // any data.
      92        1036 :   Error readLongestContiguousChunk(uint32_t Offset,
      93             :                                    ArrayRef<uint8_t> &Buffer) const {
      94        1036 :     if (Offset >= Length)
      95         145 :       return make_error<MSFError>(msf_error_code::insufficient_buffer);
      96             : 
      97        2673 :     if (auto EC = Stream->readLongestContiguousChunk(Offset, Buffer))
      98           0 :       return EC;
      99             :     // This StreamRef might refer to a smaller window over a larger stream.  In
     100             :     // that case we will have read out more bytes than we should return, because
     101             :     // we should not read past the end of the current view.
     102         891 :     uint32_t MaxLength = Length - Offset;
     103         891 :     if (Buffer.size() > MaxLength)
     104           0 :       Buffer = Buffer.slice(0, MaxLength);
     105        2673 :     return Error::success();
     106             :   }
     107             : };
     108             : 
     109             : class WritableStreamRef
     110             :     : public StreamRefBase<WritableStream, WritableStreamRef> {
     111             : public:
     112          10 :   WritableStreamRef() = default;
     113             :   WritableStreamRef(const WritableStream &Stream)
     114        5286 :       : StreamRefBase(Stream, 0, Stream.getLength()) {}
     115             :   WritableStreamRef(const WritableStream &Stream, uint32_t Offset,
     116             :                     uint32_t Length)
     117          10 :       : StreamRefBase(Stream, Offset, Length) {}
     118             : 
     119             :   // Use StreamRef.slice() instead.
     120             :   WritableStreamRef(const WritableStreamRef &S, uint32_t Offset,
     121             :                     uint32_t Length) = delete;
     122             : 
     123       41921 :   Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const {
     124       41921 :     if (Data.size() + Offset > Length)
     125           0 :       return make_error<MSFError>(msf_error_code::insufficient_buffer);
     126       41921 :     return Stream->writeBytes(ViewOffset + Offset, Data);
     127             :   }
     128             : 
     129             :   Error commit() const { return Stream->commit(); }
     130             : };
     131             : 
     132             : } // end namespace msf
     133             : } // end namespace llvm
     134             : 
     135             : #endif // LLVM_DEBUGINFO_MSF_STREAMREF_H

Generated by: LCOV version 1.13