summaryrefslogtreecommitdiff
path: root/protocols/MSN/msn_libstr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/MSN/msn_libstr.cpp')
-rw-r--r--protocols/MSN/msn_libstr.cpp455
1 files changed, 455 insertions, 0 deletions
diff --git a/protocols/MSN/msn_libstr.cpp b/protocols/MSN/msn_libstr.cpp
new file mode 100644
index 0000000000..f12c3e25fd
--- /dev/null
+++ b/protocols/MSN/msn_libstr.cpp
@@ -0,0 +1,455 @@
+/*
+Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
+Copyright (c) 2006-2012 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, "&amp;", 5)) { *q = '&'; p += 4; }
+ else if (!strncmp(p, "&apos;", 6)) { *q = '\''; p += 5; }
+ else if (!strncmp(p, "&gt;", 4)) { *q = '>'; p += 3; }
+ else if (!strncmp(p, "&lt;", 4)) { *q = '<'; p += 3; }
+ else if (!strncmp(p, "&quot;", 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, "&amp;"); q += 5; break;
+ case '\'': strcpy(q, "&apos;"); q += 6; break;
+ case '>': strcpy(q, "&gt;"); q += 4; break;
+ case '<': strcpy(q, "&lt;"); q += 4; break;
+ case '"': strcpy(q, "&quot;"); 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;
+}
+