all repos — mgba @ 8a72fe8fe69aa14cf99210deb5a5bea9440df067

mGBA Game Boy Advance Emulator

src/util/vfs.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 "vfs.h"
  7
  8#ifdef PSP2
  9#include "platform/psp2/sce-vfs.h"
 10#endif
 11
 12struct VFile* VFileOpen(const char* path, int flags) {
 13#ifdef USE_VFS_FILE
 14	const char* chflags;
 15	switch (flags & O_ACCMODE) {
 16	case O_WRONLY:
 17		if (flags & O_APPEND) {
 18			chflags = "ab";
 19		} else {
 20			chflags = "wb";
 21		}
 22		break;
 23	case O_RDWR:
 24		if (flags & O_APPEND) {
 25			chflags = "a+b";
 26		} else if (flags & O_TRUNC) {
 27			chflags = "w+b";
 28		} else {
 29			chflags = "r+b";
 30		}
 31		break;
 32	case O_RDONLY:
 33		chflags = "rb";
 34		break;
 35	}
 36	return VFileFOpen(path, chflags);
 37#elif defined(PSP2)
 38	int sceFlags = PSP2_O_RDONLY;
 39	switch (flags & O_ACCMODE) {
 40	case O_WRONLY:
 41		sceFlags = PSP2_O_WRONLY;
 42		break;
 43	case O_RDWR:
 44		sceFlags = PSP2_O_RDWR;
 45		break;
 46	case O_RDONLY:
 47		sceFlags = PSP2_O_RDONLY;
 48		break;
 49	}
 50
 51	if (flags & O_APPEND) {
 52		sceFlags |= PSP2_O_APPEND;
 53	}
 54	if (flags & O_TRUNC) {
 55		sceFlags |= PSP2_O_TRUNC;
 56	}
 57	if (flags & O_CREAT) {
 58		sceFlags |= PSP2_O_CREAT;
 59	}
 60	return VFileOpenSce(path, sceFlags, 0666);
 61#else
 62	return VFileOpenFD(path, flags);
 63#endif
 64}
 65
 66ssize_t VFileReadline(struct VFile* vf, char* buffer, size_t size) {
 67	size_t bytesRead = 0;
 68	while (bytesRead < size - 1) {
 69		ssize_t newRead = vf->read(vf, &buffer[bytesRead], 1);
 70		if (newRead <= 0) {
 71			break;
 72		}
 73		bytesRead += newRead;
 74		if (buffer[bytesRead] == '\n') {
 75			break;
 76		}
 77	}
 78	buffer[bytesRead] = '\0';
 79	return bytesRead;
 80}
 81
 82ssize_t VFileWrite32LE(struct VFile* vf, int32_t word) {
 83	uint32_t leword;
 84	STORE_32LE(word, 0, &leword);
 85	return vf->write(vf, &leword, 4);
 86}
 87
 88ssize_t VFileWrite16LE(struct VFile* vf, int16_t hword) {
 89	uint16_t lehword;
 90	STORE_16LE(hword, 0, &lehword);
 91	return vf->write(vf, &lehword, 2);
 92}
 93
 94ssize_t VFileRead32LE(struct VFile* vf, void* word) {
 95	uint32_t leword;
 96	ssize_t r = vf->read(vf, &leword, 4);
 97	if (r == 4) {
 98		STORE_32LE(leword, 0, word);
 99	}
100	return r;
101}
102
103ssize_t VFileRead16LE(struct VFile* vf, void* hword) {
104	uint16_t lehword;
105	ssize_t r = vf->read(vf, &lehword, 2);
106	if (r == 2) {
107		STORE_16LE(lehword, 0, hword);
108	}
109	return r;
110}
111
112struct VFile* VDirOptionalOpenFile(struct VDir* dir, const char* realPath, const char* prefix, const char* suffix, int mode) {
113	char path[PATH_MAX];
114	path[PATH_MAX - 1] = '\0';
115	struct VFile* vf;
116	if (!dir) {
117		if (!realPath) {
118			return 0;
119		}
120		char* dotPoint = strrchr(realPath, '.');
121		if (dotPoint - realPath + 1 >= PATH_MAX - 1) {
122			return 0;
123		}
124		if (dotPoint > strrchr(realPath, '/')) {
125			int len = dotPoint - realPath;
126			strncpy(path, realPath, len);
127			path[len] = 0;
128			strncat(path + len, suffix, PATH_MAX - len - 1);
129		} else {
130			snprintf(path, PATH_MAX - 1, "%s%s", realPath, suffix);
131		}
132		vf = VFileOpen(path, mode);
133	} else {
134		snprintf(path, PATH_MAX - 1, "%s%s", prefix, suffix);
135		vf = dir->openFile(dir, path, mode);
136	}
137	return vf;
138}