в частности, совершенно не нужно кодировать все эти русские символы из utf в %XX, это безумие
...
вставил короче urlencode, хрен с ним
А если кодировать в urlencode только служебные символы с кодами меньше 127? Я у себя в скриптах всегда так делаю, и обычно работает суперски. На сколько я вижу по коду, urlencode у вас не кодирует только небольшой набор символов:
for (outputLen = 0, s = (const BYTE*)szUrl; *s; s++) {
if (('0' <= *s && *s <= '9') || //0-9
('A' <= *s && *s <= 'Z') || //ABC...XYZ
('a' <= *s && *s <= 'z') || //abc...xyz
*s == '-' || *s == '_' || *s == '.' || *s == ' ') outputLen++;
else outputLen += 3;
}
Понимаю, что такое поведение не по RFC и бла-бла-бла, но веб-сервера отлично обрабатывают все данные в UTF-8, где все юникодные символы с кодом больше 127 никак не закодированы и представлены как есть. На сколько я вижу, эта функция работает строго с однобайтовым массивом, поэтому можно просто проверять первый бит — если он равен единице, значит кодировать не нужно. Любой юникодный символ с кодом больше 127 в каждом своём байте будет иметь первый бит установленный в единицу, поэтому это будет работать как надо.
Получится по идее что-то типа такого (извиняюсь, что не diff, добавил пару строк с условиями, не тестировал):
MIR_CORE_DLL(char*) mir_urlEncode(const char *szUrl, bool strict = false)
{
if (szUrl == NULL)
return NULL;
const BYTE *s;
int outputLen;
for (outputLen = 0, s = (const BYTE*)szUrl; *s; s++) {
if ((*s & 0x80 && !strict) || // UTF-8 multibyte
('0' <= *s && *s <= '9') || //0-9
('A' <= *s && *s <= 'Z') || //ABC...XYZ
('a' <= *s && *s <= 'z') || //abc...xyz
*s == '~' || *s == '-' || *s == '_' || *s == '.' || *s == ' ') outputLen++;
else outputLen += 3;
}
char *szOutput = (char*)mir_alloc(outputLen+1);
if (szOutput == NULL)
return NULL;
char *d = szOutput;
for (s = (const BYTE*)szUrl; *s; s++) {
if ((*s & 0x80 && !strict) || // UTF-8 multibyte
('0' <= *s && *s <= '9') || //0-9
('A' <= *s && *s <= 'Z') || //ABC...XYZ
('a' <= *s && *s <= 'z') || //abc...xyz
*s == '~' || *s == '-' || *s == '_' || *s == '.') *d++ = *s;
else if (*s == ' ') *d++='+';
else {
*d++ = '%';
*d++ = szHexDigits[*s >> 4];
*d++ = szHexDigits[*s & 0xF];
}
}
*d = '\0';
return szOutput;
}
Параметр strict на случай, если вдруг где-то понадобится кодировать все юникодные символы. Но вообще по идее должно и так работать. А ещё можно для красоты переименовать функцию в mir_url_encode

По RFC, кстати, можно смело не кодировать ещё и тильду ~, тож добавил в код
