Procházet zdrojové kódy

StringTools.unsafeCharAt (#9467)

* [std] add StringTools.unsafeCharAt

* [php] php

* [std] use unsafeCodeAt for XML parsing and String iterators
Simon Krajewski před 5 roky
rodič
revize
43f305e23d

+ 39 - 0
std/StringTools.hx

@@ -493,6 +493,45 @@ class StringTools {
 		#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 inline 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.
 

+ 3 - 4
std/haxe/format/JsonPrinter.hx

@@ -202,13 +202,12 @@ class JsonPrinter {
 		#end
 		addChar('"'.code);
 		var i = 0;
+		var length = s.length;
 		#if hl
 		var prev = -1;
 		#end
-		while (true) {
-			var c = StringTools.fastCodeAt(s, i++);
-			if (StringTools.isEof(c))
-				break;
+		while (i < length) {
+			var c = StringTools.unsafeCodeAt(s, i++);
 			switch (c) {
 				case '"'.code:
 					add('\\"');

+ 24 - 24
std/haxe/iterators/StringIterator.hx

@@ -23,33 +23,33 @@
 package haxe.iterators;
 
 /**
-  This iterator can be used to iterate over char codes in a string.
+	This iterator can be used to iterate over char codes in a string.
 
-  Note that char codes may differ across platforms because of different
-  internal encoding of strings in different of runtimes.
- **/
+	Note that char codes may differ across platforms because of different
+	internal encoding of strings in different of runtimes.
+**/
 class StringIterator {
-    var offset = 0;
-    var s:String;
+	var offset = 0;
+	var s:String;
 
-    /**
-      Create a new `StringIterator` over String `s`.
-     **/
-    public inline function new(s:String) {
-        this.s = s;
-    }
+	/**
+		Create a new `StringIterator` over String `s`.
+	**/
+	public inline function new(s:String) {
+		this.s = s;
+	}
 
-    /**
-      See `Iterator.hasNext`
-     **/
-    public inline function hasNext() {
-        return offset < s.length;
-    }
+	/**
+		See `Iterator.hasNext`
+	**/
+	public inline function hasNext() {
+		return offset < s.length;
+	}
 
-    /**
-      See `Iterator.next`
-     **/
-    public inline function next() {
-        return StringTools.fastCodeAt(s, offset++);
-    }
+	/**
+		See `Iterator.next`
+	**/
+	public inline function next() {
+		return StringTools.unsafeCodeAt(s, offset++);
+	}
 }

+ 1 - 1
std/haxe/iterators/StringIteratorUnicode.hx

@@ -60,7 +60,7 @@ class StringIteratorUnicode {
 		}
 		return c;
 		#else
-		return StringTools.fastCodeAt(s, offset++);
+		return StringTools.unsafeCodeAt(s, offset++);
 		#end
 	}
 

+ 5 - 6
std/haxe/xml/Parser.hx

@@ -126,7 +126,6 @@ class Parser {
 		var start = 0;
 		var nsubs = 0;
 		var nbrackets = 0;
-		var c = str.fastCodeAt(p);
 		var buf = new StringBuf();
 		// need extra state because next is in use
 		var escapeNext = S.BEGIN;
@@ -135,7 +134,8 @@ class Parser {
 			parent.addChild(xml);
 			nsubs++;
 		}
-		while (!StringTools.isEof(c)) {
+		while (p < str.length) {
+			var c = str.unsafeCodeAt(p);
 			switch (state) {
 				case S.IGNORE_SPACES:
 					switch (c) {
@@ -191,9 +191,8 @@ class Parser {
 								p += 8;
 								state = S.DOCTYPE;
 								start = p + 1;
-							} else if (str.fastCodeAt(p + 1) != '-'.code || str.fastCodeAt(p + 2) != '-'.code)
-								throw new XmlParserException("Expected <!--", str, p);
-							else {
+							} else if (str.fastCodeAt(p + 1) != '-'.code || str.fastCodeAt(p + 2) != '-'.code) throw new XmlParserException("Expected <!--",
+								str, p); else {
 								p += 2;
 								state = S.COMMENT;
 								start = p + 1;
@@ -384,7 +383,7 @@ class Parser {
 						state = escapeNext;
 					}
 			}
-			c = str.fastCodeAt(++p);
+			++p;
 		}
 
 		if (state == S.BEGIN) {

+ 5 - 0
std/php/_std/StringTools.hx

@@ -124,6 +124,11 @@ import haxe.iterators.StringKeyValueIterator;
 		return Boot.unsafeOrd(char);
 	}
 
+	public static function unsafeCodeAt(s:String, index:Int):Int {
+		var char:NativeString = (index == 0 ? s : Global.mb_substr(s, index, 1));
+		return Boot.unsafeOrd(char);
+	}
+
 	public static inline function iterator(s:String):StringIterator {
 		return new StringIterator(s);
 	}