Path: blob/main/contrib/llvm-project/llvm/lib/Support/BinaryStreamWriter.cpp
35232 views
//===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/Support/BinaryStreamWriter.h"910#include "llvm/ADT/StringExtras.h"11#include "llvm/Support/BinaryStreamReader.h"12#include "llvm/Support/BinaryStreamRef.h"13#include "llvm/Support/LEB128.h"1415using namespace llvm;1617BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef Ref)18: Stream(Ref) {}1920BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStream &Stream)21: Stream(Stream) {}2223BinaryStreamWriter::BinaryStreamWriter(MutableArrayRef<uint8_t> Data,24llvm::endianness Endian)25: Stream(Data, Endian) {}2627Error BinaryStreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {28if (auto EC = Stream.writeBytes(Offset, Buffer))29return EC;30Offset += Buffer.size();31return Error::success();32}3334Error BinaryStreamWriter::writeULEB128(uint64_t Value) {35uint8_t EncodedBytes[10] = {0};36unsigned Size = encodeULEB128(Value, &EncodedBytes[0]);37return writeBytes({EncodedBytes, Size});38}3940Error BinaryStreamWriter::writeSLEB128(int64_t Value) {41uint8_t EncodedBytes[10] = {0};42unsigned Size = encodeSLEB128(Value, &EncodedBytes[0]);43return writeBytes({EncodedBytes, Size});44}4546Error BinaryStreamWriter::writeCString(StringRef Str) {47if (auto EC = writeFixedString(Str))48return EC;49if (auto EC = writeObject('\0'))50return EC;5152return Error::success();53}5455Error BinaryStreamWriter::writeFixedString(StringRef Str) {5657return writeBytes(arrayRefFromStringRef(Str));58}5960Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref) {61return writeStreamRef(Ref, Ref.getLength());62}6364Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint64_t Length) {65BinaryStreamReader SrcReader(Ref.slice(0, Length));66// This is a bit tricky. If we just call readBytes, we are requiring that it67// return us the entire stream as a contiguous buffer. There is no guarantee68// this can be satisfied by returning a reference straight from the buffer, as69// an implementation may not store all data in a single contiguous buffer. So70// we iterate over each contiguous chunk, writing each one in succession.71while (SrcReader.bytesRemaining() > 0) {72ArrayRef<uint8_t> Chunk;73if (auto EC = SrcReader.readLongestContiguousChunk(Chunk))74return EC;75if (auto EC = writeBytes(Chunk))76return EC;77}78return Error::success();79}8081std::pair<BinaryStreamWriter, BinaryStreamWriter>82BinaryStreamWriter::split(uint64_t Off) const {83assert(getLength() >= Off);8485WritableBinaryStreamRef First = Stream.drop_front(Offset);8687WritableBinaryStreamRef Second = First.drop_front(Off);88First = First.keep_front(Off);89BinaryStreamWriter W1{First};90BinaryStreamWriter W2{Second};91return std::make_pair(W1, W2);92}9394Error BinaryStreamWriter::padToAlignment(uint32_t Align) {95uint64_t NewOffset = alignTo(Offset, Align);96const uint64_t ZerosSize = 64;97static constexpr char Zeros[ZerosSize] = {};98while (Offset < NewOffset)99if (auto E = writeArray(100ArrayRef<char>(Zeros, std::min(ZerosSize, NewOffset - Offset))))101return E;102return Error::success();103}104105106