/miranda/protocols/MSN/msn_libstr.cpp
C++ | 455 lines | 397 code | 37 blank | 21 comment | 89 complexity | 96e545975273f01a687770dc193235a2 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, LGPL-2.1
- /*
- Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
- Copyright (c) 2006-2014 Boris Krasnovskiy.
- Copyright (c) 2003-2005 George Hazan.
- Copyright (c) 2002-2003 Richard Hughes (original version).
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
- #include "msn_global.h"
-
- void replaceStr(char*& dest, const char* src)
- {
- if (src != NULL)
- {
- mir_free(dest);
- dest = mir_strdup(src);
- }
- }
-
- void replaceStr(wchar_t*& dest, const wchar_t* src)
- {
- if (src != NULL)
- {
- mir_free(dest);
- dest = mir_wstrdup(src);
- }
- }
-
- static TCHAR* a2tf(const TCHAR* str, bool unicode)
- {
- if (str == NULL)
- return NULL;
-
- return unicode ? mir_tstrdup(str) : mir_a2t((char*)str);
- }
-
- void overrideStr(TCHAR*& dest, const TCHAR* src, bool unicode, const TCHAR* def)
- {
- mir_free(dest);
- dest = NULL;
-
- if (src != NULL)
- dest = a2tf(src, unicode);
- else if (def != NULL)
- dest = mir_tstrdup(def);
- }
-
- char* __fastcall ltrimp(char* str)
- {
- if (str == NULL) return NULL;
- char* p = str;
-
- for (;;)
- {
- switch (*p)
- {
- case ' ': case '\t': case '\n': case '\r':
- ++p; break;
- default:
- return p;
- }
- }
- }
-
- char* __fastcall rtrim(char *string)
- {
- char* p = string + strlen(string) - 1;
-
- while (p >= string)
- {
- if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
- break;
-
- *p-- = 0;
- }
- return string;
- }
-
- wchar_t* __fastcall rtrim(wchar_t* string)
- {
- wchar_t* p = string + wcslen(string) - 1;
-
- while (p >= string)
- {
- if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
- break;
-
- *p-- = 0;
- }
- return string;
- }
-
- char* arrayToHex(BYTE* data, size_t datasz)
- {
- char* res = (char*)mir_alloc(2 * datasz + 1);
-
- char* resptr = res;
- for (unsigned i=0; i<datasz ; i++)
- {
- const BYTE ch = data[i];
-
- const char ch0 = ch >> 4;
- *resptr++ = (ch0 <= 9) ? ('0' + ch0) : (('a' - 10) + ch0);
-
- const char ch1 = ch & 0xF;
- *resptr++ = (ch1 <= 9) ? ('0' + ch1) : (('a' - 10) + ch1);
- }
- *resptr = '\0';
- return res;
- }
-
- bool txtParseParam (const char* szData, const char* presearch, const char* start, const char* finish, char* param, const int size)
- {
- const char *cp, *cp1;
- int len;
-
- if (szData == NULL) return false;
-
- if (presearch != NULL)
- {
- cp1 = strstr(szData, presearch);
- if (cp1 == NULL) return false;
- }
- else
- cp1 = szData;
-
- cp = strstr(cp1, start);
- if (cp == NULL) return false;
- cp += strlen(start);
- while (*cp == ' ') ++cp;
-
- if (finish)
- {
- cp1 = strstr(cp, finish);
- if (cp1 == NULL) return FALSE;
- while (*(cp1-1) == ' ' && cp1 > cp) --cp1;
- }
- else
- cp1 = strchr(cp, '\0');
-
- len = min(cp1 - cp, size - 1);
- memmove(param, cp, len);
- param[len] = 0;
-
- return true;
- }
-
- void parseWLID(char* wlid, char** net, char** email, char** inst)
- {
- char* col = strchr(wlid, ':');
- if (col && strncmp(wlid, "tel:", 4))
- {
- *col = 0;
- if (net) *net = wlid;
- if (email) *email = col + 1;
- ++col;
- }
- else
- {
- if (net) *net = NULL;
- if (email) *email = wlid;
- }
-
- col = strchr(wlid, ';');
- if (col)
- {
- *col = 0;
- if (inst) *inst = col + 1;
- }
- else
- if (inst) *inst = NULL;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////
- // UrlDecode - converts URL chars like %20 into printable characters
-
- static int SingleHexToDecimal(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;
- }
-
- template void UrlDecode(char* str);
- #ifdef _UNICODE
- template void UrlDecode(wchar_t* str);
- #endif
-
- template <class chartype> void UrlDecode(chartype* str)
- {
- chartype* s = str, *d = str;
-
- while(*s)
- {
- if (*s == '%')
- {
- int digit1 = SingleHexToDecimal(s[1]);
- if (digit1 != -1)
- {
- int digit2 = SingleHexToDecimal(s[2]);
- if (digit2 != -1)
- {
- s += 3;
- *d++ = (char)((digit1 << 4) | digit2);
- continue;
- }
- }
- }
- *d++ = *s++;
- }
-
- *d = 0;
- }
-
- void HtmlDecode(char* str)
- {
- char* p, *q;
-
- if (str == NULL)
- return;
-
- for (p=q=str; *p!='\0'; p++,q++)
- {
- if (*p == '&')
- {
- if (!strncmp(p, "&", 5)) { *q = '&'; p += 4; }
- else if (!strncmp(p, "'", 6)) { *q = '\''; p += 5; }
- else if (!strncmp(p, ">", 4)) { *q = '>'; p += 3; }
- else if (!strncmp(p, "<", 4)) { *q = '<'; p += 3; }
- else if (!strncmp(p, """, 6)) { *q = '"'; p += 5; }
- else { *q = *p; }
- }
- else
- {
- *q = *p;
- }
- }
- *q = '\0';
- }
-
- char* HtmlEncode(const char* str)
- {
- char* s, *p, *q;
- int c;
-
- if (str == NULL)
- return NULL;
-
- for (c=0,p=(char*)str; *p!='\0'; p++)
- {
- switch (*p)
- {
- case '&': c += 5; break;
- case '\'': c += 6; break;
- case '>': c += 4; break;
- case '<': c += 4; break;
- case '"': c += 6; break;
- default: c++; break;
- }
- }
- if ((s=(char*)mir_alloc(c+1)) != NULL)
- {
- for (p=(char*)str,q=s; *p!='\0'; p++)
- {
- switch (*p)
- {
- case '&': strcpy(q, "&"); q += 5; break;
- case '\'': strcpy(q, "'"); q += 6; break;
- case '>': strcpy(q, ">"); q += 4; break;
- case '<': strcpy(q, "<"); q += 4; break;
- case '"': strcpy(q, """); q += 6; break;
- default: *q = *p; q++; break;
- }
- }
- *q = '\0';
- }
-
- return s;
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////
- // UrlEncode - converts printable characters into URL chars like %20
-
- void UrlEncode(const char* src, char* dest, size_t cbDest)
- {
- unsigned char* d = (unsigned char*)dest;
- size_t i = 0;
-
- for (const unsigned char* s = (unsigned char*)src; *s; s++)
- {
- if ((*s <= '/' && *s != '.' && *s != '-') ||
- (*s >= ':' && *s <= '?') ||
- (*s >= '[' && *s <= '`' && *s != '_'))
- {
- if (i + 4 >= cbDest) break;
-
- *d++ = '%';
- _itoa(*s, (char*)d, 16);
- d += 2;
- i += 3;
- }
- else
- {
- if (++i >= cbDest) break;
- *d++ = *s;
- } }
-
- *d = '\0';
- }
-
-
- void stripBBCode(char* src)
- {
- bool tag = false;
- char* ps = src;
- char* pd = src;
-
- while (*ps != 0)
- {
- if (!tag && *ps == '[')
- {
- char ch = ps[1];
- if (ch == '/') ch = ps[2];
- tag = ch == 'b' || ch == 'u' || ch == 'i' || ch == 'c' || ch == 'a' || ch == 's';
- }
- if (!tag) *(pd++) = *ps;
- else tag = *ps != ']';
- ++ps;
- }
- *pd = 0;
- }
-
- void stripColorCode(char* src)
- {
- unsigned char* ps = (unsigned char*)src;
- unsigned char* pd = (unsigned char*)src;
-
- while (*ps != 0)
- {
- if (ps[0] == 0xc2 && ps[1] == 0xb7)
- {
- char ch = ps[2];
- switch (ch)
- {
- case '#':
- case '&':
- case '\'':
- case '@':
- case '0':
- ps += 3;
- continue;
-
- case '$':
- if (isdigit(ps[3]))
- {
- ps += 3;
- if (isdigit(ps[1]))
- {
- ps += 2;
- }
- else
- ++ps;
-
- if (ps[0] == ',' && isdigit(ps[1]))
- {
- ps += 2;
- if (isdigit(ps[1]))
- ps += 2;
- else
- ++ps;
- }
- continue;
- }
- else if (ps[3] == '#')
- {
- ps += 4;
- for (int i=0; i<6; ++i)
- if (isxdigit(*ps)) ++ps;
- else break;
- continue;
- }
- break;
- }
- }
- *(pd++) = *(ps++);
- }
- *pd = 0;
- }
-
- // Process a string, and double all % characters, according to chat.dll's restrictions
- // Returns a pointer to the new string (old one is not freed)
- TCHAR* EscapeChatTags(const TCHAR* pszText)
- {
- int nChars = 0;
- for (const TCHAR* p = pszText; (p = _tcschr(p, '%')) != NULL; p++)
- nChars++;
-
- if (nChars == 0)
- return mir_tstrdup(pszText);
-
- TCHAR *pszNewText = (TCHAR*)mir_alloc(sizeof(TCHAR)*(_tcslen(pszText) + 1 + nChars));
- if (pszNewText == NULL)
- return mir_tstrdup(pszText);
-
- const TCHAR *s = pszText;
- TCHAR *d = pszNewText;
- while (*s) {
- if (*s == '%')
- *d++ = '%';
- *d++ = *s++;
- }
- *d = 0;
- return pszNewText;
- }
-
- TCHAR* UnEscapeChatTags(TCHAR* str_in)
- {
- TCHAR *s = str_in, *d = str_in;
- while (*s) {
- if ((*s == '%' && s[1] == '%') || (*s == '\n' && s[1] == '\n'))
- s++;
- *d++ = *s++;
- }
- *d = 0;
- return str_in;
- }
-
- char* getNewUuid(void)
- {
- BYTE* p;
- UUID id;
-
- UuidCreate(&id);
- UuidToStringA(&id, &p);
- size_t len = strlen((char*)p) + 3;
- char* result = (char*)mir_alloc(len);
- mir_snprintf(result, len, "{%s}", p);
- _strupr(result);
- RpcStringFreeA(&p);
- return result;
- }
-