641 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			641 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright (C)2005-2019 Haxe Foundation
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Permission is hereby granted, free of charge, to any person obtaining a
							 | 
						||
| 
								 | 
							
								 * copy of this software and associated documentation files (the "Software"),
							 | 
						||
| 
								 | 
							
								 * to deal in the Software without restriction, including without limitation
							 | 
						||
| 
								 | 
							
								 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
							 | 
						||
| 
								 | 
							
								 * and/or sell copies of the Software, and to permit persons to whom the
							 | 
						||
| 
								 | 
							
								 * Software is furnished to do so, subject to the following conditions:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The above copyright notice and this permission notice shall be included in
							 | 
						||
| 
								 | 
							
								 * all copies or substantial portions of the Software.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
							 | 
						||
| 
								 | 
							
								 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
							 | 
						||
| 
								 | 
							
								 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
							 | 
						||
| 
								 | 
							
								 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
							 | 
						||
| 
								 | 
							
								 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
							 | 
						||
| 
								 | 
							
								 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
							 | 
						||
| 
								 | 
							
								 * DEALINGS IN THE SOFTWARE.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import haxe.iterators.StringIterator;
							 | 
						||
| 
								 | 
							
								import haxe.iterators.StringKeyValueIterator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if cpp
							 | 
						||
| 
								 | 
							
								using cpp.NativeString;
							 | 
						||
| 
								 | 
							
								#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
									This class provides advanced methods on Strings. It is ideally used with
							 | 
						||
| 
								 | 
							
									`using StringTools` and then acts as an [extension](https://haxe.org/manual/lf-static-extension.html)
							 | 
						||
| 
								 | 
							
									to the `String` class.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									If the first argument to any of the methods is null, the result is
							 | 
						||
| 
								 | 
							
									unspecified.
							 | 
						||
| 
								 | 
							
								**/
							 | 
						||
| 
								 | 
							
								class StringTools {
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Encode an URL by using the standard format.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									#if (!java && !cpp && !lua && !eval) inline #end public static function urlEncode(s:String):String {
							 | 
						||
| 
								 | 
							
										#if flash
							 | 
						||
| 
								 | 
							
										return untyped __global__["encodeURIComponent"](s);
							 | 
						||
| 
								 | 
							
										#elseif neko
							 | 
						||
| 
								 | 
							
										return untyped new String(_urlEncode(s.__s));
							 | 
						||
| 
								 | 
							
										#elseif js
							 | 
						||
| 
								 | 
							
										return untyped encodeURIComponent(s);
							 | 
						||
| 
								 | 
							
										#elseif cpp
							 | 
						||
| 
								 | 
							
										return untyped s.__URLEncode();
							 | 
						||
| 
								 | 
							
										#elseif java
							 | 
						||
| 
								 | 
							
										return postProcessUrlEncode(java.net.URLEncoder.encode(s, "UTF-8"));
							 | 
						||
| 
								 | 
							
										#elseif cs
							 | 
						||
| 
								 | 
							
										return untyped cs.system.Uri.EscapeDataString(s);
							 | 
						||
| 
								 | 
							
										#elseif python
							 | 
						||
| 
								 | 
							
										return python.lib.urllib.Parse.quote(s, "");
							 | 
						||
| 
								 | 
							
										#elseif hl
							 | 
						||
| 
								 | 
							
										var len = 0;
							 | 
						||
| 
								 | 
							
										var b = @:privateAccess s.bytes.urlEncode(len);
							 | 
						||
| 
								 | 
							
										return @:privateAccess String.__alloc__(b, len);
							 | 
						||
| 
								 | 
							
										#elseif lua
							 | 
						||
| 
								 | 
							
										s = lua.NativeStringTools.gsub(s, "\n", "\r\n");
							 | 
						||
| 
								 | 
							
										s = lua.NativeStringTools.gsub(s, "([^%w %-%_%.%~])", function(c) {
							 | 
						||
| 
								 | 
							
											return lua.NativeStringTools.format("%%%02X", lua.NativeStringTools.byte(c) + '');
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
										s = lua.NativeStringTools.gsub(s, " ", "+");
							 | 
						||
| 
								 | 
							
										return s;
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#if java
							 | 
						||
| 
								 | 
							
									private static function postProcessUrlEncode(s:String):String {
							 | 
						||
| 
								 | 
							
										var ret = new StringBuf();
							 | 
						||
| 
								 | 
							
										var i = 0, len = s.length;
							 | 
						||
| 
								 | 
							
										while (i < len) {
							 | 
						||
| 
								 | 
							
											switch (_charAt(s, i++)) {
							 | 
						||
| 
								 | 
							
												case '+'.code:
							 | 
						||
| 
								 | 
							
													ret.add('%20');
							 | 
						||
| 
								 | 
							
												case '%'.code if (i <= len - 2):
							 | 
						||
| 
								 | 
							
													var c1 = _charAt(s, i++), c2 = _charAt(s, i++);
							 | 
						||
| 
								 | 
							
													switch [c1, c2] {
							 | 
						||
| 
								 | 
							
														case ['2'.code, '1'.code]:
							 | 
						||
| 
								 | 
							
															ret.addChar('!'.code);
							 | 
						||
| 
								 | 
							
														case ['2'.code, '7'.code]:
							 | 
						||
| 
								 | 
							
															ret.addChar('\''.code);
							 | 
						||
| 
								 | 
							
														case ['2'.code, '8'.code]:
							 | 
						||
| 
								 | 
							
															ret.addChar('('.code);
							 | 
						||
| 
								 | 
							
														case ['2'.code, '9'.code]:
							 | 
						||
| 
								 | 
							
															ret.addChar(')'.code);
							 | 
						||
| 
								 | 
							
														case ['7'.code, 'E'.code] | ['7'.code, 'e'.code]:
							 | 
						||
| 
								 | 
							
															ret.addChar('~'.code);
							 | 
						||
| 
								 | 
							
														case _:
							 | 
						||
| 
								 | 
							
															ret.addChar('%'.code);
							 | 
						||
| 
								 | 
							
															ret.addChar(cast c1);
							 | 
						||
| 
								 | 
							
															ret.addChar(cast c2);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												case var chr:
							 | 
						||
| 
								 | 
							
													ret.addChar(cast chr);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return ret.toString();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Decode an URL using the standard format.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									#if (!java && !cpp && !lua && !eval) inline #end public static function urlDecode(s:String):String {
							 | 
						||
| 
								 | 
							
										#if flash
							 | 
						||
| 
								 | 
							
										return untyped __global__["decodeURIComponent"](s.split("+").join(" "));
							 | 
						||
| 
								 | 
							
										#elseif neko
							 | 
						||
| 
								 | 
							
										return untyped new String(_urlDecode(s.__s));
							 | 
						||
| 
								 | 
							
										#elseif js
							 | 
						||
| 
								 | 
							
										return untyped decodeURIComponent(s.split("+").join(" "));
							 | 
						||
| 
								 | 
							
										#elseif cpp
							 | 
						||
| 
								 | 
							
										return untyped s.__URLDecode();
							 | 
						||
| 
								 | 
							
										#elseif java
							 | 
						||
| 
								 | 
							
										try
							 | 
						||
| 
								 | 
							
											return java.net.URLDecoder.decode(s, "UTF-8")
							 | 
						||
| 
								 | 
							
										catch (e:Dynamic)
							 | 
						||
| 
								 | 
							
											throw e;
							 | 
						||
| 
								 | 
							
										#elseif cs
							 | 
						||
| 
								 | 
							
										return untyped cs.system.Uri.UnescapeDataString(s);
							 | 
						||
| 
								 | 
							
										#elseif python
							 | 
						||
| 
								 | 
							
										return python.lib.urllib.Parse.unquote(s);
							 | 
						||
| 
								 | 
							
										#elseif hl
							 | 
						||
| 
								 | 
							
										var len = 0;
							 | 
						||
| 
								 | 
							
										var b = @:privateAccess s.bytes.urlDecode(len);
							 | 
						||
| 
								 | 
							
										return @:privateAccess String.__alloc__(b, len);
							 | 
						||
| 
								 | 
							
										#elseif lua
							 | 
						||
| 
								 | 
							
										s = lua.NativeStringTools.gsub(s, "+", " ");
							 | 
						||
| 
								 | 
							
										s = lua.NativeStringTools.gsub(s, "%%(%x%x)", function(h) {
							 | 
						||
| 
								 | 
							
											return lua.NativeStringTools.char(lua.Lua.tonumber(h, 16));
							 | 
						||
| 
								 | 
							
										});
							 | 
						||
| 
								 | 
							
										s = lua.NativeStringTools.gsub(s, "\r\n", "\n");
							 | 
						||
| 
								 | 
							
										return s;
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Escapes HTML special characters of the string `s`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										The following replacements are made:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										- `&` becomes `&`;
							 | 
						||
| 
								 | 
							
										- `<` becomes `<`;
							 | 
						||
| 
								 | 
							
										- `>` becomes `>`;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `quotes` is true, the following characters are also replaced:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										- `"` becomes `"`;
							 | 
						||
| 
								 | 
							
										- `'` becomes `'`;
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static function htmlEscape(s:String, ?quotes:Bool):String {
							 | 
						||
| 
								 | 
							
										var buf = new StringBuf();
							 | 
						||
| 
								 | 
							
										for (code in #if neko iterator(s) #else new haxe.iterators.StringIteratorUnicode(s) #end) {
							 | 
						||
| 
								 | 
							
											switch (code) {
							 | 
						||
| 
								 | 
							
												case '&'.code:
							 | 
						||
| 
								 | 
							
													buf.add("&");
							 | 
						||
| 
								 | 
							
												case '<'.code:
							 | 
						||
| 
								 | 
							
													buf.add("<");
							 | 
						||
| 
								 | 
							
												case '>'.code:
							 | 
						||
| 
								 | 
							
													buf.add(">");
							 | 
						||
| 
								 | 
							
												case '"'.code if (quotes):
							 | 
						||
| 
								 | 
							
													buf.add(""");
							 | 
						||
| 
								 | 
							
												case '\''.code if (quotes):
							 | 
						||
| 
								 | 
							
													buf.add("'");
							 | 
						||
| 
								 | 
							
												case _:
							 | 
						||
| 
								 | 
							
													buf.addChar(code);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return buf.toString();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Unescapes HTML special characters of the string `s`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										This is the inverse operation to htmlEscape, i.e. the following always
							 | 
						||
| 
								 | 
							
										holds: `htmlUnescape(htmlEscape(s)) == s`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										The replacements follow:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										- `&` becomes `&`
							 | 
						||
| 
								 | 
							
										- `<` becomes `<`
							 | 
						||
| 
								 | 
							
										- `>` becomes `>`
							 | 
						||
| 
								 | 
							
										- `"` becomes `"`
							 | 
						||
| 
								 | 
							
										- `'` becomes `'`
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static function htmlUnescape(s:String):String {
							 | 
						||
| 
								 | 
							
										return s.split(">")
							 | 
						||
| 
								 | 
							
											.join(">")
							 | 
						||
| 
								 | 
							
											.split("<")
							 | 
						||
| 
								 | 
							
											.join("<")
							 | 
						||
| 
								 | 
							
											.split(""")
							 | 
						||
| 
								 | 
							
											.join('"')
							 | 
						||
| 
								 | 
							
											.split("'")
							 | 
						||
| 
								 | 
							
											.join("'")
							 | 
						||
| 
								 | 
							
											.split("&")
							 | 
						||
| 
								 | 
							
											.join("&");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Returns `true` if `s` contains `value` and  `false` otherwise.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										When `value` is `null`, the result is unspecified.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static inline function contains(s:String, value:String):Bool {
							 | 
						||
| 
								 | 
							
										#if (js && js_es >= 6)
							 | 
						||
| 
								 | 
							
										return (cast s).includes(value);
							 | 
						||
| 
								 | 
							
										#else 
							 | 
						||
| 
								 | 
							
										return s.indexOf(value) != -1;
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Tells if the string `s` starts with the string `start`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `start` is `null`, the result is unspecified.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `start` is the empty String `""`, the result is true.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static #if (cs || java || python || (js && js_es >= 6)) inline #end function startsWith(s:String, start:String):Bool {
							 | 
						||
| 
								 | 
							
										#if java
							 | 
						||
| 
								 | 
							
										return (cast s : java.NativeString).startsWith(start);
							 | 
						||
| 
								 | 
							
										#elseif cs
							 | 
						||
| 
								 | 
							
										return untyped s.StartsWith(start);
							 | 
						||
| 
								 | 
							
										#elseif hl
							 | 
						||
| 
								 | 
							
										return @:privateAccess (s.length >= start.length && s.bytes.compare(0, start.bytes, 0, start.length << 1) == 0);
							 | 
						||
| 
								 | 
							
										#elseif python
							 | 
						||
| 
								 | 
							
										return python.NativeStringTools.startswith(s, start);
							 | 
						||
| 
								 | 
							
										#elseif (js && js_es >= 6)
							 | 
						||
| 
								 | 
							
										return (cast s).startsWith(start);
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return (s.length >= start.length && s.lastIndexOf(start, 0) == 0);
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Tells if the string `s` ends with the string `end`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `end` is `null`, the result is unspecified.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `end` is the empty String `""`, the result is true.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static #if (cs || java || python || (js && js_es >= 6)) inline #end function endsWith(s:String, end:String):Bool {
							 | 
						||
| 
								 | 
							
										#if java
							 | 
						||
| 
								 | 
							
										return (cast s : java.NativeString).endsWith(end);
							 | 
						||
| 
								 | 
							
										#elseif cs
							 | 
						||
| 
								 | 
							
										return untyped s.EndsWith(end);
							 | 
						||
| 
								 | 
							
										#elseif hl
							 | 
						||
| 
								 | 
							
										var elen = end.length;
							 | 
						||
| 
								 | 
							
										var slen = s.length;
							 | 
						||
| 
								 | 
							
										return @:privateAccess (slen >= elen && s.bytes.compare((slen - elen) << 1, end.bytes, 0, elen << 1) == 0);
							 | 
						||
| 
								 | 
							
										#elseif python
							 | 
						||
| 
								 | 
							
										return python.NativeStringTools.endswith(s, end);
							 | 
						||
| 
								 | 
							
										#elseif (js && js_es >= 6)
							 | 
						||
| 
								 | 
							
										return (cast s).endsWith(end);
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										var elen = end.length;
							 | 
						||
| 
								 | 
							
										var slen = s.length;
							 | 
						||
| 
								 | 
							
										return (slen >= elen && s.indexOf(end, (slen - elen)) == (slen - elen));
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Tells if the character in the string `s` at position `pos` is a space.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										A character is considered to be a space character if its character code
							 | 
						||
| 
								 | 
							
										is 9,10,11,12,13 or 32.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `s` is the empty String `""`, or if pos is not a valid position within
							 | 
						||
| 
								 | 
							
										`s`, the result is false.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static function isSpace(s:String, pos:Int):Bool {
							 | 
						||
| 
								 | 
							
										#if (python || lua)
							 | 
						||
| 
								 | 
							
										if (s.length == 0 || pos < 0 || pos >= s.length)
							 | 
						||
| 
								 | 
							
											return false;
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
										var c = s.charCodeAt(pos);
							 | 
						||
| 
								 | 
							
										return (c > 8 && c < 14) || c == 32;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Removes leading space characters of `s`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										This function internally calls `isSpace()` to decide which characters to
							 | 
						||
| 
								 | 
							
										remove.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `s` is the empty String `""` or consists only of space characters, the
							 | 
						||
| 
								 | 
							
										result is the empty String `""`.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public #if cs inline #end static function ltrim(s:String):String {
							 | 
						||
| 
								 | 
							
										#if cs
							 | 
						||
| 
								 | 
							
										return untyped s.TrimStart();
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										var l = s.length;
							 | 
						||
| 
								 | 
							
										var r = 0;
							 | 
						||
| 
								 | 
							
										while (r < l && isSpace(s, r)) {
							 | 
						||
| 
								 | 
							
											r++;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (r > 0)
							 | 
						||
| 
								 | 
							
											return s.substr(r, l - r);
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											return s;
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Removes trailing space characters of `s`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										This function internally calls `isSpace()` to decide which characters to
							 | 
						||
| 
								 | 
							
										remove.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `s` is the empty String `""` or consists only of space characters, the
							 | 
						||
| 
								 | 
							
										result is the empty String `""`.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public #if cs inline #end static function rtrim(s:String):String {
							 | 
						||
| 
								 | 
							
										#if cs
							 | 
						||
| 
								 | 
							
										return untyped s.TrimEnd();
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										var l = s.length;
							 | 
						||
| 
								 | 
							
										var r = 0;
							 | 
						||
| 
								 | 
							
										while (r < l && isSpace(s, l - r - 1)) {
							 | 
						||
| 
								 | 
							
											r++;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (r > 0) {
							 | 
						||
| 
								 | 
							
											return s.substr(0, l - r);
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											return s;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Removes leading and trailing space characters of `s`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										This is a convenience function for `ltrim(rtrim(s))`.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public #if (cs || java) inline #end static function trim(s:String):String {
							 | 
						||
| 
								 | 
							
										#if cs
							 | 
						||
| 
								 | 
							
										return untyped s.Trim();
							 | 
						||
| 
								 | 
							
										#elseif java
							 | 
						||
| 
								 | 
							
										return (cast s : java.NativeString).trim();
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return ltrim(rtrim(s));
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Concatenates `c` to `s` until `s.length` is at least `l`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `c` is the empty String `""` or if `l` does not exceed `s.length`,
							 | 
						||
| 
								 | 
							
										`s` is returned unchanged.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `c.length` is 1, the resulting String length is exactly `l`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Otherwise the length may exceed `l`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `c` is null, the result is unspecified.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static function lpad(s:String, c:String, l:Int):String {
							 | 
						||
| 
								 | 
							
										if (c.length <= 0)
							 | 
						||
| 
								 | 
							
											return s;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var buf = new StringBuf();
							 | 
						||
| 
								 | 
							
										l -= s.length;
							 | 
						||
| 
								 | 
							
										while (buf.length < l) {
							 | 
						||
| 
								 | 
							
											buf.add(c);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										buf.add(s);
							 | 
						||
| 
								 | 
							
										return buf.toString();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Appends `c` to `s` until `s.length` is at least `l`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `c` is the empty String `""` or if `l` does not exceed `s.length`,
							 | 
						||
| 
								 | 
							
										`s` is returned unchanged.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `c.length` is 1, the resulting String length is exactly `l`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Otherwise the length may exceed `l`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `c` is null, the result is unspecified.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static function rpad(s:String, c:String, l:Int):String {
							 | 
						||
| 
								 | 
							
										if (c.length <= 0)
							 | 
						||
| 
								 | 
							
											return s;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										var buf = new StringBuf();
							 | 
						||
| 
								 | 
							
										buf.add(s);
							 | 
						||
| 
								 | 
							
										while (buf.length < l) {
							 | 
						||
| 
								 | 
							
											buf.add(c);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return buf.toString();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Replace all occurrences of the String `sub` in the String `s` by the
							 | 
						||
| 
								 | 
							
										String `by`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `sub` is the empty String `""`, `by` is inserted after each character
							 | 
						||
| 
								 | 
							
										of `s` except the last one. If `by` is also the empty String `""`, `s`
							 | 
						||
| 
								 | 
							
										remains unchanged.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `sub` or `by` are null, the result is unspecified.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static function replace(s:String, sub:String, by:String):String {
							 | 
						||
| 
								 | 
							
										#if java
							 | 
						||
| 
								 | 
							
										if (sub.length == 0)
							 | 
						||
| 
								 | 
							
											return s.split(sub).join(by);
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											return (cast s : java.NativeString).replace(sub, by);
							 | 
						||
| 
								 | 
							
										#elseif cs
							 | 
						||
| 
								 | 
							
										if (sub.length == 0)
							 | 
						||
| 
								 | 
							
											return s.split(sub).join(by);
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											return untyped s.Replace(sub, by);
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return s.split(sub).join(by);
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Encodes `n` into a hexadecimal representation.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										If `digits` is specified, the resulting String is padded with "0" until
							 | 
						||
| 
								 | 
							
										its `length` equals `digits`.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static function hex(n:Int, ?digits:Int) {
							 | 
						||
| 
								 | 
							
										#if flash
							 | 
						||
| 
								 | 
							
										var n:UInt = n;
							 | 
						||
| 
								 | 
							
										var s:String = untyped n.toString(16);
							 | 
						||
| 
								 | 
							
										s = s.toUpperCase();
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										var s = "";
							 | 
						||
| 
								 | 
							
										var hexChars = "0123456789ABCDEF";
							 | 
						||
| 
								 | 
							
										do {
							 | 
						||
| 
								 | 
							
											s = hexChars.charAt(n & 15) + s;
							 | 
						||
| 
								 | 
							
											n >>>= 4;
							 | 
						||
| 
								 | 
							
										} while (n > 0);
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
										#if python
							 | 
						||
| 
								 | 
							
										if (digits != null && s.length < digits) {
							 | 
						||
| 
								 | 
							
											var diff = digits - s.length;
							 | 
						||
| 
								 | 
							
											for (_ in 0...diff) {
							 | 
						||
| 
								 | 
							
												s = "0" + s;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										if (digits != null)
							 | 
						||
| 
								 | 
							
											while (s.length < digits)
							 | 
						||
| 
								 | 
							
												s = "0" + s;
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
										return s;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Returns the character code at position `index` of String `s`, or an
							 | 
						||
| 
								 | 
							
										end-of-file indicator at if `position` equals `s.length`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										This method is faster than `String.charCodeAt()` on some platforms, but
							 | 
						||
| 
								 | 
							
										the result is unspecified if `index` is negative or greater than
							 | 
						||
| 
								 | 
							
										`s.length`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										End of file status can be checked by calling `StringTools.isEof()` with
							 | 
						||
| 
								 | 
							
										the returned value as argument.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										This operation is not guaranteed to work if `s` contains the `\0`
							 | 
						||
| 
								 | 
							
										character.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static #if !eval inline #end function fastCodeAt(s:String, index:Int):Int {
							 | 
						||
| 
								 | 
							
										#if neko
							 | 
						||
| 
								 | 
							
										return untyped __dollar__sget(s.__s, index);
							 | 
						||
| 
								 | 
							
										#elseif cpp
							 | 
						||
| 
								 | 
							
										return untyped s.cca(index);
							 | 
						||
| 
								 | 
							
										#elseif flash
							 | 
						||
| 
								 | 
							
										return untyped s.cca(index);
							 | 
						||
| 
								 | 
							
										#elseif java
							 | 
						||
| 
								 | 
							
										return (index < s.length) ? cast(_charAt(s, index), Int) : -1;
							 | 
						||
| 
								 | 
							
										#elseif cs
							 | 
						||
| 
								 | 
							
										return (cast(index, UInt) < s.length) ? cast(s[index], Int) : -1;
							 | 
						||
| 
								 | 
							
										#elseif js
							 | 
						||
| 
								 | 
							
										return (cast s).charCodeAt(index);
							 | 
						||
| 
								 | 
							
										#elseif python
							 | 
						||
| 
								 | 
							
										return if (index >= s.length) -1 else python.internal.UBuiltins.ord(python.Syntax.arrayAccess(s, index));
							 | 
						||
| 
								 | 
							
										#elseif hl
							 | 
						||
| 
								 | 
							
										return @:privateAccess s.bytes.getUI16(index << 1);
							 | 
						||
| 
								 | 
							
										#elseif lua
							 | 
						||
| 
								 | 
							
										#if lua_vanilla
							 | 
						||
| 
								 | 
							
										return lua.NativeStringTools.byte(s, index + 1);
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return lua.lib.luautf8.Utf8.byte(s, index + 1);
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return untyped s.cca(index);
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Returns the character code at position `index` of String `s`, or an
							 | 
						||
| 
								 | 
							
										end-of-file indicator at if `position` equals `s.length`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										This method is faster than `String.charCodeAt()` on some platforms, but
							 | 
						||
| 
								 | 
							
										the result is unspecified if `index` is negative or greater than
							 | 
						||
| 
								 | 
							
										`s.length`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										This operation is not guaranteed to work if `s` contains the `\0`
							 | 
						||
| 
								 | 
							
										character.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static #if !eval inline #end function unsafeCodeAt(s:String, index:Int):Int {
							 | 
						||
| 
								 | 
							
										#if neko
							 | 
						||
| 
								 | 
							
										return untyped __dollar__sget(s.__s, index);
							 | 
						||
| 
								 | 
							
										#elseif cpp
							 | 
						||
| 
								 | 
							
										return untyped s.cca(index);
							 | 
						||
| 
								 | 
							
										#elseif flash
							 | 
						||
| 
								 | 
							
										return untyped s.cca(index);
							 | 
						||
| 
								 | 
							
										#elseif java
							 | 
						||
| 
								 | 
							
										return cast(_charAt(s, index), Int);
							 | 
						||
| 
								 | 
							
										#elseif cs
							 | 
						||
| 
								 | 
							
										return cast(s[index], Int);
							 | 
						||
| 
								 | 
							
										#elseif js
							 | 
						||
| 
								 | 
							
										return (cast s).charCodeAt(index);
							 | 
						||
| 
								 | 
							
										#elseif python
							 | 
						||
| 
								 | 
							
										return python.internal.UBuiltins.ord(python.Syntax.arrayAccess(s, index));
							 | 
						||
| 
								 | 
							
										#elseif hl
							 | 
						||
| 
								 | 
							
										return @:privateAccess s.bytes.getUI16(index << 1);
							 | 
						||
| 
								 | 
							
										#elseif lua
							 | 
						||
| 
								 | 
							
										#if lua_vanilla
							 | 
						||
| 
								 | 
							
										return lua.NativeStringTools.byte(s, index + 1);
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return lua.lib.luautf8.Utf8.byte(s, index + 1);
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return untyped s.cca(index);
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Returns an iterator of the char codes.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Note that char codes may differ across platforms because of different
							 | 
						||
| 
								 | 
							
										internal encoding of strings in different runtimes.
							 | 
						||
| 
								 | 
							
										For the consistent cross-platform UTF8 char codes see `haxe.iterators.StringIteratorUnicode`.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static inline function iterator(s:String):StringIterator {
							 | 
						||
| 
								 | 
							
										return new StringIterator(s);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Returns an iterator of the char indexes and codes.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Note that char codes may differ across platforms because of different
							 | 
						||
| 
								 | 
							
										internal encoding of strings in different of runtimes.
							 | 
						||
| 
								 | 
							
										For the consistent cross-platform UTF8 char codes see `haxe.iterators.StringKeyValueIteratorUnicode`.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									public static inline function keyValueIterator(s:String):StringKeyValueIterator {
							 | 
						||
| 
								 | 
							
										return new StringKeyValueIterator(s);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Tells if `c` represents the end-of-file (EOF) character.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									@:noUsing public static inline function isEof(c:Int):Bool {
							 | 
						||
| 
								 | 
							
										#if (flash || cpp || hl)
							 | 
						||
| 
								 | 
							
										return c == 0;
							 | 
						||
| 
								 | 
							
										#elseif js
							 | 
						||
| 
								 | 
							
										return c != c; // fast NaN
							 | 
						||
| 
								 | 
							
										#elseif (neko || lua || eval)
							 | 
						||
| 
								 | 
							
										return c == null;
							 | 
						||
| 
								 | 
							
										#elseif (cs || java || python)
							 | 
						||
| 
								 | 
							
										return c == -1;
							 | 
						||
| 
								 | 
							
										#else
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
										#end
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Returns a String that can be used as a single command line argument
							 | 
						||
| 
								 | 
							
										on Unix.
							 | 
						||
| 
								 | 
							
										The input will be quoted, or escaped if necessary.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									@:noCompletion
							 | 
						||
| 
								 | 
							
									@:deprecated('StringTools.quoteUnixArg() is deprecated. Use haxe.SysTools.quoteUnixArg() instead.')
							 | 
						||
| 
								 | 
							
									public static function quoteUnixArg(argument:String):String {
							 | 
						||
| 
								 | 
							
										return inline haxe.SysTools.quoteUnixArg(argument);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Character codes of the characters that will be escaped by `quoteWinArg(_, true)`.
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									@:noCompletion
							 | 
						||
| 
								 | 
							
									@:deprecated('StringTools.winMetaCharacters is deprecated. Use haxe.SysTools.winMetaCharacters instead.')
							 | 
						||
| 
								 | 
							
									public static var winMetaCharacters:Array<Int> = cast haxe.SysTools.winMetaCharacters;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
										Returns a String that can be used as a single command line argument
							 | 
						||
| 
								 | 
							
										on Windows.
							 | 
						||
| 
								 | 
							
										The input will be quoted, or escaped if necessary, such that the output
							 | 
						||
| 
								 | 
							
										will be parsed as a single argument using the rule specified in
							 | 
						||
| 
								 | 
							
										http://msdn.microsoft.com/en-us/library/ms880421
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										Examples:
							 | 
						||
| 
								 | 
							
										```haxe
							 | 
						||
| 
								 | 
							
										quoteWinArg("abc") == "abc";
							 | 
						||
| 
								 | 
							
										quoteWinArg("ab c") == '"ab c"';
							 | 
						||
| 
								 | 
							
										```
							 | 
						||
| 
								 | 
							
									**/
							 | 
						||
| 
								 | 
							
									@:noCompletion
							 | 
						||
| 
								 | 
							
									@:deprecated('StringTools.quoteWinArg() is deprecated. Use haxe.SysTools.quoteWinArg() instead.')
							 | 
						||
| 
								 | 
							
									public static function quoteWinArg(argument:String, escapeMetaCharacters:Bool):String {
							 | 
						||
| 
								 | 
							
										return inline haxe.SysTools.quoteWinArg(argument, escapeMetaCharacters);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#if java
							 | 
						||
| 
								 | 
							
									private static inline function _charAt(str:String, idx:Int):java.StdTypes.Char16
							 | 
						||
| 
								 | 
							
										return (cast str : java.NativeString).charAt(idx);
							 | 
						||
| 
								 | 
							
									#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#if neko
							 | 
						||
| 
								 | 
							
									private static var _urlEncode = neko.Lib.load("std", "url_encode", 1);
							 | 
						||
| 
								 | 
							
									private static var _urlDecode = neko.Lib.load("std", "url_decode", 1);
							 | 
						||
| 
								 | 
							
									#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									#if utf16
							 | 
						||
| 
								 | 
							
									static inline var MIN_SURROGATE_CODE_POINT = 65536;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									static inline function utf16CodePointAt(s:String, index:Int):Int {
							 | 
						||
| 
								 | 
							
										var c = StringTools.fastCodeAt(s, index);
							 | 
						||
| 
								 | 
							
										if (c >= 0xD800 && c <= 0xDBFF) {
							 | 
						||
| 
								 | 
							
											c = ((c - 0xD7C0) << 10) | (StringTools.fastCodeAt(s, index + 1) & 0x3FF);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return c;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									#end
							 | 
						||
| 
								 | 
							
								}
							 |