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