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.
|
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.
|
This is a coroutine.
|
||||||
|
|
||||||
|
@ -26,9 +26,17 @@ class Stream:
|
|||||||
# TODO yield?
|
# TODO yield?
|
||||||
self.s.close()
|
self.s.close()
|
||||||
|
|
||||||
async def read(self, n):
|
async def read(self, n=-1):
|
||||||
yield core._io_queue.queue_read(self.s)
|
r = b""
|
||||||
return self.s.read(n)
|
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):
|
async def readinto(self, buf):
|
||||||
yield core._io_queue.queue_read(self.s)
|
yield core._io_queue.queue_read(self.s)
|
||||||
|
60
tests/multi_net/uasyncio_tcp_readall.py
Normal file
60
tests/multi_net/uasyncio_tcp_readall.py
Normal file
@ -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())
|
8
tests/multi_net/uasyncio_tcp_readall.py.exp
Normal file
8
tests/multi_net/uasyncio_tcp_readall.py.exp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
--- instance0 ---
|
||||||
|
server running
|
||||||
|
close
|
||||||
|
done
|
||||||
|
--- instance1 ---
|
||||||
|
b'abc'
|
||||||
|
b''
|
||||||
|
b''
|
Loading…
Reference in New Issue
Block a user