module i3ipc.socket; import core.time : Duration, dur; import core.thread : Fiber, Thread; import std.socket : Socket, SocketException, wouldHaveBlocked; import std.exception : enforce; ubyte[] receiveExactly(Socket socket, ubyte[] buffer, Duration spinDelay = dur!"msecs"(100)) { ptrdiff_t position = 0; ptrdiff_t amountRead = 0; while (position < buffer.length) { amountRead = socket.receive(buffer[position .. $]); enforce!SocketException(0 != amountRead, "Remote closed socket prematurely"); if (Socket.ERROR == amountRead) { enforce!SocketException(wouldHaveBlocked, socket.getErrorText); if (Fiber.getThis !is null) { Fiber.yield; } else { Thread.sleep(spinDelay); } } else { position += amountRead; } } return buffer; } T receiveExactly(T)(Socket socket) if (is(T == struct)) { ubyte[T.sizeof] buffer; return *(cast (T*) socket.receiveExactly(buffer)); }