PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/miranda/protocols/MSN/msn_libstr.cpp

http://miranda.googlecode.com/
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
  1. /*
  2. Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
  3. Copyright (c) 2006-2014 Boris Krasnovskiy.
  4. Copyright (c) 2003-2005 George Hazan.
  5. Copyright (c) 2002-2003 Richard Hughes (original version).
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "msn_global.h"
  18. void replaceStr(char*& dest, const char* src)
  19. {
  20. if (src != NULL)
  21. {
  22. mir_free(dest);
  23. dest = mir_strdup(src);
  24. }
  25. }
  26. void replaceStr(wchar_t*& dest, const wchar_t* src)
  27. {
  28. if (src != NULL)
  29. {
  30. mir_free(dest);
  31. dest = mir_wstrdup(src);
  32. }
  33. }
  34. static TCHAR* a2tf(const TCHAR* str, bool unicode)
  35. {
  36. if (str == NULL)
  37. return NULL;
  38. return unicode ? mir_tstrdup(str) : mir_a2t((char*)str);
  39. }
  40. void overrideStr(TCHAR*& dest, const TCHAR* src, bool unicode, const TCHAR* def)
  41. {
  42. mir_free(dest);
  43. dest = NULL;
  44. if (src != NULL)
  45. dest = a2tf(src, unicode);
  46. else if (def != NULL)
  47. dest = mir_tstrdup(def);
  48. }
  49. char* __fastcall ltrimp(char* str)
  50. {
  51. if (str == NULL) return NULL;
  52. char* p = str;
  53. for (;;)
  54. {
  55. switch (*p)
  56. {
  57. case ' ': case '\t': case '\n': case '\r':
  58. ++p; break;
  59. default:
  60. return p;
  61. }
  62. }
  63. }
  64. char* __fastcall rtrim(char *string)
  65. {
  66. char* p = string + strlen(string) - 1;
  67. while (p >= string)
  68. {
  69. if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
  70. break;
  71. *p-- = 0;
  72. }
  73. return string;
  74. }
  75. wchar_t* __fastcall rtrim(wchar_t* string)
  76. {
  77. wchar_t* p = string + wcslen(string) - 1;
  78. while (p >= string)
  79. {
  80. if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
  81. break;
  82. *p-- = 0;
  83. }
  84. return string;
  85. }
  86. char* arrayToHex(BYTE* data, size_t datasz)
  87. {
  88. char* res = (char*)mir_alloc(2 * datasz + 1);
  89. char* resptr = res;
  90. for (unsigned i=0; i<datasz ; i++)
  91. {
  92. const BYTE ch = data[i];
  93. const char ch0 = ch >> 4;
  94. *resptr++ = (ch0 <= 9) ? ('0' + ch0) : (('a' - 10) + ch0);
  95. const char ch1 = ch & 0xF;
  96. *resptr++ = (ch1 <= 9) ? ('0' + ch1) : (('a' - 10) + ch1);
  97. }
  98. *resptr = '\0';
  99. return res;
  100. }
  101. bool txtParseParam (const char* szData, const char* presearch, const char* start, const char* finish, char* param, const int size)
  102. {
  103. const char *cp, *cp1;
  104. int len;
  105. if (szData == NULL) return false;
  106. if (presearch != NULL)
  107. {
  108. cp1 = strstr(szData, presearch);
  109. if (cp1 == NULL) return false;
  110. }
  111. else
  112. cp1 = szData;
  113. cp = strstr(cp1, start);
  114. if (cp == NULL) return false;
  115. cp += strlen(start);
  116. while (*cp == ' ') ++cp;
  117. if (finish)
  118. {
  119. cp1 = strstr(cp, finish);
  120. if (cp1 == NULL) return FALSE;
  121. while (*(cp1-1) == ' ' && cp1 > cp) --cp1;
  122. }
  123. else
  124. cp1 = strchr(cp, '\0');
  125. len = min(cp1 - cp, size - 1);
  126. memmove(param, cp, len);
  127. param[len] = 0;
  128. return true;
  129. }
  130. void parseWLID(char* wlid, char** net, char** email, char** inst)
  131. {
  132. char* col = strchr(wlid, ':');
  133. if (col && strncmp(wlid, "tel:", 4))
  134. {
  135. *col = 0;
  136. if (net) *net = wlid;
  137. if (email) *email = col + 1;
  138. ++col;
  139. }
  140. else
  141. {
  142. if (net) *net = NULL;
  143. if (email) *email = wlid;
  144. }
  145. col = strchr(wlid, ';');
  146. if (col)
  147. {
  148. *col = 0;
  149. if (inst) *inst = col + 1;
  150. }
  151. else
  152. if (inst) *inst = NULL;
  153. }
  154. /////////////////////////////////////////////////////////////////////////////////////////
  155. // UrlDecode - converts URL chars like %20 into printable characters
  156. static int SingleHexToDecimal(char c)
  157. {
  158. if (c >= '0' && c <= '9') return c-'0';
  159. if (c >= 'a' && c <= 'f') return c-'a'+10;
  160. if (c >= 'A' && c <= 'F') return c-'A'+10;
  161. return -1;
  162. }
  163. template void UrlDecode(char* str);
  164. #ifdef _UNICODE
  165. template void UrlDecode(wchar_t* str);
  166. #endif
  167. template <class chartype> void UrlDecode(chartype* str)
  168. {
  169. chartype* s = str, *d = str;
  170. while(*s)
  171. {
  172. if (*s == '%')
  173. {
  174. int digit1 = SingleHexToDecimal(s[1]);
  175. if (digit1 != -1)
  176. {
  177. int digit2 = SingleHexToDecimal(s[2]);
  178. if (digit2 != -1)
  179. {
  180. s += 3;
  181. *d++ = (char)((digit1 << 4) | digit2);
  182. continue;
  183. }
  184. }
  185. }
  186. *d++ = *s++;
  187. }
  188. *d = 0;
  189. }
  190. void HtmlDecode(char* str)
  191. {
  192. char* p, *q;
  193. if (str == NULL)
  194. return;
  195. for (p=q=str; *p!='\0'; p++,q++)
  196. {
  197. if (*p == '&')
  198. {
  199. if (!strncmp(p, "&amp;", 5)) { *q = '&'; p += 4; }
  200. else if (!strncmp(p, "&apos;", 6)) { *q = '\''; p += 5; }
  201. else if (!strncmp(p, "&gt;", 4)) { *q = '>'; p += 3; }
  202. else if (!strncmp(p, "&lt;", 4)) { *q = '<'; p += 3; }
  203. else if (!strncmp(p, "&quot;", 6)) { *q = '"'; p += 5; }
  204. else { *q = *p; }
  205. }
  206. else
  207. {
  208. *q = *p;
  209. }
  210. }
  211. *q = '\0';
  212. }
  213. char* HtmlEncode(const char* str)
  214. {
  215. char* s, *p, *q;
  216. int c;
  217. if (str == NULL)
  218. return NULL;
  219. for (c=0,p=(char*)str; *p!='\0'; p++)
  220. {
  221. switch (*p)
  222. {
  223. case '&': c += 5; break;
  224. case '\'': c += 6; break;
  225. case '>': c += 4; break;
  226. case '<': c += 4; break;
  227. case '"': c += 6; break;
  228. default: c++; break;
  229. }
  230. }
  231. if ((s=(char*)mir_alloc(c+1)) != NULL)
  232. {
  233. for (p=(char*)str,q=s; *p!='\0'; p++)
  234. {
  235. switch (*p)
  236. {
  237. case '&': strcpy(q, "&amp;"); q += 5; break;
  238. case '\'': strcpy(q, "&apos;"); q += 6; break;
  239. case '>': strcpy(q, "&gt;"); q += 4; break;
  240. case '<': strcpy(q, "&lt;"); q += 4; break;
  241. case '"': strcpy(q, "&quot;"); q += 6; break;
  242. default: *q = *p; q++; break;
  243. }
  244. }
  245. *q = '\0';
  246. }
  247. return s;
  248. }
  249. /////////////////////////////////////////////////////////////////////////////////////////
  250. // UrlEncode - converts printable characters into URL chars like %20
  251. void UrlEncode(const char* src, char* dest, size_t cbDest)
  252. {
  253. unsigned char* d = (unsigned char*)dest;
  254. size_t i = 0;
  255. for (const unsigned char* s = (unsigned char*)src; *s; s++)
  256. {
  257. if ((*s <= '/' && *s != '.' && *s != '-') ||
  258. (*s >= ':' && *s <= '?') ||
  259. (*s >= '[' && *s <= '`' && *s != '_'))
  260. {
  261. if (i + 4 >= cbDest) break;
  262. *d++ = '%';
  263. _itoa(*s, (char*)d, 16);
  264. d += 2;
  265. i += 3;
  266. }
  267. else
  268. {
  269. if (++i >= cbDest) break;
  270. *d++ = *s;
  271. } }
  272. *d = '\0';
  273. }
  274. void stripBBCode(char* src)
  275. {
  276. bool tag = false;
  277. char* ps = src;
  278. char* pd = src;
  279. while (*ps != 0)
  280. {
  281. if (!tag && *ps == '[')
  282. {
  283. char ch = ps[1];
  284. if (ch == '/') ch = ps[2];
  285. tag = ch == 'b' || ch == 'u' || ch == 'i' || ch == 'c' || ch == 'a' || ch == 's';
  286. }
  287. if (!tag) *(pd++) = *ps;
  288. else tag = *ps != ']';
  289. ++ps;
  290. }
  291. *pd = 0;
  292. }
  293. void stripColorCode(char* src)
  294. {
  295. unsigned char* ps = (unsigned char*)src;
  296. unsigned char* pd = (unsigned char*)src;
  297. while (*ps != 0)
  298. {
  299. if (ps[0] == 0xc2 && ps[1] == 0xb7)
  300. {
  301. char ch = ps[2];
  302. switch (ch)
  303. {
  304. case '#':
  305. case '&':
  306. case '\'':
  307. case '@':
  308. case '0':
  309. ps += 3;
  310. continue;
  311. case '$':
  312. if (isdigit(ps[3]))
  313. {
  314. ps += 3;
  315. if (isdigit(ps[1]))
  316. {
  317. ps += 2;
  318. }
  319. else
  320. ++ps;
  321. if (ps[0] == ',' && isdigit(ps[1]))
  322. {
  323. ps += 2;
  324. if (isdigit(ps[1]))
  325. ps += 2;
  326. else
  327. ++ps;
  328. }
  329. continue;
  330. }
  331. else if (ps[3] == '#')
  332. {
  333. ps += 4;
  334. for (int i=0; i<6; ++i)
  335. if (isxdigit(*ps)) ++ps;
  336. else break;
  337. continue;
  338. }
  339. break;
  340. }
  341. }
  342. *(pd++) = *(ps++);
  343. }
  344. *pd = 0;
  345. }
  346. // Process a string, and double all % characters, according to chat.dll's restrictions
  347. // Returns a pointer to the new string (old one is not freed)
  348. TCHAR* EscapeChatTags(const TCHAR* pszText)
  349. {
  350. int nChars = 0;
  351. for (const TCHAR* p = pszText; (p = _tcschr(p, '%')) != NULL; p++)
  352. nChars++;
  353. if (nChars == 0)
  354. return mir_tstrdup(pszText);
  355. TCHAR *pszNewText = (TCHAR*)mir_alloc(sizeof(TCHAR)*(_tcslen(pszText) + 1 + nChars));
  356. if (pszNewText == NULL)
  357. return mir_tstrdup(pszText);
  358. const TCHAR *s = pszText;
  359. TCHAR *d = pszNewText;
  360. while (*s) {
  361. if (*s == '%')
  362. *d++ = '%';
  363. *d++ = *s++;
  364. }
  365. *d = 0;
  366. return pszNewText;
  367. }
  368. TCHAR* UnEscapeChatTags(TCHAR* str_in)
  369. {
  370. TCHAR *s = str_in, *d = str_in;
  371. while (*s) {
  372. if ((*s == '%' && s[1] == '%') || (*s == '\n' && s[1] == '\n'))
  373. s++;
  374. *d++ = *s++;
  375. }
  376. *d = 0;
  377. return str_in;
  378. }
  379. char* getNewUuid(void)
  380. {
  381. BYTE* p;
  382. UUID id;
  383. UuidCreate(&id);
  384. UuidToStringA(&id, &p);
  385. size_t len = strlen((char*)p) + 3;
  386. char* result = (char*)mir_alloc(len);
  387. mir_snprintf(result, len, "{%s}", p);
  388. _strupr(result);
  389. RpcStringFreeA(&p);
  390. return result;
  391. }