// This file is a part of Framsticks SDK. http://www.framsticks.com/ // Copyright (C) 1999-2024 Maciej Komosinski and Szymon Ulatowski. // See LICENSE.txt for details. #include "stdiofile.h" #include #include #include #include #ifdef __ANDROID__ #include #include #endif #include #include #ifdef _WIN32 #include #else #include #endif VirtFILE* StdioFileSystem::Vfopen(const char *path, const char *mode) { //log_printf("Vfopen %s %s",path,mode); #if defined USE_MFILE || defined _WIN32 MFILE *f = mfopen(path, mode); #else FILE *f = fopen(path, mode); #endif //log_printf("%p",f); if (f) return new StdioFILE(f, path); else return NULL; } VirtDIR* StdioFileSystem::Vopendir(const char* path) { //log_printf("Vopendir %s",path); #ifdef __ANDROID__ int resources_prefix_length = getAppResourcesDir().length(); if (strncmp(path, getAppResourcesDir().c_str(), resources_prefix_length) == 0) //it is a resources dir { VirtDIR *vd = AndroidAPK_DIR::opendir(path + resources_prefix_length + 1); //+1 because we also skip '/' and start with a "relative" dir, otherwise it does not work. return vd; } #endif #ifdef _WIN32 DIRTYPE *d = wopendir(Convert::utf8ToUtf16(path).c_str()); #else DIR *d = opendir(path); #endif //log_printf("%p",d); if (d) return new StdioDIR(d); else return NULL; } bool StdioFileSystem::Vfexists(const char* path) { return fileExists(path); } bool StdioFileSystem::Vdirexists(const char* path, bool is_writable) { #ifdef __ANDROID__ int resources_prefix_length = getAppResourcesDir().length(); if (strncmp(path, getAppResourcesDir().c_str(), resources_prefix_length) == 0) //it is a resources dir { if (is_writable) return false; VirtDIR *vd = AndroidAPK_DIR::opendir(path + resources_prefix_length + 1); //+1 because we also skip '/' and start with a "relative" dir, otherwise it does not work. if (vd != NULL) { delete vd; return true; } else { return false; } } #endif return directoryExists(path, is_writable); } bool StdioFileSystem::Vdelete(const char* path) { return removeFile(path); } bool StdioFileSystem::Vstat(const char* path, Stat* out) { #if defined(_WIN32) && !defined(__BORLANDC__) //under windows, there are a few choices of _statXX structures: 32bit, 64bit, ansi, widechar (and their corresponding _statXX() functions). For the future: ensure utf8 filenames work. using stat = struct _stat64i32; //"struct" because there is also a function with the same name //struct _stat64i32 info; //an alternative, simple way if one does not want to use "using" above #else struct //if there was "using" earlier, then we cannot use "struct" in type name #endif stat info; #ifdef __BORLANDC__ #define _stat(a,b) stat(a,b) //embarcadero uses "stat" as struct type and "stat()" as function #endif if (_stat(path, &info) != 0) return false; out->is_file = S_ISREG(info.st_mode); #if defined IPHONE && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) out->modification_time = info.st_mtimespec.tv_sec; #else out->modification_time = info.st_mtime; #endif return true; } bool StdioFileSystem::Vsettime(const char* path, double timestamp) { #if defined(_WIN32) && !defined(__BORLANDC__) //under windows, there are a few choices of _statXX structures: 32bit, 64bit, ansi, widechar (and their corresponding _statXX() functions). For the future: ensure utf8 filenames work. using stat = struct _stat64i32; //"struct" because there is also a function with the same name //struct _stat64i32 info; //an alternative, simple way if one does not want to use "using" above #else struct //if there was "using" earlier, then we cannot use "struct" in type name #endif stat info; if (_stat(path, &info) != 0) return false; #ifdef __BORLANDC__ // when including (no "sys/"), compiles OK when using both no-underscore variants, but causes "unresolved external utime()" during linking, hence need to use both underscored variants: #define utimbuf _utimbuf #define utime(a,b) _utime(a,b) #endif struct utimbuf times; #if defined IPHONE && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) times.actime = info.st_atimespec.tv_sec; #else times.actime = info.st_atime; #endif times.modtime = (time_t)timestamp; return utime(path, ×) == 0; } #ifndef NO_STD_IN_OUT_ERR void StdioFILE::setStdio() { static StdioFILEDontClose si(stdin); static StdioFILEDontClose so(stdout); static StdioFILEDontClose se(stderr); setVstdin(&si); setVstdout(&so); setVstderr(&se); } #endif dirent* StdioDIR::Vreaddir() { //log_printf("Vreaddir %s",dir); #ifdef _WIN32 wdirent *wde = wreaddir(dir); if (wde == NULL) return NULL; strcpy(de.d_name, Convert::wstrToUtf8(wde->d_name).c_str()); return &de; #else return readdir(dir); #endif }