1//===- StreamWrite.cpp - Writes bytes and objects to a stream -------------===// 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#include "llvm/DebugInfo/CodeView/StreamWriter.h" 11 12#include "llvm/DebugInfo/CodeView/CodeViewError.h" 13#include "llvm/DebugInfo/CodeView/StreamReader.h" 14#include "llvm/DebugInfo/CodeView/StreamRef.h" 15 16using namespace llvm; 17using namespace llvm::codeview; 18 19StreamWriter::StreamWriter(StreamRef S) : Stream(S), Offset(0) {} 20 21Error StreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) { 22 if (auto EC = Stream.writeBytes(Offset, Buffer)) 23 return EC; 24 Offset += Buffer.size(); 25 return Error::success(); 26} 27 28Error StreamWriter::writeInteger(uint16_t Int) { 29 return writeObject(support::ulittle16_t(Int)); 30} 31 32Error StreamWriter::writeInteger(uint32_t Int) { 33 return writeObject(support::ulittle32_t(Int)); 34} 35 36Error StreamWriter::writeZeroString(StringRef Str) { 37 if (auto EC = writeFixedString(Str)) 38 return EC; 39 if (auto EC = writeObject('\0')) 40 return EC; 41 42 return Error::success(); 43} 44 45Error StreamWriter::writeFixedString(StringRef Str) { 46 ArrayRef<uint8_t> Bytes(Str.bytes_begin(), Str.bytes_end()); 47 if (auto EC = Stream.writeBytes(Offset, Bytes)) 48 return EC; 49 50 Offset += Str.size(); 51 return Error::success(); 52} 53 54Error StreamWriter::writeStreamRef(StreamRef Ref) { 55 if (auto EC = writeStreamRef(Ref, Ref.getLength())) 56 return EC; 57 Offset += Ref.getLength(); 58 return Error::success(); 59} 60 61Error StreamWriter::writeStreamRef(StreamRef Ref, uint32_t Length) { 62 Ref = Ref.slice(0, Length); 63 64 StreamReader SrcReader(Ref); 65 // This is a bit tricky. If we just call readBytes, we are requiring that it 66 // return us the entire stream as a contiguous buffer. For large streams this 67 // will allocate a huge amount of space from the pool. Instead, iterate over 68 // each contiguous chunk until we've consumed the entire stream. 69 while (SrcReader.bytesRemaining() > 0) { 70 ArrayRef<uint8_t> Chunk; 71 if (auto EC = SrcReader.readLongestContiguousChunk(Chunk)) 72 return EC; 73 if (auto EC = writeBytes(Chunk)) 74 return EC; 75 } 76 return Error::success(); 77} 78