all repos — mgba @ 21d808d0e2235f1f183d4aa38e2494bf69f9125f

mGBA Game Boy Advance Emulator

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	return True
 15
 16@ffi.def_extern()
 17def _vfpSeek(vf, offset, whence):
 18	vfp = ffi.cast("struct VFilePy*", vf)
 19	f = ffi.from_handle(vfp.fileobj)
 20	f.seek(offset, whence)
 21	return f.tell()
 22
 23@ffi.def_extern()
 24def _vfpRead(vf, buffer, size):
 25	vfp = ffi.cast("struct VFilePy*", vf)
 26	pybuf = ffi.buffer(buffer, size)
 27	ffi.from_handle(vfp.fileobj).readinto(pybuf)
 28	return size
 29
 30@ffi.def_extern()
 31def _vfpWrite(vf, buffer, size):
 32	vfp = ffi.cast("struct VFilePy*", vf)
 33	pybuf = ffi.buffer(buffer, size)
 34	ffi.from_handle(vfp.fileobj).write(pybuf)
 35	return size
 36
 37@ffi.def_extern()
 38def _vfpMap(vf, size, flags):
 39	pass
 40
 41@ffi.def_extern()
 42def _vfpUnmap(vf, memory, size):
 43	pass
 44
 45@ffi.def_extern()
 46def _vfpTruncate(vf, size):
 47	vfp = ffi.cast("struct VFilePy*", vf)
 48	ffi.from_handle(vfp.fileobj).truncate(size)
 49
 50@ffi.def_extern()
 51def _vfpSize(vf):
 52	vfp = ffi.cast("struct VFilePy*", vf)
 53	f = ffi.from_handle(vfp.fileobj)
 54	pos = f.tell()
 55	f.seek(0, os.SEEK_END)
 56	size = f.tell()
 57	f.seek(pos, os.SEEK_SET)
 58	return size
 59
 60@ffi.def_extern()
 61def _vfpSync(vf, buffer, size):
 62	vfp = ffi.cast("struct VFilePy*", vf)
 63	f = ffi.from_handle(vfp.fileobj)
 64	if buffer and size:
 65		pos = f.tell()
 66		f.seek(0, os.SEEK_SET)
 67		_vfpWrite(vf, buffer, size)
 68		f.seek(pos, os.SEEK_SET)
 69	f.flush()
 70	os.fsync()
 71	return True
 72
 73def open(f):
 74	handle = ffi.new_handle(f)
 75	vf = VFile(lib.VFileFromPython(handle))
 76	# Prevent garbage collection
 77	vf._fileobj = f
 78	vf._handle = handle
 79	return vf
 80
 81def openPath(path, mode="r"):
 82	flags = 0
 83	if mode.startswith("r"):
 84		flags |= os.O_RDONLY
 85	elif mode.startswith("w"):
 86		flags |= os.O_WRONLY | os.O_CREAT | os.O_TRUNC
 87	elif mode.startswith("a"):
 88		flags |= os.O_WRONLY | os.O_CREAT | os.O_APPEND
 89	else:
 90		return None
 91
 92	if "+" in mode[1:]:
 93		flags |= os.O_RDWR
 94	if "x" in mode[1:]:
 95		flags |= os.O_EXCL
 96
 97	vf = lib.VFileOpen(path.encode("UTF-8"), flags);
 98	if vf == ffi.NULL:
 99		return None
100	return VFile(vf)
101
102class VFile:
103	def __init__(self, vf):
104		self.handle = vf
105
106	def close(self):
107		return bool(self.handle.close(self.handle))
108
109	def seek(self, offset, whence):
110		return self.handle.seek(self.handle, offset, whence)
111
112	def read(self, buffer, size):
113		return self.handle.read(self.handle, buffer, size)
114
115	def readAll(self, size=0):
116		if not size:
117			size = self.size()
118		buffer = ffi.new("char[%i]" % size)
119		size = self.handle.read(self.handle, buffer, size)
120		return ffi.unpack(buffer, size)
121
122	def readline(self, buffer, size):
123		return self.handle.readline(self.handle, buffer, size)
124
125	def write(self, buffer, size):
126		return self.handle.write(self.handle, buffer, size)
127
128	def map(self, size, flags):
129		return self.handle.map(self.handle, size, flags)
130
131	def unmap(self, memory, size):
132		self.handle.unmap(self.handle, memory, size)
133
134	def truncate(self, size):
135		self.handle.truncate(self.handle, size)
136
137	def size(self):
138		return self.handle.size(self.handle)
139
140	def sync(self, buffer, size):
141		return self.handle.sync(self.handle, buffer, size)