Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/File/Path.h
3186 views
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
// WARNING: This can return wrong results if two ContentURI have different root paths.
127
bool StartsWith(const Path &other) const;
128
129
// This handles ContentURI with different paths "correctly". Very specific use case.
130
bool StartsWithGlobalAndNotEqual(const Path &other) const;
131
132
bool operator <(const Path &other) const {
133
return path_ < other.path_;
134
}
135
bool operator >(const Path &other) const {
136
return path_ > other.path_;
137
}
138
139
private:
140
// The internal representation is currently always the plain string.
141
// For CPU efficiency we could keep an AndroidStorageContentURI too,
142
// but I don't think the encode/decode cost is significant. We simply create
143
// those for processing instead.
144
std::string path_;
145
146
PathType type_;
147
};
148
149
// Utility function for fixing the case of paths. Only necessary on Unix-like systems.
150
151
enum FixPathCaseBehavior {
152
FPC_FILE_MUST_EXIST, // all path components must exist (rmdir, move from)
153
FPC_PATH_MUST_EXIST, // all except the last one must exist - still tries to fix last one (fopen, move to)
154
FPC_PARTIAL_ALLOWED, // don't care how many exist (mkdir recursive)
155
};
156
157
bool FixPathCase(const Path &basePath, std::string &path, FixPathCaseBehavior behavior);
158
159