#ifndef URLUTIL_HH #define URLUTIL_HH #include #include #include namespace url { enum class EscapeFlags : unsigned { // Default encodes all non-unreserved characters // (not the same as all reserved) to be safe. DEFAULT = 0, // Same as DEFAULT but doesn't encode SLASH, useful when the in data // is a path. KEEP_SLASH = 1, }; std::string escape(std::string_view str, EscapeFlags flags = EscapeFlags::DEFAULT); void escape(std::string_view str, std::string& out, EscapeFlags flags = EscapeFlags::DEFAULT); std::string unescape(std::string_view str); void unescape(std::string_view str, std::string& out); constexpr EscapeFlags operator&(EscapeFlags a, EscapeFlags b) noexcept { using utype = typename std::underlying_type::type; return static_cast( static_cast(a) & static_cast(b)); } constexpr EscapeFlags operator|(EscapeFlags a, EscapeFlags b) noexcept { using utype = typename std::underlying_type::type; return static_cast( static_cast(a) | static_cast(b)); } constexpr EscapeFlags operator^(EscapeFlags a, EscapeFlags b) noexcept { using utype = typename std::underlying_type::type; return static_cast( static_cast(a) ^ static_cast(b)); } constexpr EscapeFlags operator~(EscapeFlags a) noexcept { using utype = typename std::underlying_type::type; return static_cast(~static_cast(a)); } void split_and_unescape_path_and_query( std::string_view url, std::string& path, std::unordered_map& query); std::unordered_map expand_and_unescape_query( std::string_view query); } // namespace url #endif // URLUTIL_HH