From 543687f34536eb146a509554035df733ba83cffc Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 30 Apr 2014 22:50:17 +0100 Subject: [PATCH] Fixes buffered recv in asyncnet. --- lib/pure/asyncnet.nim | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index b1abf627bb..9394078c83 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -97,29 +97,35 @@ proc recv*(socket: PAsyncSocket, size: int, ## to be read then the future will complete with a value of ``""``. if socket.isBuffered: result = newString(size) - - template returnNow(readBytes: int) = - result.setLen(readBytes) - # Only increase buffer position when not peeking. - if (flags and MSG_PEEK) != MSG_PEEK: - socket.currPos.inc(readBytes) - return + let originalBufPos = socket.currPos if socket.bufLen == 0: let res = await socket.readIntoBuf(flags and (not MSG_PEEK)) - if res == 0: returnNow(0) + if res == 0: + result.setLen(0) + return var read = 0 while read < size: if socket.currPos >= socket.bufLen: + if (flags and MSG_PEEK) == MSG_PEEK: + # We don't want to get another buffer if we're peeking. + result.setLen(read) + return let res = await socket.readIntoBuf(flags and (not MSG_PEEK)) - if res == 0: returnNow(read) + if res == 0: + result.setLen(read) + return let chunk = min(socket.bufLen-socket.currPos, size-read) - copyMem(addr(result[read]), addr(socket.buffer[socket.currPos+read]), chunk) + copyMem(addr(result[read]), addr(socket.buffer[socket.currPos]), chunk) read.inc(chunk) + socket.currPos.inc(chunk) - returnNow(read) + if (flags and MSG_PEEK) == MSG_PEEK: + # Restore old buffer cursor position. + socket.currPos = originalBufPos + result.setLen(read) else: result = await recv(socket.fd.TAsyncFD, size, flags)