diff options
author | Richard Walters <rwalters@digitalstirling.com> | 2018-07-02 21:11:01 -0700 |
---|---|---|
committer | Richard Walters <rwalters@digitalstirling.com> | 2018-07-02 21:11:01 -0700 |
commit | 6974150a2c6b3b4e0fa278b08de8b2647d2c95ed (patch) | |
tree | b36d809b21c95d9659ca17c17504a06ee3fa2080 /src | |
parent | a32396b98cad2abc6c3fbf15a2fe1a2eaa3c8e91 (diff) |
Add NormalizePath method
Diffstat (limited to 'src')
-rw-r--r-- | src/Uri.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/Uri.cpp b/src/Uri.cpp index 77e561a..0153e5f 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -702,4 +702,73 @@ namespace Uri { return impl_->fragment; } + void Uri::NormalizePath() { + /* + * This is a straight-up implementation of the + * algorithm from section 5.2.4 of + * RFC 3986 (https://tools.ietf.org/html/rfc3986). + */ + // Step 1 + auto oldPath = std::move(impl_->path); + impl_->path.clear(); + // Step 2 + while (!oldPath.empty()) { + // Step 2A + if ( + (oldPath[0] == ".") + || (oldPath[0] == "..") + ) { + oldPath.erase(oldPath.begin()); + } else + + // Step 2B + if ( + (oldPath.size() >= 2) + && (oldPath[0] == "") + && (oldPath[1] == ".") + ) { + oldPath.erase(oldPath.begin() + 1); + } else + + // Step 2C + if ( + (oldPath.size() >= 2) + && (oldPath[0] == "") + && (oldPath[1] == "..") + ) { + oldPath.erase(oldPath.begin() + 1); + impl_->path.pop_back(); + } else + + // Step 2D + if ( + (oldPath.size() == 1) + && ( + (oldPath[0] == ".") + || (oldPath[0] == "..") + ) + ) { + oldPath.erase(oldPath.begin()); + } else + + // Step 2E + { + if (oldPath[0] == "") { + if (impl_->path.empty()) { + impl_->path.push_back(""); + } + oldPath.erase(oldPath.begin()); + } + if (!oldPath.empty()) { + impl_->path.push_back(oldPath[0]); + if (oldPath.size() > 1) { + oldPath[0] = ""; + } else { + oldPath.erase(oldPath.begin()); + } + } + } + } + } + } |