src/platform/psp2/sce-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 "sce-vfs.h"
7
8#include <psp2/io/dirent.h>
9
10#include "util/vfs.h"
11#include "util/memory.h"
12
13struct VFileSce {
14 struct VFile d;
15
16 SceUID fd;
17};
18
19struct VDirEntrySce {
20 struct VDirEntry d;
21 SceIoDirent ent;
22};
23
24struct VDirSce {
25 struct VDir d;
26 struct VDirEntrySce de;
27 SceUID fd;
28 char* path;
29};
30
31static bool _vfsceClose(struct VFile* vf);
32static off_t _vfsceSeek(struct VFile* vf, off_t offset, int whence);
33static ssize_t _vfsceRead(struct VFile* vf, void* buffer, size_t size);
34static ssize_t _vfsceWrite(struct VFile* vf, const void* buffer, size_t size);
35static void* _vfsceMap(struct VFile* vf, size_t size, int flags);
36static void _vfsceUnmap(struct VFile* vf, void* memory, size_t size);
37static void _vfsceTruncate(struct VFile* vf, size_t size);
38static ssize_t _vfsceSize(struct VFile* vf);
39static bool _vfsceSync(struct VFile* vf, const void* memory, size_t size);
40
41static bool _vdsceClose(struct VDir* vd);
42static void _vdsceRewind(struct VDir* vd);
43static struct VDirEntry* _vdsceListNext(struct VDir* vd);
44static struct VFile* _vdsceOpenFile(struct VDir* vd, const char* path, int mode);
45
46static const char* _vdesceName(struct VDirEntry* vde);
47
48struct VFile* VFileOpenSce(const char* path, int flags, SceMode mode) {
49 struct VFileSce* vfsce = malloc(sizeof(struct VFileSce));
50 if (!vfsce) {
51 return 0;
52 }
53
54 vfsce->fd = sceIoOpen(path, flags, mode);
55 if (vfsce->fd < 0) {
56 free(vfsce);
57 return 0;
58 }
59
60 vfsce->d.close = _vfsceClose;
61 vfsce->d.seek = _vfsceSeek;
62 vfsce->d.read = _vfsceRead;
63 vfsce->d.readline = 0;
64 vfsce->d.write = _vfsceWrite;
65 vfsce->d.map = _vfsceMap;
66 vfsce->d.unmap = _vfsceUnmap;
67 vfsce->d.truncate = _vfsceTruncate;
68 vfsce->d.size = _vfsceSize;
69 vfsce->d.sync = _vfsceSync;
70
71 return &vfsce->d;
72}
73
74bool _vfsceClose(struct VFile* vf) {
75 struct VFileSce* vfsce = (struct VFileSce*) vf;
76
77 return sceIoClose(vfsce->fd) >= 0;
78}
79
80off_t _vfsceSeek(struct VFile* vf, off_t offset, int whence) {
81 struct VFileSce* vfsce = (struct VFileSce*) vf;
82 return sceIoLseek(vfsce->fd, offset, whence);
83}
84
85ssize_t _vfsceRead(struct VFile* vf, void* buffer, size_t size) {
86 struct VFileSce* vfsce = (struct VFileSce*) vf;
87 return sceIoRead(vfsce->fd, buffer, size);
88}
89
90ssize_t _vfsceWrite(struct VFile* vf, const void* buffer, size_t size) {
91 struct VFileSce* vfsce = (struct VFileSce*) vf;
92 return sceIoWrite(vfsce->fd, buffer, size);
93}
94
95static void* _vfsceMap(struct VFile* vf, size_t size, int flags) {
96 struct VFileSce* vfsce = (struct VFileSce*) vf;
97 UNUSED(flags);
98 void* buffer = anonymousMemoryMap(size);
99 if (buffer) {
100 sceIoRead(vfsce->fd, buffer, size);
101 }
102 return buffer;
103}
104
105static void _vfsceUnmap(struct VFile* vf, void* memory, size_t size) {
106 UNUSED(vf);
107 mappedMemoryFree(memory, size);
108}
109
110static void _vfsceTruncate(struct VFile* vf, size_t size) {
111 struct VFileSce* vfsce = (struct VFileSce*) vf;
112 // TODO
113}
114
115ssize_t _vfsceSize(struct VFile* vf) {
116 struct VFileSce* vfsce = (struct VFileSce*) vf;
117 SceOff cur = sceIoLseek(vfsce->fd, 0, SEEK_CUR);
118 SceOff end = sceIoLseek(vfsce->fd, 0, SEEK_END);
119 sceIoLseek(vfsce->fd, cur, SEEK_SET);
120 return end;
121}
122
123bool _vfsceSync(struct VFile* vf, const void* buffer, size_t size) {
124 struct VFileSce* vfsce = (struct VFileSce*) vf;
125 if (buffer && size) {
126 SceOff cur = sceIoLseek(vfsce->fd, 0, SEEK_CUR);
127 sceIoLseek(vfsce->fd, 0, SEEK_SET);
128 sceIoWrite(vfsce->fd, buffer, size);
129 sceIoLseek(vfsce->fd, cur, SEEK_SET);
130 }
131 // TODO: Get the right device
132 return sceIoSync("cache0:", 0) >= 0;
133}
134
135struct VDir* VDirOpen(const char* path) {
136 SceUID dir = sceIoDopen(path);
137 if (dir < 0) {
138 return 0;
139 }
140
141 struct VDirSce* vd = malloc(sizeof(struct VDirSce));
142 vd->fd = dir;
143 vd->d.close = _vdsceClose;
144 vd->d.rewind = _vdsceRewind;
145 vd->d.listNext = _vdsceListNext;
146 vd->d.openFile = _vdsceOpenFile;
147 vd->path = strdup(path);
148
149 vd->de.d.name = _vdesceName;
150
151 return &vd->d;
152}
153
154bool _vdsceClose(struct VDir* vd) {
155 struct VDirSce* vdsce = (struct VDirSce*) vd;
156 if (sceIoDclose(vdsce->fd) < 0) {
157 return false;
158 }
159 free(vdsce->path);
160 free(vdsce);
161 return true;
162}
163
164void _vdsceRewind(struct VDir* vd) {
165 struct VDirSce* vdsce = (struct VDirSce*) vd;
166 sceIoDclose(vdsce->fd);
167 vdsce->fd = sceIoDopen(vdsce->path);
168}
169
170struct VDirEntry* _vdsceListNext(struct VDir* vd) {
171 struct VDirSce* vdsce = (struct VDirSce*) vd;
172 if (sceIoDread(vdsce->fd, &vdsce->de.ent) <= 0) {
173 return 0;
174 }
175 return &vdsce->de.d;
176}
177
178struct VFile* _vdsceOpenFile(struct VDir* vd, const char* path, int mode) {
179 struct VDirSce* vdsce = (struct VDirSce*) vd;
180 if (!path) {
181 return 0;
182 }
183 const char* dir = vdsce->path;
184 char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2));
185 sprintf(combined, "%s%s%s", dir, PATH_SEP, path);
186
187 struct VFile* file = VFileOpenSce(combined, mode, 0666);
188 free(combined);
189 return file;
190}
191
192static const char* _vdesceName(struct VDirEntry* vde) {
193 struct VDirEntrySce* vdesce = (struct VDirEntrySce*) vde;
194 return vdesce->ent.d_name;
195}