utils.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /**
  2. * Copyright (c) 2020-2022 Paul-Louis Ageneau
  3. *
  4. * This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  7. */
  8. #ifndef RTC_IMPL_UTILS_H
  9. #define RTC_IMPL_UTILS_H
  10. #include "common.hpp"
  11. #include <climits>
  12. #include <limits>
  13. #include <random>
  14. #include <vector>
  15. namespace rtc::impl::utils {
  16. std::vector<string> explode(const string &str, char delim);
  17. string implode(const std::vector<string> &tokens, char delim);
  18. // Decode URL percent-encoding (RFC 3986)
  19. // See https://www.rfc-editor.org/rfc/rfc3986.html#section-2.1
  20. string url_decode(const string &str);
  21. // Encode as base64 (RFC 4648)
  22. // See https://www.rfc-editor.org/rfc/rfc4648.html#section-4
  23. string base64_encode(const binary &data);
  24. // Return a random seed sequence
  25. std::seed_seq random_seed();
  26. // Check the buffer contains the beginning of an HTTP request
  27. bool IsHttpRequest(const byte *buffer, size_t size);
  28. template <typename Generator, typename Result = typename Generator::result_type>
  29. struct random_engine_wrapper {
  30. Generator &engine;
  31. using result_type = Result;
  32. static constexpr result_type min() { return static_cast<Result>(Generator::min()); }
  33. static constexpr result_type max() { return static_cast<Result>(Generator::max()); }
  34. inline result_type operator()() { return static_cast<Result>(engine()); }
  35. inline void discard(unsigned long long z) { engine.discard(z); }
  36. };
  37. // Return a wrapped thread-local seeded random number generator
  38. template <typename Generator = std::mt19937, typename Result = typename Generator::result_type>
  39. auto random_engine() {
  40. static thread_local std::seed_seq seed = random_seed();
  41. static thread_local Generator engine{seed};
  42. return random_engine_wrapper<Generator, Result>{engine};
  43. }
  44. // Return a wrapped thread-local seeded random bytes generator
  45. template <typename Generator = std::mt19937> auto random_bytes_engine() {
  46. using char_independent_bits_engine =
  47. std::independent_bits_engine<Generator, CHAR_BIT, unsigned short>;
  48. static_assert(char_independent_bits_engine::min() == std::numeric_limits<uint8_t>::min());
  49. static_assert(char_independent_bits_engine::max() == std::numeric_limits<uint8_t>::max());
  50. return random_engine<char_independent_bits_engine, uint8_t>();
  51. }
  52. } // namespace rtc::impl::utils
  53. #endif