all repos — mgba @ ef93f686580686e35044a0f620c37f3ddf850d18

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