src/platform/python/mgba/vfs.py (view raw)
1from _pylib import ffi, lib
2import mmap
3import os
4
5@ffi.def_extern()
6def _vfpClose(vf):
7 vfp = ffi.cast("struct VFilePy*", vf)
8 ffi.from_handle(vfp.fileobj).close()
9
10@ffi.def_extern()
11def _vfpSeek(vf, offset, whence):
12 vfp = ffi.cast("struct VFilePy*", vf)
13 f = ffi.from_handle(vfp.fileobj)
14 f.seek(offset, whence)
15 return f.tell()
16
17@ffi.def_extern()
18def _vfpRead(vf, buffer, size):
19 vfp = ffi.cast("struct VFilePy*", vf)
20 pybuf = ffi.buffer(buffer, size)
21 return ffi.from_handle(vfp.fileobj).readinto(pybuf)
22
23@ffi.def_extern()
24def _vfpWrite(vf, buffer, size):
25 vfp = ffi.cast("struct VFilePy*", vf)
26 pybuf = ffi.buffer(buffer, size)
27 return ffi.from_handle(vfp.fileobj).write(pybuf)
28
29@ffi.def_extern()
30def _vfpMap(vf, size, flags):
31 pass
32
33@ffi.def_extern()
34def _vfpUnmap(vf, memory, size):
35 pass
36
37@ffi.def_extern()
38def _vfpTruncate(vf, size):
39 vfp = ffi.cast("struct VFilePy*", vf)
40 ffi.from_handle(vfp.fileobj).truncate(size)
41
42@ffi.def_extern()
43def _vfpSize(vf):
44 vfp = ffi.cast("struct VFilePy*", vf)
45 f = ffi.from_handle(vfp.fileobj)
46 pos = f.tell()
47 f.seek(0, os.SEEK_END)
48 size = f.tell()
49 f.seek(pos, os.SEEK_SET)
50 return size
51
52@ffi.def_extern()
53def _vfpSync(vf, buffer, size):
54 vfp = ffi.cast("struct VFilePy*", vf)
55 f = ffi.from_handle(vfp.fileobj)
56 if buffer and size:
57 pos = f.tell()
58 f.seek(0, os.SEEK_SET)
59 _vfpWrite(vf, buffer, size)
60 f.seek(pos, os.SEEK_SET)
61 f.flush()
62 os.fsync()
63 return True
64
65def open(f):
66 handle = ffi.new_handle(f)
67 vf = VFile(lib.VFileFromPython(handle))
68 # Prevent garbage collection
69 vf._fileobj = f
70 vf._handle = handle
71 return vf
72
73def openPath(path, mode="r"):
74 flags = 0
75 if mode.startswith("r"):
76 flags |= os.O_RDONLY
77 elif mode.startswith("w"):
78 flags |= os.O_WRONLY | os.O_CREAT | os.O_TRUNC
79 elif mode.startswith("a"):
80 flags |= os.O_WRONLY | os.O_CREAT | os.O_APPEND
81 else:
82 return None
83
84 if "+" in mode[1:]:
85 flags |= os.O_RDWR
86 if "x" in mode[1:]:
87 flags |= os.O_EXCL
88
89 return VFile(lib.VFileOpen(path.encode("UTF-8"), flags))
90
91class VFile:
92 def __init__(self, vf):
93 self._vf = vf
94
95 def handle(self):
96 return self._vf
97
98 def close(self):
99 return self._vf.close(self._vf)
100
101 def seek(self, offset, whence):
102 return self._vf.seek(self._vf, offset, whence)
103
104 def read(self, buffer, size):
105 return self._vf.read(self._vf, buffer, size)
106
107 def readline(self, buffer, size):
108 return self._vf.readline(self._vf, buffer, size)
109
110 def write(self, buffer, size):
111 return self._vf.write(self._vf, buffer, size)
112
113 def map(self, size, flags):
114 return self._vf.map(self._vf, size, flags)
115
116 def unmap(self, memory, size):
117 self._vf.unmap(self._vf, memory, size)
118
119 def truncate(self, size):
120 self._vf.truncate(self._vf, size)
121
122 def size(self):
123 return self._vf.size(self._vf)
124
125 def sync(self, buffer, size):
126 return self._vf.sync(self._vf, buffer, size)