all repos — mgba @ 606d35ba6cc6170f200dde15ba5c839a9c553474

mGBA Game Boy Advance Emulator

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)