From f4bb73dbecd3178c58acd397eb793279ef4da3d1 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 22 Feb 2022 16:38:01 +1000 Subject: [PATCH] uri: remove parent-child component support --- uri.cpp | 124 ++++++++++++++++++++++++----------------------------- uri.cpp.rl | 10 ++--- uri.hpp | 23 +++++----- 3 files changed, 72 insertions(+), 85 deletions(-) diff --git a/uri.cpp b/uri.cpp index 03a4c224..9c348176 100644 --- a/uri.cpp +++ b/uri.cpp @@ -3,45 +3,14 @@ #include "./string.hpp" #include "./debug/panic.hpp" +#include "./debug/assert.hpp" +#include "./debug/warn.hpp" #include using cruft::uri; -/////////////////////////////////////////////////////////////////////////////// -#include -#include -#include - -#include - - -//----------------------------------------------------------------------------- -using uric = cruft::uri::component; - - -struct { - cruft::uri::component self; - // prev sibling - std::optional prev; - // parent - std::optional 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::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; diff --git a/uri.cpp.rl b/uri.cpp.rl index 98ed18dc..f7235f2f 100644 --- a/uri.cpp.rl +++ b/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 (); diff --git a/uri.hpp b/uri.hpp index 1c7741cd..9dfe85e8 100644 --- a/uri.hpp +++ b/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);