1 /** 2 * Модуль сериализатора MessagePack 3 * 4 * Copyright: (c) 2015-2017, Milofon Project. 5 * License: Subject to the terms of the BSD license, as written in the included LICENSE.txt file. 6 * Author: <m.galanin@milofon.org> Maksim Galanin 7 * Date: 2018-01-28 8 */ 9 10 module dango.service.serializer.msgpack; 11 12 private 13 { 14 import std.algorithm.searching : startsWith; 15 16 import proped : Properties; 17 import msgpack; 18 19 import dango.service.serializer.core; 20 } 21 22 23 class MsgPackSerializer : Serializer 24 { 25 private bool _withFieldName; 26 27 28 this() 29 { 30 _withFieldName = false; 31 } 32 33 34 this(bool withFieldName) 35 { 36 _withFieldName = withFieldName; 37 } 38 39 40 override void initialize(Properties config) 41 { 42 _withFieldName = config.getOrElse!bool("withFieldName", false); 43 } 44 45 46 override UniNode deserialize(ubyte[] bytes) 47 { 48 auto unpacker = StreamingUnpacker(bytes); 49 unpacker.execute(); 50 return toUniNode(unpacker.purge); 51 } 52 53 54 override ubyte[] serialize(UniNode node) 55 { 56 Value val = fromUniNode(node); 57 auto packer = Packer(_withFieldName); 58 val.toMsgpack(packer); 59 return packer.stream.data; 60 } 61 } 62 63 64 private: 65 66 67 UniNode toUniNode(Value input) 68 { 69 UniNode convert(Value node) 70 { 71 switch(node.type) with (Value) 72 { 73 case Type.nil: 74 return UniNode(); 75 case Type.boolean: 76 return UniNode(node.via.boolean); 77 case Type.unsigned: 78 return UniNode(node.via.uinteger); 79 case Type.signed: 80 return UniNode(node.via.integer); 81 case Type.floating: 82 return UniNode(node.via.floating); 83 case Type.raw: 84 return UniNode(node.via.raw); 85 case Type.array: 86 { 87 UniNode[] arr = new UniNode[](node.via.array.length); 88 foreach(i, Value ch; node.via.array) 89 arr[i] = convert(ch); 90 return UniNode(arr); 91 } 92 case Type.map: 93 { 94 UniNode[string] map; 95 foreach(Value key, Value ch; node.via.map) 96 { 97 string k = cast(string)key.via.raw; 98 map[k] = convert(ch); 99 } 100 return UniNode(map); 101 } 102 default: 103 return UniNode(); 104 } 105 } 106 107 return convert(input); 108 } 109 110 111 Value fromUniNode(UniNode input) 112 { 113 Value convert(UniNode node) 114 { 115 switch(node.type) with (UniNode) 116 { 117 case Type.nil: 118 return Value(); 119 case Type.boolean: 120 return Value(node.get!bool); 121 case Type.signed: 122 return Value(node.get!long); 123 case Type.unsigned: 124 return Value(node.get!ulong); 125 case Type.floating: 126 return Value(node.get!double); 127 case Type.raw: 128 return Value(node.get!(ubyte[])); 129 case Type.text: 130 return Value(node.get!(string)); 131 case Type.array: 132 { 133 Value[] arr; 134 foreach(UniNode ch; node.get!(UniNode[])) 135 arr ~= convert(ch); 136 return Value(arr); 137 } 138 case Type.object: 139 { 140 Value[Value] map; 141 foreach(string key, UniNode ch; node.get!(UniNode[string])) 142 map[Value(key)] = convert(ch); 143 return Value(map); 144 } 145 default: 146 return Value(); 147 } 148 } 149 150 return convert(input); 151 }