1
0
Fork 0
mirror of https://github.com/besterprotocol/bformat synced 2023-12-13 21:30:24 +01:00
bformat/source/bformat/sockets.d

132 lines
3.2 KiB
D
Raw Normal View History

2023-03-25 20:36:09 +01:00
/**
* Socket encoding/decoding functions
*/
2023-03-25 19:59:38 +01:00
module bformat.sockets;
2020-05-02 19:19:20 +02:00
2020-12-04 16:41:24 +01:00
import std.socket : Socket, SocketFlags, MSG_WAITALL;
2020-05-02 19:19:20 +02:00
2023-03-25 19:59:38 +01:00
/**
* Receives a message from the provided socket
* by decoding the streamed bytes into bformat
* and finally placing the resulting payload in
* the provided array
*
2023-03-25 19:59:38 +01:00
* Params:
* originator = the socket to receive from
* receiveMessage = the nbuffer to receive into
*
* Returns: true if the receive succeeded, false otheriwse
2023-03-25 19:59:38 +01:00
*/
2020-06-16 18:09:41 +02:00
public bool receiveMessage(Socket originator, ref byte[] receiveMessage)
2020-05-02 19:19:20 +02:00
{
/* Construct a buffer to receive into */
byte[] receiveBuffer;
2021-07-16 18:08:01 +02:00
bool status = true;
2020-12-04 17:55:25 +01:00
/* The amount of bytes received */
long bytesReceived;
2021-07-16 18:08:01 +02:00
/* Get the length of the message */
byte[4] messageLengthBytes;
bytesReceived = originator.receive(messageLengthBytes, cast(SocketFlags)MSG_WAITALL);
2020-12-04 17:55:25 +01:00
2021-07-16 18:08:01 +02:00
/* If there was an error reading from the socket */
if(!(bytesReceived > 0))
{
status = false;
}
/* If the receive was successful */
else
{
/* Response message length */
uint messageLength;
2020-12-04 17:55:25 +01:00
2021-07-16 18:08:01 +02:00
/* Little endian version you simply read if off the bone (it's already in the correct order) */
version(LittleEndian)
2020-12-04 17:55:25 +01:00
{
2021-07-16 18:08:01 +02:00
messageLength = *cast(int*)messageLengthBytes.ptr;
2020-12-04 17:55:25 +01:00
}
2021-07-16 18:08:01 +02:00
/* Big endian requires we byte-sapped the little-endian encoded number */
version(BigEndian)
{
byte[] swappedLength;
swappedLength.length = 4;
2021-07-16 18:08:01 +02:00
swappedLength[0] = messageLengthBytes[3];
swappedLength[1] = messageLengthBytes[2];
swappedLength[2] = messageLengthBytes[1];
swappedLength[3] = messageLengthBytes[0];
2021-07-16 18:08:01 +02:00
messageLength = *cast(int*)swappedLength.ptr;
}
2020-05-02 19:19:20 +02:00
2021-07-16 18:08:01 +02:00
/* Read the full message */
receiveBuffer.length = messageLength;
bytesReceived = originator.receive(receiveBuffer, cast(SocketFlags)MSG_WAITALL);
2020-12-04 17:55:25 +01:00
2021-07-16 18:08:01 +02:00
/* If there was an error reading from the socket */
2020-12-04 17:55:25 +01:00
if(!(bytesReceived > 0))
{
2021-07-16 18:08:01 +02:00
status = false;
2020-12-04 17:55:25 +01:00
}
2021-07-16 18:08:01 +02:00
/* If there was no error receiving the message */
2020-12-04 17:55:25 +01:00
else
{
2021-07-16 18:08:01 +02:00
receiveMessage = receiveBuffer;
2020-12-04 17:55:25 +01:00
}
}
2020-05-02 19:19:20 +02:00
2021-07-16 18:08:01 +02:00
return status;
2020-05-02 19:19:20 +02:00
}
2023-03-25 19:59:38 +01:00
/**
* Encodes the provided message into the bformat format
* and sends it over the provided socket
*
2023-03-25 19:59:38 +01:00
* Params:
* recipient = the socket to send over
* message = the message to encode and send
*
* Returns: true if the send succeeded, false otherwise
2023-03-25 19:59:38 +01:00
*/
2020-06-16 18:09:41 +02:00
public bool sendMessage(Socket recipient, byte[] message)
2020-05-02 19:19:20 +02:00
{
/* The message buffer */
byte[] messageBuffer;
/* Encode the 4 byte message length header (little endian) */
int payloadLength = cast(int)message.length;
byte* lengthBytes = cast(byte*)&payloadLength;
/* On little endian simply get the bytes as is (it would be encoded as little endian) */
version(LittleEndian)
{
messageBuffer ~= *(lengthBytes+0);
messageBuffer ~= *(lengthBytes+1);
messageBuffer ~= *(lengthBytes+2);
messageBuffer ~= *(lengthBytes+3);
}
/* On Big Endian you must swap the big-endian-encoded number to be in little endian ordering */
version(BigEndian)
{
messageBuffer ~= *(lengthBytes+3);
messageBuffer ~= *(lengthBytes+2);
messageBuffer ~= *(lengthBytes+1);
messageBuffer ~= *(lengthBytes+0);
}
2020-05-02 19:19:20 +02:00
/* Add the message to the buffer */
messageBuffer ~= cast(byte[])message;
/* Send the message */
long bytesSent = recipient.send(messageBuffer);
/* TODO: Compact this */
return bytesSent > 0;
}