Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/File/FileUtil.h
3186 views
1
// Copyright (C) 2003 Dolphin Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official SVN repository and contact information can be found at
16
// http://code.google.com/p/dolphin-emu/
17
18
#pragma once
19
20
#include <fstream>
21
#include <cstdio>
22
#include <string>
23
#include <string_view>
24
#include <time.h>
25
#include <cstdint>
26
27
#include "Common/File/Path.h"
28
29
// Some functions here support Android content URIs. These are marked as such.
30
31
#ifdef _WIN32
32
inline struct tm* localtime_r(const time_t *clock, struct tm *result) {
33
if (localtime_s(result, clock) == 0)
34
return result;
35
return NULL;
36
}
37
#endif
38
39
namespace File {
40
41
// Mostly to handle UTF-8 filenames better on Windows.
42
FILE *OpenCFile(const Path &filename, const char *mode);
43
44
// Reminiscent of PSP's FileAccess enum, due to its use in emulating it.
45
enum OpenFlag {
46
OPEN_NONE = 0,
47
OPEN_READ = 1,
48
OPEN_WRITE = 2,
49
OPEN_APPEND = 4,
50
OPEN_CREATE = 8,
51
OPEN_TRUNCATE = 16,
52
// EXCL?
53
};
54
55
// TODO: This currently only handles Android Content URIs, but might port the rest
56
// of DirectoryFileSystem::Open here eventually for symmetry.
57
int OpenFD(const Path &filename, OpenFlag flags);
58
59
// Cross-platform way to close FDs, corresponsing in platform support with OpenFD above.
60
void CloseFD(int fd);
61
62
// Resolves symlinks and similar.
63
std::string ResolvePath(std::string_view path);
64
65
// Returns true if file filename exists
66
bool Exists(const Path &path);
67
68
// Returns true if file filename exists in directory path.
69
bool ExistsInDir(const Path &path, const std::string &filename);
70
71
// Returns true if filename exists, and is a directory
72
// Supports Android content URIs.
73
bool IsDirectory(const Path &filename);
74
75
// Returns struct with modification date of file
76
bool GetModifTime(const Path &filename, tm &return_time);
77
// Same but with unix timestamp
78
bool GetModifTimeT(const Path &filename, time_t *return_time); // the time_t, of course, matches time_now_unix_utc().
79
80
// Returns the size of filename (64bit)
81
uint64_t GetFileSize(const Path &filename);
82
83
// Overloaded GetSize, accepts FILE*
84
uint64_t GetFileSize(FILE *f);
85
86
// Computes the recursive size of a directory. Warning: Might be slow!
87
uint64_t ComputeRecursiveDirectorySize(const Path &path);
88
89
// Returns true if successful, or path already exists.
90
bool CreateDir(const Path &filename);
91
92
void ChangeMTime(const Path &path, time_t mtime);
93
94
// Creates the full path of fullPath returns true on success
95
bool CreateFullPath(const Path &fullPath);
96
97
// Deletes a given file by name, return true on success
98
// Doesn't support deleting a directory (although it will work on some platforms - ideally shouldn't)
99
bool Delete(const Path &filename);
100
101
// Deletes a directory by name, returns true on success
102
// Directory must be empty.
103
bool DeleteDir(const Path &filename);
104
105
// Deletes the given directory and anything under it. Returns true on success.
106
bool DeleteDirRecursively(const Path &directory);
107
108
// Renames/moves file srcFilename to destFilename, returns true on success
109
// Will usually only work with in the same partition or other unit of storage,
110
// so you might have to fall back to copy/delete.
111
bool Rename(const Path &srcFilename, const Path &destFilename);
112
113
// copies file srcFilename to destFilename, returns true on success
114
bool Copy(const Path &srcFilename, const Path &destFilename);
115
116
// Tries to rename srcFilename to destFilename, if that fails,
117
// it tries to copy and delete the src if succeeded. If that fails too,
118
// returns false, otherwise returns true.
119
bool Move(const Path &srcFilename, const Path &destFilename);
120
121
// Move file, but only if it can be done quickly (rename or similar).
122
bool MoveIfFast(const Path &srcFilename, const Path &destFilename);
123
124
// creates an empty file filename, returns true on success
125
bool CreateEmptyFile(const Path &filename);
126
127
// Opens ini file (cheats, texture replacements etc.)
128
// TODO: Belongs in System or something.
129
bool OpenFileInEditor(const Path &fileName);
130
131
// Uses some heuristics to determine if this is a folder that we would want to
132
// write to.
133
bool IsProbablyInDownloadsFolder(const Path &folder);
134
135
// TODO: Belongs in System or something.
136
const Path &GetExeDirectory();
137
138
const Path GetCurDirectory();
139
140
// simple wrapper for cstdlib file functions to
141
// hopefully will make error checking easier
142
// and make forgetting an fclose() harder
143
class IOFile {
144
public:
145
IOFile() {}
146
IOFile(const Path &filename, const char openmode[]);
147
~IOFile();
148
149
// Prevent copies.
150
IOFile(const IOFile &) = delete;
151
void operator=(const IOFile &) = delete;
152
153
bool Open(const Path &filename, const char openmode[]);
154
bool Close();
155
156
template <typename T>
157
bool ReadArray(T* data, size_t length)
158
{
159
if (!IsOpen() || length != std::fread(data, sizeof(T), length, m_file))
160
m_good = false;
161
162
return m_good;
163
}
164
165
template <typename T>
166
bool WriteArray(const T* data, size_t length)
167
{
168
if (!IsOpen() || length != std::fwrite(data, sizeof(T), length, m_file))
169
m_good = false;
170
171
return m_good;
172
}
173
174
bool ReadBytes(void* data, size_t length)
175
{
176
return ReadArray(reinterpret_cast<char*>(data), length);
177
}
178
179
bool WriteBytes(const void* data, size_t length)
180
{
181
return WriteArray(reinterpret_cast<const char*>(data), length);
182
}
183
184
bool IsOpen() const { return nullptr != m_file; }
185
186
// m_good is set to false when a read, write or other function fails
187
bool IsGood() const { return m_good; }
188
operator bool() const { return IsGood() && IsOpen(); }
189
190
std::FILE* ReleaseHandle();
191
192
std::FILE* GetHandle() { return m_file; }
193
194
void SetHandle(std::FILE* file);
195
196
bool Seek(int64_t off, int origin);
197
uint64_t Tell();
198
uint64_t GetSize();
199
bool Resize(uint64_t size);
200
bool Flush();
201
202
// clear error state
203
void Clear() {
204
m_good = true;
205
#undef clearerr
206
std::clearerr(m_file);
207
}
208
209
private:
210
std::FILE *m_file = nullptr;
211
bool m_good = true;
212
};
213
214
// TODO: Refactor, this was moved from the old file_util.cpp.
215
216
// Whole-file reading/writing
217
bool WriteStringToFile(bool textFile, const std::string &str, const Path &filename);
218
bool WriteDataToFile(bool textFile, const void* data, size_t size, const Path &filename);
219
220
bool ReadFileToStringOptions(bool textFile, bool allowShort, const Path &path, std::string *str);
221
222
// Wrappers that clarify the intentions.
223
inline bool ReadBinaryFileToString(const Path &path, std::string *str) {
224
return ReadFileToStringOptions(false, false, path, str);
225
}
226
inline bool ReadSysTextFileToString(const Path &path, std::string *str) {
227
return ReadFileToStringOptions(true, true, path, str);
228
}
229
inline bool ReadTextFileToString(const Path &path, std::string *str) {
230
return ReadFileToStringOptions(true, false, path, str);
231
}
232
233
// Return value must be delete[]-d.
234
uint8_t *ReadLocalFile(const Path &path, size_t *size);
235
236
} // namespace
237
238