/** * Copyright (c) 2020-2022 Paul-Louis Ageneau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #ifndef RTC_IMPL_UTILS_H #define RTC_IMPL_UTILS_H #include "common.hpp" #include #include #include #include namespace rtc::impl::utils { std::vector explode(const string &str, char delim); string implode(const std::vector &tokens, char delim); // Decode URL percent-encoding (RFC 3986) // See https://www.rfc-editor.org/rfc/rfc3986.html#section-2.1 string url_decode(const string &str); // Encode as base64 (RFC 4648) // See https://www.rfc-editor.org/rfc/rfc4648.html#section-4 string base64_encode(const binary &data); // Return a random seed sequence std::seed_seq random_seed(); // Check the buffer contains the beginning of an HTTP request bool IsHttpRequest(const byte *buffer, size_t size); template struct random_engine_wrapper { Generator &engine; using result_type = Result; static constexpr result_type min() { return static_cast(Generator::min()); } static constexpr result_type max() { return static_cast(Generator::max()); } inline result_type operator()() { return static_cast(engine()); } inline void discard(unsigned long long z) { engine.discard(z); } }; // Return a wrapped thread-local seeded random number generator template auto random_engine() { static thread_local std::seed_seq seed = random_seed(); static thread_local Generator engine{seed}; return random_engine_wrapper{engine}; } // Return a wrapped thread-local seeded random bytes generator template auto random_bytes_engine() { using char_independent_bits_engine = std::independent_bits_engine; static_assert(char_independent_bits_engine::min() == std::numeric_limits::min()); static_assert(char_independent_bits_engine::max() == std::numeric_limits::max()); return random_engine(); } } // namespace rtc::impl::utils #endif