diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-07-29 13:49:35 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-07-29 13:49:35 +0100 |
commit | 7e9a7a6fd6214e42cd31a74c699843a7fad4ed33 (patch) | |
tree | a1846263c81b63bbe7ad289f00e6fd1392a0c3be | |
parent | Use std::to_string in setCooke if possible (diff) | |
download | icespider-7e9a7a6fd6214e42cd31a74c699843a7fad4ed33.tar.bz2 icespider-7e9a7a6fd6214e42cd31a74c699843a7fad4ed33.tar.xz icespider-7e9a7a6fd6214e42cd31a74c699843a7fad4ed33.zip |
Centralise lots of value conversion functions
-rw-r--r-- | icespider/core/Jamfile.jam | 3 | ||||
-rw-r--r-- | icespider/core/ihttpRequest.h | 37 | ||||
-rw-r--r-- | icespider/core/util.cpp | 7 | ||||
-rw-r--r-- | icespider/core/util.h | 63 | ||||
-rw-r--r-- | icespider/core/xwwwFormUrlEncoded.cpp | 6 |
5 files changed, 80 insertions, 36 deletions
diff --git a/icespider/core/Jamfile.jam b/icespider/core/Jamfile.jam index 0654c78..26a30f6 100644 --- a/icespider/core/Jamfile.jam +++ b/icespider/core/Jamfile.jam @@ -2,7 +2,7 @@ lib adhocutil : : : : <include>/usr/include/adhocutil ; lib slicer : : : : <include>/usr/include/slicer ; lib stdc++fs ; -obj util-test : util-test.cpp ; +obj util-test : util-test.cpp : <use>adhocutil ; obj routeOptions : routeOptions.ice : <toolset>tidy:<checker>none ; lib icespider-core : @@ -17,6 +17,7 @@ lib icespider-core : <implicit-dependency>routeOptions : : <include>. + <use>adhocutil <library>../common//icespider-common <implicit-dependency>../common//icespider-common <implicit-dependency>routeOptions diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h index 99de25a..6876c2b 100644 --- a/icespider/core/ihttpRequest.h +++ b/icespider/core/ihttpRequest.h @@ -1,6 +1,7 @@ #pragma once #include "exceptions.h" +#include "util.h" #include <Ice/Current.h> #include <boost/lexical_cast.hpp> #include <c++11Helpers.h> @@ -60,36 +61,12 @@ namespace IceSpider { virtual std::ostream & dump(std::ostream & s) const = 0; - static_assert(std::is_constructible_v<std::string, std::string_view>); - static_assert(std::is_convertible_v<std::string_view, std::string_view>); - template<typename T, typename K> [[nodiscard]] inline std::optional<T> getFrom(const K key, OptionalString (IHttpRequest::*src)(const K) const) const { if (auto v = (this->*src)(key)) { - if constexpr (std::is_convertible<std::string_view, T>::value) { - return *v; - } - else if constexpr (std::is_constructible<T, std::string_view>::value) { - return std::optional<T> {std::in_place, *v}; - } - else if constexpr (requires(T out) { std::from_chars(v->begin(), v->end(), out); }) { - if (T out {}; std::from_chars(v->begin(), v->end(), out).ec == std::errc {}) { - return out; - } - else { - throw Http400_BadRequest(); - } - } - else { - try { - return boost::lexical_cast<T>(*v); - } - catch (const boost::bad_lexical_cast & e) { - throw Http400_BadRequest(); - } - } + return convert<T>(*v); } else { return std::nullopt; @@ -117,13 +94,11 @@ namespace IceSpider { if (!map) { return {}; } - auto i = map->find(key); - if (i == map->end()) { - return {}; - } - else { - return boost::lexical_cast<T>(i->second); + + if (const auto i = map->find(key); i != map->end()) { + return convert<T>(i->second); } + return {}; } void responseRedirect(const std::string_view url, const OptionalString & = {}) const; diff --git a/icespider/core/util.cpp b/icespider/core/util.cpp index 62de195..b330f79 100644 --- a/icespider/core/util.cpp +++ b/icespider/core/util.cpp @@ -1,7 +1,14 @@ #include "util.h" +#include "exceptions.h" namespace IceSpider { void + conversion_failure() + { + throw Http400_BadRequest(); + } + + void remove_trailing(std::string_view & in, const char c) { if (const auto n = in.find_last_not_of(c); n != std::string_view::npos) { diff --git a/icespider/core/util.h b/icespider/core/util.h index f4d559b..d31c7da 100644 --- a/icespider/core/util.h +++ b/icespider/core/util.h @@ -2,8 +2,11 @@ #include <Ice/Optional.h> #include <array> +#include <boost/lexical_cast.hpp> +#include <charconv> #include <optional> #include <string_view> +#include <visibility.h> namespace std::experimental::Ice { template<typename T, typename TF> @@ -116,6 +119,66 @@ private: }; namespace IceSpider { + [[noreturn]] DLL_PUBLIC void conversion_failure(); + + static_assert(std::is_constructible_v<std::string, std::string_view>); + static_assert(std::is_convertible_v<std::string_view, std::string_view>); + + template<typename T> + inline T + from_chars(const std::string_view v, T && out) + { + if (std::from_chars(v.begin(), v.end(), out).ec != std::errc {}) { + conversion_failure(); + } + return out; + } + + template<typename T> + inline T + lexical_cast(const std::string_view v) + { + try { + return boost::lexical_cast<T>(v); + } + catch (const boost::bad_lexical_cast & e) { + conversion_failure(); + } + } + + template<typename T> + inline void + convert(const std::string_view v, T & out) + { + if constexpr (std::is_assignable_v<std::string_view, T>) { + out = v; + } + if constexpr (requires { std::from_chars(v.begin(), v.end(), out); }) { + from_chars(v, out); + } + else { + out = lexical_cast<T>(v); + } + } + + template<typename T> + inline T + convert(const std::string_view v) + { + if constexpr (std::is_convertible_v<std::string_view, T>) { + return v; + } + else if constexpr (std::is_constructible_v<T, std::string_view>) { + return T {v}; + } + else if constexpr (requires(T out) { std::from_chars(v.begin(), v.end(), out); }) { + return from_chars<T>(v, {}); + } + else { + return lexical_cast<T>(v); + } + } + void remove_trailing(std::string_view & in, const char c); void remove_leading(std::string_view & in, const char c); } diff --git a/icespider/core/xwwwFormUrlEncoded.cpp b/icespider/core/xwwwFormUrlEncoded.cpp index 73f77b8..639b07a 100644 --- a/icespider/core/xwwwFormUrlEncoded.cpp +++ b/icespider/core/xwwwFormUrlEncoded.cpp @@ -1,11 +1,11 @@ #include "xwwwFormUrlEncoded.h" #include "exceptions.h" +#include "util.h" #include <Ice/Config.h> #include <algorithm> #include <array> #include <boost/algorithm/string/compare.hpp> #include <boost/algorithm/string/finder.hpp> -#include <charconv> #include <cstddef> #include <cstdint> #include <factory.h> @@ -181,9 +181,7 @@ namespace IceSpider { /* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \ void set(T & t) const override \ { \ - if (const auto v = s.value(); std::from_chars(v.begin(), v.end(), t).ec != std::errc {}) { \ - throw Http400_BadRequest(); \ - } \ + convert<T>(s, t); \ } SET(Ice::Byte); |