blob: a91cffe840fd905e413c1af46f039501ae9dbc47 [file] [log] [blame]
Zachary Turner5acb4ac2016-06-10 05:09:12 +00001//===- 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
Zachary Turnera3225b02016-07-29 20:56:36 +000010#include "llvm/DebugInfo/MSF/StreamWriter.h"
Zachary Turner5acb4ac2016-06-10 05:09:12 +000011
Zachary Turnera3225b02016-07-29 20:56:36 +000012#include "llvm/DebugInfo/MSF/MSFError.h"
13#include "llvm/DebugInfo/MSF/StreamReader.h"
14#include "llvm/DebugInfo/MSF/StreamRef.h"
Zachary Turner5acb4ac2016-06-10 05:09:12 +000015
16using namespace llvm;
Zachary Turnerbac69d32016-07-22 19:56:05 +000017using namespace llvm::msf;
Zachary Turner5acb4ac2016-06-10 05:09:12 +000018
Zachary Turnerd66889c2016-07-28 19:12:28 +000019StreamWriter::StreamWriter(WritableStreamRef S) : Stream(S), Offset(0) {}
Zachary Turner5acb4ac2016-06-10 05:09:12 +000020
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
Zachary Turnerd66889c2016-07-28 19:12:28 +000054Error StreamWriter::writeStreamRef(ReadableStreamRef Ref) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +000055 if (auto EC = writeStreamRef(Ref, Ref.getLength()))
56 return EC;
Zachary Turnerd218c262016-07-22 15:46:37 +000057 // Don't increment Offset here, it is done by the overloaded call to
58 // writeStreamRef.
Zachary Turner5acb4ac2016-06-10 05:09:12 +000059 return Error::success();
60}
61
Zachary Turnerd66889c2016-07-28 19:12:28 +000062Error StreamWriter::writeStreamRef(ReadableStreamRef Ref, uint32_t Length) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +000063 Ref = Ref.slice(0, Length);
64
65 StreamReader SrcReader(Ref);
66 // This is a bit tricky. If we just call readBytes, we are requiring that it
67 // return us the entire stream as a contiguous buffer. For large streams this
68 // will allocate a huge amount of space from the pool. Instead, iterate over
69 // each contiguous chunk until we've consumed the entire stream.
70 while (SrcReader.bytesRemaining() > 0) {
71 ArrayRef<uint8_t> Chunk;
72 if (auto EC = SrcReader.readLongestContiguousChunk(Chunk))
73 return EC;
74 if (auto EC = writeBytes(Chunk))
75 return EC;
76 }
77 return Error::success();
78}