all repos — mgba @ 1a7a544ba7891471fd94f2626a1c1af2c3427228

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
 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)