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 16 using namespace llvm; 17 using namespace llvm::codeview; 18 19 StreamWriter::StreamWriter(StreamRef S) : Stream(S), Offset(0) {} 20 21 Error 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 28 Error StreamWriter::writeInteger(uint16_t Int) { 29 return writeObject(support::ulittle16_t(Int)); 30 } 31 32 Error StreamWriter::writeInteger(uint32_t Int) { 33 return writeObject(support::ulittle32_t(Int)); 34 } 35 36 Error 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 45 Error 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 54 Error 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 61 Error 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