diff --git a/CMakeLists.txt b/CMakeLists.txt index 64ff87362..cbd79d8e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -482,11 +482,9 @@ add_library(love_filesystem_physfs STATIC src/modules/filesystem/physfs/PhysfsIo.h src/modules/filesystem/physfs/PhysfsIo.cpp ) -if(ANDROID) - target_link_libraries(love_filesystem_physfs PUBLIC - lovedep::SDL - ) -endif() +target_link_libraries(love_filesystem_physfs PUBLIC + lovedep::SDL +) add_library(love_filesystem INTERFACE) target_link_libraries(love_filesystem INTERFACE @@ -1962,7 +1960,7 @@ love_group_projects(NAME "liblove" NESTED TARGETS ${LIBLOVE_DEPENDENCIES}) love_group_projects(NAME "liblove/libraries" NESTED TARGETS ${LIBLOVE_LIBRARIES}) love_group_projects(NAME "liblove" TARGETS liblove ${LOVE_EXTRA_DEPENDECIES}) -love_group_projects(NAME "lovedep" TARGETS lovedep::SDL3 lovedep::Freetype lovedep::Harfbuzz lovedep::OpenAL lovedep::Modplug lovedep::Theora lovedep::Vorbis lovedep::Ogg lovedep::Zlib lovedep::Lua) +love_group_projects(NAME "lovedep" TARGETS lovedep::SDL lovedep::Freetype lovedep::Harfbuzz lovedep::OpenAL lovedep::Modplug lovedep::Theora lovedep::Vorbis lovedep::Ogg lovedep::Zlib lovedep::Lua) love_group_projects(NAME "lovedep" TARGETS lua51 alcommon al-excommon harfbuzz-subset zlib) diff --git a/src/modules/filesystem/NativeFile.cpp b/src/modules/filesystem/NativeFile.cpp index 8760a594f..a84ec3376 100644 --- a/src/modules/filesystem/NativeFile.cpp +++ b/src/modules/filesystem/NativeFile.cpp @@ -44,22 +44,22 @@ namespace filesystem love::Type NativeFile::type("NativeFile", &File::type); NativeFile::NativeFile(const std::string &filename, Mode mode) - : filename(filename) - , file(nullptr) - , mode(MODE_CLOSED) - , bufferMode(BUFFER_NONE) - , bufferSize(0) +: filename(filename) +, file(nullptr) +, mode(MODE_CLOSED) +, bufferMode(BUFFER_NONE) +, bufferSize(0) { if (!open(mode)) throw love::Exception("Could not open file at path %s", filename.c_str()); } NativeFile::NativeFile(const NativeFile &other) - : filename(other.filename) - , file(nullptr) - , mode(MODE_CLOSED) - , bufferMode(other.bufferMode) - , bufferSize(other.bufferSize) +: filename(other.filename) +, file(nullptr) +, mode(MODE_CLOSED) +, bufferMode(other.bufferMode) +, bufferSize(other.bufferSize) { if (!open(other.mode)) throw love::Exception("Could not open file at path %s", filename.c_str()); @@ -88,49 +88,23 @@ bool NativeFile::open(Mode newmode) if (file != nullptr) return false; -#if defined(LOVE_ANDROID) - // Try to handle content:// URI - int fd = love::android::getFDFromContentProtocol(filename.c_str()); - if (fd != -1) + file = SDL_IOFromFile(filename.c_str(), getModeString(newmode)); + if (file == nullptr) { - if (newmode != MODE_READ) - { - ::close(fd); - throw love::Exception("%s is read-only.", filename.c_str()); - } + std::string err = SDL_GetError(); - file = fdopen(fd, "rb"); + if (err != "") + throw love::Exception("Could not open file %s: %s", filename.c_str(), err.c_str()); } else - file = fopen(filename.c_str(), getModeString(newmode)); -#elif defined(LOVE_WINDOWS) - // make sure non-ASCII filenames work. - std::wstring modestr = to_widestr(getModeString(newmode)); - std::wstring wfilename = to_widestr(filename); - - file = _wfopen(wfilename.c_str(), modestr.c_str()); -#else - file = fopen(filename.c_str(), getModeString(newmode)); -#endif - - if (newmode == MODE_READ && file == nullptr) - throw love::Exception("Could not open file %s. Does not exist.", filename.c_str()); - - mode = newmode; - - if (file != nullptr && !setBuffer(bufferMode, bufferSize)) - { - // Revert to buffer defaults if we don't successfully set the buffer. - bufferMode = BUFFER_NONE; - bufferSize = 0; - } + mode = newmode; return file != nullptr; } bool NativeFile::close() { - if (file == nullptr || fclose(file) != 0) + if (file == nullptr || !SDL_CloseIO(file)) return false; mode = MODE_CLOSED; @@ -146,44 +120,8 @@ bool NativeFile::isOpen() const int64 NativeFile::getSize() { - int fd = file ? fileno(file) : -1; - -#ifdef LOVE_WINDOWS - - struct _stat64 buf; - - if (fd != -1) - { - if (_fstat64(fd, &buf) != 0) - return -1; - } - else - { - // make sure non-ASCII filenames work. - std::wstring wfilename = to_widestr(filename); - - if (_wstat64(wfilename.c_str(), &buf) != 0) - return -1; - } - - return (int64) buf.st_size; - -#else - - // Assume POSIX support... - struct stat buf; - - if (fd != -1) - { - if (fstat(fd, &buf) != 0) - return -1; - } - else if (stat(filename.c_str(), &buf) != 0) - return -1; - - return (int64) buf.st_size; - -#endif + int64 size = SDL_GetIOSize(file); + return std::max(size, -1LL); } int64 NativeFile::read(void *dst, int64 size) @@ -194,7 +132,7 @@ int64 NativeFile::read(void *dst, int64 size) if (size < 0) throw love::Exception("Invalid read size."); - size_t read = fread(dst, 1, (size_t) size, file); + size_t read = SDL_ReadIO(file, dst, (size_t) size); return (int64) read; } @@ -207,7 +145,7 @@ bool NativeFile::write(const void *data, int64 size) if (size < 0) throw love::Exception("Invalid write size."); - int64 written = (int64) fwrite(data, 1, (size_t) size, file); + int64 written = SDL_WriteIO(file, data, (size_t) size); return written == size; } @@ -217,7 +155,7 @@ bool NativeFile::flush() if (!file || (mode != MODE_WRITE && mode != MODE_APPEND)) throw love::Exception("File is not opened for writing."); - return fflush(file) == 0; + return SDL_FlushIO(file); } bool NativeFile::isEOF() @@ -230,11 +168,7 @@ int64 NativeFile::tell() if (file == nullptr) return -1; -#ifdef LOVE_WINDOWS - return (int64) _ftelli64(file); -#else - return (int64) ftello(file); -#endif + return SDL_TellIO(file); } bool NativeFile::seek(int64 pos, SeekOrigin origin) @@ -242,18 +176,13 @@ bool NativeFile::seek(int64 pos, SeekOrigin origin) if (file == nullptr) return false; - int forigin = SEEK_SET; + SDL_IOWhence whence = SDL_IO_SEEK_SET; if (origin == SEEKORIGIN_CURRENT) - forigin = SEEK_CUR; + whence = SDL_IO_SEEK_CUR; else if (origin == SEEKORIGIN_END) - forigin = SEEK_END; + whence = SDL_IO_SEEK_END; - // TODO -#ifdef LOVE_WINDOWS - return _fseeki64(file, pos, forigin) == 0; -#else - return fseeko(file, (off_t) pos, forigin) == 0; -#endif + return SDL_SeekIO(file, pos, whence) >= 0; } bool NativeFile::setBuffer(BufferMode bufmode, int64 size) @@ -264,32 +193,7 @@ bool NativeFile::setBuffer(BufferMode bufmode, int64 size) if (bufmode == BUFFER_NONE) size = 0; - // If the file isn't open, we'll make sure the buffer values are set in - // NativeFile::open. - if (!isOpen()) - { - bufferMode = bufmode; - bufferSize = size; - return true; - } - - int vbufmode; - switch (bufmode) - { - case File::BUFFER_NONE: - default: - vbufmode = _IONBF; - break; - case File::BUFFER_LINE: - vbufmode = _IOLBF; - break; - case File::BUFFER_FULL: - vbufmode = _IOFBF; - break; - } - - if (setvbuf(file, nullptr, vbufmode, (size_t) size) != 0) - return false; + // FIXME: SDL doesn't have option to set buffering. bufferMode = bufmode; bufferSize = size; @@ -325,6 +229,9 @@ const char *NativeFile::getModeString(Mode mode) case File::MODE_WRITE: return "wb"; case File::MODE_APPEND: + // Note: PhysFS "append" allows the user to + // seek the write pointer, but it's not possible + // to do so with standard fopen-style modes. return "ab"; } } diff --git a/src/modules/filesystem/NativeFile.h b/src/modules/filesystem/NativeFile.h index 7b46f5c01..eea00aaac 100644 --- a/src/modules/filesystem/NativeFile.h +++ b/src/modules/filesystem/NativeFile.h @@ -25,6 +25,9 @@ // C #include +// SDL +#include + namespace love { namespace filesystem @@ -71,7 +74,7 @@ class NativeFile : public File std::string filename; - FILE *file; + SDL_IOStream *file; Mode mode;