diff options
author | Ed Tanous <ed@tanous.net> | 2020-08-24 21:29:49 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2020-10-07 21:39:41 +0300 |
commit | 988403c64f7d1937eece8c52a076d5abedfb3b60 (patch) | |
tree | 290144bdce8cf1189d9f89a525243058eab44099 | |
parent | cc0904473c19977eb0b9789b3c1be54a74ca873d (diff) | |
download | bmcweb-988403c64f7d1937eece8c52a076d5abedfb3b60.tar.xz |
Clean up utils
Lots of the utils functions have been superceeded or replaced by std::
implementations, or are no longer needed because of the removal of
middlewares.
Tested:
Ran on a bmc with this implemented. Pulled down the webui, and
observed no issues. Code compiles and passes clang-tidy cert checks.
Change-Id: If29bb5f4ba9979912aeb2a8fa4cbd9f4e4f32006
Signed-off-by: Ed Tanous <ed@tanous.net>
-rw-r--r-- | http/app.h | 2 | ||||
-rw-r--r-- | http/routing.h | 19 | ||||
-rw-r--r-- | http/utility.h | 413 | ||||
-rw-r--r-- | src/crow_test.cpp | 20 |
4 files changed, 115 insertions, 339 deletions
diff --git a/http/app.h b/http/app.h index ff8642d6d1..86cebd3674 100644 --- a/http/app.h +++ b/http/app.h @@ -17,7 +17,7 @@ #include <utility> #define BMCWEB_ROUTE(app, url) \ - app.template route<crow::black_magic::get_parameter_tag(url)>(url) + app.template route<crow::black_magic::getParameterTag(url)>(url) namespace crow { diff --git a/http/routing.h b/http/routing.h index f07e51b7bc..b49e15ea14 100644 --- a/http/routing.h +++ b/http/routing.h @@ -270,7 +270,7 @@ struct Wrapped using type = std::function<void(const crow::Request&, crow::Response&, Args...)>; using args_type = - black_magic::S<typename black_magic::promote_t<Args>...>; + black_magic::S<typename black_magic::PromoteT<Args>...>; }; template <typename... Args> @@ -279,7 +279,7 @@ struct Wrapped using type = std::function<void(const crow::Request&, crow::Response&, Args...)>; using args_type = - black_magic::S<typename black_magic::promote_t<Args>...>; + black_magic::S<typename black_magic::PromoteT<Args>...>; }; template <typename... Args> @@ -288,7 +288,7 @@ struct Wrapped using type = std::function<void(const crow::Request&, crow::Response&, Args...)>; using args_type = - black_magic::S<typename black_magic::promote_t<Args>...>; + black_magic::S<typename black_magic::PromoteT<Args>...>; }; typename HandlerTypeHelper<ArgsWrapped...>::type handler; @@ -469,9 +469,9 @@ class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule> void operator()(Func f) { using function_t = utility::function_traits<Func>; - erasedHandler = - wrap(std::move(f), black_magic::gen_seq<function_t::arity>()); + wrap(std::move(f), + std::make_integer_sequence<unsigned, function_t::arity>{}); } // enable_if Arg1 == request && Arg2 == Response @@ -479,15 +479,14 @@ class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule> // enable_if Arg1 != request template <typename Func, unsigned... Indices> - std::function<void(const Request&, Response&, const RoutingParams&)> - wrap(Func f, black_magic::Seq<Indices...>) + wrap(Func f, std::integer_sequence<unsigned, Indices...>) { - using function_t = utility::function_traits<Func>; + using function_t = crow::utility::function_traits<Func>; if (!black_magic::isParameterTagCompatible( - black_magic::getParameterTagRuntime(rule.c_str()), - black_magic::compute_parameter_tag_from_args_list< + black_magic::getParameterTag(rule.c_str()), + black_magic::computeParameterTagFromArgsList< typename function_t::template arg<Indices>...>::value)) { throw std::runtime_error("routeDynamic: Handler type is mismatched " diff --git a/http/utility.h b/http/utility.h index 862f1db145..5a184cce18 100644 --- a/http/utility.h +++ b/http/utility.h @@ -16,102 +16,35 @@ namespace crow { namespace black_magic { -struct OutOfRange -{ - OutOfRange(unsigned /*pos*/, unsigned /*length*/) - {} -}; -constexpr unsigned requiresInRange(unsigned i, unsigned len) -{ - return i >= len ? throw OutOfRange(i, len) : i; -} - -class ConstStr -{ - const char* const beginPtr; - unsigned sizeUint; - - public: - template <unsigned N> - constexpr ConstStr(const char (&arr)[N]) : beginPtr(arr), sizeUint(N - 1) - { - static_assert(N >= 1, "not a string literal"); - } - constexpr char operator[](unsigned i) const - { - requiresInRange(i, sizeUint); - return beginPtr[i]; - } - - constexpr operator const char*() const - { - return beginPtr; - } - - constexpr const char* begin() const - { - return beginPtr; - } - constexpr const char* end() const - { - return beginPtr + sizeUint; - } - constexpr unsigned size() const - { - return sizeUint; - } -}; - -constexpr unsigned findClosingTag(ConstStr s, unsigned p) +constexpr unsigned findClosingTag(std::string_view s, unsigned p) { return s[p] == '>' ? p : findClosingTag(s, p + 1); } -constexpr bool isValid(ConstStr s, unsigned i = 0, int f = 0) -{ - return i == s.size() - ? f == 0 - : f < 0 || f >= 2 - ? false - : s[i] == '<' ? isValid(s, i + 1, f + 1) - : s[i] == '>' ? isValid(s, i + 1, f - 1) - : isValid(s, i + 1, f); -} - -constexpr bool isEquN(ConstStr a, unsigned ai, ConstStr b, unsigned bi, - unsigned n) +constexpr bool isInt(std::string_view s, unsigned i) { - return ai + n > a.size() || bi + n > b.size() - ? false - : n == 0 ? true - : a[ai] != b[bi] ? false - : isEquN(a, ai + 1, b, bi + 1, n - 1); + return s.substr(i, 5) == "<int>"; } -constexpr bool isInt(ConstStr s, unsigned i) +constexpr bool isUint(std::string_view s, unsigned i) { - return isEquN(s, i, "<int>", 0, 5); + return s.substr(i, 6) == "<uint>"; } -constexpr bool isUint(ConstStr s, unsigned i) +constexpr bool isFloat(std::string_view s, unsigned i) { - return isEquN(s, i, "<uint>", 0, 6); + return s.substr(i, 7) == "<float>" || s.substr(i, 8) == "<double>"; } -constexpr bool isFloat(ConstStr s, unsigned i) +constexpr bool isStr(std::string_view s, unsigned i) { - return isEquN(s, i, "<float>", 0, 7) || isEquN(s, i, "<double>", 0, 8); + return s.substr(i, 5) == "<str>" || s.substr(i, 8) == "<string>"; } -constexpr bool isStr(ConstStr s, unsigned i) +constexpr bool isPath(std::string_view s, unsigned i) { - return isEquN(s, i, "<str>", 0, 5) || isEquN(s, i, "<string>", 0, 8); -} - -constexpr bool isPath(ConstStr s, unsigned i) -{ - return isEquN(s, i, "<path>", 0, 6); + return s.substr(i, 6) == "<path>"; } template <typename T> @@ -169,26 +102,26 @@ constexpr int getParameterTag() } template <typename... Args> -struct compute_parameter_tag_from_args_list; +struct computeParameterTagFromArgsList; template <> -struct compute_parameter_tag_from_args_list<> +struct computeParameterTagFromArgsList<> { static constexpr int value = 0; }; template <typename Arg, typename... Args> -struct compute_parameter_tag_from_args_list<Arg, Args...> +struct computeParameterTagFromArgsList<Arg, Args...> { static constexpr int subValue = - compute_parameter_tag_from_args_list<Args...>::value; + computeParameterTagFromArgsList<Args...>::value; static constexpr int value = getParameterTag<typename std::decay<Arg>::type>() ? subValue * 6 + getParameterTag<typename std::decay<Arg>::type>() : subValue; }; -static inline bool isParameterTagCompatible(uint64_t a, uint64_t b) +inline bool isParameterTagCompatible(uint64_t a, uint64_t b) { if (a == 0) { @@ -215,87 +148,44 @@ static inline bool isParameterTagCompatible(uint64_t a, uint64_t b) return isParameterTagCompatible(a / 6, b / 6); } -static inline unsigned findClosingTagRuntime(const char* s, unsigned p) +constexpr uint64_t getParameterTag(std::string_view s, unsigned p = 0) { - return s[p] == 0 ? throw std::runtime_error("unmatched tag <") - : s[p] == '>' ? p : findClosingTagRuntime(s, p + 1); -} + if (p == s.size()) + { + return 0; + } -static inline uint64_t getParameterTagRuntime(const char* s, unsigned p = 0) -{ - return s[p] == 0 - ? 0 - : s[p] == '<' - ? (std::strncmp(s + p, "<int>", 5) == 0 - ? getParameterTagRuntime( - s, findClosingTagRuntime(s, p)) * - 6 + - 1 - : std::strncmp(s + p, "<uint>", 6) == 0 - ? getParameterTagRuntime( - s, findClosingTagRuntime(s, p)) * - 6 + - 2 - : (std::strncmp(s + p, "<float>", 7) == 0 || - std::strncmp(s + p, "<double>", 8) == 0) - ? getParameterTagRuntime( - s, findClosingTagRuntime(s, p)) * - 6 + - 3 - : (std::strncmp(s + p, "<str>", 5) == - 0 || - std::strncmp(s + p, "<string>", 8) == - 0) - ? getParameterTagRuntime( - s, findClosingTagRuntime( - s, p)) * - 6 + - 4 - : std::strncmp(s + p, "<path>", - 6) == 0 - ? getParameterTagRuntime( - s, - findClosingTagRuntime( - s, p)) * - 6 + - 5 - : throw std::runtime_error( - "invalid parameter " - "type")) - : getParameterTagRuntime(s, p + 1); -} + if (s[p] != '<') + { + return getParameterTag(s, p + 1); + } -constexpr uint64_t get_parameter_tag(ConstStr s, unsigned p = 0) -{ - return p == s.size() - ? 0 - : s[p] == '<' - ? (isInt(s, p) - ? get_parameter_tag(s, findClosingTag(s, p)) * 6 + 1 - : isUint(s, p) - ? get_parameter_tag(s, findClosingTag(s, p)) * - 6 + - 2 - : isFloat(s, p) - ? get_parameter_tag( - s, findClosingTag(s, p)) * - 6 + - 3 - : isStr(s, p) - ? get_parameter_tag( - s, findClosingTag(s, p)) * - 6 + - 4 - : isPath(s, p) - ? get_parameter_tag( - s, findClosingTag( - s, p)) * - 6 + - 5 - : throw std::runtime_error( - "invalid parameter " - "type")) - : get_parameter_tag(s, p + 1); + if (isInt(s, p)) + { + return getParameterTag(s, findClosingTag(s, p)) * 6 + 1; + } + + if (isUint(s, p)) + { + return getParameterTag(s, findClosingTag(s, p)) * 6 + 2; + } + + if (isFloat(s, p)) + { + return getParameterTag(s, findClosingTag(s, p)) * 6 + 3; + } + + if (isStr(s, p)) + { + return getParameterTag(s, findClosingTag(s, p)) * 6 + 4; + } + + if (isPath(s, p)) + { + return getParameterTag(s, findClosingTag(s, p)) * 6 + 5; + } + + throw std::runtime_error("invalid parameter type"); } template <typename... T> @@ -308,8 +198,10 @@ struct S template <template <typename... Args> class U> using rebind = U<T...>; }; + template <typename F, typename Set> struct CallHelper; + template <typename F, typename... Args> struct CallHelper<F, S<Args...>> { @@ -371,129 +263,65 @@ struct Arguments<0> using type = S<>; }; -template <typename... T> -struct LastElementType +template <typename T> +struct Promote { - using type = - typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type; + using type = T; }; -template <> -struct LastElementType<> -{}; - -// from -// http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth -template <class T> -using Invoke = typename T::type; +template <typename T> +using PromoteT = typename Promote<T>::type; -template <unsigned...> -struct Seq +template <> +struct Promote<char> { - using type = Seq; + using type = int64_t; }; - -template <class S1, class S2> -struct concat; - -template <unsigned... I1, unsigned... I2> -struct concat<Seq<I1...>, Seq<I2...>> : Seq<I1..., (sizeof...(I1) + I2)...> -{}; - -template <class S1, class S2> -using Concat = Invoke<concat<S1, S2>>; - -template <size_t N> -struct gen_seq; -template <size_t N> -using GenSeq = Invoke<gen_seq<N>>; - -template <size_t N> -struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>> -{}; - template <> -struct gen_seq<0> : Seq<> -{}; +struct Promote<short> +{ + using type = int64_t; +}; template <> -struct gen_seq<1> : Seq<0> -{}; - -template <typename Seq, typename Tuple> -struct PopBackHelper; - -template <unsigned... N, typename Tuple> -struct PopBackHelper<Seq<N...>, Tuple> +struct Promote<int> { - template <template <typename... Args> class U> - using rebind = U<typename std::tuple_element<N, Tuple>::type...>; + using type = int64_t; }; - -template <typename... T> -struct PopBack //: public PopBackHelper<typename - // gen_seq<sizeof...(T)-1>::type, std::tuple<T...>> +template <> +struct Promote<long> { - template <template <typename... Args> class U> - using rebind = - typename PopBackHelper<typename gen_seq<sizeof...(T) - 1UL>::type, - std::tuple<T...>>::template rebind<U>; + using type = int64_t; }; - template <> -struct PopBack<> +struct Promote<long long> { - template <template <typename... Args> class U> - using rebind = U<>; + using type = int64_t; }; - -// from -// http://stackoverflow.com/questions/2118541/check-if-c0x-parameter-pack-contains-a-type -template <typename Tp, typename... List> -struct Contains : std::true_type -{}; - -template <typename Tp, typename Head, typename... Rest> -struct Contains<Tp, Head, Rest...> : - std::conditional<std::is_same<Tp, Head>::value, std::true_type, - Contains<Tp, Rest...>>::type -{}; - -template <typename Tp> -struct Contains<Tp> : std::false_type -{}; - -template <typename T> -struct EmptyContext -{}; - -template <typename T> -struct promote +template <> +struct Promote<unsigned char> { - using type = T; + using type = uint64_t; +}; +template <> +struct Promote<unsigned short> +{ + using type = uint64_t; +}; +template <> +struct Promote<unsigned int> +{ + using type = uint64_t; +}; +template <> +struct Promote<unsigned long> +{ + using type = uint64_t; +}; +template <> +struct Promote<unsigned long long> +{ + using type = uint64_t; }; - -#define BMCWEB_INTERNAL_PROMOTE_TYPE(t1, t2) \ - template <> \ - struct promote<t1> \ - { \ - using type = t2; \ - } - -BMCWEB_INTERNAL_PROMOTE_TYPE(char, int64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(short, int64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(int, int64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(long, int64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(long long, int64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned char, uint64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned short, uint64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned int, uint64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned long, uint64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(unsigned long long, uint64_t); -BMCWEB_INTERNAL_PROMOTE_TYPE(float, double); -#undef BMCWEB_INTERNAL_PROMOTE_TYPE - -template <typename T> -using promote_t = typename promote<T>::type; } // namespace black_magic @@ -576,57 +404,6 @@ struct function_traits<std::function<r(Args...)>> using arg = typename std::tuple_element<i, std::tuple<Args...>>::type; }; -inline static std::string base64encode( - const char* data, size_t size, - const char* key = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") -{ - std::string ret; - ret.resize((size + 2) / 3 * 4); - auto it = ret.begin(); - while (size >= 3) - { - *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2]; - unsigned char h = static_cast<unsigned char>( - (static_cast<unsigned char>(*data++) & 0x03u) << 4u); - *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xF0) >> 4)]; - h = static_cast<unsigned char>( - (static_cast<unsigned char>(*data++) & 0x0F) << 2u); - *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xC0) >> 6)]; - *it++ = key[static_cast<unsigned char>(*data++) & 0x3F]; - - size -= 3; - } - if (size == 1) - { - *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2]; - unsigned char h = static_cast<unsigned char>( - (static_cast<unsigned char>(*data++) & 0x03) << 4u); - *it++ = key[h]; - *it++ = '='; - *it++ = '='; - } - else if (size == 2) - { - *it++ = key[(static_cast<unsigned char>(*data) & 0xFC) >> 2]; - unsigned char h = static_cast<unsigned char>( - (static_cast<unsigned char>(*data++) & 0x03) << 4u); - *it++ = key[h | ((static_cast<unsigned char>(*data) & 0xF0) >> 4)]; - h = static_cast<unsigned char>( - (static_cast<unsigned char>(*data++) & 0x0F) << 2u); - *it++ = key[h]; - *it++ = '='; - } - return ret; -} - -inline static std::string base64encodeUrlsafe(const char* data, size_t size) -{ - return base64encode( - data, size, - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"); -} - // TODO this is temporary and should be deleted once base64 is refactored out of // crow inline bool base64Decode(const std::string_view input, std::string& output) diff --git a/src/crow_test.cpp b/src/crow_test.cpp index 4e0bd407be..a6852203a2 100644 --- a/src/crow_test.cpp +++ b/src/crow_test.cpp @@ -98,19 +98,19 @@ TEST(Crow, ParameterTagging) static_assert(black_magic::isValid("<int><int><int>"), "valid url"); static_assert(!black_magic::isValid("<int><int<<int>"), "invalid url"); static_assert(!black_magic::isValid("nt>"), "invalid url"); - ASSERT_EQUAL(1, black_magic::get_parameter_tag("<int>")); - ASSERT_EQUAL(2, black_magic::get_parameter_tag("<uint>")); - ASSERT_EQUAL(3, black_magic::get_parameter_tag("<float>")); - ASSERT_EQUAL(3, black_magic::get_parameter_tag("<double>")); - ASSERT_EQUAL(4, black_magic::get_parameter_tag("<str>")); - ASSERT_EQUAL(4, black_magic::get_parameter_tag("<string>")); - ASSERT_EQUAL(5, black_magic::get_parameter_tag("<path>")); + ASSERT_EQUAL(1, black_magic::getParameterTag("<int>")); + ASSERT_EQUAL(2, black_magic::getParameterTag("<uint>")); + ASSERT_EQUAL(3, black_magic::getParameterTag("<float>")); + ASSERT_EQUAL(3, black_magic::getParameterTag("<double>")); + ASSERT_EQUAL(4, black_magic::getParameterTag("<str>")); + ASSERT_EQUAL(4, black_magic::getParameterTag("<string>")); + ASSERT_EQUAL(5, black_magic::getParameterTag("<path>")); ASSERT_EQUAL(6 * 6 + 6 + 1, - black_magic::get_parameter_tag("<int><int><int>")); + black_magic::getParameterTag("<int><int><int>")); ASSERT_EQUAL(6 * 6 + 6 + 2, - black_magic::get_parameter_tag("<uint><int><int>")); + black_magic::getParameterTag("<uint><int><int>")); ASSERT_EQUAL(6 * 6 + 6 * 3 + 2, - black_magic::get_parameter_tag("<uint><double><int>")); + black_magic::getParameterTag("<uint><double><int>")); // url definition parsed in compile time, build into *one number*, and given // to template argument |