LCOV - code coverage report
Current view: top level - include/llvm/Support - BinaryStreamWriter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 72 83 86.7 %
Date: 2018-10-20 13:21:21 Functions: 17 22 77.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- BinaryStreamWriter.h - Writes objects to a BinaryStream ---*- 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_BINARYSTREAMWRITER_H
      11             : #define LLVM_SUPPORT_BINARYSTREAMWRITER_H
      12             : 
      13             : #include "llvm/ADT/ArrayRef.h"
      14             : #include "llvm/ADT/STLExtras.h"
      15             : #include "llvm/ADT/StringRef.h"
      16             : #include "llvm/Support/BinaryStreamArray.h"
      17             : #include "llvm/Support/BinaryStreamError.h"
      18             : #include "llvm/Support/BinaryStreamRef.h"
      19             : #include "llvm/Support/Endian.h"
      20             : #include "llvm/Support/Error.h"
      21             : #include <cstdint>
      22             : #include <type_traits>
      23             : #include <utility>
      24             : 
      25             : namespace llvm {
      26             : 
      27             : /// Provides write only access to a subclass of `WritableBinaryStream`.
      28             : /// Provides bounds checking and helpers for writing certain common data types
      29             : /// such as null-terminated strings, integers in various flavors of endianness,
      30             : /// etc.  Can be subclassed to provide reading and writing of custom datatypes,
      31             : /// although no methods are overridable.
      32             : class BinaryStreamWriter {
      33             : public:
      34         440 :   BinaryStreamWriter() = default;
      35             :   explicit BinaryStreamWriter(WritableBinaryStreamRef Ref);
      36             :   explicit BinaryStreamWriter(WritableBinaryStream &Stream);
      37             :   explicit BinaryStreamWriter(MutableArrayRef<uint8_t> Data,
      38             :                               llvm::support::endianness Endian);
      39             : 
      40        1760 :   BinaryStreamWriter(const BinaryStreamWriter &Other)
      41        3520 :       : Stream(Other.Stream), Offset(Other.Offset) {}
      42             : 
      43             :   BinaryStreamWriter &operator=(const BinaryStreamWriter &Other) {
      44             :     Stream = Other.Stream;
      45         880 :     Offset = Other.Offset;
      46             :     return *this;
      47             :   }
      48             : 
      49        6671 :   virtual ~BinaryStreamWriter() {}
      50             : 
      51             :   /// Write the bytes specified in \p Buffer to the underlying stream.
      52             :   /// On success, updates the offset so that subsequent writes will occur
      53             :   /// at the next unwritten position.
      54             :   ///
      55             :   /// \returns a success error code if the data was successfully written,
      56             :   /// otherwise returns an appropriate error code.
      57             :   Error writeBytes(ArrayRef<uint8_t> Buffer);
      58             : 
      59             :   /// Write the integer \p Value to the underlying stream in the
      60             :   /// specified endianness.  On success, updates the offset so that
      61             :   /// subsequent writes occur at the next unwritten position.
      62             :   ///
      63             :   /// \returns a success error code if the data was successfully written,
      64             :   /// otherwise returns an appropriate error code.
      65       47923 :   template <typename T> Error writeInteger(T Value) {
      66             :     static_assert(std::is_integral<T>::value,
      67             :                   "Cannot call writeInteger with non-integral value!");
      68             :     uint8_t Buffer[sizeof(T)];
      69       47923 :     llvm::support::endian::write<T, llvm::support::unaligned>(
      70             :         Buffer, Value, Stream.getEndian());
      71       47923 :     return writeBytes(Buffer);
      72             :   }
      73        6886 : 
      74             :   /// Similar to writeInteger
      75             :   template <typename T> Error writeEnum(T Num) {
      76             :     static_assert(std::is_enum<T>::value,
      77        6886 :                   "Cannot call writeEnum with non-Enum type");
      78             : 
      79        6886 :     using U = typename std::underlying_type<T>::type;
      80           2 :     return writeInteger<U>(static_cast<U>(Num));
      81        4886 :   }
      82             : 
      83             :   /// Write the string \p Str to the underlying stream followed by a null
      84             :   /// terminator.  On success, updates the offset so that subsequent writes
      85        4886 :   /// occur at the next unwritten position.  \p Str need not be null terminated
      86             :   /// on input.
      87        4886 :   ///
      88             :   /// \returns a success error code if the data was successfully written,
      89        2320 :   /// otherwise returns an appropriate error code.
      90             :   Error writeCString(StringRef Str);
      91             : 
      92             :   /// Write the string \p Str to the underlying stream without a null
      93        2320 :   /// terminator.  On success, updates the offset so that subsequent writes
      94             :   /// occur at the next unwritten position.
      95        2320 :   ///
      96        6794 :   /// \returns a success error code if the data was successfully written,
      97        1852 :   /// otherwise returns an appropriate error code.
      98             :   Error writeFixedString(StringRef Str);
      99             : 
     100             :   /// Efficiently reads all data from \p Ref, and writes it to this stream.
     101        1852 :   /// This operation will not invoke any copies of the source data, regardless
     102             :   /// of the source stream's implementation.
     103        1852 :   ///
     104             :   /// \returns a success error code if the data was successfully written,
     105           0 :   /// otherwise returns an appropriate error code.
     106             :   Error writeStreamRef(BinaryStreamRef Ref);
     107             : 
     108             :   /// Efficiently reads \p Size bytes from \p Ref, and writes it to this stream.
     109           0 :   /// This operation will not invoke any copies of the source data, regardless
     110             :   /// of the source stream's implementation.
     111           0 :   ///
     112          18 :   /// \returns a success error code if the data was successfully written,
     113        6873 :   /// otherwise returns an appropriate error code.
     114             :   Error writeStreamRef(BinaryStreamRef Ref, uint32_t Size);
     115             : 
     116             :   /// Writes the object \p Obj to the underlying stream, as if by using memcpy.
     117        6873 :   /// It is up to the caller to ensure that type of \p Obj can be safely copied
     118             :   /// in this fashion, as no checks are made to ensure that this is safe.
     119        6873 :   ///
     120             :   /// \returns a success error code if the data was successfully written,
     121          89 :   /// otherwise returns an appropriate error code.
     122             :   template <typename T> Error writeObject(const T &Obj) {
     123             :     static_assert(!std::is_pointer<T>::value,
     124             :                   "writeObject should not be used with pointers, to write "
     125          89 :                   "the pointed-to value dereference the pointer before calling "
     126             :                   "writeObject");
     127          89 :     return writeBytes(
     128       17989 :         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
     129        7050 :   }
     130             : 
     131             :   /// Writes an array of objects of type T to the underlying stream, as if by
     132             :   /// using memcpy.  It is up to the caller to ensure that type of \p Obj can
     133        7050 :   /// be safely copied in this fashion, as no checks are made to ensure that
     134             :   /// this is safe.
     135        7050 :   ///
     136             :   /// \returns a success error code if the data was successfully written,
     137             :   /// otherwise returns an appropriate error code.
     138        2668 :   template <typename T> Error writeArray(ArrayRef<T> Array) {
     139        2668 :     if (Array.empty())
     140             :       return Error::success();
     141        2334 :     if (Array.size() > UINT32_MAX / sizeof(T))
     142             :       return make_error<BinaryStreamError>(
     143           0 :           stream_error_code::invalid_array_size);
     144         551 : 
     145             :     return writeBytes(
     146        2228 :         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
     147        4668 :                           Array.size() * sizeof(T)));
     148             :   }
     149             : 
     150             :   /// Writes all data from the array \p Array to the underlying stream.
     151             :   ///
     152             :   /// \returns a success error code if the data was successfully written,
     153             :   /// otherwise returns an appropriate error code.
     154         267 :   template <typename T, typename U>
     155         267 :   Error writeArray(VarStreamArray<T, U> Array) {
     156             :     return writeStreamRef(Array.getUnderlyingStream());
     157         267 :   }
     158             : 
     159           0 :   /// Writes all elements from the array \p Array to the underlying stream.
     160          45 :   ///
     161             :   /// \returns a success error code if the data was successfully written,
     162         178 :   /// otherwise returns an appropriate error code.
     163         534 :   template <typename T> Error writeArray(FixedStreamArray<T> Array) {
     164             :     return writeStreamRef(Array.getUnderlyingStream());
     165          89 :   }
     166          89 : 
     167             :   /// Splits the Writer into two Writers at a given offset.
     168          89 :   std::pair<BinaryStreamWriter, BinaryStreamWriter> split(uint32_t Off) const;
     169             : 
     170        3155 :   void setOffset(uint32_t Off) { Offset = Off; }
     171           6 :   uint32_t getOffset() const { return Offset; }
     172             :   uint32_t getLength() const { return Stream.getLength(); }
     173         768 :   uint32_t bytesRemaining() const { return getLength() - getOffset(); }
     174         178 :   Error padToAlignment(uint32_t Align);
     175           0 : 
     176          89 : protected:
     177          89 :   WritableBinaryStreamRef Stream;
     178           6 :   uint32_t Offset = 0;
     179         101 : };
     180             : 
     181           0 : } // end namespace llvm
     182             : 
     183             : #endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H

Generated by: LCOV version 1.13