/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2015, 2017 Danny Robson */ #ifndef CRUFT_UTIL_URI_HPP #define CRUFT_UTIL_URI_HPP #include "debug/assert.hpp" #include "view.hpp" #include #include #include namespace cruft { // parsing of rfc3986 uniform resource identifiers // // does not currently perform normalisation (scheme or protocol), // comparison, or other associated operations. though these should be // added in the future. // // note that the parsed results may not always conform to expectations // for some protocols. eg, mailto identifiers are complex to parse // reliably and would require a specialised parser to be reliable. // // not all fields will be present for all protocols (or all instances of // any given protocol). eg, the "tel" is unlikely to have port numbers. class uri { public: uri (std::string &&); uri (const std::string&); uri (const char *); uri (view); class parse_error : public std::runtime_error { using runtime_error::runtime_error; }; // URI: 'https://user:password@example.com:80/path/to?foo=bar#fragment' // // SCHEME: 'https' // HIERARCHICAL: 'user:password@example.com:80/path/to' // AUTHORITY: 'user:password@example.com:80' // USER: 'user:password' // HOST: 'example.com' // PORT: '80' // PATH: '/path/to' // QUERY: 'foo=bar' // FRAGMENT: 'fragment' enum component { SCHEME, HIERARCHICAL, AUTHORITY, USER, HOST, PORT, PATH, QUERY, FRAGMENT, NUM_COMPONENTS }; view get (component c) const& { CHECK_INDEX (c, NUM_COMPONENTS); return m_views[c]; } cruft::view all (void) const& { return cruft::make_view (m_value); } std::string const& value (void) const& { return m_value; } cruft::view scheme (void) const& { return get (SCHEME); } cruft::view heirarchical (void) const& { return get (HIERARCHICAL); } cruft::view authority (void) const& { return get (AUTHORITY); } cruft::view user (void) const& { return get (USER); } cruft::view host (void) const& { return get (HOST); } cruft::view port (void) const& { return get (PORT); } cruft::view path (void) const& { return get (PATH); } cruft::view query (void) const& { return get (QUERY); } cruft::view fragment (void) const& { return get (FRAGMENT); } auto components (void) const& noexcept { return m_views; } static std::string percent_decode (view); private: std::array, NUM_COMPONENTS> m_views; std::string m_value; }; std::ostream& operator<< (std::ostream&, uri::component); } #endif