13static bool hack_setupWriteDirectory() {
15 return f->setupWriteDirectory();
22 : filename(filename),
file(nullptr), mode(
"c"), bufferMode(
"none"), bufferSize(0) {}
25 if (mode !=
"c")
close();
29 if (requestedMode ==
"c")
return true;
32 if (requestedMode ==
"r") requestedMode =
"rb";
33 else if (requestedMode ==
"w") requestedMode =
"wb";
34 else if (requestedMode ==
"a") requestedMode =
"ab";
36 if (!PHYSFS_isInit())
throw Exception(
"PhysFS is not initialized.");
39 if ((requestedMode ==
"rb") && !PHYSFS_exists(filename.c_str()))
40 throw Exception(
"Could not open file %s. Does not exist.", filename.c_str());
43 if ((requestedMode ==
"ab" || requestedMode ==
"wb") &&
44 (PHYSFS_getWriteDir() ==
nullptr) && !hack_setupWriteDirectory())
45 throw Exception(
"Could not set write directory.");
48 if (file !=
nullptr)
return false;
50 PHYSFS_getLastErrorCode();
51 PHYSFS_File *
handle =
nullptr;
53 if (requestedMode ==
"rb")
handle = PHYSFS_openRead(filename.c_str());
54 else if (requestedMode ==
"ab")
handle = PHYSFS_openAppend(filename.c_str());
55 else if (requestedMode ==
"wb")
handle = PHYSFS_openWrite(filename.c_str());
57 throw Exception(
"Invalid file mode %s.", requestedMode.c_str());
60 const char *err = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
61 if (err ==
nullptr) err =
"unknown error";
62 throw Exception(
"Could not open file %s (%s)", filename.c_str(), err);
67 this->mode = requestedMode;
69 if (file !=
nullptr && !
setBuffer(bufferMode, bufferSize)) {
75 return (file !=
nullptr);
79 if (file ==
nullptr || !PHYSFS_close(file))
return false;
87bool File::isOpen()
const {
return mode !=
"c" && file !=
nullptr; }
92 if (file ==
nullptr) {
94 int64_t
size = (int64_t)PHYSFS_fileLength(file);
99 return (int64_t)PHYSFS_fileLength(file);
103 if (!file || mode !=
"rb")
throw Exception(
"File is not opened for reading.");
105 int64_t
max = (int64_t)PHYSFS_fileLength(file);
106 int64_t cur = (int64_t)PHYSFS_tell(file);
107 if (
max < 0 || cur < 0)
throw Exception(
"Could not read from file.");
108 if (cur >
max)
return 0;
110 int64_t remaining =
max - cur;
112 if (
size > remaining)
size = remaining;
116 return PHYSFS_readBytes(file, dst, (PHYSFS_uint64)
size);
120 if (!file || (mode !=
"wb" && mode !=
"ab"))
throw Exception(
"File is not opened for writing.");
125 int64_t written = PHYSFS_writeBytes(file, data, (PHYSFS_uint64)
size);
128 if (written !=
size)
return false;
131 if (bufferMode ==
"newline" && bufferSize >
size) {
132 if (memchr(data,
'\n', (
size_t)
size) !=
nullptr)
flush();
139 if (!file || (mode !=
"wb" && mode !=
"ab"))
throw Exception(
"File is not opened for writing.");
141 return PHYSFS_flush(file) != 0;
144#ifdef EVENGINE_WINDOWS
146 int64_t
pos =
f->tell();
147 int64_t
size =
f->getSize();
157 if (file ==
nullptr)
return -1;
159 return (int64_t)PHYSFS_tell(file);
162bool File::seek(uint64_t
pos) {
return file !=
nullptr && PHYSFS_seek(file, (PHYSFS_uint64)
pos) != 0; }
165 if (
size < 0)
return false;
170 bufferMode = bufmode;
176 if (bufferMode ==
"newline" || bufferMode ==
"full") {
177 ret = PHYSFS_setBuffer(file,
size);
179 ret = PHYSFS_setBuffer(file, 0);
183 if (ret == 0)
return false;
185 bufferMode = bufmode;
EVENGINE_API_FOUNDATION public API.
static const int64_t ALL
Used to indicate ALL data in a file.
bool isEOF() override
True when eof.
std::string getFilename() const override
Full filename including extension.
std::string getMode() const override
Returns the mode.
bool close() override
Closes close.
bool open(std::string mode) override
Opens open.
bool seek(uint64_t pos) override
Seeks seek.
bool setBuffer(std::string bufmode, int64_t size) override
Sets the buffer.
virtual ~File()
Releases File resources.
File(std::string filename)
Constructs an File with the given ilename.
bool write(const void *data, int64_t size) override
Writes write.
int64_t read(void *dst, int64_t size) override
Reads read.
bool flush() override
Flushes flush.
int64_t getSize() override
Byte length of the owned buffer.
int64_t tell() override
Returns the current tell.
bool isOpen() const override
True when open.
std::string getBuffer(int64_t &size) const override
Returns the buffer.
bool test_eof(File *, PHYSFS_File *file)
Build metadata (engine git commit, build time, third-party version).