Skip to content

Commit 762021a

Browse files
committed
Binary file handles
1 parent 443b3e4 commit 762021a

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

computercraft/subapis/fs.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from contextlib import asynccontextmanager
2-
from typing import Optional, List
2+
from typing import Optional, List, Union
33

44
from .base import BaseSubAPI
5+
from ..errors import LuaException
56
from ..lua import lua_args
6-
from ..rproc import boolean, string, integer, nil, array_string, option_string, fact_scheme_dict
7+
from ..rproc import boolean, string, integer, nil, array_string, option_string, option_integer, fact_scheme_dict
78

89

910
attribute = fact_scheme_dict({
@@ -14,9 +15,20 @@
1415
}, {})
1516

1617

18+
class SeekMixin:
19+
async def seek(self, whence: str = None, offset: int = None) -> int:
20+
# whence: set, cur, end
21+
r = await self._send('seek', whence, offset)
22+
if isinstance(r, list):
23+
assert r[0] is False
24+
raise LuaException(r[1])
25+
return integer(r)
26+
27+
1728
class ReadHandle(BaseSubAPI):
18-
async def read(self, count: int) -> Optional[str]:
19-
return option_string(await self._send('read', count))
29+
async def read(self, count: int = None) -> Optional[Union[str, int]]:
30+
r = await self._send('read', count)
31+
return option_integer(r) if count is None else option_string(r)
2032

2133
async def readLine(self) -> Optional[str]:
2234
return option_string(await self._send('readLine'))
@@ -34,6 +46,10 @@ async def __anext__(self):
3446
return line
3547

3648

49+
class BinaryReadHandle(ReadHandle, SeekMixin):
50+
pass
51+
52+
3753
class WriteHandle(BaseSubAPI):
3854
async def write(self, text: str):
3955
return nil(await self._send('write', text))
@@ -45,6 +61,10 @@ async def flush(self):
4561
return nil(await self._send('flush'))
4662

4763

64+
class BinaryWriteHandle(WriteHandle, SeekMixin):
65+
pass
66+
67+
4868
class FSAPI(BaseSubAPI):
4969
async def list(self, path: str) -> List[str]:
5070
return array_string(await self._send('list', path))
@@ -103,7 +123,11 @@ async def open(self, path: str, mode: str):
103123
)
104124
fin_tpl = '{e}.close()'
105125
async with self._cc._create_temp_object(create_expr, fin_tpl) as var:
106-
yield (ReadHandle if 'r' in mode else WriteHandle)(self._cc, var)
126+
if 'b' in mode:
127+
hcls = BinaryReadHandle if 'r' in mode else BinaryWriteHandle
128+
else:
129+
hcls = ReadHandle if 'r' in mode else WriteHandle
130+
yield hcls(self._cc, var)
107131

108132
async def find(self, wildcard: str) -> List[str]:
109133
return array_string(await self._send('find', wildcard))

testmod.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,24 @@ async def test_fs_api(api):
484484

485485
assert await api.fs.exists('tdir/banana') is True
486486

487+
async with api.fs.open('tdir/binfile', 'wb') as f:
488+
assert await f.write('a' * 9) is None
489+
assert await f.seek() == 9
490+
assert await f.seek('set', 0) == 0
491+
assert await f.write('b' * 3) is None
492+
assert await f.seek('cur', -1) == 2
493+
assert await f.write('c' * 3) is None
494+
assert await f.seek('end') == 9
495+
assert await f.write('d' * 3) is None
496+
with assert_raises(LuaException):
497+
await f.seek('set', -10)
498+
499+
async with api.fs.open('tdir/binfile', 'rb') as f:
500+
assert await f.readAll() == 'bbcccaaaaddd'
501+
502+
async with api.fs.open('tdir/binfile', 'rb') as f:
503+
assert isinstance(await f.read(), int)
504+
487505
assert await api.fs.delete('tdir') is None
488506
assert await api.fs.delete('tfile') is None
489507
assert await api.fs.delete('doesnotexist') is None

0 commit comments

Comments
 (0)