aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRichard Walters <rwalters@digitalstirling.com>2018-07-02 21:11:01 -0700
committerRichard Walters <rwalters@digitalstirling.com>2018-07-02 21:11:01 -0700
commit6974150a2c6b3b4e0fa278b08de8b2647d2c95ed (patch)
treeb36d809b21c95d9659ca17c17504a06ee3fa2080 /src
parenta32396b98cad2abc6c3fbf15a2fe1a2eaa3c8e91 (diff)
Add NormalizePath method
Diffstat (limited to 'src')
-rw-r--r--src/Uri.cpp69
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());
+ }
+ }
+ }
+ }
+ }
+
}