bool util::string_contains(const std::experimental::string_view &str, const char c) { assert(!str.empty()); assert(c); return str.find(c) != std::experimental::string_view::npos; }
void client::raw_cmd(const std::experimental::string_view &content) { if (content.empty()) throw std::invalid_argument("content is empty."); con_.write(content.data()); }
bool Tial::Utility::Logger::toBeLoggedRuntime(Level level, const std::experimental::string_view &module) { auto moduleLevel = levels.find(module.to_string()); if(moduleLevel == levels.end()) { auto sep = module.rfind("::"); if(sep == module.npos) return level >= globalLevel; return toBeLoggedRuntime(level, module.substr(0, sep)); } return level >= moduleLevel->second; }
/* * Validates an ipv4ipv6 address and return the result. * Thanks, beej! */ bool util::valid_ipv46_addr(const std::experimental::string_view &addr) { assert(!addr.empty()); /* Unused, but required by inet_pton(). */ unsigned char buf[sizeof(struct in6_addr)]; if (ip_version(addr) == ipv4) return inet_pton(AF_INET, addr.data(), buf); else return inet_pton(AF_INET6, addr.data(), buf); }
int main () { test ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( "ABCDE"); test ( "a" ); test ( "" ); test ( L"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( L"ABCDE" ); test ( L"a" ); test ( L"" ); #if __cplusplus >= 201103L test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); test ( u"" ); test ( U"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( U"ABCDE" ); test ( U"a" ); test ( U"" ); #endif #if _LIBCPP_STD_VER > 11 { constexpr std::experimental::string_view sv1 { "ABCDE", 5 }; { constexpr std::experimental::string_view sv2 = sv1.substr ( 0, 3 ); static_assert ( sv2.size() == 3, "" ); static_assert ( sv2[0] == 'A', "" ); static_assert ( sv2[1] == 'B', "" ); static_assert ( sv2[2] == 'C', "" ); } { constexpr std::experimental::string_view sv2 = sv1.substr ( 3, 0 ); static_assert ( sv2.size() == 0, "" ); } { constexpr std::experimental::string_view sv2 = sv1.substr ( 3, 3 ); static_assert ( sv2.size() == 2, "" ); static_assert ( sv2[0] == 'D', "" ); static_assert ( sv2[1] == 'E', "" ); } } #endif }
static OutputContainer splitted(const std::experimental::string_view &collection, const Element &element) { OutputContainer output; if(!collection.empty()) { unsigned int start = 0, i = 0; for(; i != collection.size();) { if(collection[i] == element) { output.push_back(collection.substr(start, i-start)); ++i; start = i; } else ++i; } output.push_back(collection.substr(start, i)); } return output; }
int main () { test ( "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( "ABCDE"); test ( "a" ); test ( "" ); test ( L"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( L"ABCDE" ); test ( L"a" ); test ( L"" ); test ( u"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( u"ABCDE" ); test ( u"a" ); test ( u"" ); test ( U"ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE" ); test ( U"ABCDE" ); test ( U"a" ); test ( U"" ); { constexpr std::experimental::string_view sv1 { "ABCDE", 5 }; { constexpr std::experimental::string_view sv2 = sv1.substr ( 0, 3 ); static_assert ( sv2.size() == 3, "" ); static_assert ( sv2[0] == 'A', "" ); static_assert ( sv2[1] == 'B', "" ); static_assert ( sv2[2] == 'C', "" ); } { constexpr std::experimental::string_view sv2 = sv1.substr ( 3, 0 ); static_assert ( sv2.size() == 0, "" ); } { constexpr std::experimental::string_view sv2 = sv1.substr ( 3, 3 ); static_assert ( sv2.size() == 2, "" ); static_assert ( sv2[0] == 'D', "" ); static_assert ( sv2[1] == 'E', "" ); } } }
/* * Validates the syntax of hostnames, ipv4-, and ipv6-addresses. * Returns an empty string on success, non-empty on failure. * * TODO: Implement support for internationalized domain names. */ const std::string util::valid_addr(const std::experimental::string_view &addr) { if (!valid_ipv46_addr(addr)) { if (string_contains(addr, ipv6_sep)) return "invalid ipv6 address."; if (addr.length() > addr_max_length) return "the address is too long; it's illegal to exceed 255 characters."; /* * Split the hostname into its multiple sub-domains * (seperated by periods) and check them. */ std::vector<std::string> tokens = split_string(addr, period); for (const std::experimental::string_view &s: tokens) { /* * In case of "irc..hostname.tld", where the token between '..', * would be empty. */ if (s.empty()) return "a token is empty; does the address contain \"..\" somewhere?"; /* Also as per RFC 1035. */ if (s.front() == hyphen || s.back() == hyphen) { std::string element = s.data(); return "first or last character in the element \"" + element + "\" is a hyphen; that's not allowed."; } /* * O̶n̶l̶y̶ ̶[̶A̶-̶Z̶a̶-̶z̶0̶-̶9̶]̶ ̶a̶r̶e̶ ̶a̶l̶l̶o̶w̶e̶d̶.̶ * Okey, no. International domain names is a thing: * <https://en.wikipedia.org/wiki/Domain_name> * * s[first] and s[last] are checked again, but they * must be checked for non-[A-Za-z0-9], anyway. A check for * periods could be implemented here, but then we'd lose a specified * error message and we'd need more checks than what we remove. */ if (std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c) && !std::isalpha(c) && c != hyphen; }) != s.end()) { std::string element = s.data(); return "the element \"" + element + "\" contains an illegal character (not a [A-Za-z0-9\\-])."; } } } return ""; }
/* * Split a string into multiple strings when a character is met. * Returns all tokens in an array. */ std::vector<std::string> util::split_string(const std::experimental::string_view &str, const char c) { assert(!str.empty()); assert(c); using std::experimental::string_view; std::vector<std::string> result; for (string_view::const_iterator len = str.begin(); len <= str.end(); len++) { string_view::const_iterator token_start = len; while (*len != c && *len) len++; result.emplace_back(token_start, len); } return result; }
bool util::is_integer(const std::experimental::string_view &s) { assert(!s.empty()); for (char c: s) { if (!std::isdigit(c)) return false; } return true; }
std::string uri::decode(const std::experimental::string_view input) { std::string res; res.reserve(input.size()); for (auto it = input.cbegin(), e = input.cend(); it not_eq e; ++it) { if (*it == '%') { if (++it >= e) return decode_error(std::move(res)); const uint8_t nibble1 = (*it); if (++it >= e) return decode_error(std::move(res)); const uint8_t nibble2 = (*it); res += static_cast<char>(from_hex(nibble1, nibble2)); } else { if (is_reserved(*it) or is_unreserved(*it)) res += *it; else return decode_error(std::move(res)); } } return res; }
int util::ip_version(const std::experimental::string_view &addr) { assert(!addr.empty()); /* * Feels hackish. * * TODO: Look into and confirm/bust above statement. */ if (string_contains(addr, period)) return ipv4; return ipv6; }
void Tial::Testing::Thread::operator()(const std::experimental::string_view &name) { std::promise<void> result; this->result = result.get_future(); thread = std::thread([name=name, function=function, checker=Check::checker()](std::promise<void> result){ Utility::Thread::setName(name.to_string()); Check::setChecker(checker); try { function(); result.set_value_at_thread_exit(); } catch(std::exception e) { LOGC << "Exception in subthread: " << e.what(); throw; } catch(...) { LOGC << "Exception in subthread"; result.set_exception_at_thread_exit(std::current_exception()); } }, std::move(result)); }
std::string uri::encode(const std::experimental::string_view input) { static const std::array<char,16> hex = {{ '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }}; std::string res; res.reserve(input.size()); for (const auto chr : input) if (is_unreserved(chr)) { res += chr; } else { res += '%'; res += hex[ chr >> 4 ]; res += hex[ chr & 0xf ]; } return res; }
static bool isOption(const std::experimental::string_view& str) { assert(!str.empty()); return str.front() == '-'; }
Exception::Exception(ErrorCode error_id, std::experimental::string_view information) : m_error_id{error_id}, m_information{information.begin(), information.end()} {}
void Tial::Utility::Algorithm::removeSuffix(std::experimental::string_view &stringView) { stringView.remove_suffix(1); }
void Tial::Utility::Logger::setLoggingLevel(Level level, const std::experimental::string_view &module) { levels[module.to_string()] = level; }
Tial::Utility::Logger::Message::Message( const std::experimental::string_view &file, unsigned int line, const std::experimental::string_view &function, const std::experimental::string_view &prettyFunction, Level level, const std::experimental::string_view &module, const TimePoint &time ): file(file.to_string()), line(line), function(function.to_string()), prettyFunction(prettyFunction.to_string()), level(level), module(module.to_string()), time(time) {}