StringTools.hx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*
  2. * Copyright (c) 2005, The haXe Project Contributors
  3. * All rights reserved.
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * - Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * - Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  20. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  23. * DAMAGE.
  24. */
  25. /**
  26. The StringTools class contains some extra functionalities for [String]
  27. manipulation. It's stored in a different class in order to prevent
  28. the standard [String] of being bloated and thus increasing the size of
  29. each application using it.
  30. **/
  31. #if cs
  32. @:keep
  33. #end
  34. class StringTools {
  35. /**
  36. Encode an URL by using the standard format.
  37. **/
  38. public #if php inline #end static function urlEncode( s : String ) : String untyped {
  39. #if flash9
  40. return __global__["encodeURIComponent"](s);
  41. #elseif flash
  42. return _global["escape"](s);
  43. #elseif neko
  44. return new String(_urlEncode(s.__s));
  45. #elseif js
  46. return encodeURIComponent(s);
  47. #elseif php
  48. return __call__("rawurlencode", s);
  49. #elseif cpp
  50. return s.__URLEncode();
  51. #elseif java
  52. try
  53. return untyped __java__("java.net.URLEncoder.encode(s, \"UTF-8\")")
  54. catch (e:Dynamic) throw e;
  55. #elseif cs
  56. return untyped __cs__("System.Uri.EscapeUriString(s)");
  57. #else
  58. return null;
  59. #end
  60. }
  61. /**
  62. Decode an URL using the standard format.
  63. **/
  64. public #if php inline #end static function urlDecode( s : String ) : String untyped {
  65. #if flash9
  66. return __global__["decodeURIComponent"](s.split("+").join(" "));
  67. #elseif flash
  68. return _global["unescape"](s);
  69. #elseif neko
  70. return new String(_urlDecode(s.__s));
  71. #elseif js
  72. return decodeURIComponent(s.split("+").join(" "));
  73. #elseif php
  74. return __call__("urldecode", s);
  75. #elseif cpp
  76. return s.__URLDecode();
  77. #elseif java
  78. try
  79. return untyped __java__("java.net.URLDecoder.decode(s, \"UTF-8\")")
  80. catch (e:Dynamic) throw e;
  81. #elseif cs
  82. return untyped __cs__("System.Uri.UnescapeDataString(s)");
  83. #else
  84. return null;
  85. #end
  86. }
  87. /**
  88. Escape HTML special characters of the string.
  89. **/
  90. public static function htmlEscape( s : String ) : String {
  91. return s.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;");
  92. }
  93. /**
  94. Unescape HTML special characters of the string.
  95. **/
  96. public #if php inline #end static function htmlUnescape( s : String ) : String {
  97. #if php
  98. return untyped __call__("htmlspecialchars_decode", s);
  99. #else
  100. return s.split("&gt;").join(">").split("&lt;").join("<").split("&amp;").join("&");
  101. #end
  102. }
  103. /**
  104. Tells if the string [s] starts with the string [start].
  105. **/
  106. public static #if (cs || java) inline #end function startsWith( s : String, start : String ) : Bool {
  107. #if java
  108. return untyped s.startsWith(start);
  109. #elseif cs
  110. return untyped s.StartsWith(start);
  111. #else
  112. return( s.length >= start.length && s.substr(0, start.length) == start );
  113. #end
  114. }
  115. /**
  116. Tells if the string [s] ends with the string [end].
  117. **/
  118. public static #if (cs || java) inline #end function endsWith( s : String, end : String ) : Bool {
  119. #if java
  120. return untyped s.endsWith(end);
  121. #elseif cs
  122. return untyped s.EndsWith(end);
  123. #else
  124. var elen = end.length;
  125. var slen = s.length;
  126. return( slen >= elen && s.substr(slen - elen, elen) == end );
  127. #end
  128. }
  129. /**
  130. Tells if the character in the string [s] at position [pos] is a space.
  131. **/
  132. public static function isSpace( s : String, pos : Int ) : Bool {
  133. var c = s.charCodeAt( pos );
  134. return (c >= 9 && c <= 13) || c == 32;
  135. }
  136. /**
  137. Removes spaces at the left of the String [s].
  138. **/
  139. public #if (php || cs) inline #end static function ltrim( s : String ) : String {
  140. #if php
  141. return untyped __call__("ltrim", s);
  142. #elseif cs
  143. return untyped s.TrimStart();
  144. #else
  145. var l = s.length;
  146. var r = 0;
  147. while( r < l && isSpace(s,r) ){
  148. r++;
  149. }
  150. if( r > 0 )
  151. return s.substr(r, l-r);
  152. else
  153. return s;
  154. #end
  155. }
  156. /**
  157. Removes spaces at the right of the String [s].
  158. **/
  159. public #if (php || cs) inline #end static function rtrim( s : String ) : String {
  160. #if php
  161. return untyped __call__("rtrim", s);
  162. #elseif cs
  163. return untyped s.TrimEnd();
  164. #else
  165. var l = s.length;
  166. var r = 0;
  167. while( r < l && isSpace(s,l-r-1) ){
  168. r++;
  169. }
  170. if( r > 0 ){
  171. return s.substr(0, l-r);
  172. }else{
  173. return s;
  174. }
  175. #end
  176. }
  177. /**
  178. Removes spaces at the beginning and the end of the String [s].
  179. **/
  180. public #if (php || cs || java) inline #end static function trim( s : String ) : String {
  181. #if php
  182. return untyped __call__("trim", s);
  183. #elseif cs
  184. return untyped s.Trim();
  185. #elseif java
  186. return untyped s.trim();
  187. #else
  188. return ltrim(rtrim(s));
  189. #end
  190. }
  191. /**
  192. Pad the string [s] by appending [c] at its right until it reach [l] characters.
  193. **/
  194. public #if php inline #end static function rpad( s : String, c : String, l : Int ) : String {
  195. #if php
  196. return untyped __call__("str_pad", s, l, c, __php__("STR_PAD_RIGHT"));
  197. #else
  198. var sl = s.length;
  199. var cl = c.length;
  200. while( sl < l ){
  201. if( l - sl < cl ){
  202. s += c.substr(0,l-sl);
  203. sl = l;
  204. }else{
  205. s += c;
  206. sl += cl;
  207. }
  208. }
  209. return s;
  210. #end
  211. }
  212. /**
  213. Pad the string [s] by appending [c] at its left until it reach [l] characters.
  214. **/
  215. public #if php inline #end static function lpad( s : String, c : String, l : Int ) : String {
  216. #if php
  217. return untyped __call__("str_pad", s, l, c, __php__("STR_PAD_LEFT"));
  218. #else
  219. var ns = "";
  220. var sl = s.length;
  221. if( sl >= l ) return s;
  222. var cl = c.length;
  223. while( sl < l ){
  224. if( l - sl < cl ){
  225. ns += c.substr(0,l-sl);
  226. sl = l;
  227. }else{
  228. ns += c;
  229. sl += cl;
  230. }
  231. }
  232. return ns+s;
  233. #end
  234. }
  235. /**
  236. Replace all occurences of the string [sub] in the string [s] by the string [by].
  237. **/
  238. public #if (php || java || cs) inline #end static function replace( s : String, sub : String, by : String ) : String {
  239. #if php
  240. return untyped __call__("str_replace", sub, by, s);
  241. #elseif java
  242. return untyped s.replace(sub, by);
  243. #elseif cs
  244. return untyped s.Replace(sub, by);
  245. #else
  246. return s.split(sub).join(by);
  247. #end
  248. }
  249. /**
  250. Encode a number into a hexadecimal representation, with an optional number of zeros for left padding.
  251. **/
  252. public static function hex( n : Int, ?digits : Int ) {
  253. #if flash9
  254. var n : UInt = n;
  255. var s : String = untyped n.toString(16);
  256. s = s.toUpperCase();
  257. #else
  258. var s = "";
  259. var hexChars = "0123456789ABCDEF";
  260. do {
  261. s = hexChars.charAt(n&15) + s;
  262. n >>>= 4;
  263. } while( n > 0 );
  264. #end
  265. if( digits != null )
  266. while( s.length < digits )
  267. s = "0"+s;
  268. return s;
  269. }
  270. /**
  271. Provides a fast native string charCodeAt access. Since the EOF value might vary depending on the platforms, always test with StringTools.isEOF.
  272. Only guaranteed to work if index in [0,s.length] range. Might not work with strings containing \0 char.
  273. **/
  274. public static inline function fastCodeAt( s : String, index : Int ) : Int untyped {
  275. #if neko
  276. return untyped __dollar__sget(s.__s, index);
  277. #elseif cpp
  278. return s.cca(index);
  279. #elseif flash9
  280. return s.cca(index);
  281. #elseif flash
  282. return s["cca"](index);
  283. #elseif java
  284. return ( index < s.length ) ? cast(_charAt(s, index), Int) : -1;
  285. #elseif cs
  286. return ( cast(index, UInt) < s.length ) ? cast(untyped s[index], Int) : -1;
  287. #elseif js
  288. #if mt
  289. return (untyped s).cca(index);
  290. #else
  291. return (untyped s).charCodeAt(index);
  292. #end
  293. #else
  294. return s.cca(index);
  295. #end
  296. }
  297. #if java
  298. private static inline function _charAt(str:String, idx:Int):java.StdTypes.Char16 return untyped str._charAt(idx)
  299. #end
  300. /*
  301. Only to use together with fastCodeAt.
  302. */
  303. public static inline function isEOF( c : Int ) : Bool {
  304. #if (flash9 || cpp)
  305. return c == 0;
  306. #elseif flash8
  307. return c <= 0; // fast NaN
  308. #elseif js
  309. return c != c; // fast NaN
  310. #elseif neko
  311. return c == null;
  312. #elseif cs
  313. return c == -1;
  314. #elseif java
  315. return c == -1;
  316. #else
  317. return false;
  318. #end
  319. }
  320. #if neko
  321. private static var _urlEncode = neko.Lib.load("std","url_encode",1);
  322. private static var _urlDecode = neko.Lib.load("std","url_decode",1);
  323. #end
  324. }