CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/File/Path.h
Views: 1401
1
#pragma once
2
3
#include "ppsspp_config.h"
4
5
#include <string>
6
#include <string_view>
7
8
#if defined(__APPLE__)
9
10
#if TARGET_OS_IPHONE
11
#define HOST_IS_CASE_SENSITIVE 1
12
#elif TARGET_IPHONE_SIMULATOR
13
#define HOST_IS_CASE_SENSITIVE 0
14
#else
15
// Mac OSX case sensitivity defaults off, but is user configurable (when
16
// creating a filesytem), so assume the worst:
17
#define HOST_IS_CASE_SENSITIVE 1
18
#endif
19
20
#elif defined(_WIN32)
21
#define HOST_IS_CASE_SENSITIVE 0
22
23
#else // Android, Linux, BSD (and the rest?)
24
#define HOST_IS_CASE_SENSITIVE 1
25
26
#endif
27
28
enum class PathType {
29
UNDEFINED = 0,
30
NATIVE = 1, // Can be relative.
31
CONTENT_URI = 2, // Android only. Can only be absolute!
32
HTTP = 3, // http://, https://
33
};
34
35
// Windows paths are always stored with '/' slashes in a Path.
36
// On .ToWString(), they are flipped back to '\'.
37
38
class Path {
39
private:
40
void Init(std::string_view str);
41
42
public:
43
Path() : type_(PathType::UNDEFINED) {}
44
explicit Path(std::string_view str);
45
46
#if PPSSPP_PLATFORM(WINDOWS)
47
explicit Path(const std::wstring &str);
48
#endif
49
50
PathType Type() const {
51
return type_;
52
}
53
bool IsLocalType() const {
54
return type_ == PathType::NATIVE || type_ == PathType::CONTENT_URI;
55
}
56
57
bool Valid() const { return !path_.empty(); }
58
bool IsRoot() const { return path_ == "/"; } // Special value - only path that can end in a slash.
59
60
// Some std::string emulation for simplicity.
61
bool empty() const { return !Valid(); }
62
void clear() {
63
type_ = PathType::UNDEFINED;
64
path_.clear();
65
}
66
size_t size() const {
67
return path_.size();
68
}
69
70
// WARNING: Potentially unsafe usage, if it's not NATIVE.
71
const char *c_str() const {
72
return path_.c_str();
73
}
74
75
bool IsAbsolute() const;
76
77
// Returns a path extended with a subdirectory.
78
Path operator /(std::string_view subdir) const;
79
80
// Navigates down into a subdir.
81
void operator /=(std::string_view subdir);
82
83
// File extension manipulation.
84
Path WithExtraExtension(std::string_view ext) const;
85
Path WithReplacedExtension(const std::string &oldExtension, const std::string &newExtension) const;
86
Path WithReplacedExtension(const std::string &newExtension) const;
87
88
std::string GetFilename() const; // Really, GetLastComponent. Could be a file or directory. Includes the extension.
89
std::string GetFileExtension() const; // Always lowercase return. Includes the dot.
90
// Removes the last component.
91
std::string GetDirectory() const;
92
93
const std::string &ToString() const;
94
95
#if PPSSPP_PLATFORM(WINDOWS)
96
std::wstring ToWString() const;
97
std::string ToCString() const; // Flips the slashes back to Windows standard, but string still UTF-8.
98
#else
99
std::string ToCString() const {
100
return ToString();
101
}
102
#endif
103
104
// Pass in a relative root to turn the path into a relative path - if it is one!
105
std::string ToVisualString(const char *relativeRoot = nullptr) const;
106
107
bool CanNavigateUp() const;
108
Path NavigateUp() const;
109
110
// Navigates as far up as possible from this path. If not possible to navigate upwards, returns the same path.
111
// Not actually always the root of the volume, especially on systems like Mac and Linux where things are often mounted.
112
// For Android directory trees, navigates to the root of the tree.
113
Path GetRootVolume() const;
114
115
bool ComputePathTo(const Path &other, std::string &path) const;
116
117
bool operator ==(const Path &other) const {
118
return path_ == other.path_ && type_ == other.type_;
119
}
120
bool operator !=(const Path &other) const {
121
return path_ != other.path_ || type_ != other.type_;
122
}
123
124
bool FilePathContainsNoCase(std::string_view needle) const;
125
126
bool StartsWith(const Path &other) const;
127
128
bool operator <(const Path &other) const {
129
return path_ < other.path_;
130
}
131
bool operator >(const Path &other) const {
132
return path_ > other.path_;
133
}
134
135
private:
136
// The internal representation is currently always the plain string.
137
// For CPU efficiency we could keep an AndroidStorageContentURI too,
138
// but I don't think the encode/decode cost is significant. We simply create
139
// those for processing instead.
140
std::string path_;
141
142
PathType type_;
143
};
144
145
// Utility function for parsing out file extensions.
146
std::string GetExtFromString(std::string_view str);
147
148
// Utility function for fixing the case of paths. Only present on Unix-like systems.
149
150
#if HOST_IS_CASE_SENSITIVE
151
152
enum FixPathCaseBehavior {
153
FPC_FILE_MUST_EXIST, // all path components must exist (rmdir, move from)
154
FPC_PATH_MUST_EXIST, // all except the last one must exist - still tries to fix last one (fopen, move to)
155
FPC_PARTIAL_ALLOWED, // don't care how many exist (mkdir recursive)
156
};
157
158
bool FixPathCase(const Path &basePath, std::string &path, FixPathCaseBehavior behavior);
159
160
#endif
161
162