载入中...
搜索中...
未找到
File.cpp
浏览该文件的文档.
2
3#include "common/Exception.h"
4
5// Assume POSIX or Visual Studio.
6#include <sys/stat.h>
7#include <sys/types.h>
8
9#include "common/utf8.h"
10#ifdef EVENGINE_WINDOWS
11#include <wchar.h>
12#else
13#include <unistd.h> // POSIX.
14#endif
15
16namespace eve {
17namespace filesystem {
18namespace cppfs {
19
20File::File(std::string filename) : filename(filename), file(nullptr), mode("c"), bufferMode("none"), bufferSize(0) {}
21
23 if (mode != "c") close();
24}
25
26bool File::open(std::string newmode) {
27 if (newmode == "c") return true;
28
29 // File already open?
30 if (file != nullptr) return false;
31
32#ifdef EVENGINE_WINDOWS
33 // make sure non-ASCII filenames work.
34 std::wstring wnewmode = to_widestr(newmode);
35 std::wstring wfilename = to_widestr(filename);
36
37 file = _wfopen(wfilename.c_str(), wnewmode.c_str());
38#else
39 file = fopen(filename.c_str(), newmode.c_str());
40#endif
41
42 if (newmode.find('c') != std::string::npos && file == nullptr)
43 throw Exception("Could not open file %s. Does not exist.", filename.c_str());
44
45 mode = newmode;
46
47 if (file != nullptr && !setBuffer(bufferMode, bufferSize)) {
48 // Revert to buffer defaults if we don't successfully set the buffer.
49 bufferMode = "none";
50 bufferSize = 0;
51 }
52
53 return file != nullptr;
54}
55
57 if (file == nullptr || fclose(file) != 0) return false;
58
59 mode = "c";
60 file = nullptr;
61
62 return true;
63}
64
65bool File::isOpen() const { return mode != "c" && file != nullptr; }
66
67int64_t File::getSize() {
68 int fd = file ? fileno(file) : -1;
69
70#ifdef EVENGINE_WINDOWS
71
72 struct _stat64 buf;
73
74 if (fd != -1) {
75 if (_fstat64(fd, &buf) != 0) return -1;
76 } else {
77 // make sure non-ASCII filenames work.
78 std::wstring wfilename = to_widestr(filename);
79
80 if (_wstat64(wfilename.c_str(), &buf) != 0) return -1;
81 }
82
83 return (int64_t)buf.st_size;
84
85#else
86
87 // Assume POSIX support...
88 struct stat buf;
89
90 if (fd != -1) {
91 if (fstat(fd, &buf) != 0) return -1;
92 } else if (stat(filename.c_str(), &buf) != 0)
93 return -1;
94
95 return (int64_t)buf.st_size;
96
97#endif
98}
99
100int64_t File::read(void *dst, int64_t size) {
101 if (!file || mode != "rb") throw Exception("File is not opened for reading.");
102
103 if (size < 0) throw Exception("Invalid read size.");
104
105 size_t read = fread(dst, 1, (size_t)size, file);
106
107 return (int64_t)read;
108}
109
110bool File::write(const void *data, int64_t size) {
111 if (!file || (mode != "wb" && mode != "ab")) throw Exception("File is not opened for writing.");
112
113 if (size < 0) throw Exception("Invalid write size.");
114
115 int64_t written = (int64_t)fwrite(data, 1, (size_t)size, file);
116
117 return written == size;
118}
119
121 if (!file || (mode != "wb" && mode != "ab")) throw Exception("File is not opened for writing.");
122
123 return fflush(file) == 0;
124}
125
126bool File::isEOF() { return file == nullptr || tell() >= getSize(); }
127
128int64_t File::tell() {
129 if (file == nullptr) return -1;
130
131#ifdef EVENGINE_WINDOWS
132 return (int64_t)_ftelli64(file);
133#else
134 return (int64_t)ftello(file);
135#endif
136}
137
138bool File::seek(uint64_t pos) {
139 if (file == nullptr) return false;
140
141#ifdef EVENGINE_WINDOWS
142 return _fseeki64(file, (int64_t)pos, SEEK_SET) == 0;
143#else
144 return fseeko(file, (off_t)pos, SEEK_SET) == 0;
145#endif
146}
147
148bool File::setBuffer(std::string bufmode, int64_t size) {
149 if (size < 0) return false;
150
151 if (bufmode == "none") size = 0;
152
153 // If the file isn't open, we'll make sure the buffer values are set in
154 // File::open.
155 if (!isOpen()) {
156 bufferMode = bufmode;
157 bufferSize = size;
158 return true;
159 }
160
161 int vbufmode;
162 vbufmode = _IONBF;
163 if (bufferMode == "newline") vbufmode = _IOLBF;
164 if (bufferMode == "full") vbufmode = _IOFBF;
165
166 if (setvbuf(file, nullptr, vbufmode, (size_t)size) != 0) return false;
167
168 bufferMode = bufmode;
169 bufferSize = size;
170
171 return true;
172}
173
174std::string File::getBuffer(int64_t &size) const {
175 size = bufferSize;
176 return bufferMode;
177}
178
179std::string File::getFilename() const { return filename; }
180std::string File::getMode() const { return mode; }
181
182} // namespace cppfs
183} // namespace filesystem
184} // namespace eve
filesystem::File * file
Light2D::Data * data
File(std::string filename)
Definition File.cpp:20
int64_t read(void *dst, int64_t size) override
Reads data into the destination buffer.
Definition File.cpp:100
bool write(const void *data, int64_t size) override
Writes data into the File.
Definition File.cpp:110
int64_t getSize() override
Gets the size of the file.
Definition File.cpp:67
bool seek(uint64_t pos) override
Seeks to a certain position in the File.
Definition File.cpp:138
bool setBuffer(std::string bufmode, int64_t size) override
Sets the buffering mode for the file. When buffering is enabled,
Definition File.cpp:148
virtual ~File()
Destructor.
Definition File.cpp:22
bool open(std::string newmode) override
Opens the file in a certain mode.
Definition File.cpp:26
bool isOpen() const override
Gets whether the file is open.
Definition File.cpp:65
bool close() override
Closes the file.
Definition File.cpp:56
int64_t tell() override
Gets the current position in the File.
Definition File.cpp:128
bool flush() override
Flushes the currently buffered file data to disk. Only applicable in write mode.
Definition File.cpp:120
bool isEOF() override
Checks whether we are currently at end-of-file.
Definition File.cpp:126
std::string getMode() const override
Gets the current mode of the File.
Definition File.cpp:180
std::string getFilename() const override
Gets the filename for this File, or empty string if none.
Definition File.cpp:179
std::string getBuffer(int64_t &size) const override
Definition File.cpp:174
Definition Build.cpp:11