DEADSOFTWARE

portability: avoid errors on some compilers
[flatwaifu.git] / src / kos32 / streams.c
1 /* Copyright (C) 2020 SovietPony
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 */
16 #include "streams.h"
17 #include "kos32.h"
18 #include <assert.h>
19 #include <string.h>
21 static inline int ReadFile (int offset, void *data, size_t len, int enc, const void *path, int *count) {
22 struct FileExt info = { KOS32_READ_FILE, offset, 0/*high_offset*/, (int)len, (int)data, enc, path };
23 return FileExt(&info, count);
24 }
26 static inline int CreateFile (const void *data, size_t len, int enc, const void *path, int *count) {
27 struct FileExt info = { KOS32_CREATE_FILE, 0, 0, (int)len, (int)data, enc, path };
28 return FileExt(&info, count);
29 }
31 static inline int WriteFile (int offset, const void *data, size_t len, int enc, const void *path, int *count) {
32 struct FileExt info = { KOS32_WRITE_FILE, offset, 0/*high_offset*/, (int)len, (int)data, enc, path };
33 return FileExt(&info, count);
34 }
36 static inline int InfoFile (int flags, struct FileInfo *bdfe, int enc, const void *path) {
37 struct FileExt info = { KOS32_GET_INFO, 0, flags, 0, (int)bdfe, enc, path };
38 return FileExt(&info, NULL);
39 }
41 static inline int StartApp (int flags, const char *params, int enc, const void *path) {
42 struct FileExt info = { KOS32_START_APP, flags, (int)params, 0, 0, enc, path };
43 return FileExt(&info, NULL);
44 }
46 static inline int DeleteFile (int enc, const void *path) {
47 struct FileExt info = { KOS32_DELETE, 0, 0, 0, 0, enc, path };
48 return FileExt(&info, NULL);
49 }
51 static long KOS32_GetPos (Stream *r) {
52 KOS32_Stream *rd = (KOS32_Stream*)r;
53 assert(rd != NULL);
54 assert(rd->name[0] != 0);
55 return rd->pos;
56 }
58 static void KOS32_SetPos (Stream *r, long pos) {
59 KOS32_Stream *rd = (KOS32_Stream*)r;
60 assert(rd != NULL);
61 assert(rd->name[0] != 0);
62 assert(pos >= 0);
63 rd->pos = pos;
64 }
66 static long KOS32_GetLen (Stream *r) {
67 KOS32_Stream *rd = (KOS32_Stream*)r;
68 assert(rd != NULL);
69 assert(rd->name[0] != 0);
70 struct FileInfo info;
71 int res = InfoFile(0, &info, KOS32_UTF8, rd->name);
72 assert(res == KOS32_FILE_SUCCESS);
73 return info.size;
74 }
76 static void KOS32_Read (Stream *r, void *data, size_t size, size_t n) {
77 KOS32_Stream *rd = (KOS32_Stream*)r;
78 assert(rd != NULL);
79 assert(rd->name[0] != 0);
80 long long len = (long long)size * n;
81 int count = 0;
82 int res = ReadFile(rd->pos, data, len, KOS32_UTF8, rd->name, &count);
83 assert(res == KOS32_FILE_SUCCESS);
84 assert(count == len);
85 rd->pos += len;
86 }
88 static void KOS32_Write (Stream *w, const void *data, size_t size, size_t n) {
89 KOS32_Stream *wr = (KOS32_Stream*)w;
90 assert(wr != NULL);
91 assert(wr->name[0] != 0);
92 long long len = (long long)size * n;
93 int count = 0;
94 int res = WriteFile(wr->pos, data, len, KOS32_UTF8, wr->name, &count);
95 assert(res == KOS32_FILE_SUCCESS);
96 assert(count == len);
97 wr->pos += len;
98 }
100 void KOS32_Assign (KOS32_Stream *s, const char *name, long pos) {
101 assert(s != NULL);
102 assert(name != NULL);
103 assert(pos >= 0);
104 s->base.getpos = KOS32_GetPos;
105 s->base.setpos = KOS32_SetPos;
106 s->base.getlen = KOS32_GetLen;
107 s->base.read = KOS32_Read;
108 s->base.write = KOS32_Write;
109 strncpy(s->name, name, 264);
110 s->pos = pos;
113 static void getpath (char *buf, int len, const char *name) {
114 int i = GetCurrentFolderEnc(buf, len, KOS32_UTF8);
115 buf[i - 1] = '/';
116 strcpy(&buf[i], name);
119 static inline is_directory (struct FileInfo *info) {
120 return !!(info->attr & (KOS32_ATTR_MASK_VOLUME | KOS32_ATTR_MASK_FOLDER));
123 int KOS32_Open (KOS32_Stream *s, const char *name) {
124 assert(s != NULL);
125 assert(name != NULL);
126 char path[264];
127 getpath(path, 264, name);
128 struct FileInfo info;
129 int res = InfoFile(0, &info, KOS32_UTF8, path);
130 if (res == KOS32_FILE_SUCCESS && !is_directory(&info)) {
131 KOS32_Assign(s, name, 0);
132 return 1;
134 return 0;
137 int KOS32_Create (KOS32_Stream *s, const char *name) {
138 assert(s != NULL);
139 assert(name != NULL);
140 char path[264];
141 getpath(path, 264, name);
142 int res = CreateFile(NULL, 0, KOS32_UTF8, path, NULL);
143 if (res == KOS32_FILE_SUCCESS) {
144 KOS32_Assign(s, name, 0);
145 return 1;
147 return 0;
150 void KOS32_Close (KOS32_Stream *s) {
151 assert(s != NULL);
152 s->base.getpos = NULL;
153 s->base.setpos = NULL;
154 s->base.getlen = NULL;
155 s->base.read = NULL;
156 s->base.write = NULL;
157 s->name[0] = 0;
158 s->pos = 0;