2017-02-28 06:11:43 +08:00
|
|
|
//===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===//
|
2016-06-10 13:09:12 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2017-03-03 04:52:51 +08:00
|
|
|
#include "llvm/Support/BinaryStreamWriter.h"
|
2016-06-10 13:09:12 +08:00
|
|
|
|
2017-03-16 06:18:53 +08:00
|
|
|
#include "llvm/Support/BinaryStreamError.h"
|
2017-03-03 04:52:51 +08:00
|
|
|
#include "llvm/Support/BinaryStreamReader.h"
|
|
|
|
#include "llvm/Support/BinaryStreamRef.h"
|
2016-06-10 13:09:12 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2017-02-28 06:11:43 +08:00
|
|
|
BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef S)
|
|
|
|
: Stream(S), Offset(0) {}
|
2016-06-10 13:09:12 +08:00
|
|
|
|
2017-02-28 06:11:43 +08:00
|
|
|
Error BinaryStreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
|
2016-06-10 13:09:12 +08:00
|
|
|
if (auto EC = Stream.writeBytes(Offset, Buffer))
|
|
|
|
return EC;
|
|
|
|
Offset += Buffer.size();
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2017-02-28 06:11:43 +08:00
|
|
|
Error BinaryStreamWriter::writeCString(StringRef Str) {
|
2016-06-10 13:09:12 +08:00
|
|
|
if (auto EC = writeFixedString(Str))
|
|
|
|
return EC;
|
|
|
|
if (auto EC = writeObject('\0'))
|
|
|
|
return EC;
|
|
|
|
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
2017-02-28 06:11:43 +08:00
|
|
|
Error BinaryStreamWriter::writeFixedString(StringRef Str) {
|
|
|
|
return writeBytes(ArrayRef<uint8_t>(Str.bytes_begin(), Str.bytes_end()));
|
2016-06-10 13:09:12 +08:00
|
|
|
}
|
|
|
|
|
2017-02-28 06:11:43 +08:00
|
|
|
Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref) {
|
|
|
|
return writeStreamRef(Ref, Ref.getLength());
|
2016-06-10 13:09:12 +08:00
|
|
|
}
|
|
|
|
|
2017-02-28 06:11:43 +08:00
|
|
|
Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint32_t Length) {
|
|
|
|
BinaryStreamReader SrcReader(Ref.slice(0, Length));
|
2016-06-10 13:09:12 +08:00
|
|
|
// This is a bit tricky. If we just call readBytes, we are requiring that it
|
2017-02-28 06:11:43 +08:00
|
|
|
// return us the entire stream as a contiguous buffer. There is no guarantee
|
|
|
|
// this can be satisfied by returning a reference straight from the buffer, as
|
|
|
|
// an implementation may not store all data in a single contiguous buffer. So
|
|
|
|
// we iterate over each contiguous chunk, writing each one in succession.
|
2016-06-10 13:09:12 +08:00
|
|
|
while (SrcReader.bytesRemaining() > 0) {
|
|
|
|
ArrayRef<uint8_t> Chunk;
|
|
|
|
if (auto EC = SrcReader.readLongestContiguousChunk(Chunk))
|
|
|
|
return EC;
|
|
|
|
if (auto EC = writeBytes(Chunk))
|
|
|
|
return EC;
|
|
|
|
}
|
|
|
|
return Error::success();
|
|
|
|
}
|
2017-03-16 06:18:53 +08:00
|
|
|
|
2017-05-03 23:58:37 +08:00
|
|
|
std::pair<BinaryStreamWriter, BinaryStreamWriter>
|
|
|
|
BinaryStreamWriter::split(uint32_t Off) const {
|
|
|
|
assert(getLength() >= Off);
|
|
|
|
|
|
|
|
WritableBinaryStreamRef First = Stream.drop_front(Offset);
|
|
|
|
|
|
|
|
WritableBinaryStreamRef Second = First.drop_front(Off);
|
|
|
|
First = First.keep_front(Off);
|
|
|
|
BinaryStreamWriter W1{First};
|
|
|
|
BinaryStreamWriter W2{Second};
|
|
|
|
return std::make_pair(W1, W2);
|
|
|
|
}
|
|
|
|
|
2017-03-16 06:18:53 +08:00
|
|
|
Error BinaryStreamWriter::padToAlignment(uint32_t Align) {
|
|
|
|
uint32_t NewOffset = alignTo(Offset, Align);
|
|
|
|
if (NewOffset > getLength())
|
|
|
|
return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
|
|
|
|
Offset = NewOffset;
|
|
|
|
return Error::success();
|
|
|
|
}
|