extmod/uasyncio: Implement stream read(-1) to read all data up to EOF.
Fixes issue #6355. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
2a2589738c
commit
db7682e02d
|
@ -237,9 +237,11 @@ TCP stream connections
|
|||
|
||||
This is a coroutine.
|
||||
|
||||
.. method:: Stream.read(n)
|
||||
.. method:: Stream.read(n=-1)
|
||||
|
||||
Read up to *n* bytes and return them.
|
||||
Read up to *n* bytes and return them. If *n* is not provided or -1 then read all
|
||||
bytes until EOF. The returned value will be an empty bytes object if EOF is
|
||||
encountered before any bytes are read.
|
||||
|
||||
This is a coroutine.
|
||||
|
||||
|
|
|
@ -26,9 +26,17 @@ class Stream:
|
|||
# TODO yield?
|
||||
self.s.close()
|
||||
|
||||
async def read(self, n):
|
||||
yield core._io_queue.queue_read(self.s)
|
||||
return self.s.read(n)
|
||||
async def read(self, n=-1):
|
||||
r = b""
|
||||
while True:
|
||||
yield core._io_queue.queue_read(self.s)
|
||||
r2 = self.s.read(n)
|
||||
if r2 is not None:
|
||||
if n >= 0:
|
||||
return r2
|
||||
if not len(r2):
|
||||
return r
|
||||
r += r2
|
||||
|
||||
async def readinto(self, buf):
|
||||
yield core._io_queue.queue_read(self.s)
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
# Test uasyncio stream read(-1) method using TCP server/client
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
PORT = 8000
|
||||
|
||||
|
||||
async def handle_connection(reader, writer):
|
||||
writer.write(b"a")
|
||||
await writer.drain()
|
||||
|
||||
# Split the first 2 bytes up so the client must wait for the second one
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
writer.write(b"b")
|
||||
await writer.drain()
|
||||
|
||||
writer.write(b"c")
|
||||
await writer.drain()
|
||||
|
||||
print("close")
|
||||
writer.close()
|
||||
await writer.wait_closed()
|
||||
|
||||
print("done")
|
||||
ev.set()
|
||||
|
||||
|
||||
async def tcp_server():
|
||||
global ev
|
||||
ev = asyncio.Event()
|
||||
server = await asyncio.start_server(handle_connection, "0.0.0.0", PORT)
|
||||
print("server running")
|
||||
multitest.next()
|
||||
async with server:
|
||||
await asyncio.wait_for(ev.wait(), 2)
|
||||
|
||||
|
||||
async def tcp_client():
|
||||
reader, writer = await asyncio.open_connection(IP, PORT)
|
||||
print(await reader.read())
|
||||
print(await reader.read()) # should be empty
|
||||
print(await reader.read(1)) # should be empty
|
||||
|
||||
|
||||
def instance0():
|
||||
multitest.globals(IP=multitest.get_network_ip())
|
||||
asyncio.run(tcp_server())
|
||||
|
||||
|
||||
def instance1():
|
||||
multitest.next()
|
||||
asyncio.run(tcp_client())
|
|
@ -0,0 +1,8 @@
|
|||
--- instance0 ---
|
||||
server running
|
||||
close
|
||||
done
|
||||
--- instance1 ---
|
||||
b'abc'
|
||||
b''
|
||||
b''
|
Loading…
Reference in New Issue