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
130
131
132
133
134
135
136
137
138
139
140
141
|
#ifndef NULLSOFT_AUTOURLH
#define NULLSOFT_AUTOURLH
#include <windows.h>
#include "AutoChar.h"
/* benski> i'm sure there's a nice optimized way of doing this, but I need to implement it _right now_ */
#define HEXCASE(d) case 0x##d: return #@d
inline char quickhex(unsigned char in)
{
switch (in)
{
HEXCASE(0);
HEXCASE(1);
HEXCASE(2);
HEXCASE(3);
HEXCASE(4);
HEXCASE(5);
HEXCASE(6);
HEXCASE(7);
HEXCASE(8);
HEXCASE(9);
HEXCASE(A);
HEXCASE(B);
HEXCASE(C);
HEXCASE(D);
HEXCASE(E);
HEXCASE(F);
}
return 0;
}
/* encodes a UTF-8 string into a buffer */
inline void AutoUrl_Encode(const char *in, char *out, size_t len)
{
if (!len)
return;
char *dest=out;
const unsigned char *src = (const unsigned char *)in;
while (*src && --len)
{
if ((*src >= 'A' && *src <= 'Z') ||
(*src >= 'a' && *src <= 'z') ||
(*src >= '0' && *src <= '9') || *src == '.' || *src == '_' || *src == '-' || *src == '~')
{
*dest++=*src++;
}
else if (len > 2)
{
int i = *src++;
*dest++ = '%';
int b = (i >> 4) & 15;
if (b < 10) *dest++ = (char)('0' + b);
else *dest++ = (char)('A' + b - 10);
b = i & 15;
if (b < 10) *dest++ = (char)('0' + b);
else *dest++ = (char)('A' + b - 10);
}
else
break;
}
*dest=0;
}
inline char *AutoUrlDupN(const wchar_t *convert, size_t len)
{
if (!convert)
return 0;
AutoCharN utf8(convert, len, CP_UTF8);
size_t size = strlen(utf8)*3+1; // one byte might get encoded to 3 bytes, so we'll malloc for worst-case
char *url= (char *)malloc(size*sizeof(char));
AutoUrl_Encode(utf8, url, size);
return url;
}
inline char *AutoUrlDup(const wchar_t *convert)
{
if (!convert)
return 0;
AutoChar utf8(convert, CP_UTF8);
size_t size = strlen(utf8)*3+1; // one byte might get encoded to 3 bytes, so we'll malloc for worst-case
char *url= (char *)malloc(size*sizeof(char));
AutoUrl_Encode(utf8, url, size);
return url;
}
inline char *AutoUrlDup(const char *utf8)
{
if (!utf8)
return 0;
size_t size = strlen(utf8)*3+1; // one byte might get encoded to 3 bytes, so we'll malloc for worst-case
char *url= (char *)malloc(size*sizeof(char));
AutoUrl_Encode(utf8, url, size);
return url;
}
class AutoUrl
{
public:
AutoUrl(const wchar_t *convert) : narrow(0)
{
narrow = AutoUrlDup(convert);
}
AutoUrl(const wchar_t *convert, size_t len) : narrow(0)
{
narrow = AutoUrlDupN(convert, len);
}
AutoUrl(const char *convert) : narrow(0)
{
narrow = AutoUrlDup(convert);
}
AutoUrl(const AutoUrl &convert) : narrow(0)
{
if (convert.narrow)
narrow = _strdup(convert.narrow);
}
~AutoUrl()
{
free(narrow);
narrow=0;
}
operator const char *()
{
return narrow;
}
operator char *()
{
return narrow;
}
private:
char *narrow;
};
#endif
|