1 module bmessage;
2 
3 import std.socket : Socket, SocketFlags, MSG_WAITALL;
4 
5 public bool receiveMessage(Socket originator, ref byte[] receiveMessage)
6 {
7 	/* Construct a buffer to receive into */
8 	byte[] receiveBuffer;
9 
10 	bool status = true;
11 
12 
13 	/* The amount of bytes received */
14 	long bytesReceived;
15 
16 	/* Get the length of the message */
17 	byte[4] messageLengthBytes;
18 	bytesReceived = originator.receive(messageLengthBytes, cast(SocketFlags)MSG_WAITALL);
19 
20 	/* If there was an error reading from the socket */
21 	if(!(bytesReceived > 0))
22 	{
23 		status =  false;
24 	}
25 	/* If the receive was successful */
26 	else
27 	{
28 		/* Response message length */
29 		uint messageLength;
30 
31 		/* Little endian version you simply read if off the bone (it's already in the correct order) */
32 		version(LittleEndian)
33 		{
34 			messageLength = *cast(int*)messageLengthBytes.ptr;
35 		}
36 
37 		/* Big endian requires we byte-sapped the little-endian encoded number */
38 		version(BigEndian)
39 		{
40 			byte[] swappedLength;
41 			swappedLength.length = 4;
42 
43 			swappedLength[0] = messageLengthBytes[3];
44 			swappedLength[1] = messageLengthBytes[2];
45 			swappedLength[2] = messageLengthBytes[1];
46 			swappedLength[3] = messageLengthBytes[0];
47 
48 			messageLength = *cast(int*)swappedLength.ptr;
49 		}
50 
51 
52 		/* Read the full message */
53 		receiveBuffer.length = messageLength;
54 		bytesReceived = originator.receive(receiveBuffer, cast(SocketFlags)MSG_WAITALL);
55 
56 		/* If there was an error reading from the socket */
57 		if(!(bytesReceived > 0))
58 		{
59 			status = false;
60 		}
61 		/* If there was no error receiving the message */
62 		else
63 		{
64 			receiveMessage = receiveBuffer;
65 		}
66 	}
67 
68 	return status;
69 }
70 
71 public byte[] encodeBformat(byte[] message)
72 {
73 	/* The message buffer */
74 	byte[] messageBuffer;
75 
76 	/* Encode the 4 byte message length header (little endian) */
77 	int payloadLength = cast(int)message.length;
78 	byte* lengthBytes = cast(byte*)&payloadLength;
79 
80 	/* On little endian simply get the bytes as is (it would be encoded as little endian) */
81 	version(LittleEndian)
82 	{
83 		messageBuffer ~= *(lengthBytes+0);
84 		messageBuffer ~= *(lengthBytes+1);
85 		messageBuffer ~= *(lengthBytes+2);
86 		messageBuffer ~= *(lengthBytes+3);
87 	}
88 
89 	/* On Big Endian you must swap the big-endian-encoded number to be in little endian ordering */
90 	version(BigEndian)
91 	{
92 		messageBuffer ~= *(lengthBytes+3);
93 		messageBuffer ~= *(lengthBytes+2);
94 		messageBuffer ~= *(lengthBytes+1);
95 		messageBuffer ~= *(lengthBytes+0);
96 	}
97 	
98 
99 	/* Add the message to the buffer */
100 	messageBuffer ~= cast(byte[])message;
101 
102 	return messageBuffer;
103 }
104 
105 public bool sendMessage(Socket recipient, byte[] message)
106 {
107 	/* The message buffer */
108 	byte[] messageBuffer;
109 
110 	/* Encode the 4 byte message length header (little endian) */
111 	int payloadLength = cast(int)message.length;
112 	byte* lengthBytes = cast(byte*)&payloadLength;
113 
114 	/* On little endian simply get the bytes as is (it would be encoded as little endian) */
115 	version(LittleEndian)
116 	{
117 		messageBuffer ~= *(lengthBytes+0);
118 		messageBuffer ~= *(lengthBytes+1);
119 		messageBuffer ~= *(lengthBytes+2);
120 		messageBuffer ~= *(lengthBytes+3);
121 	}
122 
123 	/* On Big Endian you must swap the big-endian-encoded number to be in little endian ordering */
124 	version(BigEndian)
125 	{
126 		messageBuffer ~= *(lengthBytes+3);
127 		messageBuffer ~= *(lengthBytes+2);
128 		messageBuffer ~= *(lengthBytes+1);
129 		messageBuffer ~= *(lengthBytes+0);
130 	}
131 	
132 
133 	/* Add the message to the buffer */
134 	messageBuffer ~= cast(byte[])message;
135 
136 	/* Send the message */
137 	long bytesSent = recipient.send(messageBuffer);
138 
139 	/* TODO: Compact this */
140 	return bytesSent > 0;
141 }