LCOV - code coverage report
Current view: top level - include/llvm/Support - BinaryStreamWriter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 18 19 94.7 %
Date: 2017-09-14 15:23:50 Functions: 19 22 86.4 %
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             : /// \brief 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             :   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             :   BinaryStreamWriter(const BinaryStreamWriter &Other)
      41        1888 :       : Stream(Other.Stream), Offset(Other.Offset) {}
      42             : 
      43             :   BinaryStreamWriter &operator=(const BinaryStreamWriter &Other) {
      44        1888 :     Stream = Other.Stream;
      45         944 :     Offset = Other.Offset;
      46             :     return *this;
      47             :   }
      48             : 
      49       17613 :   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 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       33413 :   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      100239 :     llvm::support::endian::write<T, llvm::support::unaligned>(
      70             :         Buffer, Value, Stream.getEndian());
      71       33413 :     return writeBytes(Buffer);
      72             :   }
      73             : 
      74             :   /// Similar to writeInteger
      75             :   template <typename T> Error writeEnum(T Num) {
      76             :     static_assert(std::is_enum<T>::value,
      77             :                   "Cannot call writeEnum with non-Enum type");
      78             : 
      79             :     using U = typename std::underlying_type<T>::type;
      80        6278 :     return writeInteger<U>(static_cast<U>(Num));
      81             :   }
      82             : 
      83             :   /// Write the the string \p Str to the underlying stream followed by a null
      84             :   /// terminator.  On success, updates the offset so that subsequent writes
      85             :   /// occur at the next unwritten position.  \p Str need not be null terminated
      86             :   /// on input.
      87             :   ///
      88             :   /// \returns a success error code if the data was successfully written,
      89             :   /// otherwise returns an appropriate error code.
      90             :   Error writeCString(StringRef Str);
      91             : 
      92             :   /// Write the the string \p Str to the underlying stream without a null
      93             :   /// terminator.  On success, updates the offset so that subsequent writes
      94             :   /// occur at the next unwritten position.
      95             :   ///
      96             :   /// \returns a success error code if the data was successfully written,
      97             :   /// 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             :   /// This operation will not invoke any copies of the source data, regardless
     102             :   /// of the source stream's implementation.
     103             :   ///
     104             :   /// \returns a success error code if the data was successfully written,
     105             :   /// 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             :   /// This operation will not invoke any copies of the source data, regardless
     110             :   /// of the source stream's implementation.
     111             :   ///
     112             :   /// \returns a success error code if the data was successfully written,
     113             :   /// 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             :   /// 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             :   ///
     120             :   /// \returns a success error code if the data was successfully written,
     121             :   /// 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             :                   "the pointed-to value dereference the pointer before calling "
     126             :                   "writeObject");
     127             :     return writeBytes(
     128       12176 :         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
     129             :   }
     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             :   /// be safely copied in this fashion, as no checks are made to ensure that
     134             :   /// this is safe.
     135             :   ///
     136             :   /// \returns a success error code if the data was successfully written,
     137             :   /// otherwise returns an appropriate error code.
     138        1563 :   template <typename T> Error writeArray(ArrayRef<T> Array) {
     139        1563 :     if (Array.empty())
     140         726 :       return Error::success();
     141        1321 :     if (Array.size() > UINT32_MAX / sizeof(T))
     142             :       return make_error<BinaryStreamError>(
     143           0 :           stream_error_code::invalid_array_size);
     144             : 
     145             :     return writeBytes(
     146        1219 :         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
     147        2642 :                           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             :   template <typename T, typename U>
     155             :   Error writeArray(VarStreamArray<T, U> Array) {
     156             :     return writeStreamRef(Array.getUnderlyingStream());
     157             :   }
     158             : 
     159             :   /// Writes all elements from the array \p Array to the underlying stream.
     160             :   ///
     161             :   /// \returns a success error code if the data was successfully written,
     162             :   /// otherwise returns an appropriate error code.
     163             :   template <typename T> Error writeArray(FixedStreamArray<T> Array) {
     164             :     return writeStreamRef(Array.getUnderlyingStream());
     165             :   }
     166             : 
     167             :   /// Splits the Writer into two Writers at a given offset.
     168             :   std::pair<BinaryStreamWriter, BinaryStreamWriter> split(uint32_t Off) const;
     169             : 
     170        3392 :   void setOffset(uint32_t Off) { Offset = Off; }
     171             :   uint32_t getOffset() const { return Offset; }
     172        1698 :   uint32_t getLength() const { return Stream.getLength(); }
     173         541 :   uint32_t bytesRemaining() const { return getLength() - getOffset(); }
     174             :   Error padToAlignment(uint32_t Align);
     175             : 
     176             : protected:
     177             :   WritableBinaryStreamRef Stream;
     178             :   uint32_t Offset = 0;
     179             : };
     180             : 
     181             : } // end namespace llvm
     182             : 
     183             : #endif // LLVM_SUPPORT_BINARYSTREAMWRITER_H

Generated by: LCOV version 1.13