#include "Tactility/network/Url.h" #include namespace tt::network { std::map parseUrlQuery(std::string query) { std::map result; if (query.empty()) { return result; } size_t current_index = query[0] == '?' ? 1U : 0U; auto equals_index = query.find_first_of('=', current_index); while (equals_index != std::string::npos) { auto index_boundary = query.find_first_of('&', equals_index + 1); if (index_boundary == std::string::npos) { index_boundary = query.size(); } auto key = query.substr(current_index, (equals_index - current_index)); auto decodedKey = urlDecode(key); auto value = query.substr(equals_index + 1, (index_boundary - equals_index - 1)); auto decodedValue = urlDecode(value); result[decodedKey] = decodedValue; // Find next token current_index = index_boundary + 1; equals_index = query.find_first_of('=', current_index); } return result; } // Adapted from https://stackoverflow.com/a/29962178/3848666 std::string urlEncode(const std::string& input) { std::string result = ""; const char* characters = input.c_str(); char hex_buffer[10]; size_t input_length = input.length(); for (size_t i = 0;i < input_length;i++) { unsigned char c = characters[i]; // uncomment this if you want to encode spaces with + if (c==' ') { result += '+'; } else if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { result += c; } else { sprintf(hex_buffer, "%%%02X", c); //%% means '%' literal, %02X means at least two digits, paddable with a leading zero result += hex_buffer; } } return result; } // Adapted from https://stackoverflow.com/a/29962178/3848666 std::string urlDecode(const std::string& input) { std::string result; size_t conversion_buffer, input_length = input.length(); for (size_t i = 0; i < input_length; i++) { if (input[i] != '%') { if (input[i] == '+') { result += ' '; } else { result += input[i]; } } else { sscanf(input.substr(i + 1, 2).c_str(), "%x", &conversion_buffer); char c = static_cast(conversion_buffer); result += c; i = i + 2; } } return result; } } // namespace