#include "file_backend.hpp" #include #include 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 len) { if (file == NULL) return 0; return fread(ptr, 1, 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; uint8_t *ptr8 = (uint8_t*)ptr; size_t out = 0; size_t tmp; for (size_t i = 0; i < maxnum; i++) { tmp = file->read(ptr8 + (i * size), size); out++; if (tmp == 0) { break; } } return out; } 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, 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); }