uri: remove parent-child component support
This commit is contained in:
parent
2c18bc3488
commit
f4bb73dbec
124
uri.cpp
124
uri.cpp
@ -3,45 +3,14 @@
|
||||
#include "./string.hpp"
|
||||
|
||||
#include "./debug/panic.hpp"
|
||||
#include "./debug/assert.hpp"
|
||||
#include "./debug/warn.hpp"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
using cruft::uri;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <cruft/util/debug/assert.hpp>
|
||||
#include <cruft/util/debug/warn.hpp>
|
||||
#include <cruft/util/iterator/zip.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
using uric = cruft::uri::component;
|
||||
|
||||
|
||||
struct {
|
||||
cruft::uri::component self;
|
||||
// prev sibling
|
||||
std::optional<cruft::uri::component> prev;
|
||||
// parent
|
||||
std::optional<cruft::uri::component> parent;
|
||||
} COMPONENT_ORDER[cruft::uri::NUM_COMPONENTS] {
|
||||
{ uric::SCHEME, { }, {} },
|
||||
{ uric::HIERARCHICAL, {uric::SCHEME }, {} },
|
||||
{ uric::QUERY, {uric::HIERARCHICAL}, {} },
|
||||
{ uric::FRAGMENT, {uric::QUERY }, {} },
|
||||
|
||||
{ uric::AUTHORITY, { }, {uric::HIERARCHICAL} },
|
||||
{ uric::PATH, {uric::AUTHORITY}, {uric::HIERARCHICAL} },
|
||||
|
||||
{ uric::USER, { }, {uric::AUTHORITY} },
|
||||
{ uric::HOST, {uric::USER}, {uric::AUTHORITY} },
|
||||
{ uric::PORT, {uric::HOST}, {uric::AUTHORITY} },
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
cruft::uri::uri (std::string &&_value):
|
||||
m_views {
|
||||
@ -52,23 +21,18 @@ cruft::uri::uri (std::string &&_value):
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
m_value (std::move (_value))
|
||||
{
|
||||
parse ();
|
||||
|
||||
for (auto const &order: COMPONENT_ORDER) {
|
||||
if (m_views[order.self].data ())
|
||||
continue;
|
||||
if (m_views[0].begin () == nullptr)
|
||||
m_views[0] = { m_value.data (), 0 };
|
||||
|
||||
if (order.prev)
|
||||
m_views[order.self] = { m_views[*order.prev].end (), 0 };
|
||||
else if (order.parent)
|
||||
m_views[order.self] = { m_views[*order.parent].begin (), 0 };
|
||||
else
|
||||
m_views[order.self] = { m_value.data (), 0 };
|
||||
for (int i = 1; i < NUM_COMPONENTS; ++i) {
|
||||
if (m_views[i].data () != nullptr)
|
||||
continue;
|
||||
m_views[i] = { m_views[i - 1].end (), 0 };
|
||||
}
|
||||
|
||||
CHECK_SANITY (*this);
|
||||
@ -112,6 +76,8 @@ uri& uri::operator= (uri &&rhs) noexcept
|
||||
{
|
||||
m_views = std::move (rhs.m_views);
|
||||
m_value = std::move (rhs.m_value);
|
||||
|
||||
CHECK_SANITY (*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -171,6 +137,28 @@ uri::uri (
|
||||
{ ; }
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
std::string_view
|
||||
uri::heirarchical (void) const&
|
||||
{
|
||||
for (int i = USER; i <= PATH; ++i)
|
||||
if (!m_views[i].empty ())
|
||||
return { m_views[i].data (), std::size_t (m_views[PATH].end () - m_views[i].data ()) };
|
||||
return { m_views[USER].data (), 0 };
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string_view
|
||||
uri::authority (void) const&
|
||||
{
|
||||
for (int i = USER; i <= PORT; ++i)
|
||||
if (!m_views[i].empty ())
|
||||
return { m_views[i].data (), std::size_t (m_views[PORT ].end () - m_views[i].data ()) };
|
||||
return { m_views[USER].data (), 0 };
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
std::string_view
|
||||
uri::get (component c) const&
|
||||
@ -184,14 +172,23 @@ uri::get (component c) const&
|
||||
void
|
||||
uri::set (component c, std::string_view val)
|
||||
{
|
||||
auto const diff = val.size () - m_views[c].size ();
|
||||
std::ptrdiff_t const diff = val.size () - m_views[c].size ();
|
||||
|
||||
auto const base = m_value.data ();
|
||||
m_value.replace (
|
||||
m_views[c].data () - m_value.data (),
|
||||
m_views[c].size (),
|
||||
val
|
||||
);
|
||||
auto const offset = m_value.data () - base;
|
||||
|
||||
for (int i = 0; i <= c; ++i)
|
||||
m_views[i] += offset;
|
||||
m_views[c] = { m_views[c].begin (), m_views[c].end () + diff };
|
||||
for (int i = c + 1; i != component::NUM_COMPONENTS; ++i)
|
||||
m_views[i] += diff;
|
||||
m_views[i] += offset + diff;
|
||||
|
||||
CHECK_SANITY (*this);
|
||||
}
|
||||
|
||||
|
||||
@ -205,9 +202,12 @@ void uri::clear_fragment ()
|
||||
m_views[FRAGMENT].begin () - m_value.data (),
|
||||
m_views[FRAGMENT].size ()
|
||||
);
|
||||
CHECK (m_value.back () == '#');
|
||||
m_value.pop_back ();
|
||||
|
||||
// Don't set this to nullptr. Other code assumes these views aren't null
|
||||
// (eg, for offsetting during copy construction).
|
||||
m_views[FRAGMENT] = { m_views[FRAGMENT].begin (), 0 };
|
||||
m_views[FRAGMENT] = { m_views[FRAGMENT - 1].end (), 0 };
|
||||
}
|
||||
|
||||
|
||||
@ -330,8 +330,6 @@ cruft::operator<< (std::ostream &os, cruft::uri::component c)
|
||||
{
|
||||
switch (c) {
|
||||
case cruft::uri::SCHEME: return os << "SCHEME";
|
||||
case cruft::uri::HIERARCHICAL: return os << "HIERARCHICAL";
|
||||
case cruft::uri::AUTHORITY: return os << "AUTHORITY";
|
||||
case cruft::uri::USER: return os << "USER";
|
||||
case cruft::uri::HOST: return os << "HOST";
|
||||
case cruft::uri::PORT: return os << "PORT";
|
||||
@ -495,25 +493,17 @@ cruft::debug::validator<cruft::uri>::is_valid (cruft::uri const &val) noexcept
|
||||
RETURN_FALSE_UNLESS (i.end () <= value.data () + value.size ());
|
||||
}
|
||||
|
||||
// Each component reference memory after the previous component.
|
||||
// Empty components can be coincident with their siblings.
|
||||
for (auto const [selfidx, previdx, parentidx]: COMPONENT_ORDER) {
|
||||
auto const &self = components[selfidx];
|
||||
for (int i = 1; i < uri::NUM_COMPONENTS; ++i) {
|
||||
auto const &a = components[i - 1];
|
||||
auto const &b = components[i ];
|
||||
|
||||
if (previdx) {
|
||||
auto const &prev = components[*previdx];
|
||||
|
||||
RETURN_FALSE_UNLESS (prev.begin () <= self.begin ());
|
||||
RETURN_FALSE_UNLESS (prev.end () <= self.end ());
|
||||
RETURN_FALSE_UNLESS (prev.end () <= self.begin ());
|
||||
}
|
||||
|
||||
if (parentidx) {
|
||||
auto const &parent = components[*parentidx];
|
||||
|
||||
RETURN_FALSE_UNLESS (parent.begin () <= self.begin ());
|
||||
RETURN_FALSE_UNLESS (parent.end () >= self.end ());
|
||||
}
|
||||
// All of our data needs to occur before the next component
|
||||
//
|
||||
// It may not be coincident with a sibling if there is padding between
|
||||
// (as is the case directly after the scheme).
|
||||
RETURN_FALSE_UNLESS (a.begin () <= b.begin ());
|
||||
RETURN_FALSE_UNLESS (a.end () <= b.end ());
|
||||
RETURN_FALSE_UNLESS (a.end () <= b.begin ());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
10
uri.cpp.rl
10
uri.cpp.rl
@ -31,8 +31,8 @@ using cruft::uri;
|
||||
action scheme_begin { starts[SCHEME] = p; }
|
||||
action scheme_end { CHECK (starts[SCHEME]); m_views[SCHEME] = { starts[SCHEME], p }; }
|
||||
|
||||
action hier_begin { starts[HIERARCHICAL] = p; }
|
||||
action hier_end { CHECK (starts[HIERARCHICAL]); m_views[HIERARCHICAL] = { starts[HIERARCHICAL], p }; }
|
||||
action hier_begin { ; }
|
||||
action hier_end { ; }
|
||||
|
||||
action user_begin { starts[USER] = p; }
|
||||
action user_end { CHECK (starts[USER]); m_views[USER] = { starts[USER], p }; }
|
||||
@ -43,8 +43,8 @@ using cruft::uri;
|
||||
action port_begin { starts[PORT] = p; }
|
||||
action port_end { CHECK (starts[PORT]); m_views[PORT] = { starts[PORT], p }; }
|
||||
|
||||
action authority_begin { starts[AUTHORITY] = p; }
|
||||
action authority_end { CHECK (starts[AUTHORITY]); m_views[AUTHORITY] = { starts[AUTHORITY], p }; }
|
||||
action authority_begin { ; }
|
||||
action authority_end { ; }
|
||||
|
||||
action path_begin { starts[PATH] = p; }
|
||||
action path_end { CHECK (starts[PATH]); m_views[PATH] = { starts[PATH], p }; }
|
||||
@ -83,8 +83,6 @@ cruft::uri::parse (void)
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
};
|
||||
|
||||
const char *p = m_value.data ();
|
||||
|
23
uri.hpp
23
uri.hpp
@ -70,14 +70,12 @@ namespace cruft {
|
||||
// FRAGMENT: 'fragment'
|
||||
enum component {
|
||||
/* 0 */ SCHEME,
|
||||
/* 1 */ HIERARCHICAL,
|
||||
/* 2 */ AUTHORITY,
|
||||
/* 3 */ USER,
|
||||
/* 4 */ HOST,
|
||||
/* 5 */ PORT,
|
||||
/* 6 */ PATH,
|
||||
/* 7 */ QUERY,
|
||||
/* 8 */ FRAGMENT,
|
||||
/* 1 */ USER,
|
||||
/* 2 */ HOST,
|
||||
/* 3 */ PORT,
|
||||
/* 4 */ PATH,
|
||||
/* 5 */ QUERY,
|
||||
/* 6 */ FRAGMENT,
|
||||
|
||||
NUM_COMPONENTS
|
||||
};
|
||||
@ -85,14 +83,10 @@ namespace cruft {
|
||||
std::string_view
|
||||
get (component c) const&;
|
||||
|
||||
void set (component c, std::string_view);
|
||||
|
||||
std::string_view all (void) const& { return m_value; }
|
||||
std::string const& value (void) const& { return m_value; }
|
||||
|
||||
std::string_view scheme (void) const& { return get (SCHEME); }
|
||||
std::string_view heirarchical (void) const& { return get (HIERARCHICAL); }
|
||||
std::string_view authority (void) const& { return get (AUTHORITY); }
|
||||
std::string_view user (void) const& { return get (USER); }
|
||||
std::string_view host (void) const& { return get (HOST); }
|
||||
std::string_view port (void) const& { return get (PORT); }
|
||||
@ -100,6 +94,9 @@ namespace cruft {
|
||||
std::string_view query (void) const& { return get (QUERY); }
|
||||
std::string_view fragment (void) const& { return get (FRAGMENT); }
|
||||
|
||||
std::string_view heirarchical (void) const&; //{ return { user ().begin (), path ().end () }; }
|
||||
std::string_view authority (void) const&; //{ return { user ().begin (), port ().end () }; }
|
||||
|
||||
std::string_view
|
||||
pqf (void) const& {
|
||||
return {
|
||||
@ -113,6 +110,8 @@ namespace cruft {
|
||||
};
|
||||
}
|
||||
|
||||
void set (component c, std::string_view val);
|
||||
|
||||
// void clear (component);
|
||||
void clear_fragment (void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user