summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-07-29 12:34:05 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2023-07-29 12:44:41 +0100
commit7b439ff591777e8ea58045ce3fe082098d802b49 (patch)
treeb90859cb54a016acf507e9915892a0fc6d779109
parentRemove unused boost::lexical_cast wrappers (diff)
downloadicespider-7b439ff591777e8ea58045ce3fe082098d802b49.tar.bz2
icespider-7b439ff591777e8ea58045ce3fe082098d802b49.tar.xz
icespider-7b439ff591777e8ea58045ce3fe082098d802b49.zip
Use faster std::from_chars over boost::lexical_cast if possible
-rw-r--r--icespider/core/ihttpRequest.h12
-rw-r--r--icespider/core/xwwwFormUrlEncoded.cpp6
-rw-r--r--icespider/unittests/testFcgi.cpp2
-rw-r--r--icespider/unittests/testPerf.cpp9
4 files changed, 26 insertions, 3 deletions
diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h
index d1633b3..6cce145 100644
--- a/icespider/core/ihttpRequest.h
+++ b/icespider/core/ihttpRequest.h
@@ -4,6 +4,7 @@
#include <Ice/Current.h>
#include <boost/lexical_cast.hpp>
#include <c++11Helpers.h>
+#include <charconv>
#include <ctime>
#include <http.h>
#include <iosfwd>
@@ -60,6 +61,7 @@ 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>
@@ -70,7 +72,15 @@ namespace IceSpider {
return *v;
}
else if constexpr (std::is_constructible<T, std::string_view>::value) {
- return T(*v);
+ 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 {
diff --git a/icespider/core/xwwwFormUrlEncoded.cpp b/icespider/core/xwwwFormUrlEncoded.cpp
index 7bbf144..73f77b8 100644
--- a/icespider/core/xwwwFormUrlEncoded.cpp
+++ b/icespider/core/xwwwFormUrlEncoded.cpp
@@ -5,7 +5,7 @@
#include <array>
#include <boost/algorithm/string/compare.hpp>
#include <boost/algorithm/string/finder.hpp>
-#include <boost/lexical_cast.hpp>
+#include <charconv>
#include <cstddef>
#include <cstdint>
#include <factory.h>
@@ -181,7 +181,9 @@ namespace IceSpider {
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
void set(T & t) const override \
{ \
- t = boost::lexical_cast<T>(s); \
+ if (const auto v = s.value(); std::from_chars(v.begin(), v.end(), t).ec != std::errc {}) { \
+ throw Http400_BadRequest(); \
+ } \
}
SET(Ice::Byte);
diff --git a/icespider/unittests/testFcgi.cpp b/icespider/unittests/testFcgi.cpp
index e6508b3..b3ea6e2 100644
--- a/icespider/unittests/testFcgi.cpp
+++ b/icespider/unittests/testFcgi.cpp
@@ -316,6 +316,8 @@ BOOST_AUTO_TEST_CASE(cookies)
}});
BOOST_REQUIRE_EQUAL(1234, *r.IceSpider::IHttpRequest::getCookieParam<Ice::Int>("valueA"));
BOOST_REQUIRE_EQUAL("Something with spaces.", *r.IceSpider::IHttpRequest::getCookieParam<std::string>("value B"));
+ BOOST_REQUIRE_EQUAL(
+ "Something with spaces.", *r.IceSpider::IHttpRequest::getCookieParam<std::string_view>("value B"));
BOOST_REQUIRE(!r.IceSpider::IHttpRequest::getCookieParam<Ice::Int>("notAThing"));
r.setCookie("some int?[0]", 1234, "www.com"s, "/dir"s, true, 1476142378);
BOOST_REQUIRE_EQUAL("Set-Cookie: some+int%3f%5b0%5d=1234; expires=Mon, 10 Oct 2016 23:32:58 GMT; domain=www.com; "
diff --git a/icespider/unittests/testPerf.cpp b/icespider/unittests/testPerf.cpp
index b23f436..04e5deb 100644
--- a/icespider/unittests/testPerf.cpp
+++ b/icespider/unittests/testPerf.cpp
@@ -93,6 +93,15 @@ BENCHMARK_F(CoreFixture, get_query_string_param)(benchmark::State & state)
}
}
+BENCHMARK_F(CoreFixture, get_query_string_param_int)(benchmark::State & state)
+{
+ CharPtrPtrArray env(rootDir / "fixtures/env1");
+ TestRequest r(this, env);
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(r.getQueryStringParam<int>("m"));
+ }
+}
+
BENCHMARK_F(CoreFixture, get_cookie_param)(benchmark::State & state)
{
CharPtrPtrArray env(rootDir / "fixtures/env1");