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/* Copyright (c) 2013-2014 Jeffrey Pfau
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11#include "3ds-vfs.h"
12
13#include "util/memory.h"
14
15struct VFile3DS {
16 struct VFile d;
17
18 Handle handle;
19 u64 offset;
20};
21
22static bool _vf3dClose(struct VFile* vf);
23static off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence);
24static ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size);
25static ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size);
26static void* _vf3dMap(struct VFile* vf, size_t size, int flags);
27static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size);
28static void _vf3dTruncate(struct VFile* vf, size_t size);
29
30struct VFile* VFileOpen3DS(FS_archive archive, const char* path, int flags) {
31 struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS));
32 if (!vf3d) {
33 return 0;
34 }
35
36 FS_path newPath = FS_makePath(PATH_CHAR, path);
37 Result res = FSUSER_OpenFile(0, &vf3d->handle, archive, newPath, flags, FS_ATTRIBUTE_NONE);
38 if (res & 0xFFFC03FF) {
39 free(vf3d);
40 return 0;
41 }
42
43 vf3d->offset = 0;
44
45 vf3d->d.close = _vf3dClose;
46 vf3d->d.seek = _vf3dSeek;
47 vf3d->d.read = _vf3dRead;
48 vf3d->d.readline = 0;
49 vf3d->d.write = _vf3dWrite;
50 vf3d->d.map = _vf3dMap;
51 vf3d->d.unmap = _vf3dUnmap;
52 vf3d->d.truncate = _vf3dTruncate;
53
54 return &vf3d->d;
55}
56
57bool _vf3dClose(struct VFile* vf) {
58 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
59
60 FSFILE_Close(vf3d->handle);
61 svcCloseHandle(vf3d->handle);
62 return true;
63}
64
65off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence) {
66 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
67 u64 size;
68 switch (whence) {
69 case SEEK_SET:
70 vf3d->offset = offset;
71 break;
72 case SEEK_END:
73 FSFILE_GetSize(vf3d->handle, &size);
74 vf3d->offset = size;
75 // Fall through
76 case SEEK_CUR:
77 vf3d->offset += offset;
78 break;
79 }
80 return vf3d->offset;
81}
82
83ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size) {
84 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
85 u32 sizeRead;
86 Result res = FSFILE_Read(vf3d->handle, &sizeRead, vf3d->offset, buffer, size);
87 if (res) {
88 return -1;
89 }
90 vf3d->offset += sizeRead;
91 return sizeRead;
92}
93
94ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size) {
95 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
96 u32 sizeWritten;
97 Result res = FSFILE_Write(vf3d->handle, &sizeWritten, vf3d->offset, buffer, size, FS_WRITE_FLUSH);
98 if (res) {
99 return -1;
100 }
101 vf3d->offset += sizeWritten;
102 return sizeWritten;
103}
104
105// TODO: Move these to a generic implementation
106static void* _vf3dMap(struct VFile* vf, size_t size, int flags) {
107 UNUSED(flags);
108 void* buffer = anonymousMemoryMap(size);
109 vf->read(vf, buffer, size);
110 vf->seek(vf, -(off_t) size, SEEK_CUR);
111 return buffer;
112}
113
114static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size) {
115 UNUSED(vf);
116 mappedMemoryFree(memory, size);
117}
118
119static void _vf3dTruncate(struct VFile* vf, size_t size) {
120 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
121 FSFILE_SetSize(vf3d->handle, size);
122}