连接器客户端
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
#include "encoding.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cctype>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace connector {
|
||||
|
||||
std::vector<std::uint8_t> decode_base64(const std::string& value) {
|
||||
static const std::string alphabet =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
std::array<int, 256> table{};
|
||||
table.fill(-1);
|
||||
for (std::size_t index = 0; index < alphabet.size(); ++index) {
|
||||
table[static_cast<unsigned char>(alphabet[index])] = static_cast<int>(index);
|
||||
}
|
||||
if (value.size() % 4 != 0) throw std::runtime_error("图片数据格式无效");
|
||||
std::vector<std::uint8_t> output;
|
||||
output.reserve(value.size() / 4 * 3);
|
||||
int accumulator = 0;
|
||||
int bits = -8;
|
||||
bool padding = false;
|
||||
for (const unsigned char c : value) {
|
||||
if (c == '=') {
|
||||
padding = true;
|
||||
continue;
|
||||
}
|
||||
if (padding || table[c] < 0) throw std::runtime_error("图片数据格式无效");
|
||||
accumulator = (accumulator << 6) | table[c];
|
||||
bits += 6;
|
||||
if (bits >= 0) {
|
||||
output.push_back(static_cast<std::uint8_t>((accumulator >> bits) & 0xff));
|
||||
bits -= 8;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
namespace {
|
||||
int hex_value(char c) {
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string url_decode(const std::string& value) {
|
||||
std::string output;
|
||||
output.reserve(value.size());
|
||||
for (std::size_t index = 0; index < value.size(); ++index) {
|
||||
if (value[index] == '+') {
|
||||
output.push_back(' ');
|
||||
} else if (value[index] == '%' && index + 2 < value.size()) {
|
||||
const int high = hex_value(value[index + 1]);
|
||||
const int low = hex_value(value[index + 2]);
|
||||
if (high < 0 || low < 0) throw std::runtime_error("URL 编码无效");
|
||||
output.push_back(static_cast<char>((high << 4) | low));
|
||||
index += 2;
|
||||
} else {
|
||||
output.push_back(value[index]);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string url_encode(const std::string& value) {
|
||||
std::ostringstream output;
|
||||
output << std::uppercase << std::hex;
|
||||
for (const unsigned char c : value) {
|
||||
if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
output << static_cast<char>(c);
|
||||
} else {
|
||||
output << '%' << std::setw(2) << std::setfill('0') << static_cast<int>(c);
|
||||
}
|
||||
}
|
||||
return output.str();
|
||||
}
|
||||
|
||||
std::string html_escape(const std::string& value) {
|
||||
std::string output;
|
||||
output.reserve(value.size());
|
||||
for (const char c : value) {
|
||||
switch (c) {
|
||||
case '&': output += "&"; break;
|
||||
case '<': output += "<"; break;
|
||||
case '>': output += ">"; break;
|
||||
case '"': output += """; break;
|
||||
case '\'': output += "'"; break;
|
||||
default: output.push_back(c);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string trim(const std::string& value) {
|
||||
std::size_t start = 0;
|
||||
while (start < value.size() && std::isspace(static_cast<unsigned char>(value[start]))) ++start;
|
||||
std::size_t end = value.size();
|
||||
while (end > start && std::isspace(static_cast<unsigned char>(value[end - 1]))) --end;
|
||||
return value.substr(start, end - start);
|
||||
}
|
||||
|
||||
} // namespace connector
|
||||
Reference in New Issue
Block a user