Path: blob/main/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp
35233 views
//===- MsgPackWriter.cpp - Simple MsgPack writer ----------------*- C++ -*-===//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//===----------------------------------------------------------------------===//7///8/// \file9/// This file implements a MessagePack writer.10///11//===----------------------------------------------------------------------===//1213#include "llvm/BinaryFormat/MsgPackWriter.h"14#include "llvm/BinaryFormat/MsgPack.h"1516#include <cmath>1718using namespace llvm;19using namespace msgpack;2021Writer::Writer(raw_ostream &OS, bool Compatible)22: EW(OS, Endianness), Compatible(Compatible) {}2324void Writer::writeNil() { EW.write(FirstByte::Nil); }2526void Writer::write(bool b) { EW.write(b ? FirstByte::True : FirstByte::False); }2728void Writer::write(int64_t i) {29if (i >= 0) {30write(static_cast<uint64_t>(i));31return;32}3334if (i >= FixMin::NegativeInt) {35EW.write(static_cast<int8_t>(i));36return;37}3839if (i >= INT8_MIN) {40EW.write(FirstByte::Int8);41EW.write(static_cast<int8_t>(i));42return;43}4445if (i >= INT16_MIN) {46EW.write(FirstByte::Int16);47EW.write(static_cast<int16_t>(i));48return;49}5051if (i >= INT32_MIN) {52EW.write(FirstByte::Int32);53EW.write(static_cast<int32_t>(i));54return;55}5657EW.write(FirstByte::Int64);58EW.write(i);59}6061void Writer::write(uint64_t u) {62if (u <= FixMax::PositiveInt) {63EW.write(static_cast<uint8_t>(u));64return;65}6667if (u <= UINT8_MAX) {68EW.write(FirstByte::UInt8);69EW.write(static_cast<uint8_t>(u));70return;71}7273if (u <= UINT16_MAX) {74EW.write(FirstByte::UInt16);75EW.write(static_cast<uint16_t>(u));76return;77}7879if (u <= UINT32_MAX) {80EW.write(FirstByte::UInt32);81EW.write(static_cast<uint32_t>(u));82return;83}8485EW.write(FirstByte::UInt64);86EW.write(u);87}8889void Writer::write(double d) {90// If no loss of precision, encode as a Float32.91double a = std::fabs(d);92if (a >= std::numeric_limits<float>::min() &&93a <= std::numeric_limits<float>::max()) {94EW.write(FirstByte::Float32);95EW.write(static_cast<float>(d));96} else {97EW.write(FirstByte::Float64);98EW.write(d);99}100}101102void Writer::write(StringRef s) {103size_t Size = s.size();104105if (Size <= FixMax::String)106EW.write(static_cast<uint8_t>(FixBits::String | Size));107else if (!Compatible && Size <= UINT8_MAX) {108EW.write(FirstByte::Str8);109EW.write(static_cast<uint8_t>(Size));110} else if (Size <= UINT16_MAX) {111EW.write(FirstByte::Str16);112EW.write(static_cast<uint16_t>(Size));113} else {114assert(Size <= UINT32_MAX && "String object too long to be encoded");115EW.write(FirstByte::Str32);116EW.write(static_cast<uint32_t>(Size));117}118119EW.OS << s;120}121122void Writer::write(MemoryBufferRef Buffer) {123assert(!Compatible && "Attempt to write Bin format in compatible mode");124125size_t Size = Buffer.getBufferSize();126127if (Size <= UINT8_MAX) {128EW.write(FirstByte::Bin8);129EW.write(static_cast<uint8_t>(Size));130} else if (Size <= UINT16_MAX) {131EW.write(FirstByte::Bin16);132EW.write(static_cast<uint16_t>(Size));133} else {134assert(Size <= UINT32_MAX && "Binary object too long to be encoded");135EW.write(FirstByte::Bin32);136EW.write(static_cast<uint32_t>(Size));137}138139EW.OS.write(Buffer.getBufferStart(), Size);140}141142void Writer::writeArraySize(uint32_t Size) {143if (Size <= FixMax::Array) {144EW.write(static_cast<uint8_t>(FixBits::Array | Size));145return;146}147148if (Size <= UINT16_MAX) {149EW.write(FirstByte::Array16);150EW.write(static_cast<uint16_t>(Size));151return;152}153154EW.write(FirstByte::Array32);155EW.write(Size);156}157158void Writer::writeMapSize(uint32_t Size) {159if (Size <= FixMax::Map) {160EW.write(static_cast<uint8_t>(FixBits::Map | Size));161return;162}163164if (Size <= UINT16_MAX) {165EW.write(FirstByte::Map16);166EW.write(static_cast<uint16_t>(Size));167return;168}169170EW.write(FirstByte::Map32);171EW.write(Size);172}173174void Writer::writeExt(int8_t Type, MemoryBufferRef Buffer) {175size_t Size = Buffer.getBufferSize();176177switch (Size) {178case FixLen::Ext1:179EW.write(FirstByte::FixExt1);180break;181case FixLen::Ext2:182EW.write(FirstByte::FixExt2);183break;184case FixLen::Ext4:185EW.write(FirstByte::FixExt4);186break;187case FixLen::Ext8:188EW.write(FirstByte::FixExt8);189break;190case FixLen::Ext16:191EW.write(FirstByte::FixExt16);192break;193default:194if (Size <= UINT8_MAX) {195EW.write(FirstByte::Ext8);196EW.write(static_cast<uint8_t>(Size));197} else if (Size <= UINT16_MAX) {198EW.write(FirstByte::Ext16);199EW.write(static_cast<uint16_t>(Size));200} else {201assert(Size <= UINT32_MAX && "Ext size too large to be encoded");202EW.write(FirstByte::Ext32);203EW.write(static_cast<uint32_t>(Size));204}205}206207EW.write(Type);208EW.OS.write(Buffer.getBufferStart(), Size);209}210211212