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 }