diff options
Diffstat (limited to 'lib/pure/asyncnet.nim')
-rw-r--r-- | lib/pure/asyncnet.nim | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index b88fd80c0..a91bcf87a 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -419,10 +419,13 @@ proc accept*(socket: AsyncSocket, retFut.complete(future.read.client) return retFut -proc recvLineInto*(socket: AsyncSocket, resString: ptr string, +proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string], flags = {SocketFlag.SafeDisconn}) {.async.} = ## Reads a line of data from ``socket`` into ``resString``. ## + ## The ``resString`` future and the string value contained within must both + ## be initialised. + ## ## If a full line is read ``\r\L`` is not ## added to ``line``, however if solely ``\r\L`` is read then ``line`` ## will be set to it. @@ -438,16 +441,23 @@ proc recvLineInto*(socket: AsyncSocket, resString: ptr string, ## **Warning**: ``recvLineInto`` on unbuffered sockets assumes that the ## protocol uses ``\r\L`` to delimit a new line. assert SocketFlag.Peek notin flags ## TODO: + assert(not resString.mget.isNil(), + "String inside resString future needs to be initialised") result = newFuture[void]("asyncnet.recvLineInto") + # TODO: Make the async transformation check for FutureVar params and complete + # them when the result future is completed. + # Can we replace the result future with the FutureVar? + template addNLIfEmpty(): stmt = - if resString[].len == 0: - resString[].add("\c\L") + if resString.mget.len == 0: + resString.mget.add("\c\L") if socket.isBuffered: if socket.bufLen == 0: let res = socket.readIntoBuf(flags) if res == 0: + resString.complete() return var lastR = false @@ -455,7 +465,8 @@ proc recvLineInto*(socket: AsyncSocket, resString: ptr string, if socket.currPos >= socket.bufLen: let res = socket.readIntoBuf(flags) if res == 0: - resString[].setLen(0) + resString.mget().setLen(0) + resString.complete() return case socket.buffer[socket.currPos] @@ -465,13 +476,15 @@ proc recvLineInto*(socket: AsyncSocket, resString: ptr string, of '\L': addNLIfEmpty() socket.currPos.inc() + resString.complete() return else: if lastR: socket.currPos.inc() + resString.complete() return else: - resString[].add socket.buffer[socket.currPos] + resString.mget.add socket.buffer[socket.currPos] socket.currPos.inc() else: var c = "" @@ -479,18 +492,23 @@ proc recvLineInto*(socket: AsyncSocket, resString: ptr string, let recvFut = recv(socket, 1, flags) c = recvFut.read() if c.len == 0: - resString[].setLen(0) + resString.mget.setLen(0) + resString.complete() return if c == "\r": let recvFut = recv(socket, 1, flags) # Skip \L c = recvFut.read() assert c == "\L" addNLIfEmpty() + resString.complete() return elif c == "\L": addNLIfEmpty() + resString.complete() return - resString[].add c + resString.mget.add c + + resString.complete() proc recvLine*(socket: AsyncSocket, flags = {SocketFlag.SafeDisconn}): Future[string] {.async.} = @@ -516,8 +534,10 @@ proc recvLine*(socket: AsyncSocket, result.add("\c\L") assert SocketFlag.Peek notin flags ## TODO: - result = "" - await socket.recvLineInto(addr result, flags) + # TODO: Optimise this. + var resString = newFutureVar[string]("asyncnet.recvLine") + await socket.recvLineInto(resString, flags) + result = resString.mget() proc listen*(socket: AsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. |