#pragma once #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include } #include "log.hpp" #include #include enum class SeekType { SET, CUR, END }; class CustomException : public std::exception { const char *message; protected: void clear_message(bool free_message = true) { if (free_message && this->message != nullptr) { free((void*)this->message); } this->message = nullptr; } public: CustomException() { clear_message(false); } CustomException(std::string message) : CustomException() { set_message(message); } void set_message(std::string message) { clear_message(); this->message = strdup(message.c_str()); } const char *what() const throw() { return this->message; } ~CustomException() { clear_message(); } }; class NotFoundException : public CustomException { public: NotFoundException(std::string file) : CustomException() { set_message(fmt::format("File not found: {0}", file)); } NotFoundException(const char *file) : NotFoundException(std::string(file)) { } }; class File { protected: size_t len; int64_t pos; public: const char *name; File(); inline virtual void open(const char *fname) { name = fname; } inline virtual void close() { } virtual size_t read(void *ptr, size_t size, size_t len) = 0; virtual void seek(int64_t pos, SeekType seek_type) = 0; virtual size_t get_len(); virtual int64_t get_pos() = 0; inline virtual bool is_open() { return false; } inline virtual ~File() { if (is_open()) close(); } }; class CFile : public File { protected: FILE *file; public: CFile(); void open(const char *fname) override; void close() override; size_t read(void *ptr, size_t size, size_t len) override; void seek(int64_t pos, SeekType seek_type) override; int64_t get_pos() override; bool is_open() override; }; class MemFile : public File { void *ptr; size_t len; int64_t pos; bool memory_owned = true; public: MemFile(); void open_memory(void *ptr, size_t len, const char *name = ""); void open(const char *path) override; void close() override; size_t read(void *ptr, size_t size, size_t len) override; void seek(int64_t pos, SeekType seek_type) override; int64_t get_pos() override; bool is_open() override; size_t get_len() override; }; class HttpFile : public File { std::vector data; public: HttpFile(); void open(const char *url) override; void close() override; size_t read(void *ptr, size_t size, size_t len) override; void seek(int64_t pos, SeekType type) override; int64_t get_pos() override; bool is_open() override; }; #ifdef __ANDROID__ class AndroidFile : public File { protected: void *handle; public: AndroidFile(); void open(const char *fname) override; void close() override; size_t read(void *ptr, size_t size, size_t len) override; void seek(int64_t pos, SeekType seek_type) override; int64_t get_pos() override; bool is_open() override; }; #endif //#ifdef __ANDROID__ //#define FILE_TYPE AndroidFile //#else #define FILE_TYPE MemFile //#endif STREAMFILE *get_sf_from_file(File *file); SDL_RWops *get_sdl_file(File *file); File *open_file(const char *fname); File *open_url(const char *url);