uri: move non-parsing routines out of ragel source

This commit is contained in:
Danny Robson 2021-12-14 11:13:50 +10:00
parent d8d7c8f421
commit d3a7a48544
3 changed files with 127 additions and 129 deletions

View File

@ -27,7 +27,7 @@ endif()
###############################################################################
RAGEL_TARGET(uri uri.cpp.rl ${CMAKE_CURRENT_BINARY_DIR}/uri.cpp COMPILE_FLAGS -G2)
RAGEL_TARGET(uri uri.cpp.rl ${CMAKE_CURRENT_BINARY_DIR}/uri.rl.cpp COMPILE_FLAGS -G2)
RAGEL_TARGET(version version.cpp.rl ${CMAKE_CURRENT_BINARY_DIR}/version.cpp)
RAGEL_TARGET(parse8601 time/parse8601.cpp.rl ${CMAKE_CURRENT_BINARY_DIR}/time/parse8601.cpp)
@ -584,6 +584,7 @@ list (
types/tagged.hpp
types/traits.hpp
uri.cpp
uri.rl.cpp
uri.hpp
utf8.cpp
utf8.hpp

116
uri.cpp Normal file
View File

@ -0,0 +1,116 @@
#include "./uri.hpp"
#include "./debug/panic.hpp"
using cruft::uri;
///////////////////////////////////////////////////////////////////////////////
cruft::uri::uri (const char *str):
uri (std::string (str))
{ ; }
//-----------------------------------------------------------------------------
uri::uri (cruft::view<const char *> _value):
uri (std::string (_value.begin (), _value.end ()))
{ ; }
//-----------------------------------------------------------------------------
uri::uri (const std::string &_value):
uri (std::string (_value))
{ ; }
///////////////////////////////////////////////////////////////////////////////
static uint8_t
hex_to_uint (char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
unreachable ();
}
//-----------------------------------------------------------------------------
std::string
cruft::uri::percent_decode (view<const char*> s)
{
if (s.size () == 0)
return std::string ();
// Early check for late percent-encoding so we can simplify the decode loop
{
auto tail = std::find (s.size () < 3 ? s.begin ()
: s.end () - 2,
s.end (),
'%');
if (tail != s.end ())
throw parse_error ("triple overlaps end");
}
// Allocate and size a potentially overlong output string. This allows us
// to copy directly into its buffer. We'll shorten it at the end.
std::string out;
out.resize (s.size ());
// Find the percent, copy until that, decode, advance, repeat.
auto out_cursor = out.begin ();
for (auto i = s.begin (); i < s.end (); ++i) {
auto cursor = std::find (i, s.end (), '%');
if (cursor == s.end ()) {
out_cursor = std::copy (i, s.end (), out_cursor);
break;
}
out_cursor = std::copy (i, cursor, out_cursor);
*out_cursor = hex_to_uint (cursor[1]) << 4 | hex_to_uint(cursor[2]);
i += 3;
}
out.resize (out.end () - out_cursor);
return out;
}
//-----------------------------------------------------------------------------
std::ostream&
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";
case cruft::uri::PATH: return os << "PATH";
case cruft::uri::QUERY: return os << "QUERY";
case cruft::uri::FRAGMENT: return os << "FRAGMENT";
case cruft::uri::NUM_COMPONENTS:
unreachable ();
}
unreachable ();
}
//-----------------------------------------------------------------------------
std::ostream&
cruft::operator<< (std::ostream &os, cruft::uri const &val)
{
return os << val.value ();
}

View File

@ -8,8 +8,6 @@
#include "uri.hpp"
#include "debug/panic.hpp"
#include <algorithm>
#include <iostream>
@ -70,41 +68,17 @@ using cruft::uri;
///////////////////////////////////////////////////////////////////////////////
// URI
cruft::uri::uri (const char *str):
uri (std::string (str))
{ ; }
//-----------------------------------------------------------------------------
uri::uri (cruft::view<const char *> _value):
uri (std::string (_value.begin (), _value.end ()))
{ ; }
//-----------------------------------------------------------------------------
uri::uri (const std::string &_value):
uri (std::string (_value))
{ ; }
//-----------------------------------------------------------------------------
static const cruft::view<const char*> NULL_VIEW { nullptr, nullptr };
//-----------------------------------------------------------------------------
cruft::uri::uri (std::string &&_value):
m_views {
NULL_VIEW,
NULL_VIEW,
NULL_VIEW,
NULL_VIEW,
NULL_VIEW,
NULL_VIEW,
NULL_VIEW,
NULL_VIEW,
NULL_VIEW
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr
},
m_value (std::move (_value))
{
@ -121,97 +95,4 @@ cruft::uri::uri (std::string &&_value):
if (!__success)
throw parse_error ("invalid uri");
}
//-----------------------------------------------------------------------------
static uint8_t
hex_to_uint (char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
unreachable ();
}
//-----------------------------------------------------------------------------
std::string
cruft::uri::percent_decode (view<const char*> s)
{
if (s.size () == 0)
return std::string ();
// Early check for late percent-encoding so we can simplify the decode loop
{
auto tail = std::find (s.size () < 3 ? s.begin ()
: s.end () - 2,
s.end (),
'%');
if (tail != s.end ())
throw parse_error ("triple overlaps end");
}
// Allocate and size a potentially overlong output string. This allows us
// to copy directly into its buffer. We'll shorten it at the end.
std::string out;
out.resize (s.size ());
// Find the percent, copy until that, decode, advance, repeat.
auto out_cursor = out.begin ();
for (auto i = s.begin (); i < s.end (); ++i) {
auto cursor = std::find (i, s.end (), '%');
if (cursor == s.end ()) {
out_cursor = std::copy (i, s.end (), out_cursor);
break;
}
out_cursor = std::copy (i, cursor, out_cursor);
*out_cursor = hex_to_uint (cursor[1]) << 4 | hex_to_uint(cursor[2]);
i += 3;
}
out.resize (out.end () - out_cursor);
return out;
}
//-----------------------------------------------------------------------------
std::ostream&
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";
case cruft::uri::PATH: return os << "PATH";
case cruft::uri::QUERY: return os << "QUERY";
case cruft::uri::FRAGMENT: return os << "FRAGMENT";
case cruft::uri::NUM_COMPONENTS:
unreachable ();
}
unreachable ();
}
//-----------------------------------------------------------------------------
std::ostream&
cruft::operator<< (std::ostream &os, cruft::uri const &val)
{
return os << val.value ();
}