/* Copyright (C) 2020 SovietPony * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License ONLY. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "streams.h" #include "kos32.h" #include #include static inline int ReadFile (int offset, void *data, size_t len, int enc, const void *path, int *count) { struct FileExt info = { KOS32_READ_FILE, offset, 0/*high_offset*/, (int)len, (int)data, enc, path }; return FileExt(&info, count); } static inline int CreateFile (const void *data, size_t len, int enc, const void *path, int *count) { struct FileExt info = { KOS32_CREATE_FILE, 0, 0, (int)len, (int)data, enc, path }; return FileExt(&info, count); } static inline int WriteFile (int offset, const void *data, size_t len, int enc, const void *path, int *count) { struct FileExt info = { KOS32_WRITE_FILE, offset, 0/*high_offset*/, (int)len, (int)data, enc, path }; return FileExt(&info, count); } static inline int InfoFile (int flags, struct FileInfo *bdfe, int enc, const void *path) { struct FileExt info = { KOS32_GET_INFO, 0, flags, 0, (int)bdfe, enc, path }; return FileExt(&info, NULL); } static inline int StartApp (int flags, const char *params, int enc, const void *path) { struct FileExt info = { KOS32_START_APP, flags, (int)params, 0, 0, enc, path }; return FileExt(&info, NULL); } static inline int DeleteFile (int enc, const void *path) { struct FileExt info = { KOS32_DELETE, 0, 0, 0, 0, enc, path }; return FileExt(&info, NULL); } static long KOS32_GetPos (Stream *r) { KOS32_Stream *rd = (KOS32_Stream*)r; assert(rd != NULL); assert(rd->name[0] != 0); return rd->pos; } static void KOS32_SetPos (Stream *r, long pos) { KOS32_Stream *rd = (KOS32_Stream*)r; assert(rd != NULL); assert(rd->name[0] != 0); assert(pos >= 0); rd->pos = pos; } static long KOS32_GetLen (Stream *r) { KOS32_Stream *rd = (KOS32_Stream*)r; assert(rd != NULL); assert(rd->name[0] != 0); struct FileInfo info; int res = InfoFile(0, &info, KOS32_UTF8, rd->name); assert(res == KOS32_FILE_SUCCESS); return info.size; } static void KOS32_Read (Stream *r, void *data, size_t size, size_t n) { KOS32_Stream *rd = (KOS32_Stream*)r; assert(rd != NULL); assert(rd->name[0] != 0); long long len = (long long)size * n; int count = 0; int res = ReadFile(rd->pos, data, len, KOS32_UTF8, rd->name, &count); assert(res == KOS32_FILE_SUCCESS); assert(count == len); rd->pos += len; } static void KOS32_Write (Stream *w, const void *data, size_t size, size_t n) { KOS32_Stream *wr = (KOS32_Stream*)w; assert(wr != NULL); assert(wr->name[0] != 0); long long len = (long long)size * n; int count = 0; int res = WriteFile(wr->pos, data, len, KOS32_UTF8, wr->name, &count); assert(res == KOS32_FILE_SUCCESS); assert(count == len); wr->pos += len; } void KOS32_Assign (KOS32_Stream *s, const char *name, long pos) { assert(s != NULL); assert(name != NULL); assert(pos >= 0); s->base.getpos = KOS32_GetPos; s->base.setpos = KOS32_SetPos; s->base.getlen = KOS32_GetLen; s->base.read = KOS32_Read; s->base.write = KOS32_Write; strncpy(s->name, name, 264); s->pos = pos; } static void getpath (char *buf, int len, const char *name) { int i = GetCurrentFolderEnc(buf, len, KOS32_UTF8); buf[i - 1] = '/'; strcpy(&buf[i], name); } static inline is_directory (struct FileInfo *info) { return !!(info->attr & (KOS32_ATTR_MASK_VOLUME | KOS32_ATTR_MASK_FOLDER)); } int KOS32_Open (KOS32_Stream *s, const char *name) { assert(s != NULL); assert(name != NULL); char path[264]; getpath(path, 264, name); struct FileInfo info; int res = InfoFile(0, &info, KOS32_UTF8, path); if (res == KOS32_FILE_SUCCESS && !is_directory(&info)) { KOS32_Assign(s, name, 0); return 1; } return 0; } int KOS32_Create (KOS32_Stream *s, const char *name) { assert(s != NULL); assert(name != NULL); char path[264]; getpath(path, 264, name); int res = CreateFile(NULL, 0, KOS32_UTF8, path, NULL); if (res == KOS32_FILE_SUCCESS) { KOS32_Assign(s, name, 0); return 1; } return 0; } void KOS32_Close (KOS32_Stream *s) { assert(s != NULL); s->base.getpos = NULL; s->base.setpos = NULL; s->base.getlen = NULL; s->base.read = NULL; s->base.write = NULL; s->name[0] = 0; s->pos = 0; }