forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
31
Kha/Tools/linux_x64/std/cs/internal/BoxedPointer.hx
Normal file
31
Kha/Tools/linux_x64/std/cs/internal/BoxedPointer.hx
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cs.internal;
|
||||
|
||||
@:unsafe @:keep @:native('haxe.lang.BoxedPointer') @:nativeGen class BoxedPointer {
|
||||
@:readonly public var value(default, null):Pointer<Dynamic>;
|
||||
|
||||
public function new(val) {
|
||||
this.value = val;
|
||||
}
|
||||
}
|
311
Kha/Tools/linux_x64/std/cs/internal/FieldLookup.hx
Normal file
311
Kha/Tools/linux_x64/std/cs/internal/FieldLookup.hx
Normal file
@ -0,0 +1,311 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cs.internal;
|
||||
|
||||
@:native('haxe.lang.FieldHashConflict')
|
||||
@:nativeGen @:keep
|
||||
final class FieldHashConflict {
|
||||
@:readOnly public var hash(default, never):Int;
|
||||
@:readOnly public var name(default, never):String;
|
||||
public var value:Dynamic;
|
||||
public var next:FieldHashConflict;
|
||||
|
||||
public function new(hash, name, value:Dynamic, next) {
|
||||
untyped this.hash = hash;
|
||||
untyped this.name = name;
|
||||
this.value = value;
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
|
||||
@:native('haxe.lang.FieldLookup')
|
||||
@:classCode("#pragma warning disable 628\n")
|
||||
@:nativeGen @:keep @:static
|
||||
final class FieldLookup {
|
||||
@:protected private static var fieldIds:cs.NativeArray<Int>;
|
||||
@:protected private static var fields:cs.NativeArray<String>;
|
||||
@:protected private static var length:Int;
|
||||
|
||||
static function __init__() {
|
||||
length = fieldIds.Length;
|
||||
}
|
||||
|
||||
private static function addFields(nids:cs.NativeArray<Int>, nfields:cs.NativeArray<String>):Void {
|
||||
// first see if we need to add anything
|
||||
var cids = fieldIds, cfields = fields;
|
||||
var nlen = nids.Length;
|
||||
var clen = length;
|
||||
if (nfields.Length != nlen)
|
||||
throw 'Different fields length: $nlen and ${nfields.Length}';
|
||||
|
||||
// TODO optimize
|
||||
var needsChange = false;
|
||||
for (i in nids) {
|
||||
if (findHash(i, cids, clen) < 0) {
|
||||
needsChange = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we do, lock and merge
|
||||
if (needsChange) {
|
||||
cs.Lib.lock(FieldLookup, {
|
||||
// trace(cs.Lib.array(nids), cs.Lib.array(cids));
|
||||
var ansIds = new cs.NativeArray(clen + nlen),
|
||||
ansFields = new cs.NativeArray(clen + nlen);
|
||||
var ci = 0, ni = 0, ansi = 0;
|
||||
while (ci < clen && ni < nlen) {
|
||||
if (cids[ci] < nids[ni]) {
|
||||
ansIds[ansi] = cids[ci];
|
||||
ansFields[ansi] = cfields[ci];
|
||||
++ci;
|
||||
} else {
|
||||
ansIds[ansi] = nids[ni];
|
||||
ansFields[ansi] = nfields[ni];
|
||||
++ni;
|
||||
}
|
||||
++ansi;
|
||||
}
|
||||
|
||||
if (ci < clen) {
|
||||
cs.system.Array.Copy(cids, ci, ansIds, ansi, clen - ci);
|
||||
cs.system.Array.Copy(cfields, ci, ansFields, ansi, clen - ci);
|
||||
ansi += clen - ci;
|
||||
}
|
||||
|
||||
if (ni < nlen) {
|
||||
cs.system.Array.Copy(nids, ni, ansIds, ansi, nlen - ni);
|
||||
cs.system.Array.Copy(nfields, ni, ansFields, ansi, nlen - ni);
|
||||
ansi += nlen - ni;
|
||||
}
|
||||
|
||||
// trace(cs.Lib.array(ansIds));
|
||||
fieldIds = ansIds;
|
||||
fields = ansFields;
|
||||
length = ansi;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// s cannot be null here
|
||||
private static inline function doHash(s:String):Int {
|
||||
var acc = 0; // alloc_int
|
||||
for (i in 0...s.length) {
|
||||
acc = ((223 * (acc >> 1) + cast(s[i], Int)) << 1);
|
||||
}
|
||||
|
||||
return acc >>> 1; // always positive
|
||||
}
|
||||
|
||||
public static function lookupHash(key:Int):String {
|
||||
var ids = fieldIds;
|
||||
var min = 0;
|
||||
var max = length;
|
||||
|
||||
while (min < max) {
|
||||
var mid = min + Std.int((max - min) / 2);
|
||||
var imid = ids[mid];
|
||||
if (key < imid) {
|
||||
max = mid;
|
||||
} else if (key > imid) {
|
||||
min = mid + 1;
|
||||
} else {
|
||||
return fields[mid];
|
||||
}
|
||||
}
|
||||
// if not found, it's definitely an error
|
||||
throw "Field not found for hash " + key;
|
||||
}
|
||||
|
||||
public static function hash(s:String):Int {
|
||||
if (s == null)
|
||||
return 0;
|
||||
|
||||
var key = doHash(s);
|
||||
|
||||
var ids = fieldIds, fld = fields;
|
||||
var min = 0;
|
||||
var max = length;
|
||||
|
||||
var len = length;
|
||||
|
||||
while (min < max) {
|
||||
var mid = Std.int(min + (max - min) / 2); // overflow safe
|
||||
var imid = ids[mid];
|
||||
if (key < imid) {
|
||||
max = mid;
|
||||
} else if (key > imid) {
|
||||
min = mid + 1;
|
||||
} else {
|
||||
var field = fld[mid];
|
||||
if (field != s)
|
||||
return ~key; // special case
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
// if not found, min holds the value where we should insert the key
|
||||
// ensure thread safety:
|
||||
cs.Lib.lock(FieldLookup, {
|
||||
if (len != length) // race condition which will very rarely happen - other thread modified sooner.
|
||||
return hash(s); // since we already own the lock, this second try will always succeed
|
||||
|
||||
fieldIds = insertInt(fieldIds, length, min, key);
|
||||
fields = insertString(fields, length, min, s);
|
||||
++length;
|
||||
});
|
||||
return key;
|
||||
}
|
||||
|
||||
public static function findHash(hash:Int, hashs:cs.NativeArray<Int>, length:Int):Int {
|
||||
var min = 0;
|
||||
var max = length;
|
||||
|
||||
while (min < max) {
|
||||
var mid = Std.int((max + min) / 2);
|
||||
var imid = hashs[mid];
|
||||
if (hash < imid) {
|
||||
max = mid;
|
||||
} else if (hash > imid) {
|
||||
min = mid + 1;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
// if not found, return a negative value of where it should be inserted
|
||||
return ~min;
|
||||
}
|
||||
|
||||
public static function removeInt(a:cs.NativeArray<Int>, length:Int, pos:Int) {
|
||||
cs.system.Array.Copy(a, pos + 1, a, pos, length - pos - 1);
|
||||
a[length - 1] = 0;
|
||||
}
|
||||
|
||||
public static function removeFloat(a:cs.NativeArray<Float>, length:Int, pos:Int) {
|
||||
cs.system.Array.Copy(a, pos + 1, a, pos, length - pos - 1);
|
||||
a[length - 1] = 0;
|
||||
}
|
||||
|
||||
public static function removeDynamic(a:cs.NativeArray<Dynamic>, length:Int, pos:Int) {
|
||||
cs.system.Array.Copy(a, pos + 1, a, pos, length - pos - 1);
|
||||
a[length - 1] = null;
|
||||
}
|
||||
|
||||
extern static inline function __insert<T>(a:cs.NativeArray<T>, length:Int, pos:Int, x:T):cs.NativeArray<T> {
|
||||
var capacity = a.Length;
|
||||
if (pos == length) {
|
||||
if (capacity == length) {
|
||||
var newarr = new NativeArray((length << 1) + 1);
|
||||
a.CopyTo(newarr, 0);
|
||||
a = newarr;
|
||||
}
|
||||
} else if (pos == 0) {
|
||||
if (capacity == length) {
|
||||
var newarr = new NativeArray((length << 1) + 1);
|
||||
cs.system.Array.Copy(a, 0, newarr, 1, length);
|
||||
a = newarr;
|
||||
} else {
|
||||
cs.system.Array.Copy(a, 0, a, 1, length);
|
||||
}
|
||||
} else {
|
||||
if (capacity == length) {
|
||||
var newarr = new NativeArray((length << 1) + 1);
|
||||
cs.system.Array.Copy(a, 0, newarr, 0, pos);
|
||||
cs.system.Array.Copy(a, pos, newarr, pos + 1, length - pos);
|
||||
a = newarr;
|
||||
} else {
|
||||
cs.system.Array.Copy(a, pos, a, pos + 1, length - pos);
|
||||
cs.system.Array.Copy(a, 0, a, 0, pos);
|
||||
}
|
||||
}
|
||||
a[pos] = x;
|
||||
return a;
|
||||
}
|
||||
|
||||
public static function insertInt(a:cs.NativeArray<Int>, length:Int, pos:Int, x:Int):cs.NativeArray<Int>
|
||||
return __insert(a, length, pos, x);
|
||||
|
||||
public static function insertFloat(a:cs.NativeArray<Float>, length:Int, pos:Int, x:Float):cs.NativeArray<Float>
|
||||
return __insert(a, length, pos, x);
|
||||
|
||||
public static function insertDynamic(a:cs.NativeArray<Dynamic>, length:Int, pos:Int, x:Dynamic):cs.NativeArray<Dynamic>
|
||||
return __insert(a, length, pos, x);
|
||||
|
||||
public static function insertString(a:cs.NativeArray<String>, length:Int, pos:Int, x:String):cs.NativeArray<String>
|
||||
return __insert(a, length, pos, x);
|
||||
|
||||
public static function getHashConflict(head:FieldHashConflict, hash:Int, name:String):FieldHashConflict {
|
||||
while (head != null) {
|
||||
if (head.hash == hash && head.name == name) {
|
||||
return head;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function setHashConflict(head:cs.Ref<FieldHashConflict>, hash:Int, name:String, value:Dynamic):Void {
|
||||
var node = head;
|
||||
while (node != null) {
|
||||
if (node.hash == hash && node.name == name) {
|
||||
node.value = value;
|
||||
return;
|
||||
}
|
||||
node = node.next;
|
||||
}
|
||||
head = new FieldHashConflict(hash, name, value, head);
|
||||
}
|
||||
|
||||
public static function deleteHashConflict(head:cs.Ref<FieldHashConflict>, hash:Int, name:String):Bool {
|
||||
// no conflicting fields at all
|
||||
if (head == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// list head is conflicting - just point it to the next one
|
||||
if (head.hash == hash && head.name == name) {
|
||||
head = head.next;
|
||||
return true;
|
||||
}
|
||||
|
||||
// loop through the list, removing node if there's one
|
||||
var prev = head, node = head.next;
|
||||
while (node != null) {
|
||||
if (node.hash == hash && node.name == name) {
|
||||
prev.next = node.next;
|
||||
return true;
|
||||
}
|
||||
node = node.next;
|
||||
}
|
||||
|
||||
// not found
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function addHashConflictNames(head:FieldHashConflict, arr:Array<String>):Void {
|
||||
while (head != null) {
|
||||
arr.push(head.name);
|
||||
head = head.next;
|
||||
}
|
||||
}
|
||||
}
|
79
Kha/Tools/linux_x64/std/cs/internal/Function.hx
Normal file
79
Kha/Tools/linux_x64/std/cs/internal/Function.hx
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cs.internal;
|
||||
|
||||
/**
|
||||
These classes are automatically generated by the compiler. They are only
|
||||
here so there is an option for e.g. defining them as externs if you are compiling
|
||||
in modules (untested).
|
||||
**/
|
||||
@:keep @:abstract @:nativeGen @:native("haxe.lang.Function") class Function {
|
||||
function new(arity:Int, type:Int) {}
|
||||
}
|
||||
|
||||
@:keep @:nativeGen @:native("haxe.lang.VarArgsBase") private class VarArgsBase extends Function {
|
||||
public function __hx_invokeDynamic(dynArgs:cs.NativeArray<Dynamic>):Dynamic {
|
||||
throw "Abstract implementation";
|
||||
}
|
||||
}
|
||||
|
||||
@:keep @:nativeGen @:native('haxe.lang.VarArgsFunction') class VarArgsFunction extends VarArgsBase {
|
||||
private var fun:Array<Dynamic>->Dynamic;
|
||||
|
||||
public function new(fun) {
|
||||
super(-1, -1);
|
||||
this.fun = fun;
|
||||
}
|
||||
|
||||
override public function __hx_invokeDynamic(dynArgs:cs.NativeArray<Dynamic>):Dynamic {
|
||||
return fun(dynArgs == null ? [] : cs.Lib.array(dynArgs));
|
||||
}
|
||||
}
|
||||
|
||||
@:keep @:nativeGen @:native('haxe.lang.Closure') class Closure extends VarArgsBase {
|
||||
private var obj:Dynamic;
|
||||
private var field:String;
|
||||
private var hash:Int;
|
||||
|
||||
public function new(obj:Dynamic, field, hash) {
|
||||
super(-1, -1);
|
||||
this.obj = obj;
|
||||
this.field = field;
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
override public function __hx_invokeDynamic(dynArgs:cs.NativeArray<Dynamic>):Dynamic {
|
||||
return Runtime.callField(obj, field, hash, dynArgs);
|
||||
}
|
||||
|
||||
public function Equals(obj:Dynamic):Bool {
|
||||
var c = cs.Lib.as(obj, Closure);
|
||||
if (c == null)
|
||||
return false;
|
||||
return (c.obj == this.obj && c.field == this.field);
|
||||
}
|
||||
|
||||
public function GetHashCode():Int {
|
||||
return obj.GetHashCode() ^ untyped field.GetHashCode();
|
||||
}
|
||||
}
|
317
Kha/Tools/linux_x64/std/cs/internal/HxObject.hx
Normal file
317
Kha/Tools/linux_x64/std/cs/internal/HxObject.hx
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cs.internal;
|
||||
|
||||
import cs.system.Type;
|
||||
import haxe.ds.Vector;
|
||||
import cs.internal.FieldLookup;
|
||||
|
||||
private typedef StdType = std.Type;
|
||||
|
||||
@:keep @:native('haxe.lang.HxObject')
|
||||
class HxObject implements IHxObject {
|
||||
public function __hx_deleteField(field:String, hash:Int):Bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@:keep @:native('haxe.lang.IHxObject')
|
||||
interface IHxObject {}
|
||||
|
||||
#if core_api_serialize
|
||||
@:meta(System.Serializable)
|
||||
#end
|
||||
@:keep @:native('haxe.lang.DynamicObject')
|
||||
class DynamicObject extends HxObject {
|
||||
@:skipReflection var __hx_hashes:NativeArray<Int>;
|
||||
@:skipReflection var __hx_dynamics:NativeArray<Dynamic>;
|
||||
|
||||
@:skipReflection var __hx_hashes_f:NativeArray<Int>;
|
||||
@:skipReflection var __hx_dynamics_f:NativeArray<Float>;
|
||||
|
||||
@:skipReflection var __hx_length:Int;
|
||||
@:skipReflection var __hx_length_f:Int;
|
||||
@:skipReflection var __hx_conflicts:FieldHashConflict;
|
||||
|
||||
@:skipReflection static var __hx_toString_depth = 0;
|
||||
|
||||
@:overload public function new() {
|
||||
this.__hx_hashes = new NativeArray(0);
|
||||
this.__hx_dynamics = new NativeArray(0);
|
||||
this.__hx_hashes_f = new NativeArray(0);
|
||||
this.__hx_dynamics_f = new NativeArray(0);
|
||||
this.__hx_conflicts = null;
|
||||
}
|
||||
|
||||
@:overload public function new(hashes:NativeArray<Int>, dynamics:NativeArray<Dynamic>, hashes_f:NativeArray<Int>, dynamics_f:NativeArray<Float>) {
|
||||
this.__hx_hashes = hashes;
|
||||
this.__hx_dynamics = dynamics;
|
||||
this.__hx_hashes_f = hashes_f;
|
||||
this.__hx_dynamics_f = dynamics_f;
|
||||
this.__hx_length = hashes.length;
|
||||
this.__hx_length_f = hashes_f.length;
|
||||
this.__hx_conflicts = null;
|
||||
}
|
||||
|
||||
override public function __hx_deleteField(field:String, hash:Int):Bool {
|
||||
if (hash < 0) {
|
||||
return FieldLookup.deleteHashConflict(this.__hx_conflicts, hash, field);
|
||||
}
|
||||
|
||||
var res = FieldLookup.findHash(hash, this.__hx_hashes, this.__hx_length);
|
||||
if (res >= 0) {
|
||||
FieldLookup.removeInt(this.__hx_hashes, this.__hx_length, res);
|
||||
FieldLookup.removeDynamic(this.__hx_dynamics, this.__hx_length, res);
|
||||
this.__hx_length--;
|
||||
return true;
|
||||
}
|
||||
res = FieldLookup.findHash(hash, this.__hx_hashes_f, this.__hx_length_f);
|
||||
if (res >= 0) {
|
||||
FieldLookup.removeInt(this.__hx_hashes_f, this.__hx_length_f, res);
|
||||
FieldLookup.removeFloat(this.__hx_dynamics_f, this.__hx_length_f, res);
|
||||
this.__hx_length_f--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __hx_getField(field:String, hash:Int, throwErrors:Bool, isCheck:Bool, handleProperties:Bool):Dynamic {
|
||||
if (hash < 0) {
|
||||
var conflict = FieldLookup.getHashConflict(this.__hx_conflicts, hash, field);
|
||||
if (conflict != null) {
|
||||
return conflict.value;
|
||||
}
|
||||
}
|
||||
|
||||
var res = FieldLookup.findHash(hash, this.__hx_hashes, this.__hx_length);
|
||||
if (res >= 0) {
|
||||
return this.__hx_dynamics[res];
|
||||
}
|
||||
res = FieldLookup.findHash(hash, this.__hx_hashes_f, this.__hx_length_f);
|
||||
if (res >= 0) {
|
||||
return this.__hx_dynamics_f[res];
|
||||
}
|
||||
|
||||
return isCheck ? Runtime.undefined : null;
|
||||
}
|
||||
|
||||
public function __hx_setField(field:String, hash:Int, value:Dynamic, handleProperties:Bool):Dynamic {
|
||||
if (hash < 0) {
|
||||
FieldLookup.setHashConflict(this.__hx_conflicts, hash, field, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
var res = FieldLookup.findHash(hash, this.__hx_hashes, this.__hx_length);
|
||||
if (res >= 0) {
|
||||
return this.__hx_dynamics[res] = value;
|
||||
} else {
|
||||
var res = FieldLookup.findHash(hash, this.__hx_hashes_f, this.__hx_length_f);
|
||||
if (res >= 0) {
|
||||
if (Std.isOfType(value, Float)) {
|
||||
return this.__hx_dynamics_f[res] = value;
|
||||
}
|
||||
|
||||
FieldLookup.removeInt(this.__hx_hashes_f, this.__hx_length_f, res);
|
||||
FieldLookup.removeFloat(this.__hx_dynamics_f, this.__hx_length_f, res);
|
||||
this.__hx_length_f--;
|
||||
}
|
||||
}
|
||||
|
||||
this.__hx_hashes = FieldLookup.insertInt(this.__hx_hashes, this.__hx_length, ~(res), hash);
|
||||
this.__hx_dynamics = FieldLookup.insertDynamic(this.__hx_dynamics, this.__hx_length, ~(res), value);
|
||||
this.__hx_length++;
|
||||
return value;
|
||||
}
|
||||
|
||||
public function __hx_getField_f(field:String, hash:Int, throwErrors:Bool, handleProperties:Bool):Float {
|
||||
if (hash < 0) {
|
||||
var conflict = FieldLookup.getHashConflict(this.__hx_conflicts, hash, field);
|
||||
if (conflict != null) {
|
||||
return conflict.value;
|
||||
}
|
||||
}
|
||||
|
||||
var res = FieldLookup.findHash(hash, this.__hx_hashes_f, this.__hx_length_f);
|
||||
if (res >= 0) {
|
||||
return this.__hx_dynamics_f[res];
|
||||
}
|
||||
res = FieldLookup.findHash(hash, this.__hx_hashes, this.__hx_length);
|
||||
if (res >= 0) {
|
||||
return this.__hx_dynamics[res];
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public function __hx_setField_f(field:String, hash:Int, value:Float, handleProperties:Bool):Float {
|
||||
if (hash < 0) {
|
||||
FieldLookup.setHashConflict(this.__hx_conflicts, hash, field, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
var res = FieldLookup.findHash(hash, this.__hx_hashes_f, this.__hx_length_f);
|
||||
if (res >= 0) {
|
||||
return this.__hx_dynamics_f[res] = value;
|
||||
} else {
|
||||
var res = FieldLookup.findHash(hash, this.__hx_hashes, this.__hx_length);
|
||||
if (res >= 0) {
|
||||
// return this.__hx_dynamics[res] = value;
|
||||
FieldLookup.removeInt(this.__hx_hashes, this.__hx_length, res);
|
||||
FieldLookup.removeDynamic(this.__hx_dynamics, this.__hx_length, res);
|
||||
this.__hx_length--;
|
||||
}
|
||||
}
|
||||
|
||||
this.__hx_hashes_f = FieldLookup.insertInt(this.__hx_hashes_f, this.__hx_length_f, ~(res), hash);
|
||||
this.__hx_dynamics_f = FieldLookup.insertFloat(this.__hx_dynamics_f, this.__hx_length_f, ~(res), value);
|
||||
this.__hx_length_f++;
|
||||
return value;
|
||||
}
|
||||
|
||||
public function __hx_getFields(baseArr:Array<String>):Void {
|
||||
for (i in 0...this.__hx_length) {
|
||||
baseArr.push(FieldLookup.lookupHash(this.__hx_hashes[i]));
|
||||
}
|
||||
for (i in 0...this.__hx_length_f) {
|
||||
baseArr.push(FieldLookup.lookupHash(this.__hx_hashes_f[i]));
|
||||
}
|
||||
FieldLookup.addHashConflictNames(this.__hx_conflicts, baseArr);
|
||||
}
|
||||
|
||||
public function __hx_invokeField(field:String, hash:Int, dynargs:NativeArray<Dynamic>):Dynamic {
|
||||
if (field == "toString") {
|
||||
return this.toString();
|
||||
}
|
||||
var fn:Function = this.__hx_getField(field, hash, false, false, false);
|
||||
if (fn == null) {
|
||||
throw 'Cannot invoke field $field: It does not exist';
|
||||
}
|
||||
|
||||
return untyped fn.__hx_invokeDynamic(dynargs);
|
||||
}
|
||||
|
||||
@:skipReflection public function toString() {
|
||||
if (__hx_toString_depth >= 5) {
|
||||
return "...";
|
||||
}
|
||||
++__hx_toString_depth;
|
||||
try {
|
||||
var s = __hx_toString();
|
||||
--__hx_toString_depth;
|
||||
return s;
|
||||
} catch (e:Dynamic) {
|
||||
--__hx_toString_depth;
|
||||
throw(e);
|
||||
}
|
||||
}
|
||||
|
||||
@:skipReflection public function __hx_toString():String {
|
||||
var ts = Reflect.field(this, "toString");
|
||||
if (ts != null)
|
||||
return ts();
|
||||
var ret = new StringBuf();
|
||||
ret.add("{");
|
||||
var first = true;
|
||||
for (f in Reflect.fields(this)) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
ret.add(",");
|
||||
ret.add(" ");
|
||||
ret.add(f);
|
||||
ret.add(" : ");
|
||||
ret.add(Reflect.field(this, f));
|
||||
}
|
||||
if (!first)
|
||||
ret.add(" ");
|
||||
ret.add("}");
|
||||
return ret.toString();
|
||||
}
|
||||
}
|
||||
|
||||
#if !erase_generics
|
||||
@:keep @:native('haxe.lang.IGenericObject') interface IGenericObject {}
|
||||
|
||||
@:nativeGen @:keep @:native('haxe.lang.GenericInterface') class GenericInterface extends cs.system.Attribute {
|
||||
@:readOnly public var generic(default, never):cs.system.Type;
|
||||
|
||||
public function new(generic) {
|
||||
super();
|
||||
untyped this.generic = generic;
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
@:keep
|
||||
@:native('haxe.lang.Enum')
|
||||
@:nativeGen
|
||||
#if core_api_serialize
|
||||
@:meta(System.Serializable)
|
||||
#end
|
||||
class HxEnum {
|
||||
@:readOnly var _hx_index(default, never):Int;
|
||||
|
||||
@:protected function new(index:Int) {
|
||||
untyped this._hx_index = index;
|
||||
}
|
||||
|
||||
public function getTag():String {
|
||||
return throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
public function getParams():Array<{}> {
|
||||
return [];
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return getTag();
|
||||
}
|
||||
|
||||
@:protected static function paramsToString(tag:String, params:Vector<Dynamic>):String {
|
||||
var ret = new StringBuf();
|
||||
ret.add(tag);
|
||||
ret.add("(");
|
||||
var first = true;
|
||||
for (p in params) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
ret.add(",");
|
||||
ret.add(p);
|
||||
}
|
||||
ret.add(")");
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@:protected static function paramsGetHashCode(index:Int, params:Vector<Dynamic>):Int {
|
||||
var h:Int = 19;
|
||||
if (params != null)
|
||||
for (p in params) {
|
||||
h = h * 31;
|
||||
if (p != null)
|
||||
untyped h += p.GetHashCode();
|
||||
}
|
||||
h += index;
|
||||
return h;
|
||||
}
|
||||
}
|
88
Kha/Tools/linux_x64/std/cs/internal/Null.hx
Normal file
88
Kha/Tools/linux_x64/std/cs/internal/Null.hx
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cs.internal;
|
||||
|
||||
@:classCode('//This function is here to be used with Reflection, when the haxe.lang.Null type is known
|
||||
public static haxe.lang.Null<T> _ofDynamic(object obj) {
|
||||
if (obj == null) {
|
||||
return new haxe.lang.Null<T>(default(T), false);
|
||||
} else if (typeof(T).Equals(typeof(double))) {
|
||||
return new haxe.lang.Null<T>((T) (object) haxe.lang.Runtime.toDouble(obj), true);
|
||||
} else if (typeof(T).Equals(typeof(int))) {
|
||||
return new haxe.lang.Null<T>((T) (object) haxe.lang.Runtime.toInt(obj), true);
|
||||
} else {
|
||||
return new haxe.lang.Null<T>((T) obj, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator haxe.lang.Null<T>(T val) {
|
||||
return new haxe.lang.Null<T>(val, true);
|
||||
}
|
||||
|
||||
public static implicit operator Null<T>(__NoValue__ noValue) {
|
||||
return new haxe.lang.Null<T>(default(T), false);
|
||||
}
|
||||
|
||||
public sealed class __NoValue__ {
|
||||
private __NoValue__() {}
|
||||
}
|
||||
|
||||
override public string ToString() {
|
||||
if (!hasValue) return "null";
|
||||
else return value.ToString();
|
||||
}
|
||||
')
|
||||
#if core_api_serialize
|
||||
@:meta(System.Serializable)
|
||||
#end
|
||||
@:keep @:struct @:nativeGen @:native("haxe.lang.Null") private class Nullable<T> {
|
||||
@:readOnly public var value(default, never):T;
|
||||
@:readOnly public var hasValue(default, never):Bool;
|
||||
|
||||
public function new(v:T, hasValue:Bool) {
|
||||
if (hasValue && cs.system.Object.ReferenceEquals(v, null)) {
|
||||
hasValue = false;
|
||||
}
|
||||
untyped this.value = v;
|
||||
untyped this.hasValue = hasValue;
|
||||
}
|
||||
|
||||
@:functionCode('if (obj == null) {
|
||||
return new haxe.lang.Null<D>(default(D), false);
|
||||
} else if (typeof(D).Equals(typeof(double))) {
|
||||
return new haxe.lang.Null<D>((D) (object) haxe.lang.Runtime.toDouble(obj), true);
|
||||
} else if (typeof(D).Equals(typeof(int))) {
|
||||
return new haxe.lang.Null<D>((D) (object) haxe.lang.Runtime.toInt(obj), true);
|
||||
} else {
|
||||
return new haxe.lang.Null<D>((D) obj, true);
|
||||
}')
|
||||
public static function ofDynamic<D>(obj:Dynamic):Nullable<D> {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function toDynamic():Dynamic {
|
||||
if (this.hasValue)
|
||||
return value;
|
||||
return null;
|
||||
}
|
||||
}
|
712
Kha/Tools/linux_x64/std/cs/internal/Runtime.hx
Normal file
712
Kha/Tools/linux_x64/std/cs/internal/Runtime.hx
Normal file
@ -0,0 +1,712 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cs.internal;
|
||||
|
||||
import cs.Lib;
|
||||
import cs.Lib.*;
|
||||
import cs.NativeArray;
|
||||
import cs.StdTypes;
|
||||
import cs.system.Activator;
|
||||
import cs.system.IConvertible;
|
||||
import cs.system.IComparable;
|
||||
import cs.system.reflection.MethodBase;
|
||||
import cs.system.reflection.MethodInfo;
|
||||
import cs.system.reflection.*;
|
||||
import cs.system.Type;
|
||||
import cs.system.Object;
|
||||
|
||||
/**
|
||||
This class is meant for internal compiler use only. It provides the Haxe runtime
|
||||
compatibility to the host language.
|
||||
**/
|
||||
@:nativeGen
|
||||
@:native('haxe.lang.Runtime')
|
||||
@:access(String)
|
||||
@:classCode('
|
||||
public static object getField(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
|
||||
{
|
||||
if (obj == null && !throwErrors) return null;
|
||||
return obj.__hx_getField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false, false);
|
||||
}
|
||||
|
||||
public static double getField_f(haxe.lang.HxObject obj, string field, int fieldHash, bool throwErrors)
|
||||
{
|
||||
if (obj == null && !throwErrors) return 0.0;
|
||||
return obj.__hx_getField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, throwErrors, false);
|
||||
}
|
||||
|
||||
public static object setField(haxe.lang.HxObject obj, string field, int fieldHash, object value)
|
||||
{
|
||||
return obj.__hx_setField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
|
||||
}
|
||||
|
||||
public static double setField_f(haxe.lang.HxObject obj, string field, int fieldHash, double value)
|
||||
{
|
||||
return obj.__hx_setField_f(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, value, false);
|
||||
}
|
||||
|
||||
public static object callField(haxe.lang.HxObject obj, string field, int fieldHash, object[] args)
|
||||
{
|
||||
return obj.__hx_invokeField(field, (fieldHash == 0) ? haxe.lang.FieldLookup.hash(field) : fieldHash, args);
|
||||
}
|
||||
')
|
||||
@:keep class Runtime {
|
||||
@:readOnly public static var undefined(default, never):Dynamic = new cs.system.Object();
|
||||
|
||||
public static function closure(obj:Dynamic, hash:Int, field:String):Dynamic {
|
||||
return new cs.internal.Function.Closure(obj, field, hash);
|
||||
}
|
||||
|
||||
public static function eq(v1:Dynamic, v2:Dynamic):Bool {
|
||||
if (Object.ReferenceEquals(v1, v2))
|
||||
return true;
|
||||
if (Object.ReferenceEquals(v1, null) || Object.ReferenceEquals(v2, null))
|
||||
return false;
|
||||
|
||||
var v1c = Lib.as(v1, IConvertible);
|
||||
if (v1c != null) {
|
||||
var v2c = Lib.as(v2, IConvertible);
|
||||
if (v2c == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var t1 = v1c.GetTypeCode(), t2 = v2c.GetTypeCode();
|
||||
if (t1 == t2)
|
||||
return Object._Equals(v1c, v2c);
|
||||
|
||||
if (t1 == cs.system.TypeCode.String || t2 == cs.system.TypeCode.String)
|
||||
return false;
|
||||
|
||||
switch [t1, t2] {
|
||||
case [Decimal, _] | [_, Decimal]:
|
||||
return v1c.ToDecimal(null) == v2c.ToDecimal(null);
|
||||
case [Int64, _] | [_, Int64]:
|
||||
return v1c.ToInt64(null) == v2c.ToInt64(null);
|
||||
case [UInt64 | DateTime, _] | [_, UInt64 | DateTime]:
|
||||
return v1c.ToUInt64(null) == v2c.ToUInt64(null);
|
||||
case [Double | Single, _] | [_, Double | Single]:
|
||||
return v1c.ToDouble(null) == v2c.ToDouble(null);
|
||||
case _:
|
||||
return v1c.ToInt32(null) == v2c.ToInt32(null);
|
||||
}
|
||||
}
|
||||
|
||||
var v1v = Lib.as(v1, cs.system.ValueType);
|
||||
if (v1v != null) {
|
||||
return v1.Equals(v2);
|
||||
#if !erase_generics
|
||||
}
|
||||
else {
|
||||
var v1t = Lib.as(v1, Type);
|
||||
if (v1t != null) {
|
||||
var v2t = Lib.as(v2, Type);
|
||||
if (v2t != null)
|
||||
return typeEq(v1t, v2t);
|
||||
return false;
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function refEq(v1:{}, v2:{}):Bool {
|
||||
#if !erase_generics
|
||||
if (Std.isOfType(v1, Type))
|
||||
return typeEq(Lib.as(v1, Type), Lib.as(v2, Type));
|
||||
#end
|
||||
return Object.ReferenceEquals(v1, v2);
|
||||
}
|
||||
|
||||
public static function toDouble(obj:Dynamic):Float {
|
||||
return (obj == null) ? .0 : Std.isOfType(obj, Float) ? cast obj : Lib.as(obj, IConvertible).ToDouble(null);
|
||||
}
|
||||
|
||||
public static function toInt(obj:Dynamic):Int {
|
||||
return (obj == null) ? 0 : Std.isOfType(obj, Int) ? cast obj : Lib.as(obj, IConvertible).ToInt32(null);
|
||||
}
|
||||
|
||||
#if erase_generics
|
||||
public static function toLong(obj:Dynamic):Int64 {
|
||||
return (obj == null) ? 0 : Std.isOfType(obj, Int64) ? cast obj : Lib.as(obj, IConvertible).ToInt64(null);
|
||||
}
|
||||
#end
|
||||
|
||||
public static function isInt(obj:Dynamic):Bool {
|
||||
var cv1 = Lib.as(obj, IConvertible);
|
||||
if (cv1 != null) {
|
||||
switch (cv1.GetTypeCode()) {
|
||||
case Double:
|
||||
var d:Float = cast obj;
|
||||
return d >= cs.system.Int32.MinValue && d <= cs.system.Int32.MaxValue && d == (cast(d, Int));
|
||||
case UInt32, Int32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function isUInt(obj:Dynamic):Bool {
|
||||
var cv1 = Lib.as(obj, IConvertible);
|
||||
if (cv1 != null) {
|
||||
switch (cv1.GetTypeCode()) {
|
||||
case Double:
|
||||
var d:Float = cast obj;
|
||||
return d >= cs.system.UInt32.MinValue && d <= cs.system.UInt32.MaxValue && d == (cast(d, UInt));
|
||||
case UInt32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function compare(v1:Dynamic, v2:Dynamic):Int {
|
||||
if (Object.ReferenceEquals(v1, v2))
|
||||
return 0;
|
||||
if (Object.ReferenceEquals(v1, null))
|
||||
return -1;
|
||||
if (Object.ReferenceEquals(v2, null))
|
||||
return 1;
|
||||
|
||||
var cv1 = Lib.as(v1, IConvertible);
|
||||
if (cv1 != null) {
|
||||
var cv2 = Lib.as(v2, IConvertible);
|
||||
|
||||
if (cv2 == null) {
|
||||
throw new cs.system.ArgumentException("Cannot compare " + getNativeType(v1).ToString() + " and " + getNativeType(v2).ToString());
|
||||
}
|
||||
|
||||
switch (cv1.GetTypeCode()) {
|
||||
case cs.system.TypeCode.String:
|
||||
if (cv2.GetTypeCode() != cs.system.TypeCode.String)
|
||||
throw new cs.system.ArgumentException("Cannot compare " + getNativeType(v1).ToString() + " and " + getNativeType(v2).ToString());
|
||||
var s1 = Lib.as(v1, String);
|
||||
var s2 = Lib.as(v2, String);
|
||||
return String.Compare(s1, s2, cs.system.StringComparison.Ordinal);
|
||||
case cs.system.TypeCode.Double:
|
||||
var d1:Float = cast v1, d2:Float = cv2.ToDouble(null);
|
||||
return (d1 < d2) ? -1 : (d1 > d2) ? 1 : 0;
|
||||
default:
|
||||
var d1d = cv1.ToDouble(null);
|
||||
var d2d = cv2.ToDouble(null);
|
||||
return (d1d < d2d) ? -1 : (d1d > d2d) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
var c1 = Lib.as(v1, IComparable);
|
||||
var c2 = Lib.as(v2, IComparable);
|
||||
|
||||
if (c1 == null || c2 == null) {
|
||||
throw new cs.system.ArgumentException("Cannot compare " + getNativeType(v1).ToString() + " and " + getNativeType(v2).ToString());
|
||||
}
|
||||
|
||||
return c1.CompareTo(c2);
|
||||
}
|
||||
|
||||
public static function plus(v1:Dynamic, v2:Dynamic):Dynamic {
|
||||
if (Std.isOfType(v1, String) || Std.isOfType(v2, String))
|
||||
return Std.string(v1) + Std.string(v2);
|
||||
|
||||
if (v1 == null) {
|
||||
if (v2 == null)
|
||||
return null;
|
||||
v1 = 0;
|
||||
} else if (v2 == null)
|
||||
v2 = 0;
|
||||
|
||||
var cv1 = Lib.as(v1, IConvertible);
|
||||
if (cv1 != null) {
|
||||
var cv2 = Lib.as(v2, IConvertible);
|
||||
if (cv2 == null) {
|
||||
throw new cs.system.ArgumentException("Cannot dynamically add " + cs.Lib.getNativeType(v1).ToString() + " and "
|
||||
+ cs.Lib.getNativeType(v2).ToString());
|
||||
}
|
||||
return cv1.ToDouble(null) + cv2.ToDouble(null);
|
||||
}
|
||||
|
||||
throw new cs.system.ArgumentException("Cannot dynamically add " + v1 + " and " + v2);
|
||||
}
|
||||
|
||||
public static function slowGetField(obj:Dynamic, field:String, throwErrors:Bool):Dynamic {
|
||||
if (obj == null)
|
||||
if (throwErrors)
|
||||
throw new cs.system.NullReferenceException("Cannot access field \'" + field + "\' of null.");
|
||||
else
|
||||
return null;
|
||||
|
||||
var t = Lib.as(obj, cs.system.Type);
|
||||
var bf = if (t == null) {
|
||||
var s = Lib.as(obj, String);
|
||||
if (s != null)
|
||||
return cs.internal.StringExt.StringRefl.handleGetField(s, field, throwErrors);
|
||||
t = obj.GetType();
|
||||
new cs.Flags(BindingFlags.Instance) | BindingFlags.Public | BindingFlags.FlattenHierarchy;
|
||||
} else {
|
||||
if (t == Lib.toNativeType(String) && field == "fromCharCode")
|
||||
return new cs.internal.Function.Closure(StringExt, field, 0);
|
||||
|
||||
obj = null;
|
||||
new cs.Flags(BindingFlags.Static) | BindingFlags.Public;
|
||||
}
|
||||
|
||||
var f = t.GetField(field, bf);
|
||||
if (f != null) {
|
||||
return unbox(f.GetValue(obj));
|
||||
} else {
|
||||
var prop = t.GetProperty(field, bf);
|
||||
if (prop == null) {
|
||||
var m = t.GetMember(field, bf);
|
||||
if (m.length == 0 && (field == "__get" || field == "__set"))
|
||||
m = t.GetMember(field == "__get" ? "get_Item" : "set_Item", bf);
|
||||
|
||||
if (m.Length > 0) {
|
||||
return new cs.internal.Function.Closure(obj != null ? obj : t, field, 0);
|
||||
} else {
|
||||
// COM object handling
|
||||
if (t.IsCOMObject) {
|
||||
try {
|
||||
return t.InvokeMember(field, BindingFlags.GetProperty, null, obj, new cs.NativeArray(0));
|
||||
} catch (e:cs.system.Exception) {
|
||||
// Closures of COM objects not supported currently
|
||||
}
|
||||
}
|
||||
|
||||
if (throwErrors)
|
||||
throw "Cannot access field \'" + field + "\'.";
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return unbox(prop.GetValue(obj, null));
|
||||
}
|
||||
}
|
||||
|
||||
public static function slowHasField(obj:Dynamic, field:String):Bool {
|
||||
if (obj == null)
|
||||
return false;
|
||||
var t = Lib.as(obj, cs.system.Type);
|
||||
var bf = if (t == null) {
|
||||
var s = Lib.as(obj, String);
|
||||
if (s != null)
|
||||
return cs.internal.StringExt.StringRefl.handleGetField(s, field, false) != null;
|
||||
t = obj.GetType();
|
||||
new cs.Flags(BindingFlags.Instance) | BindingFlags.Public | BindingFlags.FlattenHierarchy;
|
||||
} else {
|
||||
if (t == Lib.toNativeType(String))
|
||||
return field == "fromCharCode";
|
||||
obj = null;
|
||||
new cs.Flags(BindingFlags.Static) | BindingFlags.Public;
|
||||
}
|
||||
var mi = t.GetMember(field, bf);
|
||||
return mi != null && mi.length > 0;
|
||||
}
|
||||
|
||||
public static function slowSetField(obj:Dynamic, field:String, value:Dynamic):Dynamic {
|
||||
if (obj == null)
|
||||
throw new cs.system.NullReferenceException("Cannot access field \'" + field + "\' of null.");
|
||||
|
||||
var t = Lib.as(obj, cs.system.Type);
|
||||
var bf = if (t == null) {
|
||||
t = obj.GetType();
|
||||
new cs.Flags(BindingFlags.Instance) | BindingFlags.Public | BindingFlags.FlattenHierarchy;
|
||||
} else {
|
||||
obj = null;
|
||||
new cs.Flags(BindingFlags.Static) | BindingFlags.Public;
|
||||
}
|
||||
|
||||
var f = t.GetField(field, bf);
|
||||
if (f != null) {
|
||||
if (f.FieldType.ToString().StartsWith("haxe.lang.Null")) {
|
||||
value = mkNullable(value, f.FieldType);
|
||||
}
|
||||
if (value != null
|
||||
&& Object.ReferenceEquals(Lib.toNativeType(cs.system.Double), Lib.getNativeType(value))
|
||||
&& !Object.ReferenceEquals(t, f.FieldType)) {
|
||||
var ic = Lib.as(value, IConvertible);
|
||||
value = ic.ToType(f.FieldType, null);
|
||||
}
|
||||
|
||||
f.SetValue(obj, value);
|
||||
return value;
|
||||
} else {
|
||||
var prop = t.GetProperty(field, bf);
|
||||
if (prop == null) {
|
||||
// COM object handling
|
||||
if (t.IsCOMObject) {
|
||||
try {
|
||||
return t.InvokeMember(field, BindingFlags.SetProperty, null, obj, cs.NativeArray.make(value));
|
||||
} catch (e:cs.system.Exception) {
|
||||
// Closures of COM objects not supported currently
|
||||
}
|
||||
}
|
||||
throw "Field \'" + field + "\' not found for writing from Class " + t;
|
||||
}
|
||||
|
||||
if (prop.PropertyType.ToString().StartsWith("haxe.lang.Null")) {
|
||||
value = mkNullable(value, prop.PropertyType);
|
||||
}
|
||||
if (Object.ReferenceEquals(Lib.toNativeType(cs.system.Double), Lib.getNativeType(value))
|
||||
&& !Object.ReferenceEquals(t, prop.PropertyType)) {
|
||||
var ic = Lib.as(value, IConvertible);
|
||||
value = ic.ToType(prop.PropertyType, null);
|
||||
}
|
||||
prop.SetValue(obj, value, null);
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static function callMethod(obj:Dynamic, methods:NativeArray<MethodBase>, methodLength:Int, args:cs.NativeArray<Dynamic>):Dynamic {
|
||||
if (methodLength == 0)
|
||||
throw "No available methods";
|
||||
var length = args.length;
|
||||
var oargs:NativeArray<Dynamic> = new NativeArray(length);
|
||||
var ts:NativeArray<Type> = new NativeArray(length);
|
||||
var rates:NativeArray<Int> = new NativeArray(methods.Length);
|
||||
|
||||
for (i in 0...length) {
|
||||
oargs[i] = args[i];
|
||||
if (args[i] != null)
|
||||
ts[i] = Lib.getNativeType(args[i]);
|
||||
}
|
||||
|
||||
var last = 0;
|
||||
|
||||
// first filter by number of parameters and if it is assignable
|
||||
if (methodLength > 1) {
|
||||
for (i in 0...methodLength) {
|
||||
var params = methods[i].GetParameters();
|
||||
if (params.Length != length) {
|
||||
continue;
|
||||
} else {
|
||||
var fits = true, crate = 0;
|
||||
for (i in 0...params.Length) {
|
||||
var param = params[i].ParameterType;
|
||||
var strParam = param + "";
|
||||
if (param.IsAssignableFrom(ts[i]) || (ts[i] == null && !param.IsValueType)) {
|
||||
// if it is directly assignable, we'll give it top rate
|
||||
continue;
|
||||
} else if (untyped strParam.StartsWith("haxe.lang.Null")
|
||||
|| ((oargs[i] == null || Std.isOfType(oargs[i], IConvertible))
|
||||
&& cast(untyped __typeof__(IConvertible), Type).IsAssignableFrom(param))) {
|
||||
// if it needs conversion, give a penalty. TODO rate penalty
|
||||
crate++;
|
||||
continue;
|
||||
} else if (!param.ContainsGenericParameters) { // generics don't appear as assignable, but may be in the end. no rate there.
|
||||
fits = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fits) {
|
||||
rates[last] = crate;
|
||||
methods[last++] = methods[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
methodLength = last;
|
||||
} else if (methodLength == 1 && methods[0].GetParameters().Length != length) {
|
||||
methodLength = 0;
|
||||
}
|
||||
|
||||
// At this time, we should be left with only one method.
|
||||
// Of course, realistically, we can be left with plenty of methods, if there are lots of variants with IConvertible
|
||||
// But at this time we still aren't rating the best methods
|
||||
// FIXME rate best methods
|
||||
|
||||
if (methodLength == 0)
|
||||
throw "Invalid calling parameters for method " + methods[0].Name;
|
||||
|
||||
var best = cs.system.Double.PositiveInfinity;
|
||||
var bestMethod = 0;
|
||||
for (i in 0...methodLength) {
|
||||
if (rates[i] < best) {
|
||||
bestMethod = i;
|
||||
best = rates[i];
|
||||
}
|
||||
}
|
||||
|
||||
methods[0] = methods[bestMethod];
|
||||
var params = methods[0].GetParameters();
|
||||
for (i in 0...params.Length) {
|
||||
var param = params[i].ParameterType;
|
||||
var strParam = param + "", arg = oargs[i];
|
||||
if (StringTools.startsWith(strParam, "haxe.lang.Null")) {
|
||||
oargs[i] = mkNullable(arg, param);
|
||||
} else if (cast(untyped __typeof__(IConvertible), Type).IsAssignableFrom(param)) {
|
||||
if (arg == null) {
|
||||
if (param.IsValueType)
|
||||
oargs[i] = Activator.CreateInstance(param);
|
||||
} else if (!cs.Lib.getNativeType(arg).IsAssignableFrom(param)) {
|
||||
oargs[i] = cast(arg, IConvertible).ToType(param, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (methods[0].ContainsGenericParameters && Std.isOfType(methods[0], cs.system.reflection.MethodInfo)) {
|
||||
var m:MethodInfo = cast methods[0];
|
||||
var tgs = m.GetGenericArguments();
|
||||
for (i in 0...tgs.Length) {
|
||||
tgs[i] = untyped __typeof__(Dynamic);
|
||||
}
|
||||
m = m.MakeGenericMethod(tgs);
|
||||
var retg = try
|
||||
m.Invoke(obj, oargs)
|
||||
catch(e:TargetInvocationException)
|
||||
throw e.InnerException;
|
||||
return cs.internal.Runtime.unbox(retg);
|
||||
}
|
||||
|
||||
var m = methods[0];
|
||||
if (obj == null && Std.isOfType(m, cs.system.reflection.ConstructorInfo)) {
|
||||
var ret = try
|
||||
cast(m, cs.system.reflection.ConstructorInfo).Invoke(oargs)
|
||||
catch(e:TargetInvocationException)
|
||||
throw e.InnerException;
|
||||
return unbox(ret);
|
||||
}
|
||||
|
||||
var ret = try
|
||||
m.Invoke(obj, oargs)
|
||||
catch(e:TargetInvocationException)
|
||||
throw e.InnerException;
|
||||
return unbox(ret);
|
||||
}
|
||||
|
||||
public static function unbox(dyn:Dynamic):Dynamic {
|
||||
if (dyn != null && untyped (Lib.getNativeType(dyn) + "").StartsWith("haxe.lang.Null")) {
|
||||
return dyn.toDynamic();
|
||||
} else {
|
||||
return dyn;
|
||||
}
|
||||
}
|
||||
|
||||
#if !erase_generics
|
||||
@:functionCode('
|
||||
if (nullableType.ContainsGenericParameters)
|
||||
return haxe.lang.Null<object>.ofDynamic<object>(obj);
|
||||
return nullableType.GetMethod("_ofDynamic").Invoke(null, new object[] { obj });
|
||||
')
|
||||
public static function mkNullable(obj:Dynamic, nullableType:Type):Dynamic {
|
||||
return null;
|
||||
}
|
||||
#else
|
||||
public static function mkNullable(obj:Dynamic, nullable:Type):Dynamic {
|
||||
return obj; // do nothing
|
||||
}
|
||||
#end
|
||||
|
||||
public static function slowCallField(obj:Dynamic, field:String, args:cs.NativeArray<Dynamic>):Dynamic {
|
||||
if (field == "toString" && (args == null || args.length == 0)) {
|
||||
return obj.ToString();
|
||||
}
|
||||
if (args == null)
|
||||
args = new cs.NativeArray(0);
|
||||
|
||||
var bf:BindingFlags;
|
||||
var t = Lib.as(obj, cs.system.Type);
|
||||
if (t == null) {
|
||||
var s = Lib.as(obj, String);
|
||||
if (s != null)
|
||||
return cs.internal.StringExt.StringRefl.handleCallField(untyped s, untyped field, args);
|
||||
t = untyped obj.GetType();
|
||||
bf = new Flags(BindingFlags.Instance) | BindingFlags.Public | BindingFlags.FlattenHierarchy;
|
||||
} else {
|
||||
if (t == Lib.toNativeType(String) && field == 'fromCharCode')
|
||||
return cs.internal.StringExt.fromCharCode(toInt(args[0]));
|
||||
obj = null;
|
||||
bf = new Flags(BindingFlags.Static) | BindingFlags.Public;
|
||||
}
|
||||
|
||||
var mis:NativeArray<MethodBase> = untyped t.GetMethods(bf);
|
||||
var last = 0;
|
||||
for (i in 0...mis.Length) {
|
||||
var name = mis[i].Name;
|
||||
if (name == field)
|
||||
mis[last++] = mis[i];
|
||||
}
|
||||
|
||||
if (last == 0 && (field == "__get" || field == "__set")) {
|
||||
field = field == "__get" ? "get_Item" : "set_Item";
|
||||
for (i in 0...mis.Length) {
|
||||
var name = mis[i].Name;
|
||||
if (name == field) {
|
||||
mis[last++] = mis[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last == 0 && t.IsCOMObject)
|
||||
return t.InvokeMember(field, BindingFlags.InvokeMethod, null, obj, args);
|
||||
|
||||
if (last == 0) {
|
||||
throw 'Method "$field" not found on type $t';
|
||||
}
|
||||
|
||||
return Runtime.callMethod(obj, mis, last, args);
|
||||
}
|
||||
|
||||
public static function callField(obj:Dynamic, field:String, fieldHash:Int, args:cs.NativeArray<Dynamic>):Dynamic {
|
||||
var hxObj = Lib.as(obj, HxObject);
|
||||
if (hxObj != null)
|
||||
return untyped hxObj.__hx_invokeField(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, args);
|
||||
return slowCallField(obj, field, args);
|
||||
}
|
||||
|
||||
public static function getField(obj:Dynamic, field:String, fieldHash:Int, throwErrors:Bool):Dynamic {
|
||||
var hxObj = Lib.as(obj, HxObject);
|
||||
if (hxObj != null)
|
||||
return untyped hxObj.__hx_getField(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, throwErrors, false, false);
|
||||
|
||||
return slowGetField(obj, field, throwErrors);
|
||||
}
|
||||
|
||||
public static function getField_f(obj:Dynamic, field:String, fieldHash:Int, throwErrors:Bool):Float {
|
||||
var hxObj = Lib.as(obj, HxObject);
|
||||
if (hxObj != null)
|
||||
return untyped hxObj.__hx_getField_f(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, throwErrors, false);
|
||||
|
||||
return toDouble(slowGetField(obj, field, throwErrors));
|
||||
}
|
||||
|
||||
public static function setField(obj:Dynamic, field:String, fieldHash:Int, value:Dynamic):Dynamic {
|
||||
var hxObj = Lib.as(obj, HxObject);
|
||||
if (hxObj != null)
|
||||
return untyped hxObj.__hx_setField(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, value, false);
|
||||
|
||||
return slowSetField(obj, field, value);
|
||||
}
|
||||
|
||||
public static function setField_f(obj:Dynamic, field:String, fieldHash:Int, value:Float):Float {
|
||||
var hxObj = Lib.as(obj, HxObject);
|
||||
if (hxObj != null)
|
||||
return untyped hxObj.__hx_setField_f(field, (fieldHash == 0) ? FieldLookup.hash(field) : fieldHash, value, false);
|
||||
|
||||
return toDouble(slowSetField(obj, field, value));
|
||||
}
|
||||
|
||||
public static function toString(obj:Dynamic):String {
|
||||
if (obj == null)
|
||||
return null;
|
||||
if (Std.isOfType(obj, Bool))
|
||||
if (obj)
|
||||
return "true";
|
||||
else
|
||||
return "false";
|
||||
|
||||
return untyped obj.ToString();
|
||||
}
|
||||
|
||||
#if erase_generics
|
||||
inline
|
||||
#end
|
||||
public static function typeEq(t1:Type, t2:Type):Bool {
|
||||
if (t1 == null || t2 == null)
|
||||
return t1 == t2;
|
||||
#if !erase_generics
|
||||
var t1i = t1.IsInterface, t2i = t2.IsInterface;
|
||||
if (t1i != t2i) {
|
||||
if (t1i) {
|
||||
var g = getGenericAttr(t1);
|
||||
if (g != null)
|
||||
t1 = g.generic;
|
||||
} else {
|
||||
var g = getGenericAttr(t2);
|
||||
if (g != null)
|
||||
t2 = g.generic;
|
||||
}
|
||||
}
|
||||
#end
|
||||
if (t1.GetGenericArguments().Length > 0)
|
||||
t1 = t1.GetGenericTypeDefinition();
|
||||
if (t2.GetGenericArguments().Length > 0)
|
||||
t2 = t2.GetGenericTypeDefinition();
|
||||
return Object.ReferenceEquals(t1, t2);
|
||||
}
|
||||
|
||||
#if !erase_generics
|
||||
public static function getGenericAttr(t:cs.system.Type):cs.internal.HxObject.GenericInterface {
|
||||
for (attr in t.GetCustomAttributes(true))
|
||||
if (Std.isOfType(attr, cs.internal.HxObject.GenericInterface))
|
||||
return cast attr;
|
||||
return null;
|
||||
}
|
||||
#end
|
||||
|
||||
#if !erase_generics
|
||||
@:functionCode('
|
||||
if (obj is To)
|
||||
return (To) obj;
|
||||
else if (obj == null)
|
||||
return default(To);
|
||||
if (typeof(To) == typeof(double))
|
||||
return (To)(object) toDouble(obj);
|
||||
else if (typeof(To) == typeof(int))
|
||||
return (To)(object) toInt(obj);
|
||||
else if (typeof(To) == typeof(float))
|
||||
return (To)(object)(float)toDouble(obj);
|
||||
else if (typeof(To) == typeof(long))
|
||||
return (To)(object)(long)toDouble(obj);
|
||||
else
|
||||
return (To) obj;
|
||||
')
|
||||
public static function genericCast<To>(obj:Dynamic):To {
|
||||
return null;
|
||||
}
|
||||
#end
|
||||
|
||||
@:functionCode('
|
||||
return (s1 == null ? "null" : s1) + (s2 == null ? "null" : s2);
|
||||
')
|
||||
public static function concat(s1:String, s2:String):String {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function toBool(dyn:Dynamic):Bool {
|
||||
return if (dyn == null) false else untyped __cs__("(bool){0}", dyn);
|
||||
}
|
||||
|
||||
// TODO: change from genericCast to getConverter, so we don't need to handle extra boxing associated with it
|
||||
/*@:functionCode('
|
||||
if (typeof(To).TypeHandle == typeof(double).TypeHandle)
|
||||
return (System.Converter<object,To>) new System.Converter<object,double>(toDouble);
|
||||
else if (typeof(To).TypeHandle == typeof(double).TypeHandle)
|
||||
return (System.Converter<object,To>) new System.Converter<object,double>(toDouble);
|
||||
else
|
||||
return (System.Converter<object, To>) delegate(object obj) { return (To) obj; };
|
||||
')
|
||||
public static function getConverter<To>():cs.system.Converter<Dynamic,To>
|
||||
{
|
||||
return null;
|
||||
}*/
|
||||
}
|
||||
|
||||
@:nativeGen
|
||||
@:keep @:native("haxe.lang.EmptyObject") enum EmptyObject {
|
||||
EMPTY;
|
||||
}
|
223
Kha/Tools/linux_x64/std/cs/internal/StringExt.hx
Normal file
223
Kha/Tools/linux_x64/std/cs/internal/StringExt.hx
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cs.internal;
|
||||
|
||||
import cs.internal.Function;
|
||||
|
||||
private typedef NativeString = cs.system.String;
|
||||
|
||||
@:keep @:nativeGen @:native("haxe.lang.StringExt") class StringExt {
|
||||
@:readOnly static var empty(default, never) = new NativeString(cast 0, 0);
|
||||
|
||||
public static function charAt(me:NativeString, index:Int):NativeString {
|
||||
if (cast(index, UInt) >= me.Length)
|
||||
return empty;
|
||||
else
|
||||
return new NativeString(me[index], 1);
|
||||
}
|
||||
|
||||
public static function charCodeAt(me:NativeString, index:Int):Null<Int> {
|
||||
if (cast(index, UInt) >= me.Length)
|
||||
return null;
|
||||
else
|
||||
return cast(me[index], Int);
|
||||
}
|
||||
|
||||
public static function indexOf(me:NativeString, str:String, ?startIndex:Int):Int {
|
||||
var sIndex:Int = startIndex != null ? startIndex : 0;
|
||||
if(str == '') {
|
||||
if(sIndex < 0) {
|
||||
sIndex = me.Length + sIndex;
|
||||
if(sIndex < 0) sIndex = 0;
|
||||
}
|
||||
return sIndex > me.Length ? me.Length : sIndex;
|
||||
}
|
||||
if (sIndex >= me.Length)
|
||||
return -1;
|
||||
return @:privateAccess me.IndexOf(str, sIndex, cs.system.StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static function lastIndexOf(me:NativeString, str:NativeString, ?startIndex:Int):Int {
|
||||
var sIndex:Int = startIndex == null ? me.Length - 1 : startIndex;
|
||||
if (sIndex >= me.Length)
|
||||
sIndex = me.Length - 1;
|
||||
else if (sIndex < 0)
|
||||
return -1;
|
||||
|
||||
if (str.Length == 0) {
|
||||
return startIndex == null || startIndex > me.Length ? me.Length : startIndex;
|
||||
}
|
||||
|
||||
// TestBaseTypes.hx@133 fix
|
||||
if (startIndex != null) {
|
||||
// if the number of letters between start index and the length of the string
|
||||
// is less than the length of a searched substring - shift start index to the
|
||||
// left by the difference to avoid OOB access later and save some work
|
||||
var d = me.Length - sIndex - str.Length;
|
||||
if (d < 0) {
|
||||
sIndex += d;
|
||||
}
|
||||
|
||||
var i = sIndex + 1;
|
||||
while (i-- > 0) {
|
||||
var found = true;
|
||||
for (j in 0...str.Length) {
|
||||
if (me[i + j] != str[j]) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
} else {
|
||||
return me.LastIndexOf(untyped str, sIndex, cs.system.StringComparison.Ordinal);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static function split(me:NativeString, delimiter:NativeString):Array<String> {
|
||||
var native:NativeArray<String>;
|
||||
if (delimiter.Length == 0) {
|
||||
var len = me.Length;
|
||||
native = new NativeArray(len);
|
||||
for (i in 0...len)
|
||||
native[i] = untyped new NativeString(me[i], 1);
|
||||
} else {
|
||||
var str = new NativeArray<String>(1);
|
||||
str[0] = cast delimiter;
|
||||
|
||||
native = me.Split(str, cs.system.StringSplitOptions.None);
|
||||
}
|
||||
|
||||
return cs.Lib.array(native);
|
||||
}
|
||||
|
||||
public static function substr(me:NativeString, pos:Int, ?len:Int):String {
|
||||
var meLen = me.Length;
|
||||
var targetLen = meLen;
|
||||
if (len != null) {
|
||||
targetLen = len;
|
||||
if (targetLen == 0 || (pos != 0 && targetLen < 0))
|
||||
return "";
|
||||
}
|
||||
|
||||
if (pos < 0) {
|
||||
pos = meLen + pos;
|
||||
if (pos < 0)
|
||||
pos = 0;
|
||||
} else if (targetLen < 0) {
|
||||
targetLen = meLen + targetLen - pos;
|
||||
}
|
||||
|
||||
if (pos + targetLen > meLen) {
|
||||
targetLen = meLen - pos;
|
||||
}
|
||||
|
||||
if (pos < 0 || targetLen <= 0)
|
||||
return "";
|
||||
|
||||
return me.Substring(pos, targetLen);
|
||||
}
|
||||
|
||||
public static function substring(me:NativeString, startIndex:Int, ?endIndex:Int):String {
|
||||
var len = me.Length;
|
||||
var endIdx:Int;
|
||||
if (endIndex == null)
|
||||
endIdx = len;
|
||||
else if ((endIdx = endIndex) < 0)
|
||||
endIdx = 0;
|
||||
else if (endIdx > len)
|
||||
endIdx = len;
|
||||
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
else if (startIndex > len)
|
||||
startIndex = len;
|
||||
|
||||
if (startIndex > endIdx) {
|
||||
var tmp = startIndex;
|
||||
startIndex = endIdx;
|
||||
endIdx = tmp;
|
||||
}
|
||||
|
||||
return me.Substring(startIndex, endIdx - startIndex);
|
||||
}
|
||||
|
||||
public static function toString(me:NativeString):NativeString {
|
||||
return me;
|
||||
}
|
||||
|
||||
public static function toLowerCase(me:NativeString):String {
|
||||
return me.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public static function toUpperCase(me:NativeString):String {
|
||||
return me.ToUpperInvariant();
|
||||
}
|
||||
|
||||
public static function toNativeString(me:NativeString):NativeString {
|
||||
return me;
|
||||
}
|
||||
|
||||
public static function fromCharCode(code:Int):String {
|
||||
return cs.system.Char.ConvertFromUtf32(code);
|
||||
// return new NativeString( cast(code,cs.StdTypes.Char16), 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@:keep @:nativeGen @:native('haxe.lang.StringRefl') class StringRefl {
|
||||
public static var fields = [
|
||||
"length", "toUpperCase", "toLowerCase", "charAt", "charCodeAt", "indexOf", "lastIndexOf", "split", "substr", "substring"
|
||||
];
|
||||
|
||||
public static function handleGetField(str:String, f:String, throwErrors:Bool):Dynamic {
|
||||
switch (f) {
|
||||
case "length":
|
||||
return str.length;
|
||||
case "toUpperCase", "toLowerCase", "charAt", "charCodeAt", "indexOf", "lastIndexOf", "split", "substr", "substring":
|
||||
return new Closure(str, f, 0);
|
||||
default:
|
||||
if (throwErrors)
|
||||
throw "Field not found: '" + f + "' in String";
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function handleCallField(str:NativeString, f:String, args:cs.NativeArray<Dynamic>):Dynamic {
|
||||
var _args:cs.NativeArray<Dynamic>;
|
||||
if (args == null) {
|
||||
_args = cs.NativeArray.make(str);
|
||||
} else {
|
||||
_args = new cs.NativeArray(args.length + 1);
|
||||
for (i in 0...args.length)
|
||||
_args[i + 1] = args[i];
|
||||
_args[0] = str;
|
||||
}
|
||||
return Runtime.slowCallField(StringExt, f, _args);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user