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