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);
25
26struct VFile* VFileOpen3DS(FS_archive* archive, const char* path, int flags) {
27 struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS));
28 if (!vf3d) {
29 return 0;
30 }
31
32 FS_path newPath = FS_makePath(PATH_CHAR, path);
33 Result res = FSUSER_OpenFile(0, &vf3d->handle, *archive, newPath, flags, FS_ATTRIBUTE_NONE);
34 if (res & 0xFFFC03FF) {
35 free(vf3d);
36 return 0;
37 }
38
39 vf3d->offset = 0;
40
41 vf3d->d.close = _vf3dClose;
42 vf3d->d.seek = _vf3dSeek;
43 vf3d->d.read = _vf3dRead;
44 vf3d->d.readline = 0;
45 vf3d->d.write = _vf3dWrite;
46 vf3d->d.map = _vf3dMap;
47 vf3d->d.unmap = _vf3dUnmap;
48 vf3d->d.truncate = _vf3dTruncate;
49 vf3d->d.size = _vf3dSize;
50
51 return &vf3d->d;
52}
53
54bool _vf3dClose(struct VFile* vf) {
55 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
56
57 FSFILE_Close(vf3d->handle);
58 svcCloseHandle(vf3d->handle);
59 return true;
60}
61
62off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence) {
63 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
64 u64 size;
65 switch (whence) {
66 case SEEK_SET:
67 vf3d->offset = offset;
68 break;
69 case SEEK_END:
70 FSFILE_GetSize(vf3d->handle, &size);
71 vf3d->offset = size;
72 // Fall through
73 case SEEK_CUR:
74 vf3d->offset += offset;
75 break;
76 }
77 return vf3d->offset;
78}
79
80ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size) {
81 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
82 u32 sizeRead;
83 Result res = FSFILE_Read(vf3d->handle, &sizeRead, vf3d->offset, buffer, size);
84 if (res) {
85 return -1;
86 }
87 vf3d->offset += sizeRead;
88 return sizeRead;
89}
90
91ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size) {
92 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
93 u32 sizeWritten;
94 Result res = FSFILE_Write(vf3d->handle, &sizeWritten, vf3d->offset, buffer, size, FS_WRITE_FLUSH);
95 if (res) {
96 return -1;
97 }
98 vf3d->offset += sizeWritten;
99 return sizeWritten;
100}
101
102static void* _vf3dMap(struct VFile* vf, size_t size, int flags) {
103 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
104 UNUSED(flags);
105 void* buffer = anonymousMemoryMap(size);
106 if (buffer) {
107 u32 sizeRead;
108 FSFILE_Read(vf3d->handle, &sizeRead, 0, buffer, size);
109 }
110 return buffer;
111}
112
113static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size) {
114 UNUSED(vf);
115 mappedMemoryFree(memory, size);
116}
117
118static void _vf3dTruncate(struct VFile* vf, size_t size) {
119 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
120 FSFILE_SetSize(vf3d->handle, size);
121}
122
123ssize_t _vf3dSize(struct VFile* vf) {
124 struct VFile3DS* vf3d = (struct VFile3DS*) vf;
125 u64 size;
126 FSFILE_GetSize(vf3d->handle, &size);
127 return size;
128}