looper/file_backend.cpp
2024-09-16 15:05:53 -07:00

143 lines
4 KiB
C++

#include "file_backend.hpp"
#include <filesystem>
#include <string.h>
File::File(const char *fname) {
open(fname);
}
size_t File::get_len() {
return len;
}
CFile::CFile(const char *fname) : File(fname) {
open(fname);
}
void CFile::open(const char *fname) {
name = fname;
file = fopen(fname, "rb");
if (file == NULL) {
return;
}
fseek(file, 0, SEEK_END);
len = ftell(file);
fseek(file, 0, SEEK_SET);
}
void CFile::close() {
if (file == NULL) return;
fclose(file);
file = NULL;
}
size_t CFile::read(void *ptr, size_t size, size_t len) {
if (file == NULL) return 0;
return fread(ptr, size, len, file);
}
void CFile::seek(size_t pos, SeekType seek_type) {
int whence;
switch (seek_type) {
case SeekType::SET: {
whence = SEEK_SET;
} break;
case SeekType::CUR: {
whence = SEEK_CUR;
} break;
case SeekType::END: {
whence = SEEK_END;
} break;
}
if (file == NULL) return;
fseek(file, pos, whence);
}
size_t CFile::get_pos() {
if (file == NULL) return 0;
return ftell(file);
}
bool CFile::is_open() {
return file != NULL;
}
size_t rwops_read(SDL_RWops *rwops, void *ptr, size_t size, size_t maxnum) {
File *file = (File*)rwops->hidden.unknown.data1;
return file->read(ptr, size, maxnum);
}
int rwops_close(SDL_RWops *rwops) {
File *file = (File*)rwops->hidden.unknown.data1;
file->close();
return 0;
}
Sint64 rwops_seek(SDL_RWops *rwops, Sint64 offset, int whence) {
SeekType type;
switch (whence) {
case RW_SEEK_CUR: {
type = SeekType::CUR;
} break;
case RW_SEEK_SET: {
type = SeekType::SET;
} break;
case RW_SEEK_END: {
type = SeekType::END;
} break;
}
File *file = (File*)rwops->hidden.unknown.data1;
file->seek((size_t)offset, type);
return file->get_pos();
}
Sint64 rwops_size(SDL_RWops *rwops) {
FILE_TYPE *file = (FILE_TYPE*)rwops->hidden.unknown.data1;
return file->get_len();
}
SDL_RWops *get_sdl_file(File *file) {
SDL_RWops *rwops = new SDL_RWops();
rwops->read = &rwops_read;
rwops->close = &rwops_close;
rwops->write = NULL;
rwops->seek = &rwops_seek;
rwops->size = &rwops_size;
rwops->type = SDL_RWOPS_UNKNOWN;
rwops->hidden.unknown.data1 = file;
return rwops;
}
struct file_streamfile {
STREAMFILE vt;
File *file;
};
static file_streamfile *sf_open(file_streamfile *sf, const char *const filename, size_t buf_size) {
sf->file->open(filename);
return sf;
}
static size_t sf_read(file_streamfile *sf, uint8_t *dst, offv_t offset, size_t length) {
File *file = sf->file;
file->seek(offset, SeekType::SET);
return file->read(dst, 1, length);
}
static size_t sf_size(file_streamfile *sf) {
File *file = sf->file;
return file->get_len();
}
static void sf_close(file_streamfile *sf) {
File *file = sf->file;
file->close();
}
static void sf_get_name(file_streamfile *sf, char *name, size_t name_size) {
File *file = sf->file;
int copy_size = strlen(file->name) + 1;
if (copy_size > name_size) copy_size = name_size;
memcpy(name, file->name, copy_size);
name[copy_size - 1] = '\0';
}
static offv_t sf_get_offset(file_streamfile *sf) {
return (offv_t)sf->file->get_pos();
}
STREAMFILE *get_sf_from_file(File *file) {
file_streamfile *sf = new file_streamfile();
sf->vt.read = (size_t(*)(STREAMFILE*, uint8_t*, offv_t, size_t))(void*)sf_read;
sf->vt.get_size = (size_t(*)(STREAMFILE*))(void*)(sf_size);
sf->vt.get_offset = (offv_t(*)(STREAMFILE*))(void*)(sf_get_offset);
sf->vt.get_name = (void(*)(STREAMFILE*,char*,size_t))(void*)(sf_get_name);
sf->vt.open = (STREAMFILE*(*)(STREAMFILE*,const char *const, size_t))(sf_open);
sf->vt.close = (void(*)(STREAMFILE*))(void*)(sf_close);
sf->vt.stream_index = 0;
sf->file = file;
return &sf->vt;
}
File *open_file(const char *name) {
return new FILE_TYPE(name);
}