mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-12 18:28:07 +00:00
Added thirdparty: boost library
This commit is contained in:
+426
@@ -0,0 +1,426 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
|
||||
#define BOOST_URL_DETAIL_ANY_PARAMS_ITER_HPP
|
||||
|
||||
#include <boost/url/param.hpp>
|
||||
#include <boost/url/pct_string_view.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// any_params_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
/* An iterator to a type-erased,
|
||||
possibly encoded sequence of
|
||||
query params_ref.
|
||||
*/
|
||||
struct BOOST_SYMBOL_VISIBLE
|
||||
any_params_iter
|
||||
{
|
||||
protected:
|
||||
any_params_iter(
|
||||
bool empty_,
|
||||
core::string_view s0_ = {},
|
||||
core::string_view s1_ = {}) noexcept
|
||||
: s0(s0_)
|
||||
, s1(s1_)
|
||||
, empty(empty_)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
// these are adjusted
|
||||
// when self-intersecting
|
||||
core::string_view s0;
|
||||
core::string_view s1;
|
||||
|
||||
// True if the sequence is empty
|
||||
bool empty = false;
|
||||
|
||||
BOOST_URL_DECL
|
||||
virtual
|
||||
~any_params_iter() noexcept = 0;
|
||||
|
||||
// Rewind the iterator to the beginning
|
||||
virtual
|
||||
void
|
||||
rewind() noexcept = 0;
|
||||
|
||||
// Measure and increment current element
|
||||
// element.
|
||||
// Returns false on end of range.
|
||||
// n is increased by encoded size.
|
||||
// Can throw on bad percent-escape
|
||||
virtual
|
||||
bool
|
||||
measure(std::size_t& n) = 0;
|
||||
|
||||
// Copy and increment the current
|
||||
// element. encoding is performed
|
||||
// if needed.
|
||||
virtual
|
||||
void
|
||||
copy(
|
||||
char*& dest,
|
||||
char const* end) noexcept = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// query_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// A string of plain query params
|
||||
struct BOOST_SYMBOL_VISIBLE
|
||||
query_iter
|
||||
: any_params_iter
|
||||
{
|
||||
// ne = never empty
|
||||
BOOST_URL_DECL
|
||||
explicit
|
||||
query_iter(
|
||||
core::string_view s,
|
||||
bool ne = false) noexcept;
|
||||
|
||||
private:
|
||||
core::string_view s_;
|
||||
std::size_t n_;
|
||||
char const* p_;
|
||||
bool at_end_;
|
||||
|
||||
void rewind() noexcept override;
|
||||
bool measure(std::size_t&) noexcept override;
|
||||
void copy(char*&, char const*) noexcept override;
|
||||
void increment() noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// param_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// A 1-param range allowing
|
||||
// self-intersection
|
||||
struct BOOST_SYMBOL_VISIBLE
|
||||
param_iter
|
||||
: any_params_iter
|
||||
{
|
||||
explicit
|
||||
param_iter(
|
||||
param_view const&) noexcept;
|
||||
|
||||
private:
|
||||
bool has_value_;
|
||||
bool at_end_ = false;
|
||||
|
||||
void rewind() noexcept override;
|
||||
bool measure(std::size_t&) noexcept override;
|
||||
void copy(char*&, char const*) noexcept override;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// params_iter_base
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
struct params_iter_base
|
||||
{
|
||||
protected:
|
||||
// return encoded size
|
||||
BOOST_URL_DECL
|
||||
static
|
||||
void
|
||||
measure_impl(
|
||||
std::size_t& n,
|
||||
param_view const& p) noexcept;
|
||||
|
||||
// encode to dest
|
||||
BOOST_URL_DECL
|
||||
static
|
||||
void
|
||||
copy_impl(
|
||||
char*& dest,
|
||||
char const* end,
|
||||
param_view const& v) noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// A range of plain query params_ref
|
||||
template<class FwdIt>
|
||||
struct params_iter
|
||||
: any_params_iter
|
||||
, private params_iter_base
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
std::is_convertible<
|
||||
typename std::iterator_traits<
|
||||
FwdIt>::reference,
|
||||
param_view>::value);
|
||||
|
||||
params_iter(
|
||||
FwdIt first,
|
||||
FwdIt last) noexcept
|
||||
: any_params_iter(
|
||||
first == last)
|
||||
, it0_(first)
|
||||
, it_(first)
|
||||
, end_(last)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
FwdIt it0_;
|
||||
FwdIt it_;
|
||||
FwdIt end_;
|
||||
|
||||
void
|
||||
rewind() noexcept override
|
||||
{
|
||||
it_ = it0_;
|
||||
}
|
||||
|
||||
bool
|
||||
measure(
|
||||
std::size_t& n) noexcept override
|
||||
{
|
||||
if(it_ == end_)
|
||||
return false;
|
||||
measure_impl(n,
|
||||
param_view(*it_++));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
copy(
|
||||
char*& dest,
|
||||
char const* end) noexcept override
|
||||
{
|
||||
copy_impl(dest, end,
|
||||
param_view(*it_++));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// param_encoded_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// A 1-param encoded range
|
||||
// allowing self-intersection
|
||||
struct BOOST_SYMBOL_VISIBLE
|
||||
param_encoded_iter
|
||||
: any_params_iter
|
||||
{
|
||||
explicit
|
||||
param_encoded_iter(
|
||||
param_pct_view const&) noexcept;
|
||||
|
||||
private:
|
||||
bool has_value_;
|
||||
bool at_end_ = false;
|
||||
|
||||
void rewind() noexcept override;
|
||||
bool measure(std::size_t&) noexcept override;
|
||||
void copy(char*&, char const*) noexcept override;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// params_encoded_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// Validating and copying from
|
||||
// a string of encoded params
|
||||
struct params_encoded_iter_base
|
||||
{
|
||||
protected:
|
||||
BOOST_URL_DECL
|
||||
static
|
||||
void
|
||||
measure_impl(
|
||||
std::size_t& n,
|
||||
param_view const& v) noexcept;
|
||||
|
||||
BOOST_URL_DECL
|
||||
static
|
||||
void
|
||||
copy_impl(
|
||||
char*& dest,
|
||||
char const* end,
|
||||
param_view const& v) noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// A range of encoded query params_ref
|
||||
template<class FwdIt>
|
||||
struct params_encoded_iter
|
||||
: any_params_iter
|
||||
, private params_encoded_iter_base
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
std::is_convertible<
|
||||
typename std::iterator_traits<
|
||||
FwdIt>::reference,
|
||||
param_view>::value);
|
||||
|
||||
params_encoded_iter(
|
||||
FwdIt first,
|
||||
FwdIt last) noexcept
|
||||
: any_params_iter(
|
||||
first == last)
|
||||
, it0_(first)
|
||||
, it_(first)
|
||||
, end_(last)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
FwdIt it0_;
|
||||
FwdIt it_;
|
||||
FwdIt end_;
|
||||
|
||||
void
|
||||
rewind() noexcept override
|
||||
{
|
||||
it_ = it0_;
|
||||
}
|
||||
|
||||
bool
|
||||
measure(
|
||||
std::size_t& n) override
|
||||
{
|
||||
if(it_ == end_)
|
||||
return false;
|
||||
// throw on invalid input
|
||||
measure_impl(n,
|
||||
param_pct_view(
|
||||
param_view(*it_++)));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
copy(
|
||||
char*& dest,
|
||||
char const* end
|
||||
) noexcept override
|
||||
{
|
||||
copy_impl(dest, end,
|
||||
param_view(*it_++));
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// param_value_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// An iterator which outputs
|
||||
// one value on an existing key
|
||||
struct param_value_iter
|
||||
: any_params_iter
|
||||
{
|
||||
param_value_iter(
|
||||
std::size_t nk,
|
||||
core::string_view const& value,
|
||||
bool has_value) noexcept
|
||||
: any_params_iter(
|
||||
false,
|
||||
value)
|
||||
, nk_(nk)
|
||||
, has_value_(has_value)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t nk_ = 0;
|
||||
bool has_value_ = false;
|
||||
bool at_end_ = false;
|
||||
|
||||
void rewind() noexcept override;
|
||||
bool measure(std::size_t&) noexcept override;
|
||||
void copy(char*&, char const*) noexcept override;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// param_encoded_value_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// An iterator which outputs one
|
||||
// encoded value on an existing key
|
||||
struct param_encoded_value_iter
|
||||
: any_params_iter
|
||||
{
|
||||
param_encoded_value_iter(
|
||||
std::size_t nk,
|
||||
pct_string_view const& value,
|
||||
bool has_value) noexcept
|
||||
: any_params_iter(
|
||||
false,
|
||||
value)
|
||||
, nk_(nk)
|
||||
, has_value_(has_value)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t nk_ = 0;
|
||||
bool has_value_ = false;
|
||||
bool at_end_ = false;
|
||||
|
||||
void rewind() noexcept override;
|
||||
bool measure(std::size_t&) noexcept override;
|
||||
void copy(char*&, char const*) noexcept override;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
template<class FwdIt>
|
||||
params_iter<FwdIt>
|
||||
make_params_iter(
|
||||
FwdIt first, FwdIt last)
|
||||
{
|
||||
return params_iter<
|
||||
FwdIt>(first, last);
|
||||
}
|
||||
|
||||
template<class FwdIt>
|
||||
params_encoded_iter<FwdIt>
|
||||
make_params_encoded_iter(
|
||||
FwdIt first, FwdIt last)
|
||||
{
|
||||
return params_encoded_iter<
|
||||
FwdIt>(first, last);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+327
@@ -0,0 +1,327 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
|
||||
#define BOOST_URL_DETAIL_ANY_SEGMENTS_ITER_HPP
|
||||
|
||||
#include <boost/url/pct_string_view.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
struct BOOST_SYMBOL_VISIBLE
|
||||
any_segments_iter
|
||||
{
|
||||
protected:
|
||||
explicit
|
||||
any_segments_iter(
|
||||
core::string_view s_ = {}) noexcept
|
||||
: s(s_)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~any_segments_iter() = default;
|
||||
|
||||
public:
|
||||
// this is adjusted
|
||||
// when self-intersecting
|
||||
core::string_view s;
|
||||
|
||||
// the first segment,
|
||||
// to handle special cases
|
||||
core::string_view front;
|
||||
|
||||
// quick number of segments
|
||||
// 0 = zero
|
||||
// 1 = one
|
||||
// 2 = two, or more
|
||||
int fast_nseg = 0;
|
||||
|
||||
// whether the segments should encode colons
|
||||
// when we measure and copy. the calling
|
||||
// function uses this for the first
|
||||
// segment in some cases, such as:
|
||||
// "x:y:z" -> remove_scheme -> "y%3Az"
|
||||
// as "y:z" would no longer represent a path
|
||||
bool encode_colons = false;
|
||||
|
||||
// Rewind the iterator to the beginning
|
||||
virtual void rewind() noexcept = 0;
|
||||
|
||||
// Measure and increment the current
|
||||
// element. n is increased by the
|
||||
// encoded size. Returns false on
|
||||
// end of range.
|
||||
virtual bool measure(std::size_t& n) = 0;
|
||||
|
||||
// Copy and increment the current
|
||||
// element, encoding as needed.
|
||||
virtual void copy(char*& dest,
|
||||
char const* end) noexcept = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// segment_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// A 1-segment range
|
||||
// allowing self-intersection
|
||||
struct BOOST_SYMBOL_VISIBLE
|
||||
segment_iter
|
||||
: any_segments_iter
|
||||
{
|
||||
virtual ~segment_iter() = default;
|
||||
|
||||
explicit
|
||||
segment_iter(
|
||||
core::string_view s) noexcept;
|
||||
|
||||
private:
|
||||
bool at_end_ = false;
|
||||
void rewind() noexcept override;
|
||||
bool measure(std::size_t&) noexcept override;
|
||||
void copy(char*&, char const*) noexcept override;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// segments_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
struct segments_iter_base
|
||||
{
|
||||
protected:
|
||||
BOOST_URL_DECL static void
|
||||
measure_impl(std::size_t&,
|
||||
core::string_view, bool) noexcept;
|
||||
BOOST_URL_DECL static void
|
||||
copy_impl(char*&, char const*,
|
||||
core::string_view, bool) noexcept;
|
||||
};
|
||||
|
||||
// iterates segments in a
|
||||
// plain segment range
|
||||
template<class FwdIt>
|
||||
struct segments_iter
|
||||
: any_segments_iter
|
||||
, segments_iter_base
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
std::is_convertible<
|
||||
typename std::iterator_traits<
|
||||
FwdIt>::reference,
|
||||
core::string_view>::value);
|
||||
|
||||
segments_iter(
|
||||
FwdIt first,
|
||||
FwdIt last) noexcept
|
||||
: it_(first)
|
||||
, it0_(first)
|
||||
, end_(last)
|
||||
{
|
||||
if(first != last)
|
||||
{
|
||||
front = *first;
|
||||
auto it = first;
|
||||
if(++it == last)
|
||||
fast_nseg = 1;
|
||||
else
|
||||
fast_nseg = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fast_nseg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
FwdIt it_;
|
||||
FwdIt it0_;
|
||||
FwdIt end_;
|
||||
|
||||
void
|
||||
rewind() noexcept override
|
||||
{
|
||||
it_ = it0_;
|
||||
}
|
||||
|
||||
bool
|
||||
measure(
|
||||
std::size_t& n) noexcept override
|
||||
{
|
||||
if(it_ == end_)
|
||||
return false;
|
||||
measure_impl(n,
|
||||
detail::to_sv(*it_),
|
||||
encode_colons);
|
||||
++it_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
copy(
|
||||
char*& dest,
|
||||
char const* end) noexcept override
|
||||
{
|
||||
copy_impl(dest, end,
|
||||
detail::to_sv(*it_++),
|
||||
encode_colons);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// segment_encoded_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// A 1-segment range
|
||||
// allowing self-intersection
|
||||
struct BOOST_SYMBOL_VISIBLE
|
||||
segment_encoded_iter
|
||||
: any_segments_iter
|
||||
{
|
||||
virtual ~segment_encoded_iter() = default;
|
||||
|
||||
explicit
|
||||
segment_encoded_iter(
|
||||
pct_string_view const& s) noexcept;
|
||||
|
||||
private:
|
||||
bool at_end_ = false;
|
||||
void rewind() noexcept override;
|
||||
bool measure(std::size_t&) noexcept override;
|
||||
void copy(char*&, char const*) noexcept override;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
//
|
||||
// segments_encoded_iter
|
||||
//
|
||||
//------------------------------------------------
|
||||
|
||||
// Validating and copying from
|
||||
// a string of encoded segments
|
||||
struct segments_encoded_iter_base
|
||||
{
|
||||
protected:
|
||||
BOOST_URL_DECL static void
|
||||
measure_impl(std::size_t&,
|
||||
core::string_view, bool) noexcept;
|
||||
BOOST_URL_DECL static void
|
||||
copy_impl(char*&, char const*,
|
||||
core::string_view, bool) noexcept;
|
||||
};
|
||||
|
||||
// iterates segments in an
|
||||
// encoded segment range
|
||||
template<class FwdIt>
|
||||
struct segments_encoded_iter
|
||||
: public any_segments_iter
|
||||
, public segments_encoded_iter_base
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
std::is_convertible<
|
||||
typename std::iterator_traits<
|
||||
FwdIt>::reference,
|
||||
core::string_view>::value);
|
||||
|
||||
segments_encoded_iter(
|
||||
FwdIt first,
|
||||
FwdIt last)
|
||||
: it_(first)
|
||||
, it0_(first)
|
||||
, end_(last)
|
||||
{
|
||||
if(it_ != end_)
|
||||
{
|
||||
// throw on invalid input
|
||||
front = pct_string_view(
|
||||
detail::to_sv(*first));
|
||||
auto it = first;
|
||||
if(++it == last)
|
||||
fast_nseg = 1;
|
||||
else
|
||||
fast_nseg = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fast_nseg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
FwdIt it_;
|
||||
FwdIt it0_;
|
||||
FwdIt end_;
|
||||
|
||||
void
|
||||
rewind() noexcept override
|
||||
{
|
||||
it_ = it0_;
|
||||
}
|
||||
|
||||
bool
|
||||
measure(
|
||||
std::size_t& n) override
|
||||
{
|
||||
if(it_ == end_)
|
||||
return false;
|
||||
// throw on invalid input
|
||||
measure_impl(n,
|
||||
pct_string_view(
|
||||
detail::to_sv(*it_++)),
|
||||
encode_colons);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
copy(
|
||||
char*& dest,
|
||||
char const* end) noexcept override
|
||||
{
|
||||
copy_impl(dest, end,
|
||||
detail::to_sv(*it_++),
|
||||
encode_colons);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
template<class FwdIt>
|
||||
segments_iter<FwdIt>
|
||||
make_segments_iter(
|
||||
FwdIt first, FwdIt last)
|
||||
{
|
||||
return segments_iter<
|
||||
FwdIt>(first, last);
|
||||
}
|
||||
|
||||
template<class FwdIt>
|
||||
segments_encoded_iter<FwdIt>
|
||||
make_segments_encoded_iter(
|
||||
FwdIt first, FwdIt last)
|
||||
{
|
||||
return segments_encoded_iter<
|
||||
FwdIt>(first, last);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_CONFIG_HPP
|
||||
#define BOOST_URL_DETAIL_CONFIG_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if CHAR_BIT != 8
|
||||
# error unsupported platform
|
||||
#endif
|
||||
|
||||
// Determine if compiling as a dynamic library
|
||||
#if (defined(BOOST_URL_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && !defined(BOOST_URL_STATIC_LINK)
|
||||
# define BOOST_URL_BUILD_DLL
|
||||
#endif
|
||||
|
||||
// Set visibility flags
|
||||
#if !defined(BOOST_URL_BUILD_DLL)
|
||||
# define BOOST_URL_DECL /* static library */
|
||||
#elif defined(BOOST_URL_SOURCE)
|
||||
# define BOOST_URL_DECL BOOST_SYMBOL_EXPORT /* source: dllexport/visibility */
|
||||
#else
|
||||
# define BOOST_URL_DECL BOOST_SYMBOL_IMPORT /* header: dllimport */
|
||||
#endif
|
||||
|
||||
// Set up auto-linker
|
||||
# if !defined(BOOST_URL_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_URL_NO_LIB)
|
||||
# define BOOST_LIB_NAME boost_url
|
||||
# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_URL_DYN_LINK)
|
||||
# define BOOST_DYN_LINK
|
||||
# endif
|
||||
# include <boost/config/auto_link.hpp>
|
||||
# endif
|
||||
|
||||
// Set up SSE2
|
||||
#if ! defined(BOOST_URL_NO_SSE2) && \
|
||||
! defined(BOOST_URL_USE_SSE2)
|
||||
# if (defined(_M_IX86) && _M_IX86_FP == 2) || \
|
||||
defined(_M_X64) || defined(__SSE2__)
|
||||
# define BOOST_URL_USE_SSE2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// constexpr
|
||||
#if BOOST_WORKAROUND( BOOST_GCC_VERSION, <= 72000 ) || \
|
||||
BOOST_WORKAROUND( BOOST_CLANG_VERSION, <= 35000 )
|
||||
# define BOOST_URL_CONSTEXPR
|
||||
#else
|
||||
# define BOOST_URL_CONSTEXPR constexpr
|
||||
#endif
|
||||
|
||||
// Add source location to error codes
|
||||
#ifdef BOOST_URL_NO_SOURCE_LOCATION
|
||||
# define BOOST_URL_ERR(ev) (::boost::system::error_code(ev))
|
||||
# define BOOST_URL_RETURN_EC(ev) return (ev)
|
||||
# define BOOST_URL_POS ::boost::source_location()
|
||||
#else
|
||||
# define BOOST_URL_ERR(ev) (::boost::system::error_code( (ev), [] { \
|
||||
static constexpr auto loc((BOOST_CURRENT_LOCATION)); \
|
||||
return &loc; }()))
|
||||
# define BOOST_URL_RETURN_EC(ev) \
|
||||
static constexpr auto loc ## __LINE__((BOOST_CURRENT_LOCATION)); \
|
||||
return ::boost::system::error_code((ev), &loc ## __LINE__)
|
||||
# define BOOST_URL_POS (BOOST_CURRENT_LOCATION)
|
||||
#endif
|
||||
|
||||
// String token parameters
|
||||
#ifndef BOOST_URL_STRTOK_TPARAM
|
||||
#define BOOST_URL_STRTOK_TPARAM class StringToken = string_token::return_string
|
||||
#endif
|
||||
#ifndef BOOST_URL_STRTOK_RETURN
|
||||
#define BOOST_URL_STRTOK_RETURN typename StringToken::result_type
|
||||
#endif
|
||||
#ifndef BOOST_URL_STRTOK_ARG
|
||||
#define BOOST_URL_STRTOK_ARG(name) StringToken&& token = {}
|
||||
#endif
|
||||
|
||||
// Move
|
||||
#if BOOST_WORKAROUND( BOOST_GCC_VERSION, < 80000 ) || \
|
||||
BOOST_WORKAROUND( BOOST_CLANG_VERSION, < 30900 )
|
||||
#define BOOST_URL_RETURN(x) return std::move((x))
|
||||
#else
|
||||
#define BOOST_URL_RETURN(x) return (x)
|
||||
#endif
|
||||
|
||||
// Limit tests
|
||||
#ifndef BOOST_URL_MAX_SIZE
|
||||
// we leave room for a null,
|
||||
// and still fit in size_t
|
||||
#define BOOST_URL_MAX_SIZE ((std::size_t(-1))-1)
|
||||
#endif
|
||||
|
||||
// noinline attribute
|
||||
#ifdef BOOST_GCC
|
||||
#define BOOST_URL_NO_INLINE [[gnu::noinline]]
|
||||
#else
|
||||
#define BOOST_URL_NO_INLINE
|
||||
#endif
|
||||
|
||||
// libstdcxx copy-on-write strings
|
||||
#ifndef BOOST_URL_COW_STRINGS
|
||||
#if defined(BOOST_LIBSTDCXX_VERSION) && (BOOST_LIBSTDCXX_VERSION < 60000 || (defined(_GLIBCXX_USE_CXX11_ABI) && _GLIBCXX_USE_CXX11_ABI == 0))
|
||||
#define BOOST_URL_COW_STRINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// detect 32/64 bit
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
# define BOOST_URL_ARCH 64
|
||||
#elif UINTPTR_MAX == UINT32_MAX
|
||||
# define BOOST_URL_ARCH 32
|
||||
#else
|
||||
# error Unknown or unsupported architecture, please open an issue
|
||||
#endif
|
||||
|
||||
// deprecated attribute
|
||||
#if defined(BOOST_MSVC) || defined(BOOST_URL_DOCS)
|
||||
#define BOOST_URL_DEPRECATED(msg)
|
||||
#else
|
||||
#define BOOST_URL_DEPRECATED(msg) BOOST_DEPRECATED(msg)
|
||||
#endif
|
||||
|
||||
// avoid Boost.TypeTraits for these traits
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
|
||||
template<class...> struct make_void { typedef void type; };
|
||||
template<class... Ts> using void_t = typename make_void<Ts...>::type;
|
||||
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_DECODE_HPP
|
||||
#define BOOST_URL_DETAIL_DECODE_HPP
|
||||
|
||||
#include <boost/url/encoding_opts.hpp>
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
BOOST_URL_DECL
|
||||
char
|
||||
decode_one(
|
||||
char const* it) noexcept;
|
||||
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
decode_bytes_unsafe(
|
||||
core::string_view s) noexcept;
|
||||
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
decode_unsafe(
|
||||
char* dest,
|
||||
char const* end,
|
||||
core::string_view s,
|
||||
encoding_opts opt = {}) noexcept;
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_ENCODE_HPP
|
||||
#define BOOST_URL_DETAIL_ENCODE_HPP
|
||||
|
||||
#include <boost/url/encoding_opts.hpp>
|
||||
#include <boost/url/pct_string_view.hpp>
|
||||
#include <boost/url/grammar/hexdig_chars.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
constexpr
|
||||
char const* const hexdigs[] = {
|
||||
"0123456789ABCDEF",
|
||||
"0123456789abcdef" };
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// re-encode is to percent-encode a
|
||||
// string that can already contain
|
||||
// escapes. Characters not in the
|
||||
// unreserved set are escaped, and
|
||||
// escapes are passed through unchanged.
|
||||
//
|
||||
template<class CharSet>
|
||||
std::size_t
|
||||
re_encoded_size_unsafe(
|
||||
core::string_view s,
|
||||
CharSet const& unreserved,
|
||||
encoding_opts opt) noexcept
|
||||
{
|
||||
std::size_t n = 0;
|
||||
auto const end = s.end();
|
||||
auto it = s.begin();
|
||||
if(opt.space_as_plus)
|
||||
{
|
||||
while(it != end)
|
||||
{
|
||||
if(*it != '%')
|
||||
{
|
||||
if( unreserved(*it)
|
||||
|| *it == ' ')
|
||||
n += 1;
|
||||
else
|
||||
n += 3;
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(end - it >= 3);
|
||||
BOOST_ASSERT(
|
||||
grammar::hexdig_value(
|
||||
it[1]) >= 0);
|
||||
BOOST_ASSERT(
|
||||
grammar::hexdig_value(
|
||||
it[2]) >= 0);
|
||||
n += 3;
|
||||
it += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(it != end)
|
||||
{
|
||||
if(*it != '%')
|
||||
{
|
||||
if(unreserved(*it))
|
||||
n += 1;
|
||||
else
|
||||
n += 3;
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(end - it >= 3);
|
||||
BOOST_ASSERT(
|
||||
grammar::hexdig_value(
|
||||
it[1]) >= 0);
|
||||
BOOST_ASSERT(
|
||||
grammar::hexdig_value(
|
||||
it[2]) >= 0);
|
||||
n += 3;
|
||||
it += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// unchecked
|
||||
// returns decoded size
|
||||
template<class CharSet>
|
||||
std::size_t
|
||||
re_encode_unsafe(
|
||||
char*& dest_,
|
||||
char const* const end,
|
||||
core::string_view s,
|
||||
CharSet const& unreserved,
|
||||
encoding_opts opt) noexcept
|
||||
{
|
||||
char const* const hex =
|
||||
detail::hexdigs[opt.lower_case];
|
||||
auto const encode = [end, hex](
|
||||
char*& dest,
|
||||
unsigned char c) noexcept
|
||||
{
|
||||
ignore_unused(end);
|
||||
*dest++ = '%';
|
||||
BOOST_ASSERT(dest != end);
|
||||
*dest++ = hex[c>>4];
|
||||
BOOST_ASSERT(dest != end);
|
||||
*dest++ = hex[c&0xf];
|
||||
};
|
||||
ignore_unused(end);
|
||||
|
||||
auto dest = dest_;
|
||||
auto const dest0 = dest;
|
||||
auto const last = s.end();
|
||||
std::size_t dn = 0;
|
||||
auto it = s.begin();
|
||||
|
||||
if(opt.space_as_plus)
|
||||
{
|
||||
while(it != last)
|
||||
{
|
||||
BOOST_ASSERT(dest != end);
|
||||
if(*it != '%')
|
||||
{
|
||||
if(*it == ' ')
|
||||
{
|
||||
*dest++ = '+';
|
||||
}
|
||||
else if(unreserved(*it))
|
||||
{
|
||||
*dest++ = *it;
|
||||
}
|
||||
else
|
||||
{
|
||||
encode(dest, *it);
|
||||
dn += 2;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest++ = *it++;
|
||||
BOOST_ASSERT(dest != end);
|
||||
*dest++ = *it++;
|
||||
BOOST_ASSERT(dest != end);
|
||||
*dest++ = *it++;
|
||||
dn += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(it != last)
|
||||
{
|
||||
BOOST_ASSERT(dest != end);
|
||||
if(*it != '%')
|
||||
{
|
||||
if(unreserved(*it))
|
||||
{
|
||||
*dest++ = *it;
|
||||
}
|
||||
else
|
||||
{
|
||||
encode(dest, *it);
|
||||
dn += 2;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest++ = *it++;
|
||||
BOOST_ASSERT(dest != end);
|
||||
*dest++ = *it++;
|
||||
BOOST_ASSERT(dest != end);
|
||||
*dest++ = *it++;
|
||||
dn += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
dest_ = dest;
|
||||
return dest - dest0 - dn;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_EXCEPT_HPP
|
||||
#define BOOST_URL_DETAIL_EXCEPT_HPP
|
||||
|
||||
#include <boost/url/error_types.hpp>
|
||||
#include <boost/assert/source_location.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
BOOST_URL_DECL void BOOST_NORETURN
|
||||
throw_system_error(
|
||||
system::error_code const& ec,
|
||||
source_location const& loc =
|
||||
BOOST_URL_POS);
|
||||
|
||||
BOOST_URL_DECL void BOOST_NORETURN
|
||||
throw_errc(
|
||||
boost::system::errc::errc_t ev,
|
||||
source_location const& loc =
|
||||
BOOST_URL_POS);
|
||||
|
||||
//-----
|
||||
|
||||
BOOST_URL_DECL void BOOST_NORETURN
|
||||
throw_invalid_argument(
|
||||
source_location const& loc =
|
||||
BOOST_URL_POS);
|
||||
|
||||
BOOST_URL_DECL void BOOST_NORETURN
|
||||
throw_length_error(
|
||||
source_location const& loc =
|
||||
BOOST_URL_POS);
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+340
@@ -0,0 +1,340 @@
|
||||
//
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_FORMAT_ARGS_HPP
|
||||
#define BOOST_URL_DETAIL_FORMAT_ARGS_HPP
|
||||
|
||||
#include <boost/url/detail/encode.hpp>
|
||||
#include <boost/url/grammar/lut_chars.hpp>
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <array>
|
||||
|
||||
// This file implements functions and classes to
|
||||
// type-erase format arguments.
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// state of the format string. It basically keeps
|
||||
// track of where we are in the format string.
|
||||
class format_parse_context
|
||||
{
|
||||
char const* begin_;
|
||||
char const* end_;
|
||||
std::size_t arg_id_ = 0;
|
||||
|
||||
public:
|
||||
constexpr
|
||||
format_parse_context(
|
||||
char const* first,
|
||||
char const* last,
|
||||
std::size_t arg_id = 0)
|
||||
: begin_( first )
|
||||
, end_( last )
|
||||
, arg_id_( arg_id )
|
||||
{}
|
||||
|
||||
constexpr
|
||||
format_parse_context(
|
||||
core::string_view fmt,
|
||||
std::size_t arg_id = 0)
|
||||
: format_parse_context(
|
||||
fmt.data(),
|
||||
fmt.data() + fmt.size(),
|
||||
arg_id )
|
||||
{}
|
||||
|
||||
constexpr
|
||||
char const*
|
||||
begin() const noexcept
|
||||
{
|
||||
return begin_;
|
||||
}
|
||||
|
||||
constexpr
|
||||
char const*
|
||||
end() const noexcept
|
||||
{
|
||||
return end_;
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
void
|
||||
advance_to( char const* it )
|
||||
{
|
||||
begin_ = it;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
next_arg_id()
|
||||
{
|
||||
return arg_id_++;
|
||||
}
|
||||
};
|
||||
|
||||
// State of the destination string
|
||||
class format_context;
|
||||
class measure_context;
|
||||
struct ignore_format {};
|
||||
|
||||
template <class T>
|
||||
struct named_arg
|
||||
{
|
||||
core::string_view name;
|
||||
T const& value;
|
||||
|
||||
named_arg(core::string_view n, T const& v)
|
||||
: name(n)
|
||||
, value(v)
|
||||
{}
|
||||
};
|
||||
|
||||
// A type erased format argument
|
||||
class format_arg
|
||||
{
|
||||
void const* arg_;
|
||||
void (*measure_)(
|
||||
format_parse_context&,
|
||||
measure_context&,
|
||||
grammar::lut_chars const&,
|
||||
void const* );
|
||||
void (*fmt_)(
|
||||
format_parse_context&,
|
||||
format_context&,
|
||||
grammar::lut_chars const&,
|
||||
void const* );
|
||||
core::string_view name_;
|
||||
std::size_t value_ = 0;
|
||||
bool ignore_ = false;
|
||||
|
||||
template <class A>
|
||||
static
|
||||
void
|
||||
measure_impl(
|
||||
format_parse_context& pctx,
|
||||
measure_context& mctx,
|
||||
grammar::lut_chars const& cs,
|
||||
void const* a );
|
||||
|
||||
template <class A>
|
||||
static
|
||||
void
|
||||
format_impl(
|
||||
format_parse_context& pctx,
|
||||
format_context& fctx,
|
||||
grammar::lut_chars const& cs,
|
||||
void const* a );
|
||||
|
||||
public:
|
||||
template<class A>
|
||||
format_arg( A&& a );
|
||||
|
||||
template<class A>
|
||||
format_arg( named_arg<A>&& a );
|
||||
|
||||
template<class A>
|
||||
format_arg( core::string_view name, A&& a );
|
||||
|
||||
format_arg()
|
||||
: format_arg(ignore_format{})
|
||||
{}
|
||||
|
||||
explicit
|
||||
operator bool() const noexcept
|
||||
{
|
||||
return !ignore_;
|
||||
}
|
||||
|
||||
void
|
||||
measure(
|
||||
format_parse_context& pctx,
|
||||
measure_context& mctx,
|
||||
grammar::lut_chars const& cs)
|
||||
{
|
||||
measure_( pctx, mctx, cs, arg_ );
|
||||
}
|
||||
|
||||
void
|
||||
format(
|
||||
format_parse_context& pctx,
|
||||
format_context& fctx,
|
||||
grammar::lut_chars const& cs )
|
||||
{
|
||||
fmt_( pctx, fctx, cs, arg_ );
|
||||
}
|
||||
|
||||
core::string_view
|
||||
name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
value() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
// create temp stack storage for type erased args
|
||||
template< class... Args >
|
||||
std::array<format_arg, sizeof...(Args)>
|
||||
make_format_args( Args&&... args )
|
||||
{
|
||||
return {{ std::forward<Args>(args)... }};
|
||||
}
|
||||
|
||||
// reference to an array of format_args
|
||||
class format_args
|
||||
{
|
||||
format_arg const* p_{nullptr};
|
||||
std::size_t n_{0};
|
||||
|
||||
public:
|
||||
format_args(
|
||||
detail::format_arg const* first,
|
||||
detail::format_arg const* last ) noexcept
|
||||
: p_(first)
|
||||
, n_(static_cast<std::size_t>(last - first))
|
||||
{}
|
||||
|
||||
template < std::size_t N >
|
||||
format_args( std::array<format_arg, N> const& store ) noexcept
|
||||
: p_(store.data())
|
||||
, n_(store.size())
|
||||
{}
|
||||
|
||||
format_arg
|
||||
get( std::size_t i ) const noexcept
|
||||
{
|
||||
if (i < n_)
|
||||
return p_[i];
|
||||
return {};
|
||||
}
|
||||
|
||||
format_arg
|
||||
get( core::string_view name ) const noexcept
|
||||
{
|
||||
for (std::size_t i = 0; i < n_; ++i)
|
||||
{
|
||||
if (p_[i].name() == name)
|
||||
return p_[i];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
// define the format_context after format_args
|
||||
class format_context
|
||||
{
|
||||
format_args args_;
|
||||
char* out_;
|
||||
|
||||
public:
|
||||
format_context(
|
||||
char* out,
|
||||
format_args args )
|
||||
: args_( args )
|
||||
, out_( out )
|
||||
{}
|
||||
|
||||
format_args
|
||||
args() const noexcept
|
||||
{
|
||||
return args_;
|
||||
}
|
||||
|
||||
format_arg
|
||||
arg( std::size_t id ) const noexcept
|
||||
{
|
||||
return args_.get( id );
|
||||
}
|
||||
|
||||
format_arg
|
||||
arg( core::string_view name ) const noexcept
|
||||
{
|
||||
return args_.get( name );
|
||||
}
|
||||
|
||||
char*
|
||||
out()
|
||||
{
|
||||
return out_;
|
||||
}
|
||||
|
||||
void
|
||||
advance_to( char* it )
|
||||
{
|
||||
out_ = it;
|
||||
}
|
||||
};
|
||||
|
||||
// define the measure_context after format_args
|
||||
class measure_context
|
||||
{
|
||||
format_args args_;
|
||||
std::size_t out_;
|
||||
|
||||
public:
|
||||
measure_context(
|
||||
format_args args )
|
||||
: measure_context(0, args)
|
||||
{}
|
||||
|
||||
measure_context(
|
||||
std::size_t out,
|
||||
format_args args )
|
||||
: args_( args )
|
||||
, out_( out )
|
||||
{}
|
||||
|
||||
format_args
|
||||
args() const noexcept
|
||||
{
|
||||
return args_;
|
||||
}
|
||||
|
||||
format_arg
|
||||
arg( std::size_t id ) const noexcept
|
||||
{
|
||||
return args_.get( id );
|
||||
}
|
||||
|
||||
format_arg
|
||||
arg( core::string_view name ) const noexcept
|
||||
{
|
||||
return args_.get( name );
|
||||
}
|
||||
|
||||
std::size_t
|
||||
out()
|
||||
{
|
||||
return out_;
|
||||
}
|
||||
|
||||
void
|
||||
advance_to( std::size_t n )
|
||||
{
|
||||
out_ = n;
|
||||
}
|
||||
};
|
||||
|
||||
// fwd declare the formatter
|
||||
template <class T, class = void>
|
||||
struct formatter;
|
||||
|
||||
} // detail
|
||||
} // url
|
||||
} // boost
|
||||
|
||||
#include <boost/url/detail/impl/format_args.hpp>
|
||||
|
||||
#endif
|
||||
+416
@@ -0,0 +1,416 @@
|
||||
//
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_IMPL_FORMAT_ARGS_HPP
|
||||
#define BOOST_URL_DETAIL_IMPL_FORMAT_ARGS_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
template<
|
||||
class A,
|
||||
typename std::enable_if<
|
||||
!std::is_integral<
|
||||
typename std::decay<A>::type>::value,
|
||||
int>::type = 0>
|
||||
std::size_t
|
||||
get_uvalue( A&& )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<
|
||||
class A,
|
||||
typename std::enable_if<
|
||||
std::is_integral<
|
||||
typename std::decay<A>::type>::value &&
|
||||
std::is_signed<
|
||||
typename std::decay<A>::type>::value,
|
||||
int>::type = 0>
|
||||
std::size_t
|
||||
get_uvalue( A&& a )
|
||||
{
|
||||
if (a > 0)
|
||||
return static_cast<std::size_t>(a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<
|
||||
class A,
|
||||
typename std::enable_if<
|
||||
std::is_integral<
|
||||
typename std::decay<A>::type>::value &&
|
||||
std::is_unsigned<
|
||||
typename std::decay<A>::type>::value,
|
||||
int>::type = 0>
|
||||
std::size_t
|
||||
get_uvalue( A&& a )
|
||||
{
|
||||
return static_cast<std::size_t>(a);
|
||||
}
|
||||
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
get_uvalue( core::string_view a );
|
||||
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
get_uvalue( char a );
|
||||
|
||||
template<class A>
|
||||
format_arg::
|
||||
format_arg( A&& a )
|
||||
: arg_( &a )
|
||||
, measure_( &measure_impl<A> )
|
||||
, fmt_( &format_impl<A> )
|
||||
, value_( get_uvalue(std::forward<A>(a) ))
|
||||
, ignore_( std::is_same<A, ignore_format>::value )
|
||||
{}
|
||||
|
||||
template<class A>
|
||||
format_arg::
|
||||
format_arg( named_arg<A>&& a )
|
||||
: arg_( &a.value )
|
||||
, measure_( &measure_impl<A> )
|
||||
, fmt_( &format_impl<A> )
|
||||
, name_( a.name )
|
||||
, value_( get_uvalue(a.value))
|
||||
{}
|
||||
|
||||
template<class A>
|
||||
format_arg::
|
||||
format_arg( core::string_view name, A&& a )
|
||||
: arg_( &a )
|
||||
, measure_( &measure_impl<A> )
|
||||
, fmt_( &format_impl<A> )
|
||||
, name_( name )
|
||||
, value_( get_uvalue(a) )
|
||||
{}
|
||||
|
||||
// define the type-erased implementations that
|
||||
// depends on everything: the context types,
|
||||
// formatters, and type erased args
|
||||
template <class A>
|
||||
void
|
||||
format_arg::
|
||||
measure_impl(
|
||||
format_parse_context& pctx,
|
||||
measure_context& mctx,
|
||||
grammar::lut_chars const& cs,
|
||||
void const* a )
|
||||
{
|
||||
using ref_t = typename std::remove_reference<A>::type;
|
||||
A const& ref = *static_cast<ref_t*>(
|
||||
const_cast<void*>( a ) );
|
||||
formatter<ref_t> f;
|
||||
pctx.advance_to( f.parse(pctx) );
|
||||
mctx.advance_to( f.measure( ref, mctx, cs ) );
|
||||
}
|
||||
|
||||
template <class A>
|
||||
void
|
||||
format_arg::
|
||||
format_impl(
|
||||
format_parse_context& pctx,
|
||||
format_context& fctx,
|
||||
grammar::lut_chars const& cs,
|
||||
void const* a )
|
||||
{
|
||||
using ref_t = typename std::remove_reference<A>::type;
|
||||
A const& ref = *static_cast<ref_t*>(
|
||||
const_cast<void*>( a ) );
|
||||
formatter<ref_t> f;
|
||||
pctx.advance_to( f.parse(pctx) );
|
||||
fctx.advance_to( f.format( ref, fctx, cs ) );
|
||||
}
|
||||
|
||||
// We point to formatter<ignore_format> where
|
||||
// the format_arg variant would store monostate
|
||||
template <>
|
||||
struct formatter<ignore_format>
|
||||
{
|
||||
public:
|
||||
char const*
|
||||
parse(format_parse_context& ctx) const
|
||||
{
|
||||
return parse_empty_spec(
|
||||
ctx.begin(), ctx.end());
|
||||
}
|
||||
|
||||
std::size_t
|
||||
measure(
|
||||
ignore_format,
|
||||
measure_context& ctx,
|
||||
grammar::lut_chars const&) const
|
||||
{
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
char*
|
||||
format(
|
||||
ignore_format,
|
||||
format_context& ctx,
|
||||
grammar::lut_chars const&) const
|
||||
{
|
||||
return ctx.out();
|
||||
}
|
||||
|
||||
// We ignore the modifiers in all replacements
|
||||
// for now
|
||||
static
|
||||
char const*
|
||||
parse_empty_spec(
|
||||
char const* it,
|
||||
char const* end)
|
||||
{
|
||||
// [it, end] -> "} suffix"
|
||||
BOOST_ASSERT(it != end);
|
||||
ignore_unused(end);
|
||||
// Should be always empty/valid as an
|
||||
// implementation detail
|
||||
BOOST_ASSERT(*it == '}');
|
||||
/*
|
||||
if (*it != '}')
|
||||
urls::detail::throw_invalid_argument();
|
||||
*/
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
inline
|
||||
std::size_t
|
||||
measure_one(
|
||||
char c,
|
||||
grammar::lut_chars const& unreserved)
|
||||
{
|
||||
// '%' must be reserved
|
||||
BOOST_ASSERT(! unreserved('%'));
|
||||
return 1 + !unreserved(c) * 2;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
encode_one(
|
||||
char*& out,
|
||||
char c,
|
||||
grammar::lut_chars const& unreserved)
|
||||
{
|
||||
// '%' must be reserved
|
||||
BOOST_ASSERT(! unreserved('%'));
|
||||
if(unreserved(c))
|
||||
{
|
||||
*out++ = c;
|
||||
return;
|
||||
}
|
||||
*out++ = '%';
|
||||
*out++ = urls::detail::hexdigs[0][c>>4];
|
||||
*out++ = urls::detail::hexdigs[0][c&0xf];
|
||||
}
|
||||
|
||||
// get an unsigned value from format_args
|
||||
BOOST_URL_DECL
|
||||
void
|
||||
get_width_from_args(
|
||||
std::size_t arg_idx,
|
||||
core::string_view arg_name,
|
||||
format_args args,
|
||||
std::size_t& w);
|
||||
|
||||
// formatter for string view
|
||||
template <>
|
||||
struct formatter<core::string_view>
|
||||
{
|
||||
private:
|
||||
char fill = ' ';
|
||||
char align = '\0';
|
||||
std::size_t width = 0;
|
||||
std::size_t width_idx = std::size_t(-1);
|
||||
core::string_view width_name;
|
||||
|
||||
public:
|
||||
BOOST_URL_DECL
|
||||
char const*
|
||||
parse(format_parse_context& ctx);
|
||||
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
measure(
|
||||
core::string_view str,
|
||||
measure_context& ctx,
|
||||
grammar::lut_chars const& cs) const;
|
||||
|
||||
BOOST_URL_DECL
|
||||
char*
|
||||
format(
|
||||
core::string_view str,
|
||||
format_context& ctx,
|
||||
grammar::lut_chars const& cs) const;
|
||||
};
|
||||
|
||||
// formatter for anything convertible to a
|
||||
// string view
|
||||
template <class T>
|
||||
struct formatter<
|
||||
T, typename std::enable_if<
|
||||
std::is_convertible<
|
||||
T, core::string_view>::value>::type>
|
||||
{
|
||||
formatter<core::string_view> impl_;
|
||||
|
||||
public:
|
||||
char const*
|
||||
parse(format_parse_context& ctx)
|
||||
{
|
||||
return impl_.parse(ctx);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
measure(
|
||||
core::string_view str,
|
||||
measure_context& ctx,
|
||||
grammar::lut_chars const& cs) const
|
||||
{
|
||||
return impl_.measure(str, ctx, cs);
|
||||
}
|
||||
|
||||
char*
|
||||
format(core::string_view str, format_context& ctx, grammar::lut_chars const& cs) const
|
||||
{
|
||||
return impl_.format(str, ctx, cs);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct formatter<char>
|
||||
{
|
||||
formatter<core::string_view> impl_;
|
||||
|
||||
public:
|
||||
char const*
|
||||
parse(format_parse_context& ctx)
|
||||
{
|
||||
return impl_.parse(ctx);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
measure(
|
||||
char c,
|
||||
measure_context& ctx,
|
||||
grammar::lut_chars const& cs) const
|
||||
{
|
||||
return impl_.measure({&c, 1}, ctx, cs);
|
||||
}
|
||||
|
||||
char*
|
||||
format(
|
||||
char c,
|
||||
format_context& ctx,
|
||||
grammar::lut_chars const& cs) const
|
||||
{
|
||||
return impl_.format({&c, 1}, ctx, cs);
|
||||
}
|
||||
};
|
||||
|
||||
// formatters for a single integer
|
||||
class integer_formatter_impl
|
||||
{
|
||||
char fill = ' ';
|
||||
char align = '\0';
|
||||
char sign = '-';
|
||||
bool zeros = false;
|
||||
std::size_t width = 0;
|
||||
std::size_t width_idx = std::size_t(-1);
|
||||
core::string_view width_name;
|
||||
|
||||
public:
|
||||
BOOST_URL_DECL
|
||||
char const*
|
||||
parse(format_parse_context& ctx);
|
||||
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
measure(
|
||||
unsigned long long int v,
|
||||
measure_context& ctx,
|
||||
grammar::lut_chars const& cs) const;
|
||||
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
measure(
|
||||
long long int v,
|
||||
measure_context& ctx,
|
||||
grammar::lut_chars const& cs) const;
|
||||
|
||||
BOOST_URL_DECL
|
||||
char*
|
||||
format(
|
||||
unsigned long long int v,
|
||||
format_context& ctx,
|
||||
grammar::lut_chars const& cs) const;
|
||||
|
||||
BOOST_URL_DECL
|
||||
char*
|
||||
format(
|
||||
long long int v,
|
||||
format_context& ctx,
|
||||
grammar::lut_chars const& cs) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct formatter<
|
||||
T, typename std::enable_if<
|
||||
mp11::mp_contains<mp11::mp_list<
|
||||
short int,
|
||||
int,
|
||||
long int,
|
||||
long long int,
|
||||
unsigned short int,
|
||||
unsigned int,
|
||||
unsigned long int,
|
||||
unsigned long long int>, T>::value>::type>
|
||||
{
|
||||
private:
|
||||
integer_formatter_impl impl_;
|
||||
using base_value_type = typename std::conditional<
|
||||
std::is_unsigned<T>::value,
|
||||
unsigned long long int,
|
||||
long long int
|
||||
>::type;
|
||||
|
||||
public:
|
||||
char const*
|
||||
parse(format_parse_context& ctx)
|
||||
{
|
||||
return impl_.parse(ctx);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
measure(
|
||||
T v,
|
||||
measure_context& ctx,
|
||||
grammar::lut_chars const& cs) const
|
||||
{
|
||||
return impl_.measure(
|
||||
static_cast<base_value_type>(v), ctx, cs);
|
||||
}
|
||||
|
||||
char*
|
||||
format(T v, format_context& ctx, grammar::lut_chars const& cs) const
|
||||
{
|
||||
return impl_.format(
|
||||
static_cast<base_value_type>(v), ctx, cs);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // url
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_MOVE_CHARS_HPP
|
||||
#define BOOST_URL_DETAIL_MOVE_CHARS_HPP
|
||||
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// Moves characters, and adjusts any passed
|
||||
// views if they point to any moved characters.
|
||||
|
||||
// true if s completely overlapped by buf
|
||||
inline
|
||||
bool
|
||||
is_overlapping(
|
||||
core::string_view buf,
|
||||
core::string_view s) noexcept
|
||||
{
|
||||
auto const b0 = buf.data();
|
||||
auto const e0 = b0 + buf.size();
|
||||
auto const b1 = s.data();
|
||||
auto const e1 = b1 + s.size();
|
||||
auto const less_equal =
|
||||
std::less_equal<char const*>();
|
||||
if(less_equal(e0, b1))
|
||||
return false;
|
||||
if(less_equal(e1, b0))
|
||||
return false;
|
||||
// partial overlap is undefined
|
||||
BOOST_ASSERT(less_equal(e1, e0));
|
||||
BOOST_ASSERT(less_equal(b0, b1));
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
move_chars_impl(
|
||||
std::ptrdiff_t,
|
||||
core::string_view const&) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
template<class... Sn>
|
||||
void
|
||||
move_chars_impl(
|
||||
std::ptrdiff_t d,
|
||||
core::string_view const& buf,
|
||||
core::string_view& s,
|
||||
Sn&... sn) noexcept
|
||||
{
|
||||
if(is_overlapping(buf, s))
|
||||
s = {s.data() + d, s.size()};
|
||||
move_chars_impl(d, buf, sn...);
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
void
|
||||
move_chars(
|
||||
char* dest,
|
||||
char const* src,
|
||||
std::size_t n,
|
||||
Args&... args) noexcept
|
||||
{
|
||||
core::string_view buf(src, n);
|
||||
move_chars_impl(
|
||||
dest - src,
|
||||
core::string_view(src, n),
|
||||
args...);
|
||||
std::memmove(
|
||||
dest, src, n);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
//
|
||||
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_NORMALIZED_HPP
|
||||
#define BOOST_URL_DETAIL_NORMALIZED_HPP
|
||||
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <boost/url/segments_encoded_view.hpp>
|
||||
#include <boost/url/detail/normalize.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
class fnv_1a
|
||||
{
|
||||
public:
|
||||
using digest_type = std::size_t;
|
||||
|
||||
#if BOOST_URL_ARCH == 64
|
||||
static constexpr std::size_t const prime =
|
||||
static_cast<std::size_t>(0x100000001B3ULL);
|
||||
static constexpr std::size_t init_hash =
|
||||
static_cast<std::size_t>(0xcbf29ce484222325ULL);
|
||||
#else
|
||||
static constexpr std::size_t const prime =
|
||||
static_cast<std::size_t>(0x01000193UL);
|
||||
static constexpr std::size_t init_hash =
|
||||
static_cast<std::size_t>(0x811C9DC5UL);
|
||||
#endif
|
||||
|
||||
explicit
|
||||
fnv_1a(std::size_t salt) noexcept
|
||||
: h_(init_hash + salt)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
put(char c) noexcept
|
||||
{
|
||||
h_ ^= c;
|
||||
h_ *= prime;
|
||||
}
|
||||
|
||||
void
|
||||
put(core::string_view s) noexcept
|
||||
{
|
||||
for (char c: s)
|
||||
{
|
||||
put(c);
|
||||
}
|
||||
}
|
||||
|
||||
digest_type
|
||||
digest() const noexcept
|
||||
{
|
||||
return h_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t h_;
|
||||
};
|
||||
|
||||
void
|
||||
pop_encoded_front(
|
||||
core::string_view& s,
|
||||
char& c,
|
||||
std::size_t& n) noexcept;
|
||||
|
||||
// compare two core::string_views as if they are both
|
||||
// percent-decoded
|
||||
int
|
||||
compare_encoded(
|
||||
core::string_view lhs,
|
||||
core::string_view rhs) noexcept;
|
||||
|
||||
// digest a core::string_view as if it were
|
||||
// percent-decoded
|
||||
void
|
||||
digest_encoded(
|
||||
core::string_view s,
|
||||
fnv_1a& hasher) noexcept;
|
||||
|
||||
void
|
||||
digest(
|
||||
core::string_view s,
|
||||
fnv_1a& hasher) noexcept;
|
||||
|
||||
// check if core::string_view lhs starts with core::string_view
|
||||
// rhs as if they are both percent-decoded. If
|
||||
// lhs starts with rhs, return number of chars
|
||||
// matched in the encoded core::string_view
|
||||
std::size_t
|
||||
path_starts_with(
|
||||
core::string_view lhs,
|
||||
core::string_view rhs) noexcept;
|
||||
|
||||
// check if core::string_view lhs ends with core::string_view
|
||||
// rhs as if they are both percent-decoded. If
|
||||
// lhs ends with rhs, return number of chars
|
||||
// matched in the encoded core::string_view
|
||||
std::size_t
|
||||
path_ends_with(
|
||||
core::string_view lhs,
|
||||
core::string_view rhs) noexcept;
|
||||
|
||||
// compare two core::string_views as if they are both
|
||||
// percent-decoded and lowercase
|
||||
int
|
||||
ci_compare_encoded(
|
||||
core::string_view lhs,
|
||||
core::string_view rhs) noexcept;
|
||||
|
||||
// digest a core::string_view as if it were decoded
|
||||
// and lowercase
|
||||
void
|
||||
ci_digest_encoded(
|
||||
core::string_view s,
|
||||
fnv_1a& hasher) noexcept;
|
||||
|
||||
// compare two ascii core::string_views
|
||||
int
|
||||
compare(
|
||||
core::string_view lhs,
|
||||
core::string_view rhs) noexcept;
|
||||
|
||||
// compare two core::string_views as if they are both
|
||||
// lowercase
|
||||
int
|
||||
ci_compare(
|
||||
core::string_view lhs,
|
||||
core::string_view rhs) noexcept;
|
||||
|
||||
// digest a core::string_view as if it were lowercase
|
||||
void
|
||||
ci_digest(
|
||||
core::string_view s,
|
||||
fnv_1a& hasher) noexcept;
|
||||
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
remove_dot_segments(
|
||||
char* dest,
|
||||
char const* end,
|
||||
core::string_view s) noexcept;
|
||||
|
||||
void
|
||||
pop_last_segment(
|
||||
core::string_view& s,
|
||||
core::string_view& c,
|
||||
std::size_t& level,
|
||||
bool r) noexcept;
|
||||
|
||||
char
|
||||
path_pop_back( core::string_view& s );
|
||||
|
||||
void
|
||||
normalized_path_digest(
|
||||
core::string_view s,
|
||||
bool remove_unmatched,
|
||||
fnv_1a& hasher) noexcept;
|
||||
|
||||
int
|
||||
segments_compare(
|
||||
segments_encoded_view seg0,
|
||||
segments_encoded_view seg1) noexcept;
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_OPTIONAL_STRING_HPP
|
||||
#define BOOST_URL_DETAIL_OPTIONAL_STRING_HPP
|
||||
|
||||
#include <boost/url/detail/string_view.hpp>
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
|
||||
#ifndef BOOST_URL_DOCS
|
||||
struct no_value_t;
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
struct optional_string
|
||||
{
|
||||
core::string_view s;
|
||||
bool b = false;
|
||||
};
|
||||
|
||||
template <class String>
|
||||
typename std::enable_if<
|
||||
std::is_convertible<String, core::string_view>::value,
|
||||
optional_string>::type
|
||||
get_optional_string(
|
||||
String const& s)
|
||||
{
|
||||
optional_string r;
|
||||
r.s = s;
|
||||
r.b = true;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class T, class = void>
|
||||
struct is_dereferenceable : std::false_type
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct is_dereferenceable<
|
||||
T,
|
||||
void_t<
|
||||
decltype(*std::declval<T>())
|
||||
>> : std::true_type
|
||||
{};
|
||||
|
||||
template <class OptionalString>
|
||||
typename std::enable_if<
|
||||
!std::is_convertible<OptionalString, core::string_view>::value,
|
||||
optional_string>::type
|
||||
get_optional_string(
|
||||
OptionalString const& opt)
|
||||
{
|
||||
// If this goes off, it means the rule
|
||||
// passed in did not meet the requirements.
|
||||
// Please check the documentation of functions
|
||||
// that call get_optional_string.
|
||||
static_assert(
|
||||
is_dereferenceable<OptionalString>::value &&
|
||||
std::is_constructible<bool, OptionalString>::value &&
|
||||
!std::is_convertible<OptionalString, core::string_view>::value &&
|
||||
std::is_convertible<typename std::decay<decltype(*std::declval<OptionalString>())>::type, core::string_view>::value,
|
||||
"OptionalString requirements not met");
|
||||
optional_string r;
|
||||
r.s = opt ? detail::to_sv(*opt) : core::string_view{};
|
||||
r.b = static_cast<bool>(opt);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline
|
||||
optional_string
|
||||
get_optional_string(
|
||||
std::nullptr_t)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
inline
|
||||
optional_string
|
||||
get_optional_string(
|
||||
no_value_t const&)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
|
||||
#define BOOST_URL_DETAIL_OVER_ALLOCATOR_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/type_traits/is_final.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#ifdef BOOST_NO_CXX11_ALLOCATOR
|
||||
# include <boost/core/allocator_traits.hpp>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// This is a workaround for allocator_traits
|
||||
// implementations which falsely claim C++11
|
||||
// compatibility.
|
||||
#ifdef BOOST_NO_CXX11_ALLOCATOR
|
||||
template<class Alloc>
|
||||
using allocator_traits =
|
||||
boost::allocator_traits<Alloc>;
|
||||
#else
|
||||
template<class Alloc>
|
||||
using allocator_traits = std::allocator_traits<Alloc>;
|
||||
#endif
|
||||
|
||||
template<class T, class Allocator>
|
||||
class over_allocator
|
||||
: private empty_value<Allocator>
|
||||
{
|
||||
template<class U, class OtherAlloc>
|
||||
friend class over_allocator;
|
||||
|
||||
std::size_t extra_;
|
||||
|
||||
public:
|
||||
using is_always_equal = std::false_type;
|
||||
using value_type = typename
|
||||
allocator_traits<typename allocator_traits<
|
||||
Allocator>::template rebind_alloc<T>>::value_type;
|
||||
using pointer = typename
|
||||
allocator_traits<typename allocator_traits<
|
||||
Allocator>::template rebind_alloc<T>>::pointer;
|
||||
using const_pointer = typename
|
||||
allocator_traits<typename allocator_traits<
|
||||
Allocator>::template rebind_alloc<T>>::const_pointer;
|
||||
using size_type = typename
|
||||
allocator_traits<typename allocator_traits<
|
||||
Allocator>::template rebind_alloc<T>>::size_type;
|
||||
using difference_type = typename
|
||||
allocator_traits<typename allocator_traits<
|
||||
Allocator>::template rebind_alloc<T>>::difference_type;
|
||||
|
||||
template<class U>
|
||||
struct rebind
|
||||
{
|
||||
using other = over_allocator<U, Allocator>;
|
||||
};
|
||||
|
||||
over_allocator(
|
||||
std::size_t extra,
|
||||
Allocator const& alloc)
|
||||
: empty_value<Allocator>(
|
||||
empty_init, alloc)
|
||||
, extra_(extra)
|
||||
{
|
||||
}
|
||||
|
||||
template<class U>
|
||||
over_allocator(over_allocator<U, Allocator> const& other) noexcept
|
||||
: empty_value<Allocator>(
|
||||
empty_init, other.get())
|
||||
, extra_(other.extra_)
|
||||
{
|
||||
}
|
||||
|
||||
pointer
|
||||
allocate(size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n == 1);
|
||||
using U = typename boost::type_with_alignment<
|
||||
alignof(value_type)>::type;
|
||||
auto constexpr S = sizeof(U);
|
||||
using A = typename allocator_traits<
|
||||
Allocator>::template rebind_alloc<U>;
|
||||
A a(this->get());
|
||||
return reinterpret_cast<pointer>(
|
||||
std::allocator_traits<A>::allocate(a,
|
||||
(n * sizeof(value_type) + extra_ + S - 1) / S));
|
||||
}
|
||||
|
||||
void
|
||||
deallocate(pointer p, size_type n)
|
||||
{
|
||||
BOOST_ASSERT(n == 1);
|
||||
using U = typename boost::type_with_alignment<
|
||||
alignof(value_type)>::type;
|
||||
auto constexpr S = sizeof(U);
|
||||
using A = typename allocator_traits<
|
||||
Allocator>::template rebind_alloc<U>;
|
||||
A a{this->get()};
|
||||
std::allocator_traits<A>::deallocate(a,
|
||||
reinterpret_cast<U*>(p),
|
||||
(n * sizeof(value_type) + extra_ + S - 1) / S);
|
||||
}
|
||||
|
||||
#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000
|
||||
template<class U, class... Args>
|
||||
void
|
||||
construct(U* ptr, Args&&... args)
|
||||
{
|
||||
::new((void*)ptr) U(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<class U>
|
||||
void
|
||||
destroy(U* ptr)
|
||||
{
|
||||
ptr->~U();
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class U>
|
||||
friend
|
||||
bool
|
||||
operator==(
|
||||
over_allocator const& lhs,
|
||||
over_allocator<U, Allocator> const& rhs)
|
||||
{
|
||||
return
|
||||
lhs.get() == rhs.get() &&
|
||||
lhs.extra_ == rhs.extra_;
|
||||
}
|
||||
|
||||
template<class U>
|
||||
friend
|
||||
bool
|
||||
operator!=(
|
||||
over_allocator const& lhs,
|
||||
over_allocator<U, Allocator> const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_PARAMS_ITER_IMPL_HPP
|
||||
#define BOOST_URL_DETAIL_PARAMS_ITER_IMPL_HPP
|
||||
|
||||
#include <boost/url/param.hpp>
|
||||
#include <boost/url/detail/parts_base.hpp>
|
||||
#include <boost/url/detail/url_impl.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
struct BOOST_URL_DECL params_iter_impl
|
||||
: parts_base
|
||||
{
|
||||
query_ref ref;
|
||||
std::size_t index = 0;
|
||||
std::size_t pos;
|
||||
std::size_t nk;
|
||||
std::size_t nv;
|
||||
std::size_t dk;
|
||||
std::size_t dv;
|
||||
|
||||
params_iter_impl() = default;
|
||||
params_iter_impl(
|
||||
params_iter_impl const&) = default;
|
||||
params_iter_impl& operator=(
|
||||
params_iter_impl const&) = default;
|
||||
|
||||
// begin
|
||||
params_iter_impl(
|
||||
query_ref const&) noexcept;
|
||||
|
||||
// end
|
||||
params_iter_impl(
|
||||
query_ref const&,
|
||||
int) noexcept;
|
||||
|
||||
// at index
|
||||
params_iter_impl(
|
||||
query_ref const&,
|
||||
std::size_t,
|
||||
std::size_t) noexcept;
|
||||
void setup() noexcept;
|
||||
void increment() noexcept;
|
||||
void decrement() noexcept;
|
||||
param_pct_view
|
||||
dereference() const noexcept;
|
||||
pct_string_view key() const noexcept;
|
||||
|
||||
auto
|
||||
next() const noexcept ->
|
||||
params_iter_impl
|
||||
{
|
||||
auto next = *this;
|
||||
next.increment();
|
||||
return next;
|
||||
}
|
||||
|
||||
bool
|
||||
equal(
|
||||
params_iter_impl const&
|
||||
other) const noexcept
|
||||
{
|
||||
// different containers
|
||||
BOOST_ASSERT(ref.alias_of(other.ref));
|
||||
return index == other.index;
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_PARTS_BASE_HPP
|
||||
#define BOOST_URL_DETAIL_PARTS_BASE_HPP
|
||||
|
||||
#include <boost/url/error.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// mix-in to provide part
|
||||
// constants and variables
|
||||
struct parts_base
|
||||
{
|
||||
enum
|
||||
{
|
||||
id_scheme = -1, // trailing ':'
|
||||
id_user, // leading "//"
|
||||
id_pass, // leading ':', trailing '@'
|
||||
id_host,
|
||||
id_port, // leading ':'
|
||||
id_path,
|
||||
id_query, // leading '?'
|
||||
id_frag, // leading '#'
|
||||
id_end // one past the end
|
||||
};
|
||||
|
||||
enum class from : char {
|
||||
// this belongs to a string
|
||||
string = 0,
|
||||
// this belongs to url_base
|
||||
// segments/params containers point to
|
||||
// another url
|
||||
url = 1,
|
||||
// this belongs to authority_view
|
||||
// id_user does not have the leading "//"
|
||||
authority = 2,
|
||||
};
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_PATH_HPP
|
||||
#define BOOST_URL_DETAIL_PATH_HPP
|
||||
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// Return the number of characters at
|
||||
// the front of the path that are reserved
|
||||
inline
|
||||
std::size_t
|
||||
path_prefix(
|
||||
char const* p,
|
||||
std::size_t n) noexcept
|
||||
{
|
||||
switch(n)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
if(p[0] == '/')
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
case 2:
|
||||
if(p[0] == '/')
|
||||
return 1;
|
||||
if( p[0] == '.' &&
|
||||
p[1] == '/')
|
||||
return 2;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
if(p[0] == '/')
|
||||
{
|
||||
if( p[1] == '.' &&
|
||||
p[2] == '/')
|
||||
return 3;
|
||||
return 1;
|
||||
}
|
||||
if( p[0] == '.' &&
|
||||
p[1] == '/')
|
||||
return 2;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// VFALCO DEPRECATED
|
||||
inline
|
||||
std::size_t
|
||||
path_prefix(
|
||||
core::string_view s) noexcept
|
||||
{
|
||||
return path_prefix(
|
||||
s.data(), s.size());
|
||||
}
|
||||
|
||||
// returns the number of adjusted
|
||||
// segments based on the malleable prefix.
|
||||
inline
|
||||
std::size_t
|
||||
path_segments(
|
||||
core::string_view s,
|
||||
std::size_t nseg) noexcept
|
||||
{
|
||||
switch(s.size())
|
||||
{
|
||||
case 0:
|
||||
BOOST_ASSERT(nseg == 0);
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
BOOST_ASSERT(nseg == 1);
|
||||
if(s[0] == '/')
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 2:
|
||||
if(s[0] == '/')
|
||||
return nseg;
|
||||
if( s[0] == '.' &&
|
||||
s[1] == '/')
|
||||
{
|
||||
BOOST_ASSERT(nseg > 1);
|
||||
return nseg - 1;
|
||||
}
|
||||
return nseg;
|
||||
|
||||
default:
|
||||
if(s[0] == '/')
|
||||
{
|
||||
if( s[1] == '.' &&
|
||||
s[2] == '/')
|
||||
{
|
||||
BOOST_ASSERT(nseg > 1);
|
||||
return nseg - 1;
|
||||
}
|
||||
return nseg;
|
||||
}
|
||||
if( s[0] == '.' &&
|
||||
s[1] == '/')
|
||||
{
|
||||
BOOST_ASSERT(nseg > 1);
|
||||
return nseg - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return nseg;
|
||||
}
|
||||
|
||||
// Trim reserved characters from
|
||||
// the front of the path.
|
||||
inline
|
||||
core::string_view
|
||||
clean_path(
|
||||
core::string_view s) noexcept
|
||||
{
|
||||
s.remove_prefix(
|
||||
path_prefix(s));
|
||||
return s;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_PATTERN_HPP
|
||||
#define BOOST_URL_DETAIL_PATTERN_HPP
|
||||
|
||||
#include <boost/url/error_types.hpp>
|
||||
#include <boost/url/url_base.hpp>
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
|
||||
// This file includes functions and classes
|
||||
// to parse uri templates or format strings
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
class format_args;
|
||||
|
||||
struct pattern
|
||||
{
|
||||
core::string_view scheme;
|
||||
core::string_view user;
|
||||
core::string_view pass;
|
||||
core::string_view host;
|
||||
core::string_view port;
|
||||
core::string_view path;
|
||||
core::string_view query;
|
||||
core::string_view frag;
|
||||
|
||||
bool has_authority = false;
|
||||
bool has_user = false;
|
||||
bool has_pass = false;
|
||||
bool has_port = false;
|
||||
bool has_query = false;
|
||||
bool has_frag = false;
|
||||
|
||||
BOOST_URL_DECL
|
||||
void
|
||||
apply(
|
||||
url_base& u,
|
||||
format_args const& args) const;
|
||||
};
|
||||
|
||||
BOOST_URL_DECL
|
||||
system::result<pattern>
|
||||
parse_pattern(
|
||||
core::string_view s);
|
||||
|
||||
} // detail
|
||||
} // url
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_PCT_FORMAT_HPP
|
||||
#define BOOST_URL_DETAIL_PCT_FORMAT_HPP
|
||||
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <boost/url/url.hpp>
|
||||
#include <boost/url/grammar/lut_chars.hpp>
|
||||
#include <boost/url/detail/format_args.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// measure a single string
|
||||
BOOST_URL_DECL
|
||||
std::size_t
|
||||
pct_vmeasure(
|
||||
grammar::lut_chars const& cs,
|
||||
format_parse_context& pctx,
|
||||
measure_context& mctx);
|
||||
|
||||
// format a single string
|
||||
BOOST_URL_DECL
|
||||
char*
|
||||
pct_vformat(
|
||||
grammar::lut_chars const& cs,
|
||||
format_parse_context& pctx,
|
||||
format_context& fctx);
|
||||
|
||||
} // detail
|
||||
} // url
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_PRINT_HPP
|
||||
#define BOOST_URL_DETAIL_PRINT_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// std::uint64_t
|
||||
// 18446744073709551615
|
||||
// 1 2
|
||||
template<class T>
|
||||
struct printed
|
||||
: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
// 16-bit unsigned
|
||||
template<>
|
||||
class printed<std::uint16_t>
|
||||
: std::false_type
|
||||
{
|
||||
char n_;
|
||||
char buf_[5];
|
||||
|
||||
public:
|
||||
printed(std::uint16_t n)
|
||||
{
|
||||
char* it =
|
||||
buf_ + sizeof(buf_);
|
||||
if(n == 0)
|
||||
{
|
||||
*--it = '0';
|
||||
n_ = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(n > 0)
|
||||
{
|
||||
*--it = '0' + (n % 10);
|
||||
n /= 10;
|
||||
}
|
||||
n_ = static_cast<char>(
|
||||
sizeof(buf_) - (
|
||||
it - buf_));
|
||||
}
|
||||
}
|
||||
|
||||
core::string_view
|
||||
string() const noexcept
|
||||
{
|
||||
return core::string_view(buf_ +
|
||||
sizeof(buf_) - n_, n_);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
printed<T>
|
||||
make_printed(T t)
|
||||
{
|
||||
return printed<T>(t);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_REPLACEMENT_FIELD_RULE_HPP
|
||||
#define BOOST_URL_DETAIL_REPLACEMENT_FIELD_RULE_HPP
|
||||
|
||||
#include <boost/url/error.hpp>
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <boost/url/grammar/variant_rule.hpp>
|
||||
#include <boost/url/grammar/unsigned_rule.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// replacement_field ::= "{" [arg_id] [":" format_spec "}"
|
||||
struct replacement_field_rule_t
|
||||
{
|
||||
using value_type = core::string_view;
|
||||
|
||||
BOOST_URL_DECL
|
||||
system::result<value_type>
|
||||
parse(
|
||||
char const*& it,
|
||||
char const* end) const noexcept;
|
||||
};
|
||||
|
||||
constexpr replacement_field_rule_t replacement_field_rule{};
|
||||
|
||||
// identifier ::= id_start id_continue*
|
||||
// id_start ::= "a"..."z" | "A"..."Z" | "_"
|
||||
// id_continue ::= id_start | digit
|
||||
struct identifier_rule_t
|
||||
{
|
||||
using value_type = core::string_view;
|
||||
|
||||
BOOST_URL_DECL
|
||||
system::result<value_type>
|
||||
parse(
|
||||
char const*& it,
|
||||
char const* end) const noexcept;
|
||||
};
|
||||
|
||||
constexpr identifier_rule_t identifier_rule{};
|
||||
|
||||
// arg_id ::= integer | identifier
|
||||
// integer ::= digit+
|
||||
// digit ::= "0"..."9"
|
||||
static constexpr auto arg_id_rule =
|
||||
grammar::variant_rule(
|
||||
identifier_rule,
|
||||
grammar::unsigned_rule<std::size_t>{});
|
||||
|
||||
struct format_spec_rule_t
|
||||
{
|
||||
using value_type = core::string_view;
|
||||
|
||||
system::result<value_type>
|
||||
parse(
|
||||
char const*& it,
|
||||
char const* end) const noexcept;
|
||||
};
|
||||
|
||||
constexpr format_spec_rule_t format_spec_rule{};
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_SEGMENTS_ITER_IMPL_HPP
|
||||
#define BOOST_URL_DETAIL_SEGMENTS_ITER_IMPL_HPP
|
||||
|
||||
#include <boost/url/detail/parts_base.hpp>
|
||||
#include <boost/url/detail/url_impl.hpp>
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
struct segments_iter_impl
|
||||
: private parts_base
|
||||
{
|
||||
path_ref ref;
|
||||
std::size_t pos = 0;
|
||||
std::size_t next = 0;
|
||||
std::size_t index = 0;
|
||||
std::size_t dn = 0;
|
||||
private:
|
||||
pct_string_view s_;
|
||||
public:
|
||||
|
||||
segments_iter_impl() = default;
|
||||
segments_iter_impl(
|
||||
segments_iter_impl const&) noexcept = default;
|
||||
segments_iter_impl& operator=(
|
||||
segments_iter_impl const&) noexcept = default;
|
||||
|
||||
// begin
|
||||
segments_iter_impl(
|
||||
detail::path_ref const&) noexcept;
|
||||
|
||||
// end
|
||||
segments_iter_impl(
|
||||
detail::path_ref const&,
|
||||
int) noexcept;
|
||||
|
||||
// at index
|
||||
segments_iter_impl(
|
||||
url_impl const& u_,
|
||||
std::size_t pos_,
|
||||
std::size_t i_) noexcept;
|
||||
|
||||
void update() noexcept;
|
||||
|
||||
BOOST_URL_DECL
|
||||
void
|
||||
increment() noexcept;
|
||||
|
||||
BOOST_URL_DECL
|
||||
void
|
||||
decrement() noexcept;
|
||||
|
||||
pct_string_view
|
||||
dereference() const noexcept
|
||||
{
|
||||
return s_;
|
||||
}
|
||||
|
||||
bool
|
||||
equal(
|
||||
segments_iter_impl const& other) const noexcept
|
||||
{
|
||||
BOOST_ASSERT(ref.alias_of(other.ref));
|
||||
return index == other.index;
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_STRING_VIEW_HPP
|
||||
#define BOOST_URL_DETAIL_STRING_VIEW_HPP
|
||||
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
// We use detail::to_sv(s) instead of core::string_view(s) whenever
|
||||
// we should convert to core::string_view.
|
||||
// This is a workaround for GCC >=8.0 <8.4
|
||||
// See: https://github.com/boostorg/url/issues/672
|
||||
template<class T>
|
||||
core::string_view
|
||||
to_sv(T const& t) noexcept
|
||||
{
|
||||
return core::string_view(t);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
//
|
||||
// Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_URL_IMPL_HPP
|
||||
#define BOOST_URL_DETAIL_URL_IMPL_HPP
|
||||
|
||||
#include <boost/url/host_type.hpp>
|
||||
#include <boost/url/pct_string_view.hpp>
|
||||
#include <boost/url/scheme.hpp>
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <boost/url/detail/parts_base.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
|
||||
class url_view;
|
||||
class authority_view;
|
||||
|
||||
namespace detail {
|
||||
|
||||
constexpr char const* const empty_c_str_ = "";
|
||||
|
||||
// This is the private 'guts' of a
|
||||
// url_view, exposed so different parts
|
||||
// of the implementation can work on it.
|
||||
struct BOOST_URL_DECL url_impl : parts_base
|
||||
{
|
||||
static
|
||||
constexpr
|
||||
std::size_t const zero_ = 0;
|
||||
|
||||
// never nullptr
|
||||
char const* cs_ = empty_c_str_;
|
||||
|
||||
std::size_t offset_[id_end + 1] = {};
|
||||
std::size_t decoded_[id_end] = {};
|
||||
std::size_t nseg_ = 0;
|
||||
std::size_t nparam_ = 0;
|
||||
unsigned char ip_addr_[16] = {};
|
||||
// VFALCO don't we need a bool?
|
||||
std::uint16_t port_number_ = 0;
|
||||
host_type host_type_ =
|
||||
urls::host_type::none;
|
||||
scheme scheme_ =
|
||||
urls::scheme::none;
|
||||
|
||||
from from_ = from::string;
|
||||
|
||||
url_impl(
|
||||
from b) noexcept
|
||||
: from_(b)
|
||||
{
|
||||
}
|
||||
|
||||
// in url_view.ipp
|
||||
url_view construct() const noexcept;
|
||||
|
||||
// in authority_view.ipp
|
||||
authority_view
|
||||
construct_authority() const noexcept;
|
||||
|
||||
std::size_t len(int, int) const noexcept;
|
||||
std::size_t len(int) const noexcept;
|
||||
std::size_t offset(int) const noexcept;
|
||||
core::string_view get(int) const noexcept;
|
||||
core::string_view get(int, int) const noexcept;
|
||||
pct_string_view pct_get(int) const noexcept;
|
||||
pct_string_view pct_get(int, int) const noexcept;
|
||||
void set_size(int, std::size_t) noexcept;
|
||||
void split(int, std::size_t) noexcept;
|
||||
void adjust(int, int, std::size_t) noexcept;
|
||||
void collapse(int, int, std::size_t) noexcept;
|
||||
|
||||
void apply_scheme(core::string_view) noexcept;
|
||||
void apply_userinfo(pct_string_view const&,
|
||||
pct_string_view const*) noexcept;
|
||||
void apply_host(host_type, pct_string_view,
|
||||
unsigned char const*) noexcept;
|
||||
void apply_port(core::string_view, unsigned short) noexcept;
|
||||
void apply_authority(authority_view const&) noexcept;
|
||||
void apply_path(pct_string_view, std::size_t) noexcept;
|
||||
void apply_query(pct_string_view, std::size_t) noexcept;
|
||||
void apply_frag(pct_string_view) noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// this allows a path to come from a
|
||||
// url_impl or a separate core::string_view
|
||||
class path_ref
|
||||
: private parts_base
|
||||
{
|
||||
url_impl const* impl_ = nullptr;
|
||||
char const* data_ = nullptr;
|
||||
std::size_t size_ = 0;
|
||||
std::size_t nseg_ = 0;
|
||||
std::size_t dn_ = 0;
|
||||
|
||||
public:
|
||||
path_ref() = default;
|
||||
path_ref(url_impl const& impl) noexcept;
|
||||
path_ref(core::string_view,
|
||||
std::size_t, std::size_t) noexcept;
|
||||
pct_string_view buffer() const noexcept;
|
||||
std::size_t size() const noexcept;
|
||||
char const* data() const noexcept;
|
||||
char const* end() const noexcept;
|
||||
std::size_t nseg() const noexcept;
|
||||
|
||||
bool
|
||||
alias_of(
|
||||
url_impl const& impl) const noexcept
|
||||
{
|
||||
return impl_ == &impl;
|
||||
}
|
||||
|
||||
bool
|
||||
alias_of(
|
||||
path_ref const& ref) const noexcept
|
||||
{
|
||||
if(impl_)
|
||||
return impl_ == ref.impl_;
|
||||
BOOST_ASSERT(data_ != ref.data_ || (
|
||||
size_ == ref.size_ &&
|
||||
nseg_ == ref.nseg_ &&
|
||||
dn_ == ref.dn_));
|
||||
return data_ == ref.data_;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// this allows a params to come from a
|
||||
// url_impl or a separate core::string_view
|
||||
class BOOST_URL_DECL query_ref
|
||||
: private parts_base
|
||||
{
|
||||
url_impl const* impl_ = nullptr;
|
||||
char const* data_ = nullptr;
|
||||
std::size_t size_ = 0;
|
||||
std::size_t nparam_ = 0;
|
||||
std::size_t dn_ = 0;
|
||||
bool question_mark_ = false;
|
||||
|
||||
public:
|
||||
query_ref(
|
||||
core::string_view s, // buffer, no '?'
|
||||
std::size_t dn, // decoded size
|
||||
std::size_t nparam
|
||||
) noexcept;
|
||||
query_ref() = default;
|
||||
query_ref(url_impl const& impl) noexcept;
|
||||
pct_string_view buffer() const noexcept;
|
||||
std::size_t size() const noexcept; // with '?'
|
||||
char const* begin() const noexcept; // no '?'
|
||||
char const* end() const noexcept;
|
||||
std::size_t nparam() const noexcept;
|
||||
|
||||
bool
|
||||
alias_of(
|
||||
url_impl const& impl) const noexcept
|
||||
{
|
||||
return impl_ == &impl;
|
||||
}
|
||||
|
||||
bool
|
||||
alias_of(
|
||||
query_ref const& ref) const noexcept
|
||||
{
|
||||
if(impl_)
|
||||
return impl_ == ref.impl_;
|
||||
BOOST_ASSERT(data_ != ref.data_ || (
|
||||
size_ == ref.size_ &&
|
||||
nparam_ == ref.nparam_ &&
|
||||
dn_ == ref.dn_));
|
||||
return data_ == ref.data_;
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
} // urls
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/url
|
||||
//
|
||||
|
||||
#ifndef BOOST_URL_DETAIL_FORMAT_HPP
|
||||
#define BOOST_URL_DETAIL_FORMAT_HPP
|
||||
|
||||
#include <boost/url/detail/format_args.hpp>
|
||||
#include <boost/url/detail/pattern.hpp>
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <boost/url/url.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace urls {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
void
|
||||
vformat_to(
|
||||
url_base& u,
|
||||
core::string_view fmt,
|
||||
detail::format_args args)
|
||||
{
|
||||
parse_pattern(fmt)
|
||||
.value().apply(u, args);
|
||||
}
|
||||
|
||||
inline
|
||||
url
|
||||
vformat(
|
||||
core::string_view fmt,
|
||||
detail::format_args args)
|
||||
{
|
||||
url u;
|
||||
vformat_to(u, fmt, args);
|
||||
return u;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // url
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user