update io::path::normalized()
This commit is contained in:
parent
596132ebe2
commit
b1740bf7eb
@ -10,29 +10,69 @@ void path::checkValid() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path path::parent() const {
|
||||||
|
size_t length = str.length();
|
||||||
|
while (length && str[length-1] == '/') {
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
size_t slashpos = length;
|
||||||
|
slashpos = str.rfind('/', slashpos-1);
|
||||||
|
if (length >= 2 && str.rfind("..") == length - 2) {
|
||||||
|
return normalized().parent();
|
||||||
|
}
|
||||||
|
if (slashpos == std::string::npos) {
|
||||||
|
return colonPos == std::string::npos ? "" : str.substr(0, colonPos+1);
|
||||||
|
}
|
||||||
|
while (slashpos && str[slashpos-1] == '/') {
|
||||||
|
slashpos--;
|
||||||
|
}
|
||||||
|
return str.substr(0, slashpos);
|
||||||
|
}
|
||||||
|
|
||||||
path path::normalized() const {
|
path path::normalized() const {
|
||||||
io::path path = pathPart();
|
io::path path = pathPart();
|
||||||
|
|
||||||
std::stack<std::string> parts;
|
std::stack<io::path> parts;
|
||||||
do {
|
int64_t pos = 0;
|
||||||
parts.push(path.name());
|
int64_t prev = pos-1;
|
||||||
path.str = path.parent().string();
|
while (pos < path.str.length()) {
|
||||||
} while (!path.empty());
|
pos = path.str.find('/', pos);
|
||||||
|
if (pos == std::string::npos) {
|
||||||
while (!parts.empty()) {
|
parts.push(path.str.substr(prev + 1));
|
||||||
const std::string part = parts.top();
|
break;
|
||||||
parts.pop();
|
}
|
||||||
if (part == ".") {
|
if (pos - prev == 0) {
|
||||||
|
prev = pos;
|
||||||
|
pos = prev + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (part == "..") {
|
auto token = path.str.substr(prev + 1, pos - (prev + 1));
|
||||||
throw access_error("entry point reached");
|
prev = pos;
|
||||||
|
if (token == ".") {
|
||||||
|
continue;
|
||||||
|
} else if (token == "..") {
|
||||||
|
if (parts.empty()) {
|
||||||
|
throw access_error("entry-point reached");
|
||||||
|
}
|
||||||
|
parts.pop();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
parts.push(std::move(token));
|
||||||
path = path / part;
|
|
||||||
}
|
}
|
||||||
if (path.colonPos != std::string::npos) {
|
bool started = false;
|
||||||
path = path.entryPoint() + ":" + path.string();
|
|
||||||
|
path = "";
|
||||||
|
while (!parts.empty()) {
|
||||||
|
const auto& token = parts.top();
|
||||||
|
if (path.empty()) {
|
||||||
|
path = token;
|
||||||
|
} else {
|
||||||
|
path = token / path;
|
||||||
|
}
|
||||||
|
parts.pop();
|
||||||
|
}
|
||||||
|
if (colonPos != std::string::npos) {
|
||||||
|
path = str.substr(0, colonPos+1) + path.string();
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,13 +115,7 @@ namespace io {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Get parent path
|
/// @brief Get parent path
|
||||||
path parent() const {
|
path parent() const;
|
||||||
size_t slashpos = str.rfind('/');
|
|
||||||
if (slashpos == std::string::npos) {
|
|
||||||
return colonPos == std::string::npos ? "" : str;
|
|
||||||
}
|
|
||||||
return str.substr(0, slashpos);
|
|
||||||
}
|
|
||||||
|
|
||||||
path normalized() const;
|
path normalized() const;
|
||||||
|
|
||||||
|
|||||||
@ -12,3 +12,9 @@ TEST(Path, Path) {
|
|||||||
EXPECT_EQ(p / "child", "entry_point:path/file.ext/child");
|
EXPECT_EQ(p / "child", "entry_point:path/file.ext/child");
|
||||||
EXPECT_EQ(p.parent(), "entry_point:path");
|
EXPECT_EQ(p.parent(), "entry_point:path");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Path, DotElements) {
|
||||||
|
io::path p("entry_point:a/b/c/../../d/e/../");
|
||||||
|
EXPECT_EQ(p.normalized(), "entry_point:a/d");
|
||||||
|
EXPECT_EQ(io::path("test:a///b//////c/").parent(), io::path("test:a///b"));
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user