2015-02-11 16:18:18 +11:00
|
|
|
/*
|
2019-03-19 16:00:44 +11:00
|
|
|
* 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/.
|
2015-02-11 16:18:18 +11:00
|
|
|
*
|
|
|
|
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
|
|
|
*/
|
|
|
|
|
2015-02-09 17:43:24 +11:00
|
|
|
#include "uri.hpp"
|
|
|
|
|
2021-12-21 14:56:28 +11:00
|
|
|
#include <cruft/util/debug/assert.hpp>
|
|
|
|
|
2015-02-09 17:43:24 +11:00
|
|
|
#include <algorithm>
|
|
|
|
#include <iostream>
|
|
|
|
|
2018-05-03 18:32:08 +10:00
|
|
|
// We generate some really old style C code via ragel here, so we have to
|
|
|
|
// disable some noisy warnings (doubly so given -Werror)
|
|
|
|
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
|
|
|
|
2018-08-05 14:42:02 +10:00
|
|
|
using cruft::uri;
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2017-12-26 17:33:06 +11:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2015-02-09 17:43:24 +11:00
|
|
|
%%{
|
2017-12-20 12:45:05 +11:00
|
|
|
machine impl;
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2015-02-11 16:41:35 +11:00
|
|
|
action trace { if (0) std::cerr << *p; }
|
2015-02-09 17:43:24 +11:00
|
|
|
action success {__success = true; }
|
|
|
|
action failure {__success = false; }
|
|
|
|
|
2021-12-21 14:56:28 +11:00
|
|
|
action scheme_begin { starts[SCHEME] = p; }
|
2022-05-18 16:00:34 +10:00
|
|
|
action scheme_end { record_component (SCHEME); }
|
2017-12-15 18:57:10 +11:00
|
|
|
|
2022-02-22 17:38:01 +11:00
|
|
|
action hier_begin { ; }
|
|
|
|
action hier_end { ; }
|
2017-12-15 18:57:10 +11:00
|
|
|
|
2021-12-21 14:56:28 +11:00
|
|
|
action user_begin { starts[USER] = p; }
|
2022-05-18 16:00:34 +10:00
|
|
|
action user_end { record_component (USER); }
|
2017-12-15 18:57:10 +11:00
|
|
|
|
2021-12-21 14:56:28 +11:00
|
|
|
action host_begin { starts[HOST] = p; }
|
2022-05-18 16:00:34 +10:00
|
|
|
action host_end { record_component (HOST); }
|
2017-12-15 18:57:10 +11:00
|
|
|
|
2021-12-21 14:56:28 +11:00
|
|
|
action port_begin { starts[PORT] = p; }
|
2022-05-18 16:00:34 +10:00
|
|
|
action port_end { record_component (PORT); }
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2022-02-22 17:38:01 +11:00
|
|
|
action authority_begin { ; }
|
|
|
|
action authority_end { ; }
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2021-12-21 14:56:28 +11:00
|
|
|
action path_begin { starts[PATH] = p; }
|
2022-05-18 16:00:34 +10:00
|
|
|
action path_end { record_component (PATH); }
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2021-12-21 14:56:28 +11:00
|
|
|
action query_begin { starts[QUERY] = p; }
|
2022-05-18 16:00:34 +10:00
|
|
|
action query_end { record_component (QUERY); }
|
2021-12-17 11:46:59 +11:00
|
|
|
|
2021-12-21 14:56:28 +11:00
|
|
|
action fragment_begin { starts[FRAGMENT] = p; }
|
2022-05-18 16:00:34 +10:00
|
|
|
action fragment_end { record_component (FRAGMENT); }
|
2015-02-09 17:43:24 +11:00
|
|
|
|
2017-12-20 12:45:05 +11:00
|
|
|
action uri_begin {}
|
2021-12-21 14:56:28 +11:00
|
|
|
action uri_end {}
|
2017-12-20 12:45:05 +11:00
|
|
|
|
|
|
|
include rfc3986 'rfc3986.rl';
|
|
|
|
|
2017-12-26 17:28:00 +11:00
|
|
|
impl := URI >uri_begin %uri_end
|
2015-02-09 17:43:24 +11:00
|
|
|
%success
|
|
|
|
$!failure
|
|
|
|
$trace;
|
|
|
|
|
|
|
|
write data;
|
|
|
|
}%%
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2022-03-08 07:47:21 +11:00
|
|
|
#include <fmt/format.h>
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2021-12-21 14:56:28 +11:00
|
|
|
void
|
|
|
|
cruft::uri::parse (void)
|
|
|
|
{
|
|
|
|
char const *starts[NUM_COMPONENTS] = {};
|
|
|
|
|
2022-05-18 16:00:34 +10:00
|
|
|
const char *str = m_value.data ();
|
2015-02-09 17:43:24 +11:00
|
|
|
const char *p = m_value.data ();
|
|
|
|
const char *pe = m_value.data () + m_value.size ();
|
|
|
|
const char *eof = pe;
|
|
|
|
|
2022-05-18 16:00:34 +10:00
|
|
|
m_offsets = {};
|
|
|
|
auto record_component = [&] (int const idx) {
|
|
|
|
// CHECK (m_offsets[idx].first == 0);
|
|
|
|
// CHECK (m_offsets[idx].second == 0);
|
|
|
|
|
|
|
|
CHECK (starts[idx]);
|
|
|
|
|
2022-08-18 13:11:54 +10:00
|
|
|
m_offsets[idx].first = cruft::cast::narrow<int> (starts[idx] - str);
|
|
|
|
m_offsets[idx].second = cruft::cast::narrow<int> ( p - str);
|
2022-05-18 16:00:34 +10:00
|
|
|
};
|
|
|
|
|
2015-02-09 17:43:24 +11:00
|
|
|
bool __success = false;
|
|
|
|
|
|
|
|
int cs;
|
|
|
|
|
|
|
|
%%write init;
|
|
|
|
%%write exec;
|
|
|
|
|
2022-05-18 16:00:34 +10:00
|
|
|
if constexpr (debug_enabled) {
|
|
|
|
if (!m_value.empty ())
|
|
|
|
CHECK (std::any_of (
|
|
|
|
m_offsets.begin (),
|
|
|
|
m_offsets.end (),
|
|
|
|
[] (auto const &i)
|
|
|
|
{
|
|
|
|
return !!i.second;
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2015-02-09 17:43:24 +11:00
|
|
|
if (!__success)
|
2022-03-08 07:47:21 +11:00
|
|
|
throw parse_error (fmt::format ("invalid uri '{}'", m_value));
|
2021-12-13 16:55:01 +11:00
|
|
|
}
|