| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include "end_point.h" |
| #include "ignite_error.h" |
| |
| #include <algorithm> |
| #include <functional> |
| #include <sstream> |
| #include <string_view> |
| #include <optional> |
| #include <limits> |
| |
| #include <cctype> |
| |
| namespace ignite { |
| |
| /** |
| * Remove leading spaces. |
| * |
| * @param str String view. |
| * @return String view without leading spaces. |
| */ |
| inline std::string_view ltrim(std::string_view str) { |
| while (!str.empty() && std::isspace(str.front())) |
| str.remove_prefix(1); |
| |
| return str; |
| } |
| |
| /** |
| * Remove trailing spaces. |
| * |
| * @param str String view. |
| * @return String view without trailing spaces. |
| */ |
| inline std::string_view rtrim(std::string_view str) { |
| while (!str.empty() && std::isspace(str.back())) |
| str.remove_suffix(1); |
| |
| return str; |
| } |
| |
| /** |
| * Remove leading and trailing spaces. |
| * |
| * @param str String view. |
| * @return String view without leading and trailing spaces. |
| */ |
| inline std::string_view trim(std::string_view str) { |
| return ltrim(rtrim(str)); |
| } |
| |
| /** |
| * Split string once by delimiter. |
| * If string has no delimiter, the second returned string is empty. |
| * |
| * @param delimiter Delimiter. |
| * @return Pair of values split by the first encountered delimiter. Delimiter itself is not included. |
| */ |
| inline std::pair<std::string_view, std::string_view> split_once(std::string_view str, char delimiter) { |
| auto delim_pos = str.find(delimiter); |
| if (delim_pos == decltype(str)::npos) |
| return {str, {}}; |
| |
| std::string_view first{str.data(), delim_pos}; |
| std::string_view second{str}; |
| second.remove_prefix(delim_pos + 1); |
| return {first, second}; |
| } |
| |
| /** |
| * Call action for every substring separated by delimiter. |
| * |
| * @param str String. |
| * @param delimiter Delimiter. |
| * @param action Action to perform. |
| */ |
| inline void for_every_delimited( |
| std::string_view str, char delimiter, const std::function<void(std::string_view)> &action) { |
| while (!str.empty()) { |
| auto res = split_once(str, delimiter); |
| action(res.first); |
| str = res.second; |
| } |
| } |
| |
| /** |
| * Split string by delimiter. |
| * |
| * @param delimiter Delimiter. |
| * @return Vector with resulting string parts. |
| */ |
| inline std::vector<std::string_view> split(std::string_view str, char delimiter) { |
| std::vector<std::string_view> res; |
| for_every_delimited(str, delimiter, [&res](auto part) { res.push_back(part); }); |
| return res; |
| } |
| |
| /** |
| * Casts value of one type to another type, using string stream. |
| * |
| * @param val Input value. |
| * @param res Resulted value. |
| */ |
| template<typename T1, typename T2> |
| void lexical_cast(const T2 &val, T1 &res) { |
| std::stringstream converter; |
| |
| converter << val; |
| converter >> res; |
| } |
| |
| /** |
| * Casts value of one type to another type, using string stream. |
| * |
| * @param val Input value. |
| * @return Resulted value. |
| */ |
| template<typename T1, typename T2> |
| T1 lexical_cast(const T2 &val) { |
| T1 res; |
| |
| lexical_cast<T1, T2>(val, res); |
| |
| return res; |
| } |
| |
| /** |
| * Convert to lower. |
| * |
| * @param value Value. |
| * @return Lower value. |
| */ |
| [[nodiscard]] inline std::string to_lower(std::string value) { |
| std::transform(value.begin(), value.end(), value.begin(), ::tolower); |
| return value; |
| } |
| |
| /** |
| * Convert to upper. |
| * |
| * @param value Value. |
| * @return Upper value. |
| */ |
| [[nodiscard]] inline std::string to_upper(std::string value) { |
| std::transform(value.begin(), value.end(), value.begin(), ::toupper); |
| return value; |
| } |
| |
| /** |
| * Parse a single address. |
| * |
| * @throw ignite_error On parsing error. |
| * @param value End pont in the string format. |
| * @param default_port Default port to use if there is no port included in the address. |
| */ |
| [[nodiscard]] end_point parse_single_address(std::string_view value, std::uint16_t default_port); |
| |
| /** |
| * Parse integer value. |
| * |
| * @param value String value to parse. |
| * @return @c Int value on success and std::nullopt on failure. |
| */ |
| [[nodiscard]] std::optional<std::int64_t> parse_int64(std::string_view value); |
| |
| /** |
| * Parse integer value. |
| * |
| * @param value String value to parse. |
| * @return @c Int value on success and std::nullopt on failure. |
| */ |
| template<typename T> |
| [[nodiscard]] std::optional<T> parse_int(std::string_view value) { |
| auto i64 = parse_int64(value); |
| if (!i64) |
| return std::nullopt; |
| |
| if (*i64 > std::numeric_limits<T>::max() || *i64 < std::numeric_limits<T>::min()) |
| return std::nullopt; |
| |
| return T(*i64); |
| } |
| |
| /** |
| * Parse single network port. |
| * |
| * @throw ignite_error On parsing error. |
| * @param value String value to parse. |
| * @return @c Port value on success. |
| */ |
| [[nodiscard]] std::uint16_t parse_port(std::string_view value); |
| |
| } // namespace ignite |