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