PageRenderTime 87ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 1ms

/src/sys/dotnet/fan/sys/FanStr.cs

https://bitbucket.org/bedlaczech/fan-1.0
C# | 990 lines | 809 code | 125 blank | 56 comment | 282 complexity | a8ca26f6b6c1321d7ef591a6917d43d3 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //
  2. // Copyright (c) 2006, Brian Frank and Andy Frank
  3. // Licensed under the Academic Free License version 3.0
  4. //
  5. // History:
  6. // 13 Sep 06 Andy Frank Creation
  7. // 21 Oct 08 Andy Frank Refactor String into FanStr
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Text;
  12. using System.Text.RegularExpressions;
  13. using Fanx.Serial;
  14. using Fanx.Util;
  15. namespace Fan.Sys
  16. {
  17. /// <summary>
  18. /// FanStr defines the methods for sys::string. The actual
  19. /// class used for representation is F.lang.String.
  20. /// </summary>
  21. public sealed class FanStr
  22. {
  23. //////////////////////////////////////////////////////////////////////////
  24. // Construction
  25. //////////////////////////////////////////////////////////////////////////
  26. public static string fromChars(List chars)
  27. {
  28. if (chars.sz() == 0) return "";
  29. StringBuilder s = new StringBuilder(chars.sz());
  30. for (int i=0; i<chars.sz(); ++i)
  31. s.Append((char)((Long)chars.get(i)).longValue());
  32. return s.ToString();
  33. }
  34. public static string makeTrim(StringBuilder s)
  35. {
  36. int start = 0;
  37. int end = s.Length;
  38. while (start < end) if (FanInt.isSpace(s[start])) start++; else break;
  39. while (end > start) if (FanInt.isSpace(s[end-1])) end--; else break;
  40. return s.ToString(start, end-start);
  41. }
  42. //////////////////////////////////////////////////////////////////////////
  43. // Identity
  44. //////////////////////////////////////////////////////////////////////////
  45. public static bool equals(string self, object obj)
  46. {
  47. if (obj is string)
  48. return self == (string)obj;
  49. else
  50. return false;
  51. }
  52. public static bool equalsIgnoreCase(string a, string b)
  53. {
  54. if (a == b) return true;
  55. int an = a.Length;
  56. int bn = b.Length;
  57. if (an != bn) return false;
  58. for (int i=0; i<an; i++)
  59. {
  60. int ac = a[i];
  61. int bc = b[i];
  62. if ('A' <= ac && ac <= 'Z') ac |= 0x20;
  63. if ('A' <= bc && bc <= 'Z') bc |= 0x20;
  64. if (ac != bc) return false;
  65. }
  66. return true;
  67. }
  68. public static long compare(string self, object obj)
  69. {
  70. int cmp = String.CompareOrdinal(self, (string)obj);
  71. if (cmp < 0) return -1;
  72. return cmp == 0 ? 0 : +1;
  73. }
  74. public static long compareIgnoreCase(string a, string b)
  75. {
  76. if (a == b) return 0;
  77. int an = a.Length;
  78. int bn = b.Length;
  79. for (int i=0; i<an && i<bn; i++)
  80. {
  81. int ac = a[i];
  82. int bc = b[i];
  83. if ('A' <= ac && ac <= 'Z') ac |= 0x20;
  84. if ('A' <= bc && bc <= 'Z') bc |= 0x20;
  85. if (ac != bc) return ac < bc ? -1 : +1;
  86. }
  87. if (an == bn) return 0;
  88. return an < bn ? -1 : +1;
  89. }
  90. public static long hash(string self)
  91. {
  92. return self.GetHashCode();
  93. }
  94. public static int caseInsensitiveHash(string self)
  95. {
  96. int n = self.Length;
  97. int hash = 0;
  98. for (int i=0; i<n; i++)
  99. {
  100. int c = self[i];
  101. if ('A' <= c && c <= 'Z') c |= 0x20;
  102. hash = 31*hash + c;
  103. }
  104. return hash;
  105. }
  106. public static string toStr(string self)
  107. {
  108. return self;
  109. }
  110. public static string toLocale(string self)
  111. {
  112. return self;
  113. }
  114. public static Type type(string self)
  115. {
  116. return Sys.StrType;
  117. }
  118. //////////////////////////////////////////////////////////////////////////
  119. // Operators
  120. //////////////////////////////////////////////////////////////////////////
  121. public static long get(string self, long index)
  122. {
  123. try
  124. {
  125. int i = (int)index;
  126. if (i < 0) i = self.Length+i;
  127. return self[i];
  128. }
  129. catch (System.IndexOutOfRangeException)
  130. {
  131. throw IndexErr.make(index).val;
  132. }
  133. }
  134. public static long getSafe(String self, long index) { return getSafe(self, index, 0); }
  135. public static long getSafe(String self, long index, long def)
  136. {
  137. try
  138. {
  139. int i = (int)index;
  140. if (i < 0) i = self.Length+i;
  141. return self[i];
  142. }
  143. catch (System.IndexOutOfRangeException)
  144. {
  145. return def;
  146. }
  147. }
  148. public static string getRange(string self, Range r)
  149. {
  150. int size = self.Length;
  151. int s = r.start(size);
  152. int e = r.end(size);
  153. if (e+1 < s) throw IndexErr.make(r).val;
  154. return self.Substring(s, (e-s)+1);
  155. }
  156. public static string plus(string self, object obj)
  157. {
  158. if (obj == null) return String.Concat(self, "null");
  159. string x = FanObj.toStr(obj);
  160. if (x == "") return self;
  161. return String.Concat(self, x);
  162. }
  163. //////////////////////////////////////////////////////////////////////////
  164. // Identity
  165. //////////////////////////////////////////////////////////////////////////
  166. public static string intern(string self)
  167. {
  168. return String.Intern(self);
  169. }
  170. public static bool isEmpty(string self)
  171. {
  172. return self.Length == 0;
  173. }
  174. public static long size(string self)
  175. {
  176. return self.Length;
  177. }
  178. public static bool startsWith(string self, string s)
  179. {
  180. return self.StartsWith(s);
  181. }
  182. public static bool endsWith(string self, string s)
  183. {
  184. return self.EndsWith(s);
  185. }
  186. public static bool contains(string self, string s)
  187. {
  188. return index(self, s, 0) != null;
  189. }
  190. public static bool containsChar(string self, long ch)
  191. {
  192. return self.IndexOf((char)ch) >= 0;
  193. }
  194. public static Long index(string self, string s) { return index(self, s, 0); }
  195. public static Long index(string self, string s, long off)
  196. {
  197. int i = (int)off;
  198. if (i < 0) i = self.Length+i;
  199. int r;
  200. if (s.Length == 1)
  201. r = self.IndexOf(s[0], i);
  202. else
  203. r = self.IndexOf(s, i);
  204. if (r < 0) return null;
  205. return Long.valueOf(r);
  206. }
  207. public static Long indexr(string self, string s) { return indexr(self, s, -1); }
  208. public static Long indexr(string self, string s, long off)
  209. {
  210. int i = (int)off;
  211. if (i < 0) i = self.Length+i;
  212. int r;
  213. if (s.Length == 1)
  214. r = self.LastIndexOf(s[0], i);
  215. else
  216. {
  217. // this doesn't match Java impl - so we have to roll
  218. // our own - prob alot of room for improvement...
  219. //r = val.LastIndexOf(sval, i, StringComparison.InvariantCulture);
  220. int len = self.Length;
  221. int slen = s.Length;
  222. if (len < slen) return null;
  223. r = -1;
  224. for (; i>=0; i--)
  225. if (nStartsWith(self, s, i))
  226. { r = i; break; }
  227. }
  228. if (r < 0) return null;
  229. return Long.valueOf(r);
  230. }
  231. public static Long indexIgnoreCase(string self, string s) { return indexIgnoreCase(self, s, 0); }
  232. public static Long indexIgnoreCase(string self, string s, long off)
  233. {
  234. int vlen = self.Length, slen = s.Length;
  235. int r = -1;
  236. int i = (int)off;
  237. if (i < 0) i = vlen+i;
  238. int first = s[0];
  239. for (; i<=vlen-slen; ++i)
  240. {
  241. // test first char
  242. if (neic(first, self[i])) continue;
  243. // test remainder of chars
  244. r = i;
  245. for (int si=1, vi=i+1; si<slen; ++si, ++vi)
  246. if (neic(s[si], self[vi]))
  247. { r = -1; break; }
  248. if (r >= 0) break;
  249. }
  250. if (r < 0) return null;
  251. return Long.valueOf(r);
  252. }
  253. public static Long indexrIgnoreCase(string self, string s) { return indexrIgnoreCase(self, s, -1); }
  254. public static Long indexrIgnoreCase(string self, string s, long off)
  255. {
  256. int vlen = self.Length, slen = s.Length;
  257. int r = -1;
  258. int i = (int)off;
  259. if (i < 0) i = vlen+i;
  260. if (i+slen >= vlen) i = vlen-slen;
  261. int first = s[0];
  262. for (; i>=0; --i)
  263. {
  264. // test first char
  265. if (neic(first, self[i])) continue;
  266. // test remainder of chars
  267. r = i;
  268. for (int si=1, vi=i+1; si<slen; ++si, ++vi)
  269. if (neic(s[si], self[vi]))
  270. { r = -1; break; }
  271. if (r >= 0) break;
  272. }
  273. if (r < 0) return null;
  274. return Long.valueOf(r);
  275. }
  276. private static bool neic(int a, int b)
  277. {
  278. if (a == b) return false;
  279. if ((a | 0x20) == (b | 0x20)) return FanInt.lower(a) != FanInt.lower(b);
  280. return true;
  281. }
  282. private static bool nStartsWith(string s, string pre, int off)
  283. {
  284. if (off >= s.Length) return false;
  285. int slen = s.Length;
  286. int plen = pre.Length;
  287. if (off+plen > s.Length) return false;
  288. for (int i=0; i<plen && i+off<slen; i++)
  289. if (s[i+off] != pre[i]) return false;
  290. return true;
  291. }
  292. //////////////////////////////////////////////////////////////////////////
  293. // Iterators
  294. //////////////////////////////////////////////////////////////////////////
  295. public static List chars(string self)
  296. {
  297. int len = self.Length;
  298. if (len == 0) return Sys.IntType.emptyList();
  299. Long[] chars = new Long[len];
  300. for (int i=0; i<len; ++i) chars[i] = Long.valueOf(self[i]);
  301. return new List(Sys.IntType, chars);
  302. }
  303. public static void each(string self, Func f)
  304. {
  305. int len = self.Length;
  306. for (int i=0; i<len ; i++)
  307. f.call(self[i], i);
  308. }
  309. public static void eachr(string self, Func f)
  310. {
  311. for (int i=self.Length-1; i>=0; --i)
  312. f.call(self[i], i);
  313. }
  314. public static bool any(string self, Func f)
  315. {
  316. int len = self.Length;
  317. for (int i=0; i<len ; i++)
  318. if (f.call(self[i], i) == Boolean.True)
  319. return true;
  320. return false;
  321. }
  322. public static bool all(string self, Func f)
  323. {
  324. int len = self.Length;
  325. for (int i=0; i<len ; i++)
  326. if (f.call(self[i], i) == Boolean.False)
  327. return false;
  328. return true;
  329. }
  330. //////////////////////////////////////////////////////////////////////////
  331. // Utils
  332. //////////////////////////////////////////////////////////////////////////
  333. public static string spaces(long n)
  334. {
  335. // do an array lookup for reasonable length
  336. // strings since that is the common case
  337. int count = (int)n;
  338. try { return m_spaces[count]; } catch (IndexOutOfRangeException) {}
  339. // otherwise we build a new one
  340. StringBuilder s = new StringBuilder(m_spaces[m_spaces.Length-1]);
  341. for (int i=m_spaces.Length-1; i<count; i++)
  342. s.Append(' ');
  343. return s.ToString();
  344. }
  345. public static string lower(string self)
  346. {
  347. StringBuilder s = new StringBuilder(self.Length);
  348. for (int i=0; i<self.Length; i++)
  349. {
  350. int ch = self[i];
  351. if ('A' <= ch && ch <= 'Z') ch |= 0x20;
  352. s.Append((char)ch);
  353. }
  354. return s.ToString();
  355. }
  356. public static string upper(string self)
  357. {
  358. StringBuilder s = new StringBuilder(self.Length);
  359. for (int i=0; i<self.Length; i++)
  360. {
  361. int ch = self[i];
  362. if ('a' <= ch && ch <= 'z') ch &= ~0x20;
  363. s.Append((char)ch);
  364. }
  365. return s.ToString();
  366. }
  367. public static string capitalize(string self)
  368. {
  369. if (self.Length > 0)
  370. {
  371. int ch = self[0];
  372. if ('a' <= ch && ch <= 'z')
  373. {
  374. StringBuilder s = new StringBuilder(self.Length);
  375. s.Append((char)(ch & ~0x20));
  376. s.Append(self, 1, self.Length-1);
  377. return s.ToString();
  378. }
  379. }
  380. return self;
  381. }
  382. public static string decapitalize(string self)
  383. {
  384. if (self.Length > 0)
  385. {
  386. int ch = self[0];
  387. if ('A' <= ch && ch <= 'Z')
  388. {
  389. StringBuilder s = new StringBuilder(self.Length);
  390. s.Append((char)(ch | 0x20));
  391. s.Append(self, 1, self.Length-1);
  392. return s.ToString();
  393. }
  394. }
  395. return self;
  396. }
  397. public static string toDisplayName(string self)
  398. {
  399. if (self.Length == 0) return "";
  400. StringBuilder s = new StringBuilder(self.Length+4);
  401. // capitalize first word
  402. int c = self[0];
  403. if ('a' <= c && c <= 'z') c &= ~0x20;
  404. s.Append((char)c);
  405. // insert spaces before every capital
  406. int last = c;
  407. for (int i=1; i<self.Length; ++i)
  408. {
  409. c = self[i];
  410. if ('A' <= c && c <= 'Z' && last != '_')
  411. {
  412. int next = i+1 < self.Length ? self[i+1] : 'Q';
  413. if (!('A' <= last && last <= 'Z') || !('A' <= next && next <= 'Z'))
  414. s.Append(' ');
  415. }
  416. else if ('a' <= c && c <= 'z')
  417. {
  418. if ('0' <= last && last <= '9') { s.Append(' '); c &= ~0x20; }
  419. else if (last == '_') c &= ~0x20;
  420. }
  421. else if ('0' <= c && c <= '9')
  422. {
  423. if (!('0' <= last && last <= '9')) s.Append(' ');
  424. }
  425. else if (c == '_')
  426. {
  427. s.Append(' ');
  428. last = c;
  429. continue;
  430. }
  431. s.Append((char)c);
  432. last = c;
  433. }
  434. return s.ToString();
  435. }
  436. public static string fromDisplayName(string self)
  437. {
  438. if (self.Length == 0) return "";
  439. StringBuilder s = new StringBuilder(self.Length);
  440. int c = self[0];
  441. int c2 = self.Length == 1 ? 0 : self[1];
  442. if ('A' <= c && c <= 'Z' && !('A' <= c2 && c2 <= 'Z')) c |= 0x20;
  443. s.Append((char)c);
  444. int last = c;
  445. for (int i=1; i<self.Length; ++i)
  446. {
  447. c = self[i];
  448. if (c != ' ')
  449. {
  450. if (last == ' ' && 'a' <= c && c <= 'z') c &= ~0x20;
  451. s.Append((char)c);
  452. }
  453. last = c;
  454. }
  455. return s.ToString();
  456. }
  457. public static string justl(string self, long width)
  458. {
  459. return padr(self, width, ' ');
  460. }
  461. public static string justr(string self, long width)
  462. {
  463. return padl(self, width, ' ');
  464. }
  465. public static string padl(string self, long width) { return padl(self, width, ' '); }
  466. public static string padl(string self, long width, long ch)
  467. {
  468. int w = (int)width;
  469. if (self.Length >= w) return self;
  470. char c = (char)ch;
  471. StringBuilder s = new StringBuilder(w);
  472. for (int i=self.Length; i<w; i++) s.Append(c);
  473. s.Append(self);
  474. return s.ToString();
  475. }
  476. public static string padr(string self, long width) { return padr(self, width, ' '); }
  477. public static string padr(string self, long width, long ch)
  478. {
  479. int w = (int)width;
  480. if (self.Length >= w) return self;
  481. char c = (char)ch;
  482. StringBuilder s = new StringBuilder(w);
  483. s.Append(self);
  484. for (int i=self.Length; i<w; i++) s.Append(c);
  485. return s.ToString();
  486. }
  487. public static string reverse(string self)
  488. {
  489. if (self.Length < 2) return self;
  490. StringBuilder s = new StringBuilder(self.Length);
  491. for (int i=self.Length-1; i>=0; i--)
  492. s.Append(self[i]);
  493. return s.ToString();
  494. }
  495. public static string trim(string self)
  496. {
  497. int len = self.Length;
  498. if (len == 0) return self;
  499. if (self[0] > ' ' && self[len-1] > ' ') return self;
  500. return self.Trim(m_trimChars);
  501. }
  502. public static string trimStart(string self)
  503. {
  504. int len = self.Length;
  505. if (len == 0) return self;
  506. if (self[0] > ' ') return self;
  507. int pos = 1;
  508. while (pos < len && self[pos] <= ' ') pos++;
  509. return self.Substring(pos, len-pos);
  510. }
  511. public static string trimEnd(string self)
  512. {
  513. int len = self.Length;
  514. if (len == 0) return self;
  515. int pos = len-1;
  516. if (self[pos] > ' ') return self;
  517. while (pos >= 0 && self[pos] <= ' ') pos--;
  518. return self.Substring(0, pos+1);
  519. }
  520. public static List split(string self) { return split(self, null, true); }
  521. public static List split(string self, Long separator) { return split(self, separator, true); }
  522. public static List split(string self, Long separator, bool trim)
  523. {
  524. if (separator == null) return splitws(self);
  525. int sep = separator.intValue();
  526. List toks = new List(Sys.StrType, 16);
  527. int len = self.Length;
  528. int x = 0;
  529. for (int i=0; i<len; ++i)
  530. {
  531. if (self[i] != sep) continue;
  532. if (x <= i) toks.add(splitStr(self, x, i, trim));
  533. x = i+1;
  534. }
  535. if (x <= len) toks.add(splitStr(self, x, len, trim));
  536. return toks;
  537. }
  538. private static string splitStr(String val, int s, int e, bool trim)
  539. {
  540. if (trim)
  541. {
  542. while (s < e && val[s] <= ' ') ++s;
  543. while (e > s && val[e-1] <= ' ') --e;
  544. }
  545. return val.Substring(s, e-s);
  546. }
  547. public static List splitws(String val)
  548. {
  549. List toks = new List(Sys.StrType, 16);
  550. int len = val.Length;
  551. while (len > 0 && val[len-1] <= ' ') --len;
  552. int x = 0;
  553. while (x < len && val[x] <= ' ') ++x;
  554. for (int i=x; i<len; ++i)
  555. {
  556. if (val[i] > ' ') continue;
  557. toks.add(val.Substring(x, i-x));
  558. x = i + 1;
  559. while (x < len && val[x] <= ' ') ++x;
  560. i = x;
  561. }
  562. if (x <= len) toks.add(val.Substring(x, len-x));
  563. if (toks.sz() == 0) toks.add("");
  564. return toks;
  565. }
  566. public static List splitLines(string self)
  567. {
  568. List lines = new List(Sys.StrType, 16);
  569. int len = self.Length;
  570. int s = 0;
  571. for (int i=0; i<len; ++i)
  572. {
  573. int c = self[i];
  574. if (c == '\n' || c == '\r')
  575. {
  576. lines.add(self.Substring(s, i-s));
  577. s = i+1;
  578. if (c == '\r' && s < len && self[s] == '\n') { i++; s++; }
  579. }
  580. }
  581. lines.add(self.Substring(s, len-s));
  582. return lines;
  583. }
  584. public static string replace(string self, string from, string to)
  585. {
  586. if (self.Length == 0) return self;
  587. return StrUtil.Replace(self, from, to);
  588. }
  589. public static long numNewlines(string self)
  590. {
  591. int numLines = 0;
  592. int len = self.Length;
  593. for (int i=0; i<len; ++i)
  594. {
  595. int c = self[i];
  596. if (c == '\n') numLines++;
  597. else if (c == '\r')
  598. {
  599. numLines++;
  600. if (i+1<len && self[i+1] == '\n') i++;
  601. }
  602. }
  603. return numLines;
  604. }
  605. public static bool isAscii(string self)
  606. {
  607. int len = self.Length;
  608. for (int i=0; i<len; ++i)
  609. if (self[i] >= 128) return false;
  610. return true;
  611. }
  612. public static bool isSpace(string self)
  613. {
  614. int len = self.Length;
  615. for (int i=0; i<len; i++)
  616. {
  617. int ch = self[i];
  618. if (ch >= 128 || (FanInt.charMap[ch] & FanInt.SPACE) == 0)
  619. return false;
  620. }
  621. return true;
  622. }
  623. public static bool isUpper(string self)
  624. {
  625. int len = self.Length;
  626. for (int i=0; i<len; ++i)
  627. {
  628. int ch = self[i];
  629. if (ch >= 128 || (FanInt.charMap[ch] & FanInt.UPPER) == 0)
  630. return false;
  631. }
  632. return true;
  633. }
  634. public static bool isLower(string self)
  635. {
  636. int len = self.Length;
  637. for (int i=0; i<len; ++i)
  638. {
  639. int ch = self[i];
  640. if (ch >= 128 || (FanInt.charMap[ch] & FanInt.LOWER) == 0)
  641. return false;
  642. }
  643. return true;
  644. }
  645. public static bool isAlpha(string self)
  646. {
  647. int len = self.Length;
  648. for (int i=0; i<len; ++i)
  649. {
  650. int ch = self[i];
  651. if (ch >= 128 || (FanInt.charMap[ch] & FanInt.ALPHA) == 0)
  652. return false;
  653. }
  654. return true;
  655. }
  656. public static bool isAlphaNum(string self)
  657. {
  658. int len = self.Length;
  659. for (int i=0; i<len; ++i)
  660. {
  661. int ch = self[i];
  662. if (ch >= 128 || (FanInt.charMap[ch] & FanInt.ALPHANUM) == 0)
  663. return false;
  664. }
  665. return true;
  666. }
  667. public static bool isEveryChar(string self, int ch)
  668. {
  669. int len = self.Length;
  670. for (int i=0; i<len; ++i)
  671. if (self[i] != ch) return false;
  672. return true;
  673. }
  674. public static InStream @in(string self)
  675. {
  676. return new StrInStream(self);
  677. }
  678. public static Buf toBuf(string self) { return toBuf(self, Charset.m_utf8); }
  679. public static Buf toBuf(string self, Charset charset)
  680. {
  681. MemBuf buf = new MemBuf(self.Length*2);
  682. buf.charset(charset);
  683. buf.print(self);
  684. return buf.flip();
  685. }
  686. //////////////////////////////////////////////////////////////////////////
  687. // Locale
  688. //////////////////////////////////////////////////////////////////////////
  689. public static long localeCompare(string self, string x)
  690. {
  691. int cmp = String.Compare(self, x, true, Locale.cur().dotnet());
  692. if (cmp < 0) return -1;
  693. return cmp == 0 ? 0 : +1;
  694. }
  695. public static string localeLower(string self)
  696. {
  697. return self.ToLower(Locale.cur().dotnet());
  698. }
  699. public static string localeUpper(string self)
  700. {
  701. return self.ToUpper(Locale.cur().dotnet());
  702. }
  703. public static string localeCapitalize(string self)
  704. {
  705. if (self.Length > 0)
  706. {
  707. int ch = self[0];
  708. if (Char.IsLower((char)ch))
  709. {
  710. StringBuilder s = new StringBuilder(self.Length);
  711. s.Append(Char.ToUpper((char)ch, Locale.cur().dotnet()));
  712. s.Append(self, 1, self.Length-1);
  713. return s.ToString();
  714. }
  715. }
  716. return self;
  717. }
  718. public static string localeDecapitalize(string self)
  719. {
  720. if (self.Length > 0)
  721. {
  722. int ch = self[0];
  723. if (Char.IsUpper((char)ch))
  724. {
  725. StringBuilder s = new StringBuilder(self.Length);
  726. s.Append(Char.ToLower((char)ch, Locale.cur().dotnet()));
  727. s.Append(self, 1, self.Length-1);
  728. return s.ToString();
  729. }
  730. }
  731. return self;
  732. }
  733. //////////////////////////////////////////////////////////////////////////
  734. // Conversion
  735. //////////////////////////////////////////////////////////////////////////
  736. public static Boolean toBool(string self) { return FanBool.fromStr(self, true); }
  737. public static Boolean toBool(string self, bool check) { return FanBool.fromStr(self, check); }
  738. public static Long toInt(string self) { return FanInt.fromStr(self, 10, true); }
  739. public static Long toInt(string self, long radix) { return FanInt.fromStr(self, radix, true); }
  740. public static Long toInt(string self, long radix, bool check) { return FanInt.fromStr(self, radix, check); }
  741. public static Double toFloat(string self) { return FanFloat.fromStr(self, true); }
  742. public static Double toFloat(string self, bool check) { return FanFloat.fromStr(self, check); }
  743. public static BigDecimal toDecimal(string self) { return FanDecimal.fromStr(self, true); }
  744. public static BigDecimal toDecimal(string self, bool check) { return FanDecimal.fromStr(self, check); }
  745. public static Uri toUri(string self) { return Uri.fromStr(self); }
  746. public static Regex toRegex(string self) { return Regex.fromStr(self); }
  747. public static string toCode(string self) { return toCode(self, Long.valueOf('"'), false); }
  748. public static string toCode(string self, Long quote) { return toCode(self, quote, false); }
  749. public static string toCode(string self, Long quote, bool escapeUnicode)
  750. {
  751. StringBuilder s = new StringBuilder(self.Length+10);
  752. // opening quote
  753. bool escu = escapeUnicode;
  754. int q = 0;
  755. if (quote != null)
  756. {
  757. q = quote.intValue();
  758. s.Append((char)q);
  759. }
  760. // NOTE: these escape sequences are duplicated in ObjEncoder
  761. int len = self.Length;
  762. for (int i=0; i<len; ++i)
  763. {
  764. int c = self[i];
  765. switch (c)
  766. {
  767. case '\n': s.Append('\\').Append('n'); break;
  768. case '\r': s.Append('\\').Append('r'); break;
  769. case '\f': s.Append('\\').Append('f'); break;
  770. case '\t': s.Append('\\').Append('t'); break;
  771. case '\\': s.Append('\\').Append('\\'); break;
  772. case '"': if (q == '"') s.Append('\\').Append('"'); else s.Append((char)c); break;
  773. case '`': if (q == '`') s.Append('\\').Append('`'); else s.Append((char)c); break;
  774. case '\'': if (q == '\'') s.Append('\\').Append('\''); else s.Append((char)c); break;
  775. case '$': s.Append('\\').Append('$'); break;
  776. default:
  777. if (c < ' ' || (escu && c > 127))
  778. {
  779. s.Append('\\').Append('u')
  780. .Append((char)hex((c>>12)&0xf))
  781. .Append((char)hex((c>>8)&0xf))
  782. .Append((char)hex((c>>4)&0xf))
  783. .Append((char)hex(c&0xf));
  784. }
  785. else
  786. {
  787. s.Append((char)c);
  788. }
  789. break;
  790. }
  791. }
  792. // closing quote
  793. if (q != 0) s.Append((char)q);
  794. return s.ToString();
  795. }
  796. private static int hex(int nib) { return "0123456789abcdef"[nib]; }
  797. public static string toXml(string self)
  798. {
  799. StringBuilder s = null;
  800. int len = self.Length;
  801. for (int i=0; i<len; ++i)
  802. {
  803. int c = self[i];
  804. if (c > '>')
  805. {
  806. if (s != null) s.Append((char)c);
  807. }
  808. else
  809. {
  810. string esc = m_xmlEsc[c];
  811. if (esc != null && (c != '>' || i==0 || self[i-1] == ']'))
  812. {
  813. if (s == null)
  814. {
  815. s = new StringBuilder(len+12);
  816. s.Append(self, 0, i);
  817. }
  818. s.Append(esc);
  819. }
  820. else if (s != null)
  821. {
  822. s.Append((char)c);
  823. }
  824. }
  825. }
  826. if (s == null) return self;
  827. return s.ToString();
  828. }
  829. //////////////////////////////////////////////////////////////////////////
  830. // Fields
  831. //////////////////////////////////////////////////////////////////////////
  832. private static readonly Hashtable interns = new Hashtable();
  833. public static readonly string m_defVal = "";
  834. internal static readonly string[] m_ascii = new string[128];
  835. internal static string[] m_spaces = new string[20];
  836. internal static readonly char[] m_trimChars;
  837. internal static string[] m_xmlEsc = new string['>'+1];
  838. static FanStr()
  839. {
  840. // ascii
  841. for (int i=0; i<m_ascii.Length; i++)
  842. m_ascii[i] = String.Intern(""+(char)i);
  843. // spaces
  844. StringBuilder s = new StringBuilder();
  845. for (int i=0; i<m_spaces.Length; i++)
  846. {
  847. m_spaces[i] = s.ToString();
  848. s.Append(' ');
  849. }
  850. // trim chars
  851. m_trimChars = new char[0x20+1];
  852. for (int i=0; i<=0x20; i++)
  853. m_trimChars[i] = (char)i;
  854. // xml
  855. m_xmlEsc['&'] = "&amp;";
  856. m_xmlEsc['<'] = "&lt;";
  857. m_xmlEsc['>'] = "&gt;";
  858. m_xmlEsc['\''] = "&#39;";
  859. m_xmlEsc['"'] = "&quot;";
  860. }
  861. }
  862. }