.. _program_listing_file_rcdiscover_utils.h: Program Listing for File utils.h ================================ |exhale_lsh| :ref:`Return to documentation for file ` (``rcdiscover/utils.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * rcdiscover - the network discovery tool for Roboception devices * * Copyright (c) 2017 Roboception GmbH * All rights reserved * * Author: Raphael Schaller * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef RCDISCOVER_UTILS_H #define RCDISCOVER_UTILS_H #include #include #include #include #include #include inline std::string mac2string(const uint64_t mac) { std::ostringstream out; out << std::hex << std::setfill('0'); out << std::setw(2) << ((mac>>40)&0xff) << ':' << std::setw(2) << ((mac>>32)&0xff) << ':' << std::setw(2) << ((mac>>24)&0xff) << ':' << std::setw(2) << ((mac>>16)&0xff) << ':' << std::setw(2) << ((mac>>8)&0xff) << ':' << std::setw(2) << (mac&0xff); return out.str(); } inline std::string ip2string(const uint32_t ip) { std::ostringstream out; out << ((ip>>24)&0xff) << '.' << ((ip>>16)&0xff) << '.' << ((ip>>8)&0xff) << '.' << (ip&0xff); return out.str(); } template std::array split(const std::string& s, const char sep) { std::array result; if (!s.empty()) { if (s.front() == sep || s.back() == sep) { throw std::invalid_argument("strings starts or ends with separator"); } } std::istringstream iss(s); for (uint32_t i = 0; i < n; ++i) { if (!std::getline(iss, result[i], sep)) { throw std::out_of_range("n"); } } std::string tmp; if (std::getline(iss, tmp, sep)) { throw std::out_of_range("n"); } return result; } template std::array string2byte(const std::string& s, const int base, const char sep) { const auto splitted = split(s, sep); std::array result; std::transform(std::begin(splitted), std::end(splitted), std::begin(result), [&base](const std::string& s) -> std::uint8_t { const auto v = std::stoul(s, nullptr, base); if (v > 255) { throw std::out_of_range("number is larger than 255"); } return static_cast(v); }); return result; } inline std::array string2mac(const std::string& mac) { return string2byte<6>(mac, 16, ':'); } inline std::array string2ip(const std::string& ip) { return string2byte<4>(ip, 10, '.'); } template struct MinFittingType { }; template<> struct MinFittingType<1> { using type = std::uint8_t; }; template<> struct MinFittingType<2> { using type = std::uint16_t; }; template<> struct MinFittingType<3> { using type = std::uint32_t; }; template<> struct MinFittingType<4> { using type = std::uint32_t; }; template<> struct MinFittingType<5> { using type = std::uint64_t; }; template<> struct MinFittingType<6> { using type = std::uint64_t; }; template<> struct MinFittingType<7> { using type = std::uint64_t; }; template<> struct MinFittingType<8> { using type = std::uint64_t; }; template typename MinFittingType::type byteArrayToInt(const std::array &a) { using ReturnType = typename MinFittingType::type; ReturnType result{}; for (std::size_t i = 0; i < N; ++i) { result |= (static_cast(a[i]) << ((N - 1 - i) * 8)); } return result; } inline bool wildcardMatch(std::string::const_iterator str_first, std::string::const_iterator str_last, std::string::const_iterator p_first, std::string::const_iterator p_last) { if (str_first == str_last && p_first == p_last) { return true; } if (str_first == str_last) { if (*p_first == '*') { // if there is no more character after * => match return std::next(p_first) == p_last; } } if (p_first == p_last) { return false; } if (*p_first == '?' || std::tolower(*p_first) == std::tolower(*str_first)) { return wildcardMatch(std::next(str_first), str_last, std::next(p_first), p_last); } if (*p_first == '*') { return wildcardMatch(std::next(str_first), str_last, p_first, p_last) || wildcardMatch(str_first, str_last, std::next(p_first), p_last); } return false; } #endif // RCDISCOVER_UTILS_H