LCOV - code coverage report
Current view: top level - include/llvm/Support - BinaryStreamRef.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 56 57 98.2 %
Date: 2017-09-14 15:23:50 Functions: 12 12 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- BinaryStreamRef.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_SUPPORT_BINARYSTREAMREF_H
      11             : #define LLVM_SUPPORT_BINARYSTREAMREF_H
      12             : 
      13             : #include "llvm/ADT/ArrayRef.h"
      14             : #include "llvm/Support/BinaryStream.h"
      15             : #include "llvm/Support/BinaryStreamError.h"
      16             : #include "llvm/Support/Error.h"
      17             : #include <algorithm>
      18             : #include <cstdint>
      19             : #include <memory>
      20             : 
      21             : namespace llvm {
      22             : 
      23             : /// Common stuff for mutable and immutable StreamRefs.
      24      371348 : template <class RefType, class StreamType> class BinaryStreamRefBase {
      25             : protected:
      26       17826 :   BinaryStreamRefBase() = default;
      27        1458 :   BinaryStreamRefBase(std::shared_ptr<StreamType> SharedImpl, uint32_t Offset,
      28             :                       uint32_t Length)
      29             :       : SharedImpl(SharedImpl), BorrowedImpl(SharedImpl.get()),
      30        2916 :         ViewOffset(Offset), Length(Length) {}
      31       19048 :   BinaryStreamRefBase(StreamType &BorrowedImpl, uint32_t Offset,
      32             :                       uint32_t Length)
      33       38096 :       : BorrowedImpl(&BorrowedImpl), ViewOffset(Offset), Length(Length) {}
      34      201500 :   BinaryStreamRefBase(const BinaryStreamRefBase &Other) = default;
      35             :   BinaryStreamRefBase &operator=(const BinaryStreamRefBase &Other) = default;
      36             : 
      37             :   BinaryStreamRefBase &operator=(BinaryStreamRefBase &&Other) = default;
      38       59348 :   BinaryStreamRefBase(BinaryStreamRefBase &&Other) = default;
      39             : 
      40             : public:
      41             :   llvm::support::endianness getEndian() const {
      42       84004 :     return BorrowedImpl->getEndian();
      43             :   }
      44             : 
      45             :   uint32_t getLength() const { return Length; }
      46             : 
      47             :   /// Return a new BinaryStreamRef with the first \p N elements removed.
      48       19266 :   RefType drop_front(uint32_t N) const {
      49       19266 :     if (!BorrowedImpl)
      50           2 :       return RefType();
      51             : 
      52       38528 :     N = std::min(N, Length);
      53       19264 :     RefType Result(static_cast<const RefType &>(*this));
      54       19264 :     Result.ViewOffset += N;
      55       19264 :     Result.Length -= N;
      56       19264 :     return Result;
      57             :   }
      58             : 
      59             :   /// Return a new BinaryStreamRef with the first \p N elements removed.
      60        6886 :   RefType drop_back(uint32_t N) const {
      61        6886 :     if (!BorrowedImpl)
      62           0 :       return RefType();
      63             : 
      64       13772 :     N = std::min(N, Length);
      65        6886 :     RefType Result(static_cast<const RefType &>(*this));
      66        6886 :     Result.Length -= N;
      67        6886 :     return Result;
      68             :   }
      69             : 
      70             :   /// Return a new BinaryStreamRef with only the first \p N elements remaining.
      71             :   RefType keep_front(uint32_t N) const {
      72             :     assert(N <= getLength());
      73        6884 :     return drop_back(getLength() - N);
      74             :   }
      75             : 
      76             :   /// Return a new BinaryStreamRef with only the last \p N elements remaining.
      77             :   RefType keep_back(uint32_t N) const {
      78             :     assert(N <= getLength());
      79           1 :     return drop_front(getLength() - N);
      80             :   }
      81             : 
      82             :   /// Return a new BinaryStreamRef with the first and last \p N elements
      83             :   /// removed.
      84           1 :   RefType drop_symmetric(uint32_t N) const {
      85           2 :     return drop_front(N).drop_back(N);
      86             :   }
      87             : 
      88             :   /// Return a new BinaryStreamRef with the first \p Offset elements removed,
      89             :   /// and retaining exactly \p Len elements.
      90        6038 :   RefType slice(uint32_t Offset, uint32_t Len) const {
      91       18114 :     return drop_front(Offset).keep_front(Len);
      92             :   }
      93             : 
      94             :   bool valid() const { return BorrowedImpl != nullptr; }
      95             : 
      96             :   bool operator==(const RefType &Other) const {
      97         602 :     if (BorrowedImpl != Other.BorrowedImpl)
      98             :       return false;
      99         602 :     if (ViewOffset != Other.ViewOffset)
     100             :       return false;
     101         602 :     if (Length != Other.Length)
     102             :       return false;
     103             :     return true;
     104             :   }
     105             : 
     106             : protected:
     107      217855 :   Error checkOffset(uint32_t Offset, uint32_t DataSize) const {
     108      217855 :     if (Offset > getLength())
     109           6 :       return make_error<BinaryStreamError>(stream_error_code::invalid_offset);
     110      217849 :     if (getLength() < DataSize + Offset)
     111         197 :       return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
     112      652956 :     return Error::success();
     113             :   }
     114             : 
     115             :   std::shared_ptr<StreamType> SharedImpl;
     116             :   StreamType *BorrowedImpl = nullptr;
     117             :   uint32_t ViewOffset = 0;
     118             :   uint32_t Length = 0;
     119             : };
     120             : 
     121             : /// \brief BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.  It
     122             : /// provides copy-semantics and read only access to a "window" of the underlying
     123             : /// BinaryStream. Note that BinaryStreamRef is *not* a BinaryStream.  That is to
     124             : /// say, it does not inherit and override the methods of BinaryStream.  In
     125             : /// general, you should not pass around pointers or references to BinaryStreams
     126             : /// and use inheritance to achieve polymorphism.  Instead, you should pass
     127             : /// around BinaryStreamRefs by value and achieve polymorphism that way.
     128      317631 : class BinaryStreamRef
     129             :     : public BinaryStreamRefBase<BinaryStreamRef, BinaryStream> {
     130             :   friend BinaryStreamRefBase<BinaryStreamRef, BinaryStream>;
     131             :   friend class WritableBinaryStreamRef;
     132             :   BinaryStreamRef(std::shared_ptr<BinaryStream> Impl, uint32_t ViewOffset,
     133             :                   uint32_t Length)
     134             :       : BinaryStreamRefBase(Impl, ViewOffset, Length) {}
     135             : 
     136             : public:
     137       17712 :   BinaryStreamRef() = default;
     138             :   BinaryStreamRef(BinaryStream &Stream);
     139             :   BinaryStreamRef(BinaryStream &Stream, uint32_t Offset, uint32_t Length);
     140             :   explicit BinaryStreamRef(ArrayRef<uint8_t> Data,
     141             :                            llvm::support::endianness Endian);
     142             :   explicit BinaryStreamRef(StringRef Data, llvm::support::endianness Endian);
     143             : 
     144      184192 :   BinaryStreamRef(const BinaryStreamRef &Other) = default;
     145             :   BinaryStreamRef &operator=(const BinaryStreamRef &Other) = default;
     146       56288 :   BinaryStreamRef(BinaryStreamRef &&Other) = default;
     147             :   BinaryStreamRef &operator=(BinaryStreamRef &&Other) = default;
     148             : 
     149             :   // Use BinaryStreamRef.slice() instead.
     150             :   BinaryStreamRef(BinaryStreamRef &S, uint32_t Offset,
     151             :                   uint32_t Length) = delete;
     152             : 
     153             :   /// Given an Offset into this StreamRef and a Size, return a reference to a
     154             :   /// buffer owned by the stream.
     155             :   ///
     156             :   /// \returns a success error code if the entire range of data is within the
     157             :   /// bounds of this BinaryStreamRef's view and the implementation could read
     158             :   /// the data, and an appropriate error code otherwise.
     159             :   Error readBytes(uint32_t Offset, uint32_t Size,
     160             :                   ArrayRef<uint8_t> &Buffer) const;
     161             : 
     162             :   /// Given an Offset into this BinaryStreamRef, return a reference to the
     163             :   /// largest buffer the stream could support without necessitating a copy.
     164             :   ///
     165             :   /// \returns a success error code if implementation could read the data,
     166             :   /// and an appropriate error code otherwise.
     167             :   Error readLongestContiguousChunk(uint32_t Offset,
     168             :                                    ArrayRef<uint8_t> &Buffer) const;
     169             : };
     170             : 
     171       15964 : struct BinarySubstreamRef {
     172             :   uint32_t Offset;            // Offset in the parent stream
     173             :   BinaryStreamRef StreamData; // Stream Data
     174             : 
     175           6 :   BinarySubstreamRef slice(uint32_t Off, uint32_t Size) const {
     176          12 :     BinaryStreamRef SubSub = StreamData.slice(Off, Size);
     177          18 :     return {Off + Offset, SubSub};
     178             :   }
     179             :   BinarySubstreamRef drop_front(uint32_t N) const {
     180           2 :     return slice(N, size() - N);
     181             :   }
     182           2 :   BinarySubstreamRef keep_front(uint32_t N) const { return slice(0, N); }
     183             : 
     184             :   std::pair<BinarySubstreamRef, BinarySubstreamRef>
     185           2 :   split(uint32_t Offset) const {
     186          10 :     return std::make_pair(keep_front(Offset), drop_front(Offset));
     187             :   }
     188             : 
     189         286 :   uint32_t size() const { return StreamData.getLength(); }
     190         202 :   bool empty() const { return size() == 0; }
     191             : };
     192             : 
     193       37847 : class WritableBinaryStreamRef
     194             :     : public BinaryStreamRefBase<WritableBinaryStreamRef,
     195             :                                  WritableBinaryStream> {
     196             :   friend BinaryStreamRefBase<WritableBinaryStreamRef, WritableBinaryStream>;
     197             :   WritableBinaryStreamRef(std::shared_ptr<WritableBinaryStream> Impl,
     198             :                           uint32_t ViewOffset, uint32_t Length)
     199             :       : BinaryStreamRefBase(Impl, ViewOffset, Length) {}
     200             : 
     201             : public:
     202         114 :   WritableBinaryStreamRef() = default;
     203             :   WritableBinaryStreamRef(WritableBinaryStream &Stream);
     204             :   WritableBinaryStreamRef(WritableBinaryStream &Stream, uint32_t Offset,
     205             :                           uint32_t Length);
     206             :   explicit WritableBinaryStreamRef(MutableArrayRef<uint8_t> Data,
     207             :                                    llvm::support::endianness Endian);
     208       17308 :   WritableBinaryStreamRef(const WritableBinaryStreamRef &Other) = default;
     209             :   WritableBinaryStreamRef &
     210             :   operator=(const WritableBinaryStreamRef &Other) = default;
     211             : 
     212        3060 :   WritableBinaryStreamRef(WritableBinaryStreamRef &&Other) = default;
     213             :   WritableBinaryStreamRef &operator=(WritableBinaryStreamRef &&Other) = default;
     214             : 
     215             :   // Use WritableBinaryStreamRef.slice() instead.
     216             :   WritableBinaryStreamRef(WritableBinaryStreamRef &S, uint32_t Offset,
     217             :                           uint32_t Length) = delete;
     218             : 
     219             :   /// Given an Offset into this WritableBinaryStreamRef and some input data,
     220             :   /// writes the data to the underlying stream.
     221             :   ///
     222             :   /// \returns a success error code if the data could fit within the underlying
     223             :   /// stream at the specified location and the implementation could write the
     224             :   /// data, and an appropriate error code otherwise.
     225             :   Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const;
     226             : 
     227             :   /// Conver this WritableBinaryStreamRef to a read-only BinaryStreamRef.
     228             :   operator BinaryStreamRef() const;
     229             : 
     230             :   /// \brief For buffered streams, commits changes to the backing store.
     231             :   Error commit();
     232             : };
     233             : 
     234             : } // end namespace llvm
     235             : 
     236             : #endif // LLVM_SUPPORT_BINARYSTREAMREF_H

Generated by: LCOV version 1.13