#pragma once
#include "ppsspp_config.h"
#include <string>
#include <string_view>
#if defined(__APPLE__)
#if TARGET_OS_IPHONE
#define HOST_IS_CASE_SENSITIVE 1
#elif TARGET_IPHONE_SIMULATOR
#define HOST_IS_CASE_SENSITIVE 0
#else
#define HOST_IS_CASE_SENSITIVE 1
#endif
#elif defined(_WIN32)
#define HOST_IS_CASE_SENSITIVE 0
#else
#define HOST_IS_CASE_SENSITIVE 1
#endif
enum class PathType {
UNDEFINED = 0,
NATIVE = 1,
CONTENT_URI = 2,
HTTP = 3,
};
class Path {
private:
void Init(std::string_view str);
public:
Path() : type_(PathType::UNDEFINED) {}
explicit Path(std::string_view str);
#if PPSSPP_PLATFORM(WINDOWS)
explicit Path(const std::wstring &str);
#endif
PathType Type() const {
return type_;
}
bool IsLocalType() const {
return type_ == PathType::NATIVE || type_ == PathType::CONTENT_URI;
}
bool Valid() const { return !path_.empty(); }
bool IsRoot() const { return path_ == "/"; }
bool empty() const { return !Valid(); }
void clear() {
type_ = PathType::UNDEFINED;
path_.clear();
}
size_t size() const {
return path_.size();
}
const char *c_str() const {
return path_.c_str();
}
bool IsAbsolute() const;
Path operator /(std::string_view subdir) const;
void operator /=(std::string_view subdir);
Path WithExtraExtension(std::string_view ext) const;
Path WithReplacedExtension(const std::string &oldExtension, const std::string &newExtension) const;
Path WithReplacedExtension(const std::string &newExtension) const;
std::string GetFilename() const;
std::string GetFileExtension() const;
std::string GetDirectory() const;
const std::string &ToString() const;
#if PPSSPP_PLATFORM(WINDOWS)
std::wstring ToWString() const;
std::string ToCString() const;
#else
std::string ToCString() const {
return ToString();
}
#endif
std::string ToVisualString(const char *relativeRoot = nullptr) const;
bool CanNavigateUp() const;
Path NavigateUp() const;
Path GetRootVolume() const;
bool ComputePathTo(const Path &other, std::string &path) const;
bool operator ==(const Path &other) const {
return path_ == other.path_ && type_ == other.type_;
}
bool operator !=(const Path &other) const {
return path_ != other.path_ || type_ != other.type_;
}
bool FilePathContainsNoCase(std::string_view needle) const;
bool StartsWith(const Path &other) const;
bool StartsWithGlobalAndNotEqual(const Path &other) const;
bool operator <(const Path &other) const {
return path_ < other.path_;
}
bool operator >(const Path &other) const {
return path_ > other.path_;
}
private:
std::string path_;
PathType type_;
};
enum FixPathCaseBehavior {
FPC_FILE_MUST_EXIST,
FPC_PATH_MUST_EXIST,
FPC_PARTIAL_ALLOWED,
};
bool FixPathCase(const Path &basePath, std::string &path, FixPathCaseBehavior behavior);