1 module libchonky; 2 3 /** 4 * libchonky 5 * 6 * 7 */ 8 9 import std.socket; 10 import core.sys.posix.sys.socket; 11 12 public final class ChonkReader 13 { 14 /* The socket to read from */ 15 private Socket socket; 16 private ptrdiff_t chunkSize; 17 18 this(Socket socket, ptrdiff_t chunkSize = 50) 19 { 20 /* THe socket must in STREAM mode */ 21 /* TODO */ 22 23 /* Save the socket */ 24 this.socket = socket; 25 26 /* Set the chunk size */ 27 this.chunkSize = chunkSize; 28 } 29 30 /** 31 * Read the amount given by the size of the buffer 32 * This uses MSG_WAITALL and will only return when 33 * the full amount bytes requested is fulfilled, 34 * not just the currently available amount in the 35 * kernel network queue 36 * 37 * Number of bytes received `0` if socket closed 38 * (follow the normal D-standard) or Socket.ERROR 39 * 40 * ptrdiff_t is signed (long -> int, depending on arch (compiler time)) 41 */ 42 public ptrdiff_t receiveAll(byte[] buffer) 43 { 44 /* Enable `MSG_WAITALL` flag */ 45 SocketFlags flags = cast(SocketFlags)MSG_WAITALL; 46 47 48 return socket.receive(buffer, flags); 49 } 50 51 52 /** 53 * Some applications have no header for length but 54 * demarcate the data ending by closing the socket 55 * here one would want to chunk read as making 56 * an assumption about how much data is sent would 57 * be futile 58 * 59 * This will read in chunks of `chunkSize` whilst 60 * stiching an array toghether. It will take in 61 * a pointer to (len, ptr) (a.k.a. an array) 62 * and set those for you. 63 * 64 * The total number of bytes is returned 65 */ 66 public ulong receiveUntilClose(ref byte[] buffer) 67 { 68 /* Temporary array */ 69 byte[] temp; 70 temp.length=chunkSize; 71 ulong bytesReceived; 72 73 while(true) 74 { 75 /* Receive chunk many bytes */ 76 ptrdiff_t byteCount = receiveAll(temp); 77 78 /* Ending (0 is closed socket, and I believe anything less would then be other errors) */ 79 if(byteCount <= 0) 80 { 81 break; 82 } 83 else 84 { 85 buffer ~= temp[0..byteCount]; 86 bytesReceived = bytesReceived + byteCount; 87 } 88 } 89 /* TODO: Implement me */ 90 return bytesReceived; 91 } 92 }