#pragma once #include "base/base.hpp" #include #include #include #include namespace impl { void ToHexRaw(void const * src, size_t size, void * dst); void FromHexRaw(void const * src, size_t size, void * dst); } inline std::string ToHex(const void * ptr, size_t size) { std::string result; if (size == 0) return result; result.resize(size * 2); ::impl::ToHexRaw(ptr, size, &result[0]); return result; } template inline std::string ToHex(ContainerT const & container) { static_assert(sizeof(*container.begin()) == 1, ""); if (container.empty()) return {}; return ToHex(&*container.begin(), container.end() - container.begin()); } /// Conversion with specializations to avoid warnings /// @{ template inline std::string NumToHex(IntT n) { static_assert(std::is_integral::value, ""); uint8_t buf[sizeof(n)]; for (size_t i = 0; i < sizeof(n); ++i) { buf[i] = (n >> ((sizeof(n) - 1) * 8)); n <<= 8; } return ToHex(buf, sizeof(buf)); } template <> inline std::string NumToHex(int8_t c) { return ToHex(&c, sizeof(c)); } template <> inline std::string NumToHex(uint8_t c) { return ToHex(&c, sizeof(c)); } template <> inline std::string NumToHex(char c) { return ToHex(&c, sizeof(c)); } /// @} inline std::string FromHex(void const * ptr, size_t size) { std::string result; result.resize(size / 2); ::impl::FromHexRaw(ptr, size, &result[0]); return result; } inline std::string FromHex(std::string const & src) { return FromHex(src.c_str(), src.size()); } inline std::string ByteToQuat(uint8_t n) { std::string result; for (size_t i = 0; i < 4; ++i) { result += char(((n & 0xC0) >> 6) + '0'); n <<= 2; } return result; } template inline std::string NumToQuat(IntT n) { std::string result; for (size_t i = 0; i < sizeof(n); ++i) { uint8_t ub = n >> (sizeof(n) * 8 - 8); result += ByteToQuat(ub); n <<= 8; } return result; }