10#ifdef EVENGINE_WINDOWS
20File::File(std::string filename) : filename(filename),
file(nullptr), mode(
"c"), bufferMode(
"none"), bufferSize(0) {}
23 if (mode !=
"c")
close();
27 if (newmode ==
"c")
return true;
30 if (file !=
nullptr)
return false;
32#ifdef EVENGINE_WINDOWS
34 std::wstring wnewmode = to_widestr(newmode);
35 std::wstring wfilename = to_widestr(filename);
37 file = _wfopen(wfilename.c_str(), wnewmode.c_str());
39 file = fopen(filename.c_str(), newmode.c_str());
42 if (newmode.find(
'c') != std::string::npos && file ==
nullptr)
43 throw Exception(
"Could not open file %s. Does not exist.", filename.c_str());
47 if (file !=
nullptr && !
setBuffer(bufferMode, bufferSize)) {
53 return file !=
nullptr;
57 if (file ==
nullptr || fclose(file) != 0)
return false;
65bool File::isOpen()
const {
return mode !=
"c" && file !=
nullptr; }
68 int fd = file ? fileno(file) : -1;
70#ifdef EVENGINE_WINDOWS
75 if (_fstat64(fd, &buf) != 0)
return -1;
78 std::wstring wfilename = to_widestr(filename);
80 if (_wstat64(wfilename.c_str(), &buf) != 0)
return -1;
83 return (int64_t)buf.st_size;
91 if (fstat(fd, &buf) != 0)
return -1;
92 }
else if (stat(filename.c_str(), &buf) != 0)
95 return (int64_t)buf.st_size;
101 if (!
file || mode !=
"rb")
throw Exception(
"File is not opened for reading.");
103 if (size < 0)
throw Exception(
"Invalid read size.");
105 size_t read = fread(dst, 1, (
size_t)size,
file);
107 return (int64_t)
read;
111 if (!
file || (mode !=
"wb" && mode !=
"ab"))
throw Exception(
"File is not opened for writing.");
113 if (size < 0)
throw Exception(
"Invalid write size.");
115 int64_t written = (int64_t)fwrite(
data, 1, (
size_t)size,
file);
117 return written == size;
121 if (!
file || (mode !=
"wb" && mode !=
"ab"))
throw Exception(
"File is not opened for writing.");
123 return fflush(
file) == 0;
129 if (
file ==
nullptr)
return -1;
131#ifdef EVENGINE_WINDOWS
132 return (int64_t)_ftelli64(
file);
134 return (int64_t)ftello(
file);
139 if (
file ==
nullptr)
return false;
141#ifdef EVENGINE_WINDOWS
142 return _fseeki64(
file, (int64_t)
pos, SEEK_SET) == 0;
144 return fseeko(
file, (off_t)
pos, SEEK_SET) == 0;
149 if (size < 0)
return false;
151 if (bufmode ==
"none") size = 0;
156 bufferMode = bufmode;
163 if (bufferMode ==
"newline") vbufmode = _IOLBF;
164 if (bufferMode ==
"full") vbufmode = _IOFBF;
166 if (setvbuf(
file,
nullptr, vbufmode, (
size_t)size) != 0)
return false;
168 bufferMode = bufmode;
File(std::string filename)
int64_t read(void *dst, int64_t size) override
Reads data into the destination buffer.
bool write(const void *data, int64_t size) override
Writes data into the File.
int64_t getSize() override
Gets the size of the file.
bool seek(uint64_t pos) override
Seeks to a certain position in the File.
bool setBuffer(std::string bufmode, int64_t size) override
Sets the buffering mode for the file. When buffering is enabled,
virtual ~File()
Destructor.
bool open(std::string newmode) override
Opens the file in a certain mode.
bool isOpen() const override
Gets whether the file is open.
bool close() override
Closes the file.
int64_t tell() override
Gets the current position in the File.
bool flush() override
Flushes the currently buffered file data to disk. Only applicable in write mode.
bool isEOF() override
Checks whether we are currently at end-of-file.
std::string getMode() const override
Gets the current mode of the File.
std::string getFilename() const override
Gets the filename for this File, or empty string if none.
std::string getBuffer(int64_t &size) const override