summary refs log tree commit diff stats
diff options
context:
space:
mode:
authordef <dennis@felsin9.de>2015-03-17 18:15:47 +0100
committerdef <dennis@felsin9.de>2015-03-17 19:40:22 +0100
commite127ed77b1ef94a551c86b6a78ae8a08dcbba159 (patch)
tree5165c7cc22173a8961e499e3672b7d1fd52f1966
parent43ed83384c41a97f3b36c4569e1dfd1ec4f43226 (diff)
downloadNim-e127ed77b1ef94a551c86b6a78ae8a08dcbba159.tar.gz
Make recvLineInto a proc instead of template
-rw-r--r--lib/pure/asynchttpserver.nim4
-rw-r--r--lib/pure/asyncnet.nim98
2 files changed, 50 insertions, 52 deletions
diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim
index 5c32389cc..22ea5e4bb 100644
--- a/lib/pure/asynchttpserver.nim
+++ b/lib/pure/asynchttpserver.nim
@@ -163,7 +163,7 @@ proc processClient(client: AsyncSocket, address: string,
 
     # First line - GET /path HTTP/1.1
     line.setLen(0)
-    client.recvLineInto(line) # TODO: Timeouts.
+    await client.recvLineInto(addr line) # TODO: Timeouts.
     if line == "":
       client.close()
       return
@@ -189,7 +189,7 @@ proc processClient(client: AsyncSocket, address: string,
     while true:
       i = 0
       line.setLen(0)
-      client.recvLineInto(line)
+      await client.recvLineInto(addr line)
 
       if line == "":
         client.close(); return
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index cb137cfe5..0c8ed8a08 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -307,8 +307,8 @@ proc accept*(socket: AsyncSocket,
         retFut.complete(future.read.client)
   return retFut
 
-template recvLineInto*(socket: AsyncSocket, resString: var string,
-    flags = {SocketFlag.SafeDisconn}) =
+proc recvLineInto*(socket: AsyncSocket, resString: ptr string,
+    flags = {SocketFlag.SafeDisconn}): Future[void] {.async.} =
   ## Reads a line of data from ``socket`` into ``resString``.
   ##
   ## If a full line is read ``\r\L`` is not
@@ -326,61 +326,59 @@ template recvLineInto*(socket: AsyncSocket, resString: var string,
   ## **Warning**: ``recvLineInto`` on unbuffered sockets assumes that the
   ## protocol uses ``\r\L`` to delimit a new line.
   assert SocketFlag.Peek notin flags ## TODO:
+  result = newFuture[void]("asyncnet.recvLineInto")
 
   template addNLIfEmpty(): stmt =
-    if resString.len == 0:
-      resString.add("\c\L")
+    if resString[].len == 0:
+      resString[].add("\c\L")
 
-  block recvLineInto:
-    if socket.isBuffered:
-      if socket.bufLen == 0:
+  if socket.isBuffered:
+    if socket.bufLen == 0:
+      let res = socket.readIntoBuf(flags)
+      if res == 0:
+        return
+
+    var lastR = false
+    while true:
+      if socket.currPos >= socket.bufLen:
         let res = socket.readIntoBuf(flags)
         if res == 0:
-          break recvLineInto
-
-      var lastR = false
-      while true:
-        if socket.currPos >= socket.bufLen:
-          let res = socket.readIntoBuf(flags)
-          if res == 0:
-            resString.setLen(0)
-            break recvLineInto
-
-        case socket.buffer[socket.currPos]
-        of '\r':
-          lastR = true
-          addNLIfEmpty()
-        of '\L':
-          addNLIfEmpty()
+          resString[].setLen(0)
+          return
+
+      case socket.buffer[socket.currPos]
+      of '\r':
+        lastR = true
+        addNLIfEmpty()
+      of '\L':
+        addNLIfEmpty()
+        socket.currPos.inc()
+        return
+      else:
+        if lastR:
           socket.currPos.inc()
-          break recvLineInto
+          return
         else:
-          if lastR:
-            socket.currPos.inc()
-            break recvLineInto
-          else:
-            resString.add socket.buffer[socket.currPos]
-        socket.currPos.inc()
-    else:
-      var c = ""
-      while true:
-        let recvFut = recv(socket, 1, flags)
-        yield recvFut
+          resString[].add socket.buffer[socket.currPos]
+      socket.currPos.inc()
+  else:
+    var c = ""
+    while true:
+      let recvFut = recv(socket, 1, flags)
+      c = recvFut.read()
+      if c.len == 0:
+        resString[].setLen(0)
+        return
+      if c == "\r":
+        let recvFut = recv(socket, 1, flags) # Skip \L
         c = recvFut.read()
-        if c.len == 0:
-          resString.setLen(0)
-          break recvLineInto
-        if c == "\r":
-          let recvFut = recv(socket, 1, flags) # Skip \L
-          yield recvFut
-          c = recvFut.read()
-          assert c == "\L"
-          addNLIfEmpty()
-          break recvLineInto
-        elif c == "\L":
-          addNLIfEmpty()
-          break recvLineInto
-        add(resString, c)
+        assert c == "\L"
+        addNLIfEmpty()
+        return
+      elif c == "\L":
+        addNLIfEmpty()
+        return
+      add(resString[], c)
 
 proc recvLine*(socket: AsyncSocket,
     flags = {SocketFlag.SafeDisconn}): Future[string] {.async.} =
@@ -407,7 +405,7 @@ proc recvLine*(socket: AsyncSocket,
   assert SocketFlag.Peek notin flags ## TODO:
 
   result = ""
-  socket.recvLineInto(result, flags)
+  await socket.recvLineInto(addr result, flags)
 
 proc listen*(socket: AsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
   ## Marks ``socket`` as accepting connections.