blob: 7e1b0e1fdff8eedbd7078e5e8536f5ea9cc73b61 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "fdict.h"
#include <string>
using namespace std;
Dict FD::dict_;
bool FD::frozen_ = false;
static int HexPairValue(const char * code) {
int value = 0;
const char * pch = code;
for (;;) {
int digit = *pch++;
if (digit >= '0' && digit <= '9') {
value += digit - '0';
}
else if (digit >= 'A' && digit <= 'F') {
value += digit - 'A' + 10;
}
else if (digit >= 'a' && digit <= 'f') {
value += digit - 'a' + 10;
}
else {
return -1;
}
if (pch == code + 2)
return value;
value <<= 4;
}
}
int UrlDecode(const char *source, char *dest)
{
char * start = dest;
while (*source) {
switch (*source) {
case '+':
*(dest++) = ' ';
break;
case '%':
if (source[1] && source[2]) {
int value = HexPairValue(source + 1);
if (value >= 0) {
*(dest++) = value;
source += 2;
}
else {
*dest++ = '?';
}
}
else {
*dest++ = '?';
}
break;
default:
*dest++ = *source;
}
source++;
}
*dest = 0;
return dest - start;
}
int UrlEncode(const char *source, char *dest, unsigned max) {
static const char *digits = "0123456789ABCDEF";
unsigned char ch;
unsigned len = 0;
char *start = dest;
while (len < max - 4 && *source)
{
ch = (unsigned char)*source;
if (*source == ' ') {
*dest++ = '+';
}
else if (strchr("=:;,_| %", ch)) {
*dest++ = '%';
*dest++ = digits[(ch >> 4) & 0x0F];
*dest++ = digits[ ch & 0x0F];
}
else {
*dest++ = *source;
}
source++;
}
*dest = 0;
return start - dest;
}
std::string UrlDecodeString(const std::string & encoded) {
const char * sz_encoded = encoded.c_str();
size_t needed_length = encoded.length();
for (const char * pch = sz_encoded; *pch; pch++) {
if (*pch == '%')
needed_length += 2;
}
needed_length += 10;
char stackalloc[64];
char * buf = needed_length > sizeof(stackalloc)/sizeof(*stackalloc) ?
(char *)malloc(needed_length) : stackalloc;
UrlDecode(encoded.c_str(), buf);
std::string result(buf);
if (buf != stackalloc) {
free(buf);
}
return result;
}
std::string UrlEncodeString(const std::string & decoded) {
const char * sz_decoded = decoded.c_str();
size_t needed_length = decoded.length() * 3 + 3;
char stackalloc[64];
char * buf = needed_length > sizeof(stackalloc)/sizeof(*stackalloc) ?
(char *)malloc(needed_length) : stackalloc;
UrlEncode(decoded.c_str(), buf, needed_length);
std::string result(buf);
if (buf != stackalloc) {
free(buf);
}
return result;
}
string FD::Escape(const string& s) {
return UrlEncodeString(s);
}
|