src/platform/3ds/3ds-vfs.c (view raw)
1/* Copyright (c) 2013-2014 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 "3ds-vfs.h"
7
8#include "util/memory.h"
9
10struct VFile3DS {
11 struct VFile d;
12
13 Handle handle;
14 u64 offset;
15};
16
17static bool _vf3dClose(struct VFile* vf);
18static off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence);
19static ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size);
20static ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size);
21static void* _vf3dMap(struct VFile* vf, size_t size, int flags);
22static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size);
23static void _vf3dTruncate(struct VFile* vf, size_t size);
24static ssize_t _vf3dSize(struct VFile* vf);
25static bool _vf3dSync(struct VFile* vf, const void* buffer, size_t size);
26
27struct VFile* VFileOpen3DS(FS_archive* archive, const char* path, int flags) {
28 struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS));
29 if (!vf3d) {
30 return 0;
31 }
32
33 FS_path newPath = FS_makePath(PATH_CHAR, path);
34 Result res = FSUSER_OpenFile(0, &vf3d->handle, *archive, newPath, flags, FS_ATTRIBUTE_NONE);
35 if (res & 0xFFFC03FF) {
36 free(vf3d);
37 return 0;
38 }
39
40 vf3d->offset = 0;
41
42 vf3d->d.close = _vf3dClose;
43 vf3d->d.seek = _vf3dSeek;
44 vf3d->d.read = _vf3dRead;
45 vf3d->d.readline = 0;
46 vf3d->d.write = _vf3dWrite;
47 vf3d->d.map = _vf3dMap;
48 vf3d->d.unmap = _vf3dUnmap;
49 vf3d->d.truncate = _vf3dTruncate;
50 vf3d->d.size = _vf3dSize;
51 vf3d->d.sync = _vf3dSync;
52
53 return &vf3d->d;
54}
55
56bool _vf3dClose(struct VFile* vf) {
57 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
58
59 FSFILE_Close(vf3d->handle);
60 svcCloseHandle(vf3d->handle);
61 return true;
62}
63
64off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence) {
65 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
66 u64 size;
67 switch (whence) {
68 case SEEK_SET:
69 vf3d->offset = offset;
70 break;
71 case SEEK_END:
72 FSFILE_GetSize(vf3d->handle, &size);
73 vf3d->offset = size;
74 // Fall through
75 case SEEK_CUR:
76 vf3d->offset += offset;
77 break;
78 }
79 return vf3d->offset;
80}
81
82ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size) {
83 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
84 u32 sizeRead;
85 Result res = FSFILE_Read(vf3d->handle, &sizeRead, vf3d->offset, buffer, size);
86 if (res) {
87 return -1;
88 }
89 vf3d->offset += sizeRead;
90 return sizeRead;
91}
92
93ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size) {
94 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
95 u32 sizeWritten;
96 Result res = FSFILE_Write(vf3d->handle, &sizeWritten, vf3d->offset, buffer, size, FS_WRITE_FLUSH);
97 if (res) {
98 return -1;
99 }
100 vf3d->offset += sizeWritten;
101 return sizeWritten;
102}
103
104static void* _vf3dMap(struct VFile* vf, size_t size, int flags) {
105 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
106 UNUSED(flags);
107 void* buffer = anonymousMemoryMap(size);
108 if (buffer) {
109 u32 sizeRead;
110 FSFILE_Read(vf3d->handle, &sizeRead, 0, buffer, size);
111 }
112 return buffer;
113}
114
115static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size) {
116 UNUSED(vf);
117 mappedMemoryFree(memory, size);
118}
119
120static void _vf3dTruncate(struct VFile* vf, size_t size) {
121 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
122 FSFILE_SetSize(vf3d->handle, size);
123}
124
125ssize_t _vf3dSize(struct VFile* vf) {
126 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
127 u64 size;
128 FSFILE_GetSize(vf3d->handle, &size);
129 return size;
130}
131
132static bool _vf3dSync(struct VFile* vf, const void* buffer, size_t size) {
133 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
134 if (buffer) {
135 u32 sizeWritten;
136 Result res = FSFILE_Write(vf3d->handle, &sizeWritten, 0, buffer, size, FS_WRITE_FLUSH);
137 if (res) {
138 return false;
139 }
140 }
141 FSFILE_Flush(vf3d->handle);
142 return true;
143}