libcruft-util/uri.hpp
Danny Robson f6056153e3 rename root namespace from util to cruft
This places, at long last, the core library code into the same namespace
as the extended library code.
2018-08-05 14:42:02 +10:00

103 lines
3.3 KiB
C++

/*
* 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 <danny@nerdcruft.net>
*/
#ifndef CRUFT_UTIL_URI_HPP
#define CRUFT_UTIL_URI_HPP
#include "debug.hpp"
#include "view.hpp"
#include <array>
#include <string>
#include <stdexcept>
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:
explicit uri (std::string &&);
explicit uri (const std::string&);
explicit uri (const char *);
explicit uri (cruft::view<const char *>);
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<const char*>
get (component c) const&
{
CHECK_LIMIT (c, 0, NUM_COMPONENTS);
return m_views[c];
}
cruft::view<const char*> all (void) const& { return cruft::make_view (m_value); }
cruft::view<const char*> scheme (void) const& { return get (SCHEME); }
cruft::view<const char*> heirarchical (void) const& { return get (HIERARCHICAL); }
cruft::view<const char*> authority (void) const& { return get (AUTHORITY); }
cruft::view<const char*> user (void) const& { return get (USER); }
cruft::view<const char*> host (void) const& { return get (HOST); }
cruft::view<const char*> port (void) const& { return get (PORT); }
cruft::view<const char*> path (void) const& { return get (PATH); }
cruft::view<const char*> query (void) const& { return get (QUERY); }
cruft::view<const char*> fragment (void) const& { return get (FRAGMENT); }
auto components (void) const& noexcept { return m_views; }
static std::string percent_decode (view<const char*>);
private:
std::array<view<const char*>, NUM_COMPONENTS> m_views;
std::string m_value;
};
std::ostream& operator<< (std::ostream&, uri::component);
}
#endif