1 /** 2 * Standalone encoding/decoding functions 3 */ 4 module bformat.marshall; 5 6 import niknaks.bits : toBytes, bytesToIntegral, order, Order; 7 8 /** 9 * Decodes the provided bformat message into the 10 * message itself 11 * 12 * Params: 13 * bformatBytes = the bformat payload the decode 14 * Returns: the decoded message 15 */ 16 public byte[] decodeMessage(byte[] bformatBytes) 17 { 18 /* Construct a buffer to receive into */ 19 byte[] receiveBuffer; 20 21 /* Get the length of the message */ 22 byte[4] messageLengthBytes = bformatBytes[0..4]; 23 24 /* Response message length */ 25 uint messageLength; 26 27 /* Order the bytes into Little endian (only flips if host order doesn't match LE) */ 28 messageLength = order(bytesToIntegral!(uint)(cast(ubyte[])messageLengthBytes), Order.LE); 29 30 31 /* Read the full message */ 32 receiveBuffer = bformatBytes[4..4+messageLength]; 33 34 return receiveBuffer; 35 } 36 37 /** 38 * Encodes the provided message into the bformat format 39 * 40 * Params: 41 * message = the buffer containing bytes to encode 42 * Returns: the encoded payload 43 */ 44 public byte[] encodeBformat(byte[] message) 45 { 46 /* The message buffer */ 47 byte[] messageBuffer; 48 49 /* Encode the 4 byte message length header (little endian) */ 50 messageBuffer ~= cast(byte[])toBytes(order(cast(int)message.length, Order.LE)); 51 52 /* Add the message to the buffer */ 53 messageBuffer ~= cast(byte[])message; 54 55 return messageBuffer; 56 } 57 58 version(unittest) 59 { 60 import std.string : cmp; 61 } 62 63 unittest 64 { 65 string message = "This is my message"; 66 byte[] bformatEncoded = encodeBformat(cast(byte[])message); 67 68 byte[] decodedMessageBytes = decodeMessage(bformatEncoded); 69 string decodedMessage = cast(string)decodedMessageBytes; 70 71 assert(cmp(message, decodedMessage) == 0); 72 }