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