ppsspp/Common/File/Path.cpp
2021-05-13 10:39:16 +02:00

137 lines
3 KiB
C++

#include "Common/File/Path.h"
#include "Common/StringUtils.h"
#include "Common/Data/Encoding/Utf8.h"
Path::Path(const std::string &str) {
if (str.empty()) {
type_ = PathType::UNDEFINED;
} else if (startsWith(str, "http://") || startsWith(str, "https://")) {
type_ = PathType::HTTP;
} else {
type_ = PathType::NATIVE;
}
Init(str);
}
#if PPSSPP_PLATFORM(WINDOWS)
Path::Path(const std::wstring &str) {
type_ = PathType::NATIVE;
Init(ConvertWStringToUTF8(str));
}
#endif
void Path::Init(const std::string &str) {
path_ = str;
#if PPSSPP_PLATFORM(WINDOWS)
// Flip all the slashes around. We flip them back on ToWString().
for (size_t i = 0; i < path_.size(); i++) {
if (path_[i] == '\\') {
path_[i] = '/';
}
}
#endif
if (type_ == PathType::NATIVE && !path_.empty() && path_.back() == '/') {
path_.pop_back();
}
}
Path Path::operator /(const std::string &subdir) const {
// We always use forward slashes internally, we convert to backslash only when
// converted to a wstring.
return Path(path_ + "/" + subdir);
}
void Path::operator /=(const std::string &subdir) {
path_ += path_ + "/" + subdir;
}
Path Path::WithExtraExtension(const std::string &ext) const {
return Path(path_ + "." + ext);
}
Path Path::WithReplacedExtension(const std::string &oldExtension, const std::string &newExtension) const {
if (endsWithNoCase(path_, "." + oldExtension)) {
std::string newPath = path_.substr(path_.size() - oldExtension.size() - 1);
return Path(newPath + "." + newExtension);
} else {
return Path(*this);
}
}
std::string Path::GetFileExtension() const {
size_t pos = path_.rfind(".");
if (pos == std::string::npos) {
return "";
}
size_t slash_pos = path_.rfind("/");
if (slash_pos != std::string::npos && slash_pos > pos) {
// Don't want to detect "df/file" from "/as.df/file"
return "";
}
std::string ext = path_.substr(pos + 1);
for (size_t i = 0; i < ext.size(); i++) {
ext[i] = tolower(ext[i]);
}
return ext;
}
Path Path::Directory() const {
std::string directory;
SplitPath(path_, &directory, nullptr, nullptr);
return Path(directory);
}
bool Path::FilePathContains(const std::string &needle) const {
const std::string &haystack = path_;
return haystack.find(needle) != std::string::npos;
}
bool Path::StartsWith(const Path &other) const {
if (type_ != other.type_) {
// Bad
return false;
}
return startsWith(path_, other.path_);
}
const std::string &Path::ToString() const {
return path_;
}
#if PPSSPP_PLATFORM(WINDOWS)
std::wstring Path::ToWString() const {
std::wstring w = ConvertUTF8ToWString(path_);
for (size_t i = 0; i < w.size(); i++) {
if (w[i] == '/') {
w[i] = '\\';
}
}
return w;
}
#endif
std::string Path::ToVisualString() const {
return path_;
}
bool Path::CanNavigateUp() const {
if (path_ == "/" || path_ == "") {
return false;
}
return true;
}
bool Path::IsAbsolute() const {
if (path_.empty())
return true;
else if (path_.front() == '/')
return true;
else if (path_.size() > 3 && path_[1] == ':')
return true; // Windows path with drive letter
else
return false;
}