Added some basic HTTP and ip address parsing.

This commit is contained in:
2024-08-18 23:06:09 +02:00
parent 03c899f17e
commit 35e7131780
9 changed files with 497 additions and 35 deletions

View File

@@ -4,8 +4,11 @@
#if !defined(MIJIN_UTIL_STRING_HPP_INCLUDED)
#define MIJIN_UTIL_STRING_HPP_INCLUDED 1
#include <array>
#include <charconv>
#include <iterator>
#include <limits>
#include <locale>
#include <sstream>
#include <string>
#include <string_view>
@@ -24,6 +27,13 @@ namespace mijin
// public constants
//
//
// public traits
//
template<typename TString>
using char_type_t = decltype(std::string_view(std::declval<TString>()))::value_type;
//
// public types
//
@@ -151,8 +161,35 @@ bool equalsIgnoreCaseImpl(std::basic_string_view<TChar, TTraitsA> stringA, std::
return true;
}
template<typename TChar, typename TTraits>
std::basic_string_view<TChar, TTraits> trimPrefixImpl(std::basic_string_view<TChar, TTraits> stringView,
std::basic_string_view<TChar, TTraits> charsToTrim)
{
stringView.remove_prefix(std::min(stringView.find_first_not_of(charsToTrim), stringView.size()));
return stringView;
}
template<typename TChar, typename TTraits>
std::basic_string_view<TChar, TTraits> trimSuffixImpl(std::basic_string_view<TChar, TTraits> stringView,
std::basic_string_view<TChar, TTraits> charsToTrim)
{
stringView.remove_suffix(stringView.size() - std::min(stringView.find_last_not_of(charsToTrim) + 1, stringView.size()));
return stringView;
}
template<typename TChar, typename TTraits>
std::basic_string_view<TChar, TTraits> trimImpl(std::basic_string_view<TChar, TTraits> stringView,
std::basic_string_view<TChar, TTraits> charsToTrim)
{
return trimPrefixImpl(trimSuffixImpl(stringView, charsToTrim), charsToTrim);
}
template<typename TChar>
static const TChar SPACE = TChar(' ');
static const std::array DEFAULT_TRIM_CHARS_DATA = {TChar(' '), TChar('\t'), TChar('\r'), TChar('\n')};
template<typename TChar>
static const std::basic_string_view<TChar, std::char_traits<TChar>> DEFAULT_TRIM_CHARS
= {DEFAULT_TRIM_CHARS_DATA<TChar>.begin(), DEFAULT_TRIM_CHARS_DATA<TChar>.end()};
}
template<typename TLeft, typename TRight>
@@ -162,27 +199,46 @@ template<typename TLeft, typename TRight>
std::basic_string_view(std::forward<TRight>(separator)), options);
}
template<typename TChar, typename TTraits>
std::basic_string_view<TChar, TTraits> trimPrefix(std::basic_string_view<TChar, TTraits> stringView,
std::basic_string_view<TChar, TTraits> charsToTrim = {&detail::SPACE<TChar>, &detail::SPACE<TChar> + 1})
template<typename TString, typename TChars>
[[nodiscard]]
auto trimPrefix(TString&& string, TChars&& chars)
{
stringView.remove_prefix(std::min(stringView.find_first_not_of(charsToTrim), stringView.size()));
return stringView;
return detail::trimPrefixImpl(std::string_view(std::forward<TString>(string)), std::string_view(std::forward<TChars>(chars)));
}
template<typename TChar, typename TTraits>
std::basic_string_view<TChar, TTraits> trimSuffix(std::basic_string_view<TChar, TTraits> stringView,
std::basic_string_view<TChar, TTraits> charsToTrim = {&detail::SPACE<TChar>, &detail::SPACE<TChar> + 1})
template<typename TString>
[[nodiscard]]
auto trimPrefix(TString&& string)
{
stringView.remove_suffix(stringView.size() - std::min(stringView.find_last_not_of(charsToTrim) + 1, stringView.size()));
return stringView;
return trimPrefix(string, detail::DEFAULT_TRIM_CHARS<char_type_t<TString>>);
}
template<typename TChar, typename TTraits>
std::basic_string_view<TChar, TTraits> trim(std::basic_string_view<TChar, TTraits> stringView,
std::basic_string_view<TChar, TTraits> charsToTrim = {&detail::SPACE<TChar>, &detail::SPACE<TChar> + 1})
template<typename TString, typename TChars>
[[nodiscard]]
auto trimSuffix(TString&& string, TChars&& chars)
{
return trimPrefix(trimSuffix(stringView, charsToTrim), charsToTrim);
return detail::trimSuffixImpl(std::string_view(std::forward<TString>(string)), std::string_view(std::forward<TChars>(chars)));
}
template<typename TString>
[[nodiscard]]
auto trimSuffix(TString&& string)
{
return trimSuffix(string, detail::DEFAULT_TRIM_CHARS<char_type_t<TString>>);
}
template<typename TString, typename TChars>
[[nodiscard]]
auto trim(TString&& string, TChars&& chars)
{
return detail::trimImpl(std::string_view(std::forward<TString>(string)), std::string_view(std::forward<TChars>(chars)));
}
template<typename TString>
[[nodiscard]]
auto trim(TString&& string)
{
return trim(string, detail::DEFAULT_TRIM_CHARS<char_type_t<TString>>);
}
template<typename TLeft, typename TRight>
@@ -191,6 +247,51 @@ template<typename TLeft, typename TRight>
return detail::equalsIgnoreCaseImpl(std::string_view(left), std::string_view(right));
}
template<typename TChar, typename TTraits, typename TAllocator>
void makeLower(std::basic_string<TChar, TTraits, TAllocator>& string)
{
std::transform(string.begin(), string.end(), string.begin(), [locale = std::locale()](TChar chr)
{
return std::tolower<TChar>(chr, locale);
});
}
template<typename TChar, typename TTraits, typename TAllocator>
void makeUpper(std::basic_string<TChar, TTraits, TAllocator>& string)
{
std::transform(string.begin(), string.end(), string.begin(), [locale = std::locale()](TChar chr)
{
return std::toupper<TChar>(chr, locale);
});
}
template<typename... TArgs>
[[nodiscard]]
auto toLower(TArgs&&... args)
{
std::basic_string string(std::forward<TArgs>(args)...);
makeLower(string);
return string;
}
template<typename... TArgs>
[[nodiscard]]
auto toUpper(TArgs&&... args)
{
std::basic_string string(std::forward<TArgs>(args)...);
makeUpper(string);
return string;
}
template<typename TNumber>
[[nodiscard]]
bool toNumber(std::string_view stringView, TNumber& outNumber, int base = 10) noexcept
{
const std::from_chars_result res = std::from_chars(&*stringView.begin(), &*stringView.end(), outNumber, base);
return res.ec == std::errc{} && res.ptr == &*stringView.end();
}
namespace pipe
{
struct Join