Extend DbPath with RootLength function
This commit is contained in:
parent
e9fd9c5b14
commit
691ba6775c
@ -4,9 +4,6 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "leveldb/export.h"
|
|
||||||
#include "leveldb/status.h"
|
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
namespace path {
|
namespace path {
|
||||||
@ -23,10 +20,9 @@ public:
|
|||||||
const std::string& Name() const { return path_; }
|
const std::string& Name() const { return path_; }
|
||||||
const char* CName() const { return path_.c_str(); }
|
const char* CName() const { return path_.c_str(); }
|
||||||
|
|
||||||
static bool IsDirectorySeparator(const char c);
|
|
||||||
|
|
||||||
virtual bool IsAbsolute() const = 0;
|
virtual bool IsAbsolute() const = 0;
|
||||||
virtual bool IsRelative() const = 0;
|
virtual bool IsRelative() const = 0;
|
||||||
|
virtual size_t RootLength() = 0;
|
||||||
|
|
||||||
inline size_t Size() const { return path_.size(); }
|
inline size_t Size() const { return path_.size(); }
|
||||||
inline bool IsEmpty() const { return path_.empty(); }
|
inline bool IsEmpty() const { return path_.empty(); }
|
||||||
@ -38,9 +34,14 @@ protected:
|
|||||||
|
|
||||||
std::string path_;
|
std::string path_;
|
||||||
|
|
||||||
|
static bool IsDirectorySeparator(const char c);
|
||||||
|
|
||||||
|
bool StartsWith(const std::string& value, bool ignore_case = false);
|
||||||
|
|
||||||
virtual void Normalize() = 0;
|
virtual void Normalize() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Win path
|
||||||
class WindowsDbPath : public DbPath {
|
class WindowsDbPath : public DbPath {
|
||||||
public:
|
public:
|
||||||
explicit WindowsDbPath(const std::string& path) : DbPath(path) {
|
explicit WindowsDbPath(const std::string& path) : DbPath(path) {
|
||||||
@ -48,13 +49,19 @@ public:
|
|||||||
}
|
}
|
||||||
~WindowsDbPath() {}
|
~WindowsDbPath() {}
|
||||||
|
|
||||||
static bool IsValidDriveChar(const char c);
|
|
||||||
|
|
||||||
bool IsAbsolute() const override;
|
bool IsAbsolute() const override;
|
||||||
bool IsRelative() const override;
|
bool IsRelative() const override;
|
||||||
|
|
||||||
|
size_t RootLength() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static bool IsValidDriveChar(const char c);
|
||||||
|
|
||||||
void Normalize() override;
|
void Normalize() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* kExtendedPathPrefix = "\\\\?\\";
|
||||||
|
const char* kUncExtendedPathPrefix = "\\\\?\\UNC\\";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,6 +7,17 @@ bool DbPath::IsDirectorySeparator(const char c) {
|
|||||||
return (c == DbPath::kDirectorySeparator || c == DbPath::kAltDirecttorySeparator);
|
return (c == DbPath::kDirectorySeparator || c == DbPath::kAltDirecttorySeparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DbPath::StartsWith(const std::string& value, bool ignore_case) {
|
||||||
|
if (value.size() > path_.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ignore_case) {
|
||||||
|
auto ignore_case_cmp_func = [](char a, char b) { return std::tolower(a) == std::tolower(b); };
|
||||||
|
return std::equal(value.begin(), value.end(), path_.begin(), ignore_case_cmp_func);
|
||||||
|
}
|
||||||
|
return std::equal(value.begin(), value.end(), path_.begin());
|
||||||
|
}
|
||||||
|
|
||||||
// Windows
|
// Windows
|
||||||
|
|
||||||
bool WindowsDbPath::IsAbsolute() const {
|
bool WindowsDbPath::IsAbsolute() const {
|
||||||
@ -55,6 +66,45 @@ bool WindowsDbPath::IsValidDriveChar(const char c) {
|
|||||||
return drive_char >= 'A' && drive_char <= 'Z';
|
return drive_char >= 'A' && drive_char <= 'Z';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t WindowsDbPath::RootLength() {
|
||||||
|
size_t path_length = path_.size();
|
||||||
|
size_t root_length = 0;
|
||||||
|
size_t volume_separator_length = 2;
|
||||||
|
size_t unc_root_length = 2;
|
||||||
|
|
||||||
|
bool extended_syntax = StartsWith(kExtendedPathPrefix);
|
||||||
|
bool extended_unc_syntax = StartsWith(kUncExtendedPathPrefix);
|
||||||
|
|
||||||
|
if (extended_syntax) {
|
||||||
|
if (extended_unc_syntax) {
|
||||||
|
unc_root_length = std::strlen(kUncExtendedPathPrefix);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
volume_separator_length += std::strlen(kExtendedPathPrefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!extended_syntax || extended_unc_syntax) && path_length != 0 && IsDirectorySeparator(path_[0])) {
|
||||||
|
root_length = 1;
|
||||||
|
|
||||||
|
if (extended_unc_syntax || (path_length > 1 && IsDirectorySeparator(path_[1]))) {
|
||||||
|
root_length = unc_root_length;
|
||||||
|
int n = 2; // maximum separators to skip
|
||||||
|
while (root_length < path_length && (!IsDirectorySeparator(path_[root_length]) || --n > 0)) {
|
||||||
|
++root_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (path_length >= volume_separator_length && path_[volume_separator_length - 1] == kVolumeSeparatorChar) {
|
||||||
|
root_length = volume_separator_length;
|
||||||
|
if (path_length >= volume_separator_length && IsDirectorySeparator(path_[volume_separator_length])) {
|
||||||
|
++root_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return root_length;
|
||||||
|
}
|
||||||
|
|
||||||
// Windows path
|
// Windows path
|
||||||
|
|
||||||
DbPath* PathFactory::Create(const std::string& path) {
|
DbPath* PathFactory::Create(const std::string& path) {
|
||||||
|
Loading…
Reference in New Issue
Block a user