brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · d3b557d Raw
211 lines · cpp
1//===- MsgPackWriter.cpp - Simple MsgPack writer ----------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9///  \file10///  This file implements a MessagePack writer.11///12//===----------------------------------------------------------------------===//13 14#include "llvm/BinaryFormat/MsgPackWriter.h"15#include "llvm/BinaryFormat/MsgPack.h"16 17#include <cmath>18 19using namespace llvm;20using namespace msgpack;21 22Writer::Writer(raw_ostream &OS, bool Compatible)23    : EW(OS, Endianness), Compatible(Compatible) {}24 25void Writer::writeNil() { EW.write(FirstByte::Nil); }26 27void Writer::write(bool b) { EW.write(b ? FirstByte::True : FirstByte::False); }28 29void Writer::write(int64_t i) {30  if (i >= 0) {31    write(static_cast<uint64_t>(i));32    return;33  }34 35  if (i >= FixMin::NegativeInt) {36    EW.write(static_cast<int8_t>(i));37    return;38  }39 40  if (i >= INT8_MIN) {41    EW.write(FirstByte::Int8);42    EW.write(static_cast<int8_t>(i));43    return;44  }45 46  if (i >= INT16_MIN) {47    EW.write(FirstByte::Int16);48    EW.write(static_cast<int16_t>(i));49    return;50  }51 52  if (i >= INT32_MIN) {53    EW.write(FirstByte::Int32);54    EW.write(static_cast<int32_t>(i));55    return;56  }57 58  EW.write(FirstByte::Int64);59  EW.write(i);60}61 62void Writer::write(uint64_t u) {63  if (u <= FixMax::PositiveInt) {64    EW.write(static_cast<uint8_t>(u));65    return;66  }67 68  if (u <= UINT8_MAX) {69    EW.write(FirstByte::UInt8);70    EW.write(static_cast<uint8_t>(u));71    return;72  }73 74  if (u <= UINT16_MAX) {75    EW.write(FirstByte::UInt16);76    EW.write(static_cast<uint16_t>(u));77    return;78  }79 80  if (u <= UINT32_MAX) {81    EW.write(FirstByte::UInt32);82    EW.write(static_cast<uint32_t>(u));83    return;84  }85 86  EW.write(FirstByte::UInt64);87  EW.write(u);88}89 90void Writer::write(double d) {91  // If no loss of precision, encode as a Float32.92  double a = std::fabs(d);93  if (a >= std::numeric_limits<float>::min() &&94      a <= std::numeric_limits<float>::max()) {95    EW.write(FirstByte::Float32);96    EW.write(static_cast<float>(d));97  } else {98    EW.write(FirstByte::Float64);99    EW.write(d);100  }101}102 103void Writer::write(StringRef s) {104  size_t Size = s.size();105 106  if (Size <= FixMax::String)107    EW.write(static_cast<uint8_t>(FixBits::String | Size));108  else if (!Compatible && Size <= UINT8_MAX) {109    EW.write(FirstByte::Str8);110    EW.write(static_cast<uint8_t>(Size));111  } else if (Size <= UINT16_MAX) {112    EW.write(FirstByte::Str16);113    EW.write(static_cast<uint16_t>(Size));114  } else {115    assert(Size <= UINT32_MAX && "String object too long to be encoded");116    EW.write(FirstByte::Str32);117    EW.write(static_cast<uint32_t>(Size));118  }119 120  EW.OS << s;121}122 123void Writer::write(MemoryBufferRef Buffer) {124  assert(!Compatible && "Attempt to write Bin format in compatible mode");125 126  size_t Size = Buffer.getBufferSize();127 128  if (Size <= UINT8_MAX) {129    EW.write(FirstByte::Bin8);130    EW.write(static_cast<uint8_t>(Size));131  } else if (Size <= UINT16_MAX) {132    EW.write(FirstByte::Bin16);133    EW.write(static_cast<uint16_t>(Size));134  } else {135    assert(Size <= UINT32_MAX && "Binary object too long to be encoded");136    EW.write(FirstByte::Bin32);137    EW.write(static_cast<uint32_t>(Size));138  }139 140  EW.OS.write(Buffer.getBufferStart(), Size);141}142 143void Writer::writeArraySize(uint32_t Size) {144  if (Size <= FixMax::Array) {145    EW.write(static_cast<uint8_t>(FixBits::Array | Size));146    return;147  }148 149  if (Size <= UINT16_MAX) {150    EW.write(FirstByte::Array16);151    EW.write(static_cast<uint16_t>(Size));152    return;153  }154 155  EW.write(FirstByte::Array32);156  EW.write(Size);157}158 159void Writer::writeMapSize(uint32_t Size) {160  if (Size <= FixMax::Map) {161    EW.write(static_cast<uint8_t>(FixBits::Map | Size));162    return;163  }164 165  if (Size <= UINT16_MAX) {166    EW.write(FirstByte::Map16);167    EW.write(static_cast<uint16_t>(Size));168    return;169  }170 171  EW.write(FirstByte::Map32);172  EW.write(Size);173}174 175void Writer::writeExt(int8_t Type, MemoryBufferRef Buffer) {176  size_t Size = Buffer.getBufferSize();177 178  switch (Size) {179  case FixLen::Ext1:180    EW.write(FirstByte::FixExt1);181    break;182  case FixLen::Ext2:183    EW.write(FirstByte::FixExt2);184    break;185  case FixLen::Ext4:186    EW.write(FirstByte::FixExt4);187    break;188  case FixLen::Ext8:189    EW.write(FirstByte::FixExt8);190    break;191  case FixLen::Ext16:192    EW.write(FirstByte::FixExt16);193    break;194  default:195    if (Size <= UINT8_MAX) {196      EW.write(FirstByte::Ext8);197      EW.write(static_cast<uint8_t>(Size));198    } else if (Size <= UINT16_MAX) {199      EW.write(FirstByte::Ext16);200      EW.write(static_cast<uint16_t>(Size));201    } else {202      assert(Size <= UINT32_MAX && "Ext size too large to be encoded");203      EW.write(FirstByte::Ext32);204      EW.write(static_cast<uint32_t>(Size));205    }206  }207 208  EW.write(Type);209  EW.OS.write(Buffer.getBufferStart(), Size);210}211