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}