all repos — mgba @ 2495b650a4dbf12c4955e187f8b3551b67f76297

mGBA Game Boy Advance Emulator

src/util/vfs/vfs-devlist.c (view raw)

  1/* Copyright (c) 2013-2015 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/. */
  6#include "util/vfs.h"
  7
  8#include <fat.h>
  9
 10static bool _vdlClose(struct VDir* vd);
 11static void _vdlRewind(struct VDir* vd);
 12static struct VDirEntry* _vdlListNext(struct VDir* vd);
 13static struct VFile* _vdlOpenFile(struct VDir* vd, const char* path, int mode);
 14static struct VDir* _vdlOpenDir(struct VDir* vd, const char* path);
 15
 16static const char* _vdleName(struct VDirEntry* vde);
 17static enum VFSType _vdleType(struct VDirEntry* vde);
 18
 19extern const struct {
 20	const char* name; 
 21	const DISC_INTERFACE* (*getInterface)(void);
 22} _FAT_disc_interfaces[];
 23
 24struct VDirEntryDevList {
 25	struct VDirEntry d;
 26	size_t index;
 27	char* name;
 28};
 29
 30struct VDirDevList {
 31	struct VDir d;
 32	struct VDirEntryDevList vde;
 33};
 34
 35struct VDir* VDeviceList() {
 36	struct VDirDevList* vd = malloc(sizeof(struct VDirDevList));
 37	if (!vd) {
 38		return 0;
 39	}
 40
 41	vd->d.close = _vdlClose;
 42	vd->d.rewind = _vdlRewind;
 43	vd->d.listNext = _vdlListNext;
 44	vd->d.openFile = _vdlOpenFile;
 45	vd->d.openDir = _vdlOpenDir;
 46
 47	vd->vde.d.name = _vdleName;
 48	vd->vde.d.type = _vdleType;
 49	vd->vde.index = 0;
 50	vd->vde.name = 0;
 51
 52	return &vd->d;
 53}
 54
 55static bool _vdlClose(struct VDir* vd) {
 56	struct VDirDevList* vdl = (struct VDirDevList*) vd;
 57	free(vdl->vde.name);
 58	free(vdl);
 59	return true;
 60}
 61
 62static void _vdlRewind(struct VDir* vd) {
 63	struct VDirDevList* vdl = (struct VDirDevList*) vd;
 64	free(vdl->vde.name);
 65	vdl->vde.name = 0;
 66	vdl->vde.index = 0;
 67}
 68
 69static struct VDirEntry* _vdlListNext(struct VDir* vd) {
 70	struct VDirDevList* vdl = (struct VDirDevList*) vd;
 71	if (vdl->vde.name) {
 72		++vdl->vde.index;
 73		free(vdl->vde.name);
 74		vdl->vde.name = 0;
 75	}
 76	while (true) {
 77		if (!_FAT_disc_interfaces[vdl->vde.index].name || !_FAT_disc_interfaces[vdl->vde.index].getInterface) {
 78			return 0;
 79		}
 80		const DISC_INTERFACE* iface = _FAT_disc_interfaces[vdl->vde.index].getInterface();
 81		if (iface && iface->isInserted()) {
 82			vdl->vde.name = malloc(strlen(_FAT_disc_interfaces[vdl->vde.index].name) + 3);
 83			sprintf(vdl->vde.name, "%s:", _FAT_disc_interfaces[vdl->vde.index].name);
 84			return &vdl->vde.d;
 85		}
 86
 87		++vdl->vde.index;
 88	}
 89}
 90
 91static struct VFile* _vdlOpenFile(struct VDir* vd, const char* path, int mode) {
 92	UNUSED(vd);
 93	UNUSED(path);
 94	UNUSED(mode);
 95	return 0;
 96}
 97
 98static struct VDir* _vdlOpenDir(struct VDir* vd, const char* path) {
 99	UNUSED(vd);
100	return VDirOpen(path);
101}
102
103static const char* _vdleName(struct VDirEntry* vde) {
104	struct VDirEntryDevList* vdle = (struct VDirEntryDevList*) vde;
105	return vdle->name;
106}
107
108static enum VFSType _vdleType(struct VDirEntry* vde) {
109	UNUSED(vde);
110	return VFS_DIRECTORY;
111}