1 /* 2 * Copyright (c) 2017-2019 sel-project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in all 12 * copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 */ 23 /** 24 * Copyright: Copyright (c) 2017-2019 sel-project 25 * License: MIT 26 * Authors: Kripth 27 * Source: $(HTTP github.com/sel-project/selery/source/selery/hncom/io.d, selery/hncom/io.d) 28 */ 29 module selery.hncom.io; 30 31 import std.json : JSONValue, parseJSON, JSONException; 32 import std.socket : Address, InternetAddress, Internet6Address, UnknownAddress; 33 import std.system : Endian; 34 import std.uuid : UUID; 35 36 import xpacket; 37 38 alias HncomPacket = PacketImpl!(Endian.littleEndian, ubyte, ushort); 39 40 struct HncomUUID { 41 42 public static void serialize(UUID value, Buffer buffer) { 43 buffer.write(value.data); 44 } 45 46 public static UUID deserialize(Buffer buffer) { 47 return UUID(read16(buffer)); 48 } 49 50 } 51 52 struct HncomAddress { 53 54 public static void serialize(Address value, Buffer buffer) { 55 if(cast(InternetAddress)value) { 56 InternetAddress address = cast(InternetAddress)value; 57 buffer.write!ubyte(4); 58 buffer.write!(Endian.littleEndian)(address.addr); 59 buffer.write!(Endian.littleEndian)(address.port); 60 } else if(cast(Internet6Address)value) { 61 Internet6Address address = cast(Internet6Address)value; 62 buffer.write!ubyte(6); 63 buffer.write(address.addr); 64 buffer.write!(Endian.littleEndian)(address.port); 65 } else { 66 buffer.write!ubyte(0); 67 } 68 } 69 70 public static Address deserialize(Buffer buffer) { 71 switch(buffer.read!ubyte()) { 72 case 4: return new InternetAddress(buffer.read!(Endian.littleEndian, int)(), buffer.read!(Endian.littleEndian, ushort)()); 73 case 6: return new Internet6Address(read16(buffer), buffer.read!(Endian.littleEndian, ushort)()); 74 default: return new UnknownAddress(); 75 } 76 } 77 78 } 79 80 ubyte[16] read16(Buffer buffer) { 81 ubyte[16] ret = buffer.read!(ubyte[])(16); 82 return ret; 83 } 84 85 mixin template Make() { 86 87 static import xserial.serial; 88 89 mixin({ 90 91 string ret = "this("; 92 foreach(member ; xserial.serial.Members!(typeof(this), null)) { 93 ret ~= "typeof(" ~ member ~ ") " ~ member ~ "=typeof(" ~ member ~ ").init,"; 94 } 95 ret ~= "){"; 96 foreach(member ;xserial.serial.Members!(typeof(this), null)) { 97 ret ~= "this." ~ member ~ "=" ~ member ~ ";"; 98 } 99 return ret ~ "}"; 100 101 }()); 102 103 static import xpacket.maker; 104 105 mixin xpacket.maker.Make; 106 107 static typeof(this) fromBuffer(ubyte[] buffer) { 108 typeof(this) ret = new typeof(this)(); 109 ret.decode(buffer); 110 return ret; 111 } 112 113 }