/trunk/src/common/Text/GString.cpp

# · C++ · 887 lines · 751 code · 119 blank · 17 comment · 278 complexity · 5ccb229e0a189a42648b3778b647e4f9 MD5 · raw file

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include "GMem.h"
  5. #include "LgiOsDefs.h"
  6. #include "GString.h"
  7. #include "GContainers.h"
  8. #include "LgiCommon.h"
  9. char WhiteSpace[] = " \t\r\n";
  10. // 8 Bit
  11. char *strnchr(const char *s, char c, int Len)
  12. {
  13. if (s)
  14. {
  15. for (int i=0; i<Len; i++)
  16. {
  17. if (s[i] == c)
  18. {
  19. return (char*)s + i;
  20. }
  21. }
  22. }
  23. return 0;
  24. }
  25. char *strnstr(char *a, const char *b, int n)
  26. {
  27. if (a && b)
  28. {
  29. int SLen = strlen(b);
  30. int DLen = 0;
  31. while (DLen < n && a[DLen])
  32. {
  33. DLen++;
  34. }
  35. while (SLen <= DLen && n >= SLen)
  36. {
  37. int i;
  38. for (i=0; i<SLen && a[i] == b[i]; i++);
  39. if (i == SLen) return a;
  40. n--;
  41. DLen--;
  42. a++;
  43. }
  44. }
  45. return NULL;
  46. }
  47. char *strnistr(char *a, const char *b, int n)
  48. {
  49. if (a && b)
  50. {
  51. int SLen = strlen(b);
  52. while (n >= SLen)
  53. {
  54. int i;
  55. for (i=0; a[i] && i<SLen && tolower(a[i]) == tolower(b[i]); i++);
  56. if (i == SLen) return a;
  57. if (a[i] == 0) return 0;
  58. n--;
  59. a++;
  60. }
  61. }
  62. return NULL;
  63. }
  64. int strnicmp(const char *a, const char *b, int i)
  65. {
  66. int Cmp = -1;
  67. if (a && b && i > 0)
  68. {
  69. for (Cmp = 0; i-- && Cmp == 0; )
  70. {
  71. Cmp += tolower(*a) - tolower(*b);
  72. if (!*a || !*b) break;
  73. a++;
  74. b++;
  75. }
  76. }
  77. return Cmp;
  78. }
  79. char *stristr(const char *a, const char *b)
  80. {
  81. if (a && b)
  82. {
  83. while (a && *a)
  84. {
  85. if (tolower(*a) == tolower(*b))
  86. {
  87. int i;
  88. for (i=0; a[i] && tolower(a[i]) == tolower(b[i]); i++)
  89. ;
  90. if (b[i] == 0) return (char*)a;
  91. }
  92. a++;
  93. }
  94. }
  95. return NULL;
  96. }
  97. char *strsafecpy(char *dst, const char *src, int len)
  98. {
  99. char *d = dst;
  100. if (dst && src && len > 0)
  101. {
  102. while (*src && len > 1)
  103. {
  104. *dst++ = *src++;
  105. len--;
  106. }
  107. *dst++ = 0;
  108. }
  109. return d;
  110. }
  111. char *strsafecat(char *dst, const char *src, int len)
  112. {
  113. char *d = dst;
  114. if (dst && src && len > 0)
  115. {
  116. // Seek past the dst string
  117. while (*dst && len > 1)
  118. {
  119. dst++;
  120. len--;
  121. }
  122. // Copy the source onto the end
  123. while (*src && len > 1)
  124. {
  125. *dst++ = *src++;
  126. len--;
  127. }
  128. *dst++ = 0;
  129. }
  130. return d;
  131. }
  132. int strcmp(char *a, char *b)
  133. {
  134. int c = -1;
  135. if (a && b)
  136. {
  137. c = 0;
  138. while (!c)
  139. {
  140. c = *a - *b;
  141. if (!*a || !*b) break;
  142. a++;
  143. b++;
  144. }
  145. }
  146. return c;
  147. }
  148. #ifndef WIN32
  149. int stricmp(const char *a, const char *b)
  150. {
  151. int c = -1;
  152. if (a && b)
  153. {
  154. c = 0;
  155. while (!c)
  156. {
  157. c = tolower(*a) - tolower(*b);
  158. if (!*a || !*b) break;
  159. a++;
  160. b++;
  161. }
  162. }
  163. return c;
  164. }
  165. char *strupr(char *a)
  166. {
  167. for (char *s = a; s && *s; s++)
  168. {
  169. *s = tolower(*s);
  170. }
  171. return a;
  172. }
  173. char *strlwr(char *a)
  174. {
  175. for (char *s = a; s && *s; s++)
  176. {
  177. *s = tolower(*s);
  178. }
  179. return a;
  180. }
  181. #endif
  182. char *TrimStr(const char *s, const char *Delim)
  183. {
  184. if (s)
  185. {
  186. const char *Start = s;
  187. while (*Start && strchr(Delim, *Start))
  188. {
  189. Start++;
  190. }
  191. int StartLen = strlen(Start);
  192. if (StartLen > 0)
  193. {
  194. const char *End = Start + strlen(Start) - 1;
  195. while (*End && End > Start && strchr(Delim, *End))
  196. {
  197. End--;
  198. }
  199. if (*Start)
  200. {
  201. int Len = (End - Start) + 1;
  202. char *n = new char[Len+1];
  203. if (n)
  204. {
  205. memcpy(n, Start, Len);
  206. n[Len] = 0;
  207. return n;
  208. }
  209. }
  210. }
  211. }
  212. return NULL;
  213. }
  214. bool ValidStr(const char *s)
  215. {
  216. if (s)
  217. {
  218. while (*s)
  219. {
  220. if (*s != ' ' &&
  221. *s != '\t' &&
  222. *s != '\r' &&
  223. *s != '\n' &&
  224. ((uchar)*s) != 0xa0)
  225. {
  226. return true;
  227. }
  228. s++;
  229. }
  230. }
  231. return false;
  232. }
  233. char *NewStr(const char *s, int Len)
  234. {
  235. if (s)
  236. {
  237. if (Len < 0) Len = strlen(s);
  238. char *Ret = new char[Len+1];
  239. if (Ret)
  240. {
  241. if (Len > 0) memcpy(Ret, s, Len);
  242. Ret[Len] = 0;
  243. return Ret;
  244. }
  245. }
  246. return NULL;
  247. }
  248. #ifdef BEOS
  249. #define toupper(c) ( ((c)>='a' && (c)<='z') ? (c)-'a'+'A' : (c) )
  250. #define tolower(c) ( ((c)>='A' && (c)<='Z') ? (c)-'A'+'a' : (c) )
  251. #endif
  252. bool MatchStr(const char *Template, const char *Data)
  253. {
  254. if (!Template)
  255. {
  256. return false;
  257. }
  258. if (stricmp(Template, (char*)"*") == 0)
  259. {
  260. // matches anything
  261. return true;
  262. }
  263. if (!Data)
  264. {
  265. return false;
  266. }
  267. while (*Template && *Data)
  268. {
  269. if (*Template == '*')
  270. {
  271. Template++;
  272. if (*Template)
  273. {
  274. const char *EndA;
  275. for (EndA = Template; *EndA && *EndA!='?' && *EndA!='*'; EndA++);
  276. int SegLen = EndA - Template;
  277. char *Seg = NewStr(Template, SegLen);
  278. if (!Seg) return false;
  279. // find end of non match
  280. while (*Data)
  281. {
  282. if (strnicmp(Data, Seg, SegLen) == 0)
  283. {
  284. break;
  285. }
  286. Data++;
  287. }
  288. DeleteArray(Seg);
  289. if (*Data)
  290. {
  291. Template += SegLen;
  292. Data += SegLen;
  293. }
  294. else
  295. {
  296. // can't find any matching part in Data
  297. return false;
  298. }
  299. }
  300. else
  301. {
  302. // '*' matches everything
  303. return true;
  304. }
  305. }
  306. else if (*Template == '?')
  307. {
  308. Template++;
  309. Data++;
  310. }
  311. else
  312. {
  313. if (tolower(*Template) != tolower(*Data))
  314. {
  315. return false;
  316. }
  317. Template++;
  318. Data++;
  319. }
  320. }
  321. return ((*Template == 0) || (stricmp(Template, (char*)"*") == 0)) &&
  322. (*Data == 0);
  323. }
  324. int htoi(const char *a)
  325. {
  326. int Status = 0;
  327. for (; a && *a; a++)
  328. {
  329. if (*a >= '0' && *a <= '9')
  330. {
  331. Status <<= 4;
  332. Status |= *a - '0';
  333. }
  334. else if (*a >= 'a' && *a <= 'f')
  335. {
  336. Status <<= 4;
  337. Status |= *a - 'a' + 10;
  338. }
  339. else if (*a >= 'A' && *a <= 'F')
  340. {
  341. Status <<= 4;
  342. Status |= *a - 'A' + 10;
  343. }
  344. else break;
  345. }
  346. return Status;
  347. }
  348. int64 htoi64(const char *a)
  349. {
  350. int64 Status = 0;
  351. for (; a && *a; a++)
  352. {
  353. if (*a >= '0' && *a <= '9')
  354. {
  355. Status <<= 4;
  356. Status |= *a - '0';
  357. }
  358. else if (*a >= 'a' && *a <= 'f')
  359. {
  360. Status <<= 4;
  361. Status |= *a - 'a' + 10;
  362. }
  363. else if (*a >= 'A' && *a <= 'F')
  364. {
  365. Status <<= 4;
  366. Status |= *a - 'A' + 10;
  367. }
  368. else break;
  369. }
  370. return Status;
  371. }
  372. //////////////////////////////////////////////////////////////////////////
  373. // UTF-16
  374. #define CompareDefault (a && b ? *a - *b : -1)
  375. char16 *StrchrW(const char16 *s, char16 c)
  376. {
  377. if (s)
  378. {
  379. while (*s)
  380. {
  381. if (*s == c) return (char16*) s;
  382. s++;
  383. }
  384. }
  385. return 0;
  386. }
  387. char16 *StrnchrW(char16 *s, char16 c, int Len)
  388. {
  389. if (s)
  390. {
  391. while (*s && Len > 0)
  392. {
  393. if (*s == c)
  394. return s;
  395. s++;
  396. Len--;
  397. }
  398. }
  399. return 0;
  400. }
  401. char16 *StrrchrW(char16 *s, char16 c)
  402. {
  403. char16 *Last = 0;
  404. while (s && *s)
  405. {
  406. if (*s == c)
  407. Last = s;
  408. s++;
  409. }
  410. return Last;
  411. }
  412. char16 *StrstrW(char16 *a, const char16 *b)
  413. {
  414. if (a && b)
  415. {
  416. int Len = StrlenW(b);
  417. for (char16 *s=a; *s; s++)
  418. {
  419. if (*s == *b)
  420. {
  421. // check match
  422. if (StrncmpW(s+1, b+1, Len-1) == 0)
  423. return s;
  424. }
  425. }
  426. }
  427. return 0;
  428. }
  429. char16 *StristrW(char16 *a, const char16 *b)
  430. {
  431. if (a && b)
  432. {
  433. int Len = StrlenW(b);
  434. for (char16 *s=a; *s; s++)
  435. {
  436. if (tolower(*s) == tolower(*b))
  437. {
  438. // check match
  439. if (StrnicmpW(s+1, b+1, Len-1) == 0)
  440. return s;
  441. }
  442. }
  443. }
  444. return 0;
  445. }
  446. char16 *StrnstrW(char16 *a, const char16 *b, int n)
  447. {
  448. if (a && b)
  449. {
  450. int Len = StrlenW(b);
  451. for (char16 *s=a; n >= Len && *s; s++, n--)
  452. {
  453. if (*s == *b)
  454. {
  455. // check match
  456. if (StrncmpW(s+1, b+1, Len-1) == 0)
  457. return s;
  458. }
  459. }
  460. }
  461. return 0;
  462. }
  463. char16 *StrnistrW(char16 *a, const char16 *b, int n)
  464. {
  465. if (a && b)
  466. {
  467. int Len = StrlenW(b);
  468. for (char16 *s=a; n >= Len && *s; s++, n--)
  469. {
  470. if (*s == *b)
  471. {
  472. // check match
  473. if (StrnicmpW(s+1, b+1, Len-1) == 0)
  474. return s;
  475. }
  476. }
  477. }
  478. return 0;
  479. }
  480. int StrcmpW(const char16 *a, const char16 *b)
  481. {
  482. if (a && b)
  483. {
  484. while (true)
  485. {
  486. if (!*a || !*b || *a != *b)
  487. return *a - *b;
  488. a++;
  489. b++;
  490. }
  491. return 0;
  492. }
  493. return -1;
  494. }
  495. int StricmpW(const char16 *a, const char16 *b)
  496. {
  497. if (a && b)
  498. {
  499. while (true)
  500. {
  501. char16 A = tolower(*a);
  502. char16 B = tolower(*b);
  503. if (!A || !B || A != B)
  504. return A - B;
  505. a++;
  506. b++;
  507. }
  508. return 0;
  509. }
  510. return -1;
  511. }
  512. int StrncmpW(const char16 *a, const char16 *b, int n)
  513. {
  514. if (a && b)
  515. {
  516. while (n > 0)
  517. {
  518. if (!*a || !*b || *a != *b)
  519. return *a - *b;
  520. a++;
  521. b++;
  522. n--;
  523. }
  524. return 0;
  525. }
  526. return -1;
  527. }
  528. int StrnicmpW(const char16 *a, const char16 *b, int n)
  529. {
  530. if (a && b)
  531. {
  532. while (n > 0)
  533. {
  534. char16 A = tolower(*a);
  535. char16 B = tolower(*b);
  536. if (!A || !B || A != B)
  537. return A - B;
  538. a++;
  539. b++;
  540. n--;
  541. }
  542. return 0;
  543. }
  544. return -1;
  545. }
  546. char16 *StrcpyW(char16 *a, const char16 *b)
  547. {
  548. if (a && b)
  549. {
  550. do
  551. {
  552. *a++ = *b++;
  553. }
  554. while (*b);
  555. *a++ = 0;
  556. }
  557. return a;
  558. }
  559. char16 *StrncpyW(char16 *a, const char16 *b, int n)
  560. {
  561. if (a && b && n > 0)
  562. {
  563. while (*b && --n > 0)
  564. {
  565. *a++ = *b++;
  566. }
  567. *a++ = 0; // always NULL terminate
  568. }
  569. return a;
  570. }
  571. void StrcatW(char16 *a, const char16 *b)
  572. {
  573. if (a && b)
  574. {
  575. // Seek to end of string
  576. while (*a)
  577. {
  578. *a++;
  579. }
  580. // Append 'b'
  581. while (*b)
  582. {
  583. *a++ = *b++;
  584. }
  585. *a++ = 0;
  586. }
  587. }
  588. int StrlenW(const char16 *a)
  589. {
  590. if (!a)
  591. return 0;
  592. int i = 0;
  593. while (*a++)
  594. {
  595. i++;
  596. }
  597. return i;
  598. }
  599. int AtoiW(const char16 *a)
  600. {
  601. int i = 0;
  602. while (a && *a >= '0' && *a <= '9')
  603. {
  604. i *= 10;
  605. i += *a - '0';
  606. a++;
  607. }
  608. return i;
  609. }
  610. int HtoiW(const char16 *a)
  611. {
  612. int i = 0;
  613. if (a)
  614. {
  615. while (*a)
  616. {
  617. if (*a >= '0' && *a <= '9')
  618. {
  619. i <<= 4;
  620. i |= *a - '0';
  621. }
  622. else if (*a >= 'a' && *a <= 'f')
  623. {
  624. i <<= 4;
  625. i |= *a - 'a' + 10;
  626. }
  627. else if (*a >= 'A' && *a <= 'F')
  628. {
  629. i <<= 4;
  630. i |= *a - 'A' + 10;
  631. }
  632. else break;
  633. }
  634. }
  635. return i;
  636. }
  637. char16 *TrimStrW(const char16 *s, const char16 *Delim)
  638. {
  639. if (!Delim)
  640. {
  641. static char16 Def[] = {' ', '\r', '\n', '\t', 0};
  642. Delim = Def;
  643. }
  644. if (s)
  645. {
  646. // Leading delim
  647. while (StrchrW(Delim, *s))
  648. {
  649. s++;
  650. }
  651. // Trailing delim
  652. int i = StrlenW(s);
  653. while (i > 0 && StrchrW(Delim, s[i-1]))
  654. {
  655. i--;
  656. }
  657. return NewStrW(s, i);
  658. }
  659. return 0;
  660. }
  661. bool MatchStrW(const char16 *a, const char16 *b)
  662. {
  663. LgiAssert(0);
  664. return 0;
  665. }
  666. char16 *NewStrW(const char16 *Str, int l)
  667. {
  668. char16 *s = 0;
  669. if (Str)
  670. {
  671. if (l < 0) l = StrlenW(Str);
  672. s = new char16[l+1];
  673. if (s)
  674. {
  675. memcpy(s, Str, l * sizeof(char16));
  676. s[l] = 0;
  677. }
  678. }
  679. return s;
  680. }
  681. bool ValidStrW(const char16 *s)
  682. {
  683. if (s)
  684. {
  685. for (const char16 *c=s; *c; c++)
  686. {
  687. if (*c != ' ' && *c != '\t') return true;
  688. }
  689. }
  690. return false;
  691. }
  692. char *LgiDecodeUri(const char *uri, int len)
  693. {
  694. GStringPipe p;
  695. if (uri)
  696. {
  697. const char *end = len >= 0 ? uri + len : 0;
  698. for (const char *s=uri; s && *s; )
  699. {
  700. int Len;
  701. const char *e = s;
  702. for (Len = 0; *e && *e != '%' && (!end || e < end); e++)
  703. Len++;
  704. p.Push(s, Len);
  705. if ((!end || e < end) && *e)
  706. {
  707. e++;
  708. if (e[0] && e[1])
  709. {
  710. char h[3] = { e[0], e[1], 0 };
  711. char c = htoi(h);
  712. p.Push(&c, 1);
  713. e += 2;
  714. s = e;
  715. }
  716. else break;
  717. }
  718. else
  719. {
  720. break;
  721. }
  722. }
  723. }
  724. return p.NewStr();
  725. }
  726. char *LgiEncodeUri(const char *uri, int len)
  727. {
  728. GStringPipe p;
  729. if (uri)
  730. {
  731. const char *end = len >= 0 ? uri + len : 0;
  732. for (const char *s=uri; s && *s; )
  733. {
  734. int Len;
  735. const char *e = s;
  736. for
  737. (
  738. Len = 0;
  739. *e
  740. &&
  741. (!end || e < end)
  742. &&
  743. *e > ' '
  744. &&
  745. (uchar)*e < 0x7f
  746. &&
  747. strchr("$&+,/:;=?@\'\"<>#%{}|\\^~[]`", *e) == 0;
  748. e++
  749. )
  750. {
  751. Len++;
  752. }
  753. p.Push(s, Len);
  754. if ((!end || e < end) && *e)
  755. {
  756. char h[4];
  757. sprintf(h, "%%%2.2X", (uchar)*e);
  758. p.Push(h, 3);
  759. s = ++e;
  760. }
  761. else
  762. {
  763. break;
  764. }
  765. }
  766. }
  767. return p.NewStr();
  768. }