import t, c from . import syscall as syscall O_RDONLY: t.CDefine = 0x01 O_WRONLY: t.CDefine = 0x02 O_RDWR: t.CDefine = 0x03 O_CREAT: t.CDefine = 0x04 O_TRUNC: t.CDefine = 0x08 O_APPEND: t.CDefine = 0x30 SEEK_SET: t.CDefine = 0 SEEK_CUR: t.CDefine = 1 SEEK_END: t.CDefine = 2 DT_UNKNOWN: t.CDefine = 0 DT_FILE: t.CDefine = 1 DT_DIR: t.CDefine = 2 def open(path: t.CConst | t.CChar | t.CPtr, flags: t.CUInt32T) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.OPEN), t.CUInt64T(path), t.CUInt64T(flags), 0)) def close(fd: t.CInt) -> t.CInt: return t.CInt(syscall._syscall1(t.CUInt64T(syscall.CLOSE), t.CUInt64T(fd))) def read(fd: t.CInt, buf: t.CVoid | t.CPtr, count: t.CUInt32T) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.READ), t.CUInt64T(fd), t.CUInt64T(buf), t.CUInt64T(count))) def write(fd: t.CInt, buf: t.CVoid | t.CPtr, count: t.CUInt32T) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.WRITE), t.CUInt64T(fd), t.CUInt64T(buf), t.CUInt64T(count))) def seek(fd: t.CInt, offset: t.CUInt32T) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.SEEK), t.CUInt64T(fd), t.CUInt64T(offset), 0)) def tell(fd: t.CInt) -> t.CUInt32T: return t.CUInt32T(syscall._syscall1(t.CUInt64T(syscall.TELL), t.CUInt64T(fd))) def fsize(fd: t.CInt) -> t.CUInt32T: return t.CUInt32T(syscall._syscall1(t.CUInt64T(syscall.SIZE), t.CUInt64T(fd))) def mkdir(path: t.CConst | t.CChar | t.CPtr) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.MKDIR), t.CUInt64T(path), 0, 0)) def remove(path: t.CConst | t.CChar | t.CPtr) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.REMOVE), t.CUInt64T(path), 0, 0)) def opendir(path: t.CConst | t.CChar | t.CPtr) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.OPENDIR), t.CUInt64T(path), 0, 0)) def readdir(dd: t.CInt, info: t.CVoid | t.CPtr) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.READDIR), t.CUInt64T(dd), t.CUInt64T(info), 0)) def closedir(dd: t.CInt) -> t.CInt: return t.CInt(syscall._syscall1(t.CUInt64T(syscall.CLOSEDIR), t.CUInt64T(dd))) def stat(path: t.CConst | t.CChar | t.CPtr, info: t.CVoid | t.CPtr) -> t.CInt: return t.CInt(syscall._syscall3(t.CUInt64T(syscall.STAT), t.CUInt64T(path), t.CUInt64T(info), 0)) @t.Object class FileIO: _fd: t.CInt _pos: t.CUInt32T _size: t.CUInt32T _flags: t.CUInt32T _closed: t.CInt def __init__(self, fd: t.CInt, flags: t.CUInt32T): self._fd = fd self._flags = flags self._pos = 0 self._size = fsize(fd) self._closed = 0 def read(self, buf: t.CVoid | t.CPtr, count: t.CUInt32T) -> t.CInt: if self._closed: return -1 n: t.CInt = read(self._fd, buf, count) if n > 0: self._pos = self._pos + t.CUInt32T(n) return n def write(self, buf: t.CVoid | t.CPtr, count: t.CUInt32T) -> t.CInt: if self._closed: return -1 n: t.CInt = write(self._fd, buf, count) if n > 0: self._pos = self._pos + t.CUInt32T(n) if self._pos > self._size: self._size = self._pos return n def seek(self, offset: t.CUInt32T) -> t.CInt: if self._closed: return -1 res: t.CInt = seek(self._fd, offset) if res == 0: self._pos = offset return res def tell(self) -> t.CUInt32T: return self._pos def size(self) -> t.CUInt32T: return self._size def close(self) -> t.CInt: if self._closed: return 0 self._closed = 1 return close(self._fd) def is_closed(self) -> t.CInt: return self._closed @t.Object class DirIO: _dd: t.CInt _closed: t.CInt def __init__(self, dd: t.CInt): self._dd = dd self._closed = 0 def read(self, info: t.CVoid | t.CPtr) -> t.CInt: if self._closed: return -1 return readdir(self._dd, info) def close(self) -> t.CInt: if self._closed: return 0 self._closed = 1 return closedir(self._dd) def is_closed(self) -> t.CInt: return self._closed def open_file(path: t.CConst | t.CChar | t.CPtr, flags: t.CUInt32T) -> FileIO | t.CPtr: fd: t.CInt = open(path, flags) if fd < 0: return None return FileIO(fd, flags) def open_dir(path: t.CConst | t.CChar | t.CPtr) -> DirIO | t.CPtr: dd: t.CInt = opendir(path) if dd < 0: return None return DirIO(dd)