diff options
author | Robert Pösel <robyer@seznam.cz> | 2016-12-03 10:11:26 +0100 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2016-12-03 10:11:26 +0100 |
commit | a5d5de36daa8a810784f0e14a40ccb72bf6c8faf (patch) | |
tree | 58bfee182fb1dd55f6b1582a63148b5cbd34f889 /protocols/SkypeWeb/src | |
parent | 563ccc952ef6cd57642b958ef8753e1cc8bba1a0 (diff) |
SkypeWeb: Decode numeric html entities (fixes #639)
Code taken from 'utils\std_string_utils.cpp'. We should combine both codes and move the better / more effective code to the mentioned file so more plugins can share it.
Diffstat (limited to 'protocols/SkypeWeb/src')
-rw-r--r-- | protocols/SkypeWeb/src/skype_utils.cpp | 1194 |
1 files changed, 621 insertions, 573 deletions
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp index 41d01665b8..5bdc3eab4a 100644 --- a/protocols/SkypeWeb/src/skype_utils.cpp +++ b/protocols/SkypeWeb/src/skype_utils.cpp @@ -1,574 +1,622 @@ -/*
-Copyright (c) 2015-16 Miranda NG project (http://miranda-ng.org)
-
-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 version 2
-of the License.
-
-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 "stdafx.h"
-
-#pragma warning(disable:4566)
-
-time_t CSkypeProto::IsoToUnixTime(const char *stamp)
-{
- char date[9];
- int i, y;
-
- if (stamp == NULL)
- return 0;
-
- char *p = NEWSTR_ALLOCA(stamp);
-
- // skip '-' chars
- int si = 0, sj = 0;
- while (true) {
- if (p[si] == '-')
- si++;
- else if (!(p[sj++] = p[si++]))
- break;
- }
-
- // Get the date part
- for (i = 0; *p != '\0' && i < 8 && isdigit(*p); p++, i++)
- date[i] = *p;
-
- // Parse year
- if (i == 6) {
- // 2-digit year (1970-2069)
- y = (date[0] - '0') * 10 + (date[1] - '0');
- if (y < 70) y += 100;
- }
- else if (i == 8) {
- // 4-digit year
- y = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0';
- y -= 1900;
- }
- else return 0;
-
- struct tm timestamp;
- timestamp.tm_year = y;
-
- // Parse month
- timestamp.tm_mon = (date[i - 4] - '0') * 10 + date[i - 3] - '0' - 1;
-
- // Parse date
- timestamp.tm_mday = (date[i - 2] - '0') * 10 + date[i - 1] - '0';
-
- // Skip any date/time delimiter
- for (; *p != '\0' && !isdigit(*p); p++);
-
- // Parse time
- if (sscanf(p, "%d:%d:%d", ×tamp.tm_hour, ×tamp.tm_min, ×tamp.tm_sec) != 3)
- return (time_t)0;
-
- timestamp.tm_isdst = 0; // DST is already present in _timezone below
- time_t t = mktime(×tamp);
-
- _tzset();
- t -= _timezone;
- return (t >= 0) ? t : 0;
-}
-
-struct HtmlEntity
-{
- const char *entity;
- const char *symbol;
-};
-
-const HtmlEntity htmlEntities[] =
-{
- { "AElig", "\u00C6" },
- { "Aacute", "\u00C1" },
- { "Acirc", "\u00C2" },
- { "Agrave", "\u00C0" },
- { "Alpha", "\u0391" },
- { "Aring", "\u00C5" },
- { "Atilde", "\u00C3" },
- { "Auml", "\u00C4" },
- { "Beta", "\u0392" },
- { "Ccedil", "\u00C7" },
- { "Chi", "\u03A7" },
- { "Dagger", "‡" },
- { "Delta", "\u0394" },
- { "ETH", "\u00D0" },
- { "Eacute", "\u00C9" },
- { "Ecirc", "\u00CA" },
- { "Egrave", "\u00C8" },
- { "Epsilon", "\u0395" },
- { "Eta", "\u0397" },
- { "Euml", "\u00CB" },
- { "Gamma", "\u0393" },
- { "Iacute", "\u00CD" },
- { "Icirc", "\u00CE" },
- { "Igrave", "\u00CC" },
- { "Iota", "\u0399" },
- { "Iuml", "\u00CF" },
- { "Kappa", "\u039A" },
- { "Lambda", "\u039B" },
- { "Mu", "\u039C" },
- { "Ntilde", "\u00D1" },
- { "Nu", "\u039D" },
- { "OElig", "\u0152" },
- { "Oacute", "\u00D3" },
- { "Ocirc", "\u00D4" },
- { "Ograve", "\u00D2" },
- { "Omega", "\u03A9" },
- { "Omicron", "\u039F" },
- { "Oslash", "\u00D8" },
- { "Otilde", "\u00D5" },
- { "Ouml", "\u00D6" },
- { "Phi", "\u03A6" },
- { "Pi", "\u03A0" },
- { "Prime", "\u2033" },
- { "Psi", "\u03A8" },
- { "Rho", "\u03A1" },
- { "Scaron", "Š" },
- { "Sigma", "Σ" },
- { "THORN", "Þ" },
- { "Tau", "Τ" },
- { "Theta", "Θ" },
- { "Uacute", "Ú" },
- { "Ucirc", "Û" },
- { "Ugrave", "Ù" },
- { "Upsilon", "Υ" },
- { "Uuml", "Ü" },
- { "Xi", "Ξ" },
- { "Yacute", "Ý" },
- { "Yuml", "Ÿ" },
- { "Zeta", "Ζ" },
- { "aacute", "á" },
- { "acirc", "â" },
- { "acute", "´" },
- { "aelig", "æ" },
- { "agrave", "à" },
- { "alefsym", "ℵ" },
- { "alpha", "α" },
- { "amp", "&" },
- { "and", "∧" },
- { "ang", "∠" },
- { "apos", "'" },
- { "aring", "å" },
- { "asymp", "≈" },
- { "atilde", "ã" },
- { "auml", "ä" },
- { "bdquo", "„" },
- { "beta", "β" },
- { "brvbar", "¦" },
- { "bull", "•" },
- { "cap", "∩" },
- { "ccedil", "ç" },
- { "cedil", "¸" },
- { "cent", "¢" },
- { "chi", "χ" },
- { "circ", "ˆ" },
- { "clubs", "♣" },
- { "cong", "≅" },
- { "copy", "©" },
- { "crarr", "↵" },
- { "cup", "∪" },
- { "curren", "¤" },
- { "dArr", "⇓" },
- { "dagger", "†" },
- { "darr", "↓" },
- { "deg", "°" },
- { "delta", "δ" },
- { "diams", "♦" },
- { "divide", "÷" },
- { "eacute", "é" },
- { "ecirc", "ê" },
- { "egrave", "è" },
- { "empty", "∅" },
- { "emsp", " " },
- { "ensp", " " },
- { "epsilon", "ε" },
- { "equiv", "≡" },
- { "eta", "η" },
- { "eth", "ð" },
- { "euml", "ë" },
- { "euro", "€" },
- { "exist", "∃" },
- { "fnof", "ƒ" },
- { "forall", "∀" },
- { "frac12", "½" },
- { "frac14", "¼" },
- { "frac34", "¾" },
- { "frasl", "⁄" },
- { "gamma", "γ" },
- { "ge", "≥" },
- { "gt", ">" },
- { "hArr", "⇔" },
- { "harr", "↔" },
- { "hearts", "♥" },
- { "hellip", "…" },
- { "iacute", "í" },
- { "icirc", "î" },
- { "iexcl", "¡" },
- { "igrave", "ì" },
- { "image", "ℑ" },
- { "infin", "∞" },
- { "int", "∫" },
- { "iota", "ι" },
- { "iquest", "¿" },
- { "isin", "∈" },
- { "iuml", "ï" },
- { "kappa", "κ" },
- { "lArr", "⇐" },
- { "lambda", "λ" },
- { "lang", "〈" },
- { "laquo", "«" },
- { "larr", "←" },
- { "lceil", "⌈" },
- { "ldquo", "“" },
- { "le", "≤" },
- { "lfloor", "⌊" },
- { "lowast", "∗" },
- { "loz", "◊" },
- { "lrm", "\xE2\x80\x8E" },
- { "lsaquo", "‹" },
- { "lsquo", "‘" },
- { "lt", "<" },
- { "macr", "¯" },
- { "mdash", "—" },
- { "micro", "µ" },
- { "middot", "·" },
- { "minus", "−" },
- { "mu", "μ" },
- { "nabla", "∇" },
- { "nbsp", " " },
- { "ndash", "–" },
- { "ne", "≠" },
- { "ni", "∋" },
- { "not", "¬" },
- { "notin", "∉" },
- { "nsub", "⊄" },
- { "ntilde", "ñ" },
- { "nu", "ν" },
- { "oacute", "ó" },
- { "ocirc", "ô" },
- { "oelig", "œ" },
- { "ograve", "ò" },
- { "oline", "‾" },
- { "omega", "ω" },
- { "omicron", "ο" },
- { "oplus", "⊕" },
- { "or", "∨" },
- { "ordf", "ª" },
- { "ordm", "º" },
- { "oslash", "ø" },
- { "otilde", "õ" },
- { "otimes", "⊗" },
- { "ouml", "ö" },
- { "para", "¶" },
- { "part", "∂" },
- { "permil", "‰" },
- { "perp", "⊥" },
- { "phi", "φ" },
- { "pi", "π" },
- { "piv", "ϖ" },
- { "plusmn", "±" },
- { "pound", "£" },
- { "prime", "′" },
- { "prod", "∏" },
- { "prop", "∝" },
- { "psi", "ψ" },
- { "quot", "\"" },
- { "rArr", "⇒" },
- { "radic", "√" },
- { "rang", "〉" },
- { "raquo", "»" },
- { "rarr", "→" },
- { "rceil", "⌉" },
- { "rdquo", "”" },
- { "real", "ℜ" },
- { "reg", "®" },
- { "rfloor", "⌋" },
- { "rho", "ρ" },
- { "rlm", "\xE2\x80\x8F" },
- { "rsaquo", "›" },
- { "rsquo", "’" },
- { "sbquo", "‚" },
- { "scaron", "š" },
- { "sdot", "⋅" },
- { "sect", "§" },
- { "shy", "\xC2\xAD" },
- { "sigma", "σ" },
- { "sigmaf", "ς" },
- { "sim", "∼" },
- { "spades", "♠" },
- { "sub", "⊂" },
- { "sube", "⊆" },
- { "sum", "∑" },
- { "sup", "⊃" },
- { "sup1", "¹" },
- { "sup2", "²" },
- { "sup3", "³" },
- { "supe", "⊇" },
- { "szlig", "ß" },
- { "tau", "τ" },
- { "there4", "∴" },
- { "theta", "θ" },
- { "thetasym", "ϑ" },
- { "thinsp", " " },
- { "thorn", "þ" },
- { "tilde", "˜" },
- { "times", "×" },
- { "trade", "™" },
- { "uArr", "⇑" },
- { "uacute", "ú" },
- { "uarr", "↑" },
- { "ucirc", "û" },
- { "ugrave", "ù" },
- { "uml", "¨" },
- { "upsih", "ϒ" },
- { "upsilon", "υ" },
- { "uuml", "ü" },
- { "weierp", "℘" },
- { "xi", "ξ" },
- { "yacute", "ý" },
- { "yen", "¥" },
- { "yuml", "ÿ" },
- { "zeta", "ζ" },
- { "zwj", "\xE2\x80\x8D" },
- { "zwnj", "\xE2\x80\x8C" }
-};
-
-char *CSkypeProto::RemoveHtml(const char *text)
-{
- std::string new_string = "";
- std::string data = text;
-
- for (std::string::size_type i = 0; i < data.length(); i++)
- {
- if (data.at(i) == '<')
- {
- i = data.find(">", i);
- if (i == std::string::npos)
- break;
-
- continue;
- }
-
- if (data.at(i) == '&') {
- std::string::size_type begin = i;
- i = data.find(";", i);
- if (i == std::string::npos) {
- i = begin;
- }
- else {
- std::string entity = data.substr(begin + 1, i - begin - 1);
-
- bool found = false;
- for (int j = 0; j < _countof(htmlEntities); j++)
- {
- if (!mir_strcmpi(entity.c_str(), htmlEntities[j].entity))
- {
- new_string += htmlEntities[j].symbol;
- found = true;
- break;
- }
- }
-
- if (found)
- continue;
- else
- i = begin;
- }
- }
-
- new_string += data.at(i);
- }
-
- return mir_strdup(new_string.c_str());
-}
-
-const char *CSkypeProto::MirandaToSkypeStatus(int status)
-{
- switch (status)
- {
- case ID_STATUS_AWAY:
- return "Away";
-
- case ID_STATUS_DND:
- return "Busy";
-
- case ID_STATUS_IDLE:
- return "Idle";
-
- case ID_STATUS_INVISIBLE:
- return "Hidden";
- }
- return "Online";
-}
-
-int CSkypeProto::SkypeToMirandaStatus(const char *status)
-{
- if (!mir_strcmpi(status, "Online"))
- return ID_STATUS_ONLINE;
- else if (!mir_strcmpi(status, "Hidden"))
- return ID_STATUS_INVISIBLE;
- else if (!mir_strcmpi(status, "Away"))
- return ID_STATUS_AWAY;
- else if (!mir_strcmpi(status, "Idle"))
- return /*ID_STATUS_IDLE*/ID_STATUS_AWAY;
- else if (!mir_strcmpi(status, "Busy"))
- return ID_STATUS_DND;
- else
- return ID_STATUS_OFFLINE;
-}
-
-bool CSkypeProto::IsFileExists(std::wstring path)
-{
- return _waccess(path.c_str(), 0) == 0;
-}
-
-// url parsing
-
-CMStringA CSkypeProto::ParseUrl(const char *url, const char *token)
-{
- const char *start = strstr(url, token);
- if (start == NULL)
- return CMStringA();
-
- start = start + mir_strlen(token);
- const char *end = strchr(start, '/');
- if (end == NULL)
- return CMStringA(start);
- return CMStringA(start, end - start);
-}
-
-CMStringA CSkypeProto::GetStringChunk(const char *haystack, const char *start, const char *end)
-{
- const char *sstart = strstr(haystack, start);
- if (sstart == NULL)
- return CMStringA();
-
- sstart = sstart + mir_strlen(start);
- const char *send = strstr(sstart, end);
- if (send == NULL)
- return CMStringA(sstart);
- return CMStringA(sstart, send - sstart);
-}
-
-CMStringA CSkypeProto::UrlToSkypename(const char *url)
-{
- CMStringA szResult;
-
- if (strstr(url, "/1:"))
- szResult = ParseUrl(url, "/1:");
- else if (strstr(url, "/8:"))
- szResult = ParseUrl(url, "/8:");
- else if (strstr(url, "/19:"))
- szResult = ParseUrl(url, "/19:");
-
- return szResult;
-}
-
-CMStringA CSkypeProto::GetServerFromUrl(const char *url)
-{
- return ParseUrl(url, "://");
-}
-
-INT_PTR CSkypeProto::ParseSkypeUriService(WPARAM, LPARAM lParam)
-{
- wchar_t *arg = (wchar_t *)lParam;
- if (arg == NULL)
- return 1;
-
- // skip leading prefix
- wchar_t szUri[1024];
- wcsncpy_s(szUri, arg, _TRUNCATE);
- wchar_t *szJid = wcschr(szUri, ':');
- if (szJid == NULL)
- return 1;
-
- // empty jid?
- if (!*szJid)
- return 1;
-
- // command code
- wchar_t *szCommand = szJid;
- szCommand = wcschr(szCommand, '?');
- if (szCommand)
- *(szCommand++) = 0;
-
- // parameters
- wchar_t *szSecondParam = szCommand ? wcschr(szCommand, '&') : NULL;
- if (szSecondParam)
- *(szSecondParam++) = 0;
-
- // no command or message command
- if (!szCommand || (szCommand && !mir_wstrcmpi(szCommand, L"chat")))
- {
- if (szSecondParam)
- {
- wchar_t *szChatId = wcsstr(szSecondParam, L"id=");
- if (szChatId)
- {
- szChatId += 5;
- StartChatRoom(szChatId, szChatId);
- return 0;
- }
- }
- MCONTACT hContact = AddContact(_T2A(szJid), true);
- CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, NULL);
- return 0;
- }
- else if (!mir_wstrcmpi(szCommand, L"call"))
- {
- MCONTACT hContact = AddContact(_T2A(szJid), true);
- NotifyEventHooks(g_hCallEvent, (WPARAM)hContact, (LPARAM)0);
- return 0;
- }
- else if (!mir_wstrcmpi(szCommand, L"userinfo")){ return 0; }
- else if (!mir_wstrcmpi(szCommand, L"add"))
- {
- MCONTACT hContact = FindContact(_T2A(szJid));
- if (hContact == NULL)
- {
- PROTOSEARCHRESULT psr = { 0 };
- psr.cbSize = sizeof(psr);
- psr.id.w = mir_wstrdup(szJid);
- psr.nick.w = mir_wstrdup(szJid);
- psr.flags = PSR_UNICODE;
-
- ADDCONTACTSTRUCT acs = { 0 };
- acs.handleType = HANDLE_SEARCHRESULT;
- acs.szProto = m_szModuleName;
- acs.psr = &psr;
-
- CallService(MS_ADDCONTACT_SHOW, 0, (LPARAM)&acs);
- }
- return 0;
- }
- if (!mir_wstrcmpi(szCommand, L"sendfile"))
- {
- MCONTACT hContact = AddContact(_T2A(szJid), true);
- CallService(MS_FILE_SENDFILE, hContact, NULL);
- return 1;
- }
- if (!mir_wstrcmpi(szCommand, L"voicemail"))
- {
- return 1;
- }
- return 1;
-}
-
-INT_PTR CSkypeProto::GlobalParseSkypeUriService(WPARAM wParam, LPARAM lParam)
-{
- mir_cslock lck(accountsLock);
- for (int i = 0; i < Accounts.getCount(); i++)
- if (Accounts[i]->IsOnline())
- return Accounts[i]->ParseSkypeUriService(wParam, lParam);
-
- return 1;
+/* +Copyright (c) 2015-16 Miranda NG project (http://miranda-ng.org) + +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 version 2 +of the License. + +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 "stdafx.h" + +#pragma warning(disable:4566) + +time_t CSkypeProto::IsoToUnixTime(const char *stamp) +{ + char date[9]; + int i, y; + + if (stamp == NULL) + return 0; + + char *p = NEWSTR_ALLOCA(stamp); + + // skip '-' chars + int si = 0, sj = 0; + while (true) { + if (p[si] == '-') + si++; + else if (!(p[sj++] = p[si++])) + break; + } + + // Get the date part + for (i = 0; *p != '\0' && i < 8 && isdigit(*p); p++, i++) + date[i] = *p; + + // Parse year + if (i == 6) { + // 2-digit year (1970-2069) + y = (date[0] - '0') * 10 + (date[1] - '0'); + if (y < 70) y += 100; + } + else if (i == 8) { + // 4-digit year + y = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0'; + y -= 1900; + } + else return 0; + + struct tm timestamp; + timestamp.tm_year = y; + + // Parse month + timestamp.tm_mon = (date[i - 4] - '0') * 10 + date[i - 3] - '0' - 1; + + // Parse date + timestamp.tm_mday = (date[i - 2] - '0') * 10 + date[i - 1] - '0'; + + // Skip any date/time delimiter + for (; *p != '\0' && !isdigit(*p); p++); + + // Parse time + if (sscanf(p, "%d:%d:%d", ×tamp.tm_hour, ×tamp.tm_min, ×tamp.tm_sec) != 3) + return (time_t)0; + + timestamp.tm_isdst = 0; // DST is already present in _timezone below + time_t t = mktime(×tamp); + + _tzset(); + t -= _timezone; + return (t >= 0) ? t : 0; +} + +struct HtmlEntity +{ + const char *entity; + const char *symbol; +}; + +const HtmlEntity htmlEntities[] = +{ + { "AElig", "\u00C6" }, + { "Aacute", "\u00C1" }, + { "Acirc", "\u00C2" }, + { "Agrave", "\u00C0" }, + { "Alpha", "\u0391" }, + { "Aring", "\u00C5" }, + { "Atilde", "\u00C3" }, + { "Auml", "\u00C4" }, + { "Beta", "\u0392" }, + { "Ccedil", "\u00C7" }, + { "Chi", "\u03A7" }, + { "Dagger", "‡" }, + { "Delta", "\u0394" }, + { "ETH", "\u00D0" }, + { "Eacute", "\u00C9" }, + { "Ecirc", "\u00CA" }, + { "Egrave", "\u00C8" }, + { "Epsilon", "\u0395" }, + { "Eta", "\u0397" }, + { "Euml", "\u00CB" }, + { "Gamma", "\u0393" }, + { "Iacute", "\u00CD" }, + { "Icirc", "\u00CE" }, + { "Igrave", "\u00CC" }, + { "Iota", "\u0399" }, + { "Iuml", "\u00CF" }, + { "Kappa", "\u039A" }, + { "Lambda", "\u039B" }, + { "Mu", "\u039C" }, + { "Ntilde", "\u00D1" }, + { "Nu", "\u039D" }, + { "OElig", "\u0152" }, + { "Oacute", "\u00D3" }, + { "Ocirc", "\u00D4" }, + { "Ograve", "\u00D2" }, + { "Omega", "\u03A9" }, + { "Omicron", "\u039F" }, + { "Oslash", "\u00D8" }, + { "Otilde", "\u00D5" }, + { "Ouml", "\u00D6" }, + { "Phi", "\u03A6" }, + { "Pi", "\u03A0" }, + { "Prime", "\u2033" }, + { "Psi", "\u03A8" }, + { "Rho", "\u03A1" }, + { "Scaron", "Š" }, + { "Sigma", "Σ" }, + { "THORN", "Þ" }, + { "Tau", "Τ" }, + { "Theta", "Θ" }, + { "Uacute", "Ú" }, + { "Ucirc", "Û" }, + { "Ugrave", "Ù" }, + { "Upsilon", "Υ" }, + { "Uuml", "Ü" }, + { "Xi", "Ξ" }, + { "Yacute", "Ý" }, + { "Yuml", "Ÿ" }, + { "Zeta", "Ζ" }, + { "aacute", "á" }, + { "acirc", "â" }, + { "acute", "´" }, + { "aelig", "æ" }, + { "agrave", "à" }, + { "alefsym", "ℵ" }, + { "alpha", "α" }, + { "amp", "&" }, + { "and", "∧" }, + { "ang", "∠" }, + { "apos", "'" }, + { "aring", "å" }, + { "asymp", "≈" }, + { "atilde", "ã" }, + { "auml", "ä" }, + { "bdquo", "„" }, + { "beta", "β" }, + { "brvbar", "¦" }, + { "bull", "•" }, + { "cap", "∩" }, + { "ccedil", "ç" }, + { "cedil", "¸" }, + { "cent", "¢" }, + { "chi", "χ" }, + { "circ", "ˆ" }, + { "clubs", "♣" }, + { "cong", "≅" }, + { "copy", "©" }, + { "crarr", "↵" }, + { "cup", "∪" }, + { "curren", "¤" }, + { "dArr", "⇓" }, + { "dagger", "†" }, + { "darr", "↓" }, + { "deg", "°" }, + { "delta", "δ" }, + { "diams", "♦" }, + { "divide", "÷" }, + { "eacute", "é" }, + { "ecirc", "ê" }, + { "egrave", "è" }, + { "empty", "∅" }, + { "emsp", " " }, + { "ensp", " " }, + { "epsilon", "ε" }, + { "equiv", "≡" }, + { "eta", "η" }, + { "eth", "ð" }, + { "euml", "ë" }, + { "euro", "€" }, + { "exist", "∃" }, + { "fnof", "ƒ" }, + { "forall", "∀" }, + { "frac12", "½" }, + { "frac14", "¼" }, + { "frac34", "¾" }, + { "frasl", "⁄" }, + { "gamma", "γ" }, + { "ge", "≥" }, + { "gt", ">" }, + { "hArr", "⇔" }, + { "harr", "↔" }, + { "hearts", "♥" }, + { "hellip", "…" }, + { "iacute", "í" }, + { "icirc", "î" }, + { "iexcl", "¡" }, + { "igrave", "ì" }, + { "image", "ℑ" }, + { "infin", "∞" }, + { "int", "∫" }, + { "iota", "ι" }, + { "iquest", "¿" }, + { "isin", "∈" }, + { "iuml", "ï" }, + { "kappa", "κ" }, + { "lArr", "⇐" }, + { "lambda", "λ" }, + { "lang", "〈" }, + { "laquo", "«" }, + { "larr", "←" }, + { "lceil", "⌈" }, + { "ldquo", "“" }, + { "le", "≤" }, + { "lfloor", "⌊" }, + { "lowast", "∗" }, + { "loz", "◊" }, + { "lrm", "\xE2\x80\x8E" }, + { "lsaquo", "‹" }, + { "lsquo", "‘" }, + { "lt", "<" }, + { "macr", "¯" }, + { "mdash", "—" }, + { "micro", "µ" }, + { "middot", "·" }, + { "minus", "−" }, + { "mu", "μ" }, + { "nabla", "∇" }, + { "nbsp", " " }, + { "ndash", "–" }, + { "ne", "≠" }, + { "ni", "∋" }, + { "not", "¬" }, + { "notin", "∉" }, + { "nsub", "⊄" }, + { "ntilde", "ñ" }, + { "nu", "ν" }, + { "oacute", "ó" }, + { "ocirc", "ô" }, + { "oelig", "œ" }, + { "ograve", "ò" }, + { "oline", "‾" }, + { "omega", "ω" }, + { "omicron", "ο" }, + { "oplus", "⊕" }, + { "or", "∨" }, + { "ordf", "ª" }, + { "ordm", "º" }, + { "oslash", "ø" }, + { "otilde", "õ" }, + { "otimes", "⊗" }, + { "ouml", "ö" }, + { "para", "¶" }, + { "part", "∂" }, + { "permil", "‰" }, + { "perp", "⊥" }, + { "phi", "φ" }, + { "pi", "π" }, + { "piv", "ϖ" }, + { "plusmn", "±" }, + { "pound", "£" }, + { "prime", "′" }, + { "prod", "∏" }, + { "prop", "∝" }, + { "psi", "ψ" }, + { "quot", "\"" }, + { "rArr", "⇒" }, + { "radic", "√" }, + { "rang", "〉" }, + { "raquo", "»" }, + { "rarr", "→" }, + { "rceil", "⌉" }, + { "rdquo", "”" }, + { "real", "ℜ" }, + { "reg", "®" }, + { "rfloor", "⌋" }, + { "rho", "ρ" }, + { "rlm", "\xE2\x80\x8F" }, + { "rsaquo", "›" }, + { "rsquo", "’" }, + { "sbquo", "‚" }, + { "scaron", "š" }, + { "sdot", "⋅" }, + { "sect", "§" }, + { "shy", "\xC2\xAD" }, + { "sigma", "σ" }, + { "sigmaf", "ς" }, + { "sim", "∼" }, + { "spades", "♠" }, + { "sub", "⊂" }, + { "sube", "⊆" }, + { "sum", "∑" }, + { "sup", "⊃" }, + { "sup1", "¹" }, + { "sup2", "²" }, + { "sup3", "³" }, + { "supe", "⊇" }, + { "szlig", "ß" }, + { "tau", "τ" }, + { "there4", "∴" }, + { "theta", "θ" }, + { "thetasym", "ϑ" }, + { "thinsp", " " }, + { "thorn", "þ" }, + { "tilde", "˜" }, + { "times", "×" }, + { "trade", "™" }, + { "uArr", "⇑" }, + { "uacute", "ú" }, + { "uarr", "↑" }, + { "ucirc", "û" }, + { "ugrave", "ù" }, + { "uml", "¨" }, + { "upsih", "ϒ" }, + { "upsilon", "υ" }, + { "uuml", "ü" }, + { "weierp", "℘" }, + { "xi", "ξ" }, + { "yacute", "ý" }, + { "yen", "¥" }, + { "yuml", "ÿ" }, + { "zeta", "ζ" }, + { "zwj", "\xE2\x80\x8D" }, + { "zwnj", "\xE2\x80\x8C" } +}; + +char *CSkypeProto::RemoveHtml(const char *text) +{ + std::string new_string = ""; + std::string data = text; + + for (std::string::size_type i = 0; i < data.length(); i++) + { + if (data.at(i) == '<') + { + i = data.find(">", i); + if (i == std::string::npos) + break; + + continue; + } + + if (data.at(i) == '&') + { + std::string::size_type begin = i; + i = data.find(";", i); + if (i == std::string::npos) + { + i = begin; + } + else { + std::string entity = data.substr(begin + 1, i - begin - 1); + + bool found = false; + if (entity.length() > 1 && entity.at(0) == '#') + { + // Numeric replacement + bool hex = false; + if (data.at(1) == 'x') + { + hex = true; + entity = entity.substr(2); + } + else + { + entity = entity.substr(1); + } + if (!entity.empty()) + { + unsigned long value = strtoul(entity.c_str(), NULL, hex ? 16 : 10); + + if (value <= 127) + { // U+0000 .. U+007F + new_string += (char)value; + } + else if (value >= 128 && value <= 2047) + { // U+0080 .. U+07FF + new_string += (char)(192 + (value / 64)); + new_string += (char)(128 + (value % 64)); + } + else if (value >= 2048 && value <= 65535) + { // U+0800 .. U+FFFF + new_string += (char)(224 + (value / 4096)); + new_string += (char)(128 + ((value / 64) % 64)); + new_string += (char)(128 + (value % 64)); + } + else + { + new_string += (char)((value >> 24) & 0xFF); + new_string += (char)((value >> 16) & 0xFF); + new_string += (char)((value >> 8) & 0xFF); + new_string += (char)((value)& 0xFF); + } + found = true; + } + } + else + { + // Keyword replacement + for (int j = 0; j < _countof(htmlEntities); j++) + { + if (!mir_strcmpi(entity.c_str(), htmlEntities[j].entity)) + { + new_string += htmlEntities[j].symbol; + found = true; + break; + } + } + } + + if (found) + continue; + else + i = begin; + } + } + + new_string += data.at(i); + } + + return mir_strdup(new_string.c_str()); +} + +const char *CSkypeProto::MirandaToSkypeStatus(int status) +{ + switch (status) + { + case ID_STATUS_AWAY: + return "Away"; + + case ID_STATUS_DND: + return "Busy"; + + case ID_STATUS_IDLE: + return "Idle"; + + case ID_STATUS_INVISIBLE: + return "Hidden"; + } + return "Online"; +} + +int CSkypeProto::SkypeToMirandaStatus(const char *status) +{ + if (!mir_strcmpi(status, "Online")) + return ID_STATUS_ONLINE; + else if (!mir_strcmpi(status, "Hidden")) + return ID_STATUS_INVISIBLE; + else if (!mir_strcmpi(status, "Away")) + return ID_STATUS_AWAY; + else if (!mir_strcmpi(status, "Idle")) + return /*ID_STATUS_IDLE*/ID_STATUS_AWAY; + else if (!mir_strcmpi(status, "Busy")) + return ID_STATUS_DND; + else + return ID_STATUS_OFFLINE; +} + +bool CSkypeProto::IsFileExists(std::wstring path) +{ + return _waccess(path.c_str(), 0) == 0; +} + +// url parsing + +CMStringA CSkypeProto::ParseUrl(const char *url, const char *token) +{ + const char *start = strstr(url, token); + if (start == NULL) + return CMStringA(); + + start = start + mir_strlen(token); + const char *end = strchr(start, '/'); + if (end == NULL) + return CMStringA(start); + return CMStringA(start, end - start); +} + +CMStringA CSkypeProto::GetStringChunk(const char *haystack, const char *start, const char *end) +{ + const char *sstart = strstr(haystack, start); + if (sstart == NULL) + return CMStringA(); + + sstart = sstart + mir_strlen(start); + const char *send = strstr(sstart, end); + if (send == NULL) + return CMStringA(sstart); + return CMStringA(sstart, send - sstart); +} + +CMStringA CSkypeProto::UrlToSkypename(const char *url) +{ + CMStringA szResult; + + if (strstr(url, "/1:")) + szResult = ParseUrl(url, "/1:"); + else if (strstr(url, "/8:")) + szResult = ParseUrl(url, "/8:"); + else if (strstr(url, "/19:")) + szResult = ParseUrl(url, "/19:"); + + return szResult; +} + +CMStringA CSkypeProto::GetServerFromUrl(const char *url) +{ + return ParseUrl(url, "://"); +} + +INT_PTR CSkypeProto::ParseSkypeUriService(WPARAM, LPARAM lParam) +{ + wchar_t *arg = (wchar_t *)lParam; + if (arg == NULL) + return 1; + + // skip leading prefix + wchar_t szUri[1024]; + wcsncpy_s(szUri, arg, _TRUNCATE); + wchar_t *szJid = wcschr(szUri, ':'); + if (szJid == NULL) + return 1; + + // empty jid? + if (!*szJid) + return 1; + + // command code + wchar_t *szCommand = szJid; + szCommand = wcschr(szCommand, '?'); + if (szCommand) + *(szCommand++) = 0; + + // parameters + wchar_t *szSecondParam = szCommand ? wcschr(szCommand, '&') : NULL; + if (szSecondParam) + *(szSecondParam++) = 0; + + // no command or message command + if (!szCommand || (szCommand && !mir_wstrcmpi(szCommand, L"chat"))) + { + if (szSecondParam) + { + wchar_t *szChatId = wcsstr(szSecondParam, L"id="); + if (szChatId) + { + szChatId += 5; + StartChatRoom(szChatId, szChatId); + return 0; + } + } + MCONTACT hContact = AddContact(_T2A(szJid), true); + CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, NULL); + return 0; + } + else if (!mir_wstrcmpi(szCommand, L"call")) + { + MCONTACT hContact = AddContact(_T2A(szJid), true); + NotifyEventHooks(g_hCallEvent, (WPARAM)hContact, (LPARAM)0); + return 0; + } + else if (!mir_wstrcmpi(szCommand, L"userinfo")){ return 0; } + else if (!mir_wstrcmpi(szCommand, L"add")) + { + MCONTACT hContact = FindContact(_T2A(szJid)); + if (hContact == NULL) + { + PROTOSEARCHRESULT psr = { 0 }; + psr.cbSize = sizeof(psr); + psr.id.w = mir_wstrdup(szJid); + psr.nick.w = mir_wstrdup(szJid); + psr.flags = PSR_UNICODE; + + ADDCONTACTSTRUCT acs = { 0 }; + acs.handleType = HANDLE_SEARCHRESULT; + acs.szProto = m_szModuleName; + acs.psr = &psr; + + CallService(MS_ADDCONTACT_SHOW, 0, (LPARAM)&acs); + } + return 0; + } + if (!mir_wstrcmpi(szCommand, L"sendfile")) + { + MCONTACT hContact = AddContact(_T2A(szJid), true); + CallService(MS_FILE_SENDFILE, hContact, NULL); + return 1; + } + if (!mir_wstrcmpi(szCommand, L"voicemail")) + { + return 1; + } + return 1; +} + +INT_PTR CSkypeProto::GlobalParseSkypeUriService(WPARAM wParam, LPARAM lParam) +{ + mir_cslock lck(accountsLock); + for (int i = 0; i < Accounts.getCount(); i++) + if (Accounts[i]->IsOnline()) + return Accounts[i]->ParseSkypeUriService(wParam, lParam); + + return 1; }
\ No newline at end of file |