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 writeEnum(T Num)39 template <typename T> Error writeEnum(T Num) { 40 return writeInteger( 41 static_cast<typename std::underlying_type<T>::type>(Num)); 42 } 43 writeObject(const T & Obj)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 writeArray(ArrayRef<T> Array)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> writeArray(VarStreamArray<T,U> Array)66 Error writeArray(VarStreamArray<T, U> Array) { 67 return writeStreamRef(Array.getUnderlyingStream()); 68 } 69 writeArray(FixedStreamArray<T> Array)70 template <typename T> Error writeArray(FixedStreamArray<T> Array) { 71 return writeStreamRef(Array.getUnderlyingStream()); 72 } 73 setOffset(uint32_t Off)74 void setOffset(uint32_t Off) { Offset = Off; } getOffset()75 uint32_t getOffset() const { return Offset; } getLength()76 uint32_t getLength() const { return Stream.getLength(); } bytesRemaining()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