Home | History | Annotate | Download | only in CodeView
      1 //===- StreamWriter.h - Writes bytes and objects 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_CODEVIEW_STREAMWRITER_H
     11 #define LLVM_DEBUGINFO_CODEVIEW_STREAMWRITER_H
     12 
     13 #include "llvm/ADT/ArrayRef.h"
     14 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
     15 #include "llvm/DebugInfo/CodeView/StreamArray.h"
     16 #include "llvm/DebugInfo/CodeView/StreamInterface.h"
     17 #include "llvm/Support/Endian.h"
     18 #include "llvm/Support/Error.h"
     19 
     20 #include <string>
     21 
     22 namespace llvm {
     23 namespace codeview {
     24 
     25 class StreamRef;
     26 
     27 class StreamWriter {
     28 public:
     29   StreamWriter(StreamRef Stream);
     30 
     31   Error writeBytes(ArrayRef<uint8_t> Buffer);
     32   Error writeInteger(uint16_t Dest);
     33   Error writeInteger(uint32_t Dest);
     34   Error writeZeroString(StringRef Str);
     35   Error writeFixedString(StringRef Str);
     36   Error writeStreamRef(StreamRef Ref);
     37   Error writeStreamRef(StreamRef Ref, uint32_t Size);
     38 
     39   template <typename T> Error writeEnum(T Num) {
     40     return writeInteger(
     41         static_cast<typename std::underlying_type<T>::type>(Num));
     42   }
     43 
     44   template <typename T> Error writeObject(const T &Obj) {
     45     static_assert(!std::is_pointer<T>::value,
     46                   "writeObject should not be used with pointers, to write "
     47                   "the pointed-to value dereference the pointer before calling "
     48                   "writeObject");
     49     return writeBytes(
     50         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T)));
     51   }
     52 
     53   template <typename T> Error writeArray(ArrayRef<T> Array) {
     54     if (Array.size() == 0)
     55       return Error::success();
     56 
     57     if (Array.size() > UINT32_MAX / sizeof(T))
     58       return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
     59 
     60     return writeBytes(
     61         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()),
     62                           Array.size() * sizeof(T)));
     63   }
     64 
     65   template <typename T, typename U>
     66   Error writeArray(VarStreamArray<T, U> Array) {
     67     return writeStreamRef(Array.getUnderlyingStream());
     68   }
     69 
     70   template <typename T> Error writeArray(FixedStreamArray<T> Array) {
     71     return writeStreamRef(Array.getUnderlyingStream());
     72   }
     73 
     74   void setOffset(uint32_t Off) { Offset = Off; }
     75   uint32_t getOffset() const { return Offset; }
     76   uint32_t getLength() const { return Stream.getLength(); }
     77   uint32_t bytesRemaining() const { return getLength() - getOffset(); }
     78 
     79 private:
     80   StreamRef Stream;
     81   uint32_t Offset;
     82 };
     83 } // namespace codeview
     84 } // namespace llvm
     85 
     86 #endif // LLVM_DEBUGINFO_CODEVIEW_STREAMREADER_H
     87