aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Walters <rwalters@digitalstirling.com>2018-07-04 16:30:34 -0700
committerRichard Walters <rwalters@digitalstirling.com>2018-07-04 16:30:34 -0700
commit872905197e3dbcdf0041930fda67cbd371c240ac (patch)
tree0f3c694e2b65eea87d0e6d3403353f0ef8f9b23e
parent4603102722e1cc2abc3494c9446bc576d008e7fa (diff)
Add GenerateString (incomplete)
Add methods to set scheme, host, and query elements. Add ability to generate URI strings out of scheme, host, and query elements. This does not yet support userinfo, port, or fragment elements.
-rw-r--r--include/Uri/Uri.hpp34
-rw-r--r--src/Uri.cpp32
-rw-r--r--test/src/UriTests.cpp31
3 files changed, 97 insertions, 0 deletions
diff --git a/include/Uri/Uri.hpp b/include/Uri/Uri.hpp
index 1288a52..0b4a22c 100644
--- a/include/Uri/Uri.hpp
+++ b/include/Uri/Uri.hpp
@@ -212,6 +212,40 @@ namespace Uri {
*/
Uri Resolve(const Uri& relativeReference) const;
+ /**
+ * This method sets the scheme element of the URI.
+ *
+ * @param[in] scheme
+ * This is the scheme to set for the URI.
+ */
+ void SetScheme(const std::string& scheme);
+
+ /**
+ * This method sets the host element of the URI.
+ *
+ * @param[in] host
+ * This is the host to set for the URI.
+ */
+ void SetHost(const std::string& host);
+
+ /**
+ * This method sets the query element of the URI.
+ *
+ * @param[in] query
+ * This is the query to set for the URI.
+ */
+ void SetQuery(const std::string& query);
+
+ /**
+ * This method constructs and returns the string
+ * rendering of the URI, according to the rules
+ * in RFC 3986 (https://tools.ietf.org/html/rfc3986).
+ *
+ * @return
+ * The string rendering of the URI is returned.
+ */
+ std::string GenerateString() const;
+
// Private properties
private:
/**
diff --git a/src/Uri.cpp b/src/Uri.cpp
index dbc9ff6..5d36a9d 100644
--- a/src/Uri.cpp
+++ b/src/Uri.cpp
@@ -14,6 +14,7 @@
#include <functional>
#include <inttypes.h>
#include <memory>
+#include <sstream>
#include <string>
#include <Uri/Uri.hpp>
#include <vector>
@@ -1243,4 +1244,35 @@ namespace Uri {
target.impl_->CopyFragment(relativeReference);
return target;
}
+
+ void Uri::SetScheme(const std::string& scheme) {
+ impl_->scheme = scheme;
+ }
+
+ void Uri::SetHost(const std::string& host) {
+ impl_->host = host;
+ }
+
+ void Uri::SetQuery(const std::string& query) {
+ impl_->query = query;
+ }
+
+ std::string Uri::GenerateString() const {
+ std::ostringstream buffer;
+ if (!impl_->scheme.empty()) {
+ buffer << impl_->scheme << ':';
+ }
+ if (!impl_->host.empty()) {
+ buffer << "//";
+ if (ValidateIpv6Address(impl_->host)) {
+ buffer << '[' << impl_->host << ']';
+ } else {
+ buffer << impl_->host;
+ }
+ }
+ if (!impl_->query.empty()) {
+ buffer << '?' << impl_->query;
+ }
+ return buffer.str();
+ }
}
diff --git a/test/src/UriTests.cpp b/test/src/UriTests.cpp
index 7f4a1a0..e2ad7bd 100644
--- a/test/src/UriTests.cpp
+++ b/test/src/UriTests.cpp
@@ -755,3 +755,34 @@ TEST(UriTests, IPv6Address) {
++index;
}
}
+
+TEST(UriTests, GenerateString) {
+ struct TestVector {
+ std::string scheme;
+ std::string host;
+ std::string query;
+ std::string expectedUriString;
+ };
+ const std::vector< TestVector > testVectors{
+ {"http", "www.example.com", "foobar", "http://www.example.com?foobar"},
+ {"", "example.com", "bar", "//example.com?bar"},
+ {"", "example.com", "", "//example.com"},
+ {"", "", "bar", "?bar"},
+ {"http", "", "bar", "http:?bar"},
+ {"http", "", "", "http:"},
+ {"http", "::1", "", "http://[::1]"},
+ {"http", "::1.2.3.4", "", "http://[::1.2.3.4]"},
+ {"http", "1.2.3.4", "", "http://1.2.3.4"},
+ {"", "", "", ""},
+ };
+ size_t index = 0;
+ for (const auto& testVector : testVectors) {
+ Uri::Uri uri;
+ uri.SetScheme(testVector.scheme);
+ uri.SetHost(testVector.host);
+ uri.SetQuery(testVector.query);
+ const auto actualUriString = uri.GenerateString();
+ ASSERT_EQ(testVector.expectedUriString, actualUriString) << index;
+ ++index;
+ }
+}