Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,49 @@
/*
* 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;
import cs.internal.FieldLookup;
import cs.internal.Function;
import cs.internal.HxObject;
import cs.internal.Runtime;
#if !erase_generics
import cs.internal.Null;
#end
import cs.internal.StringExt;
#if unsafe
import cs.internal.BoxedPointer;
#end
import cs.StdTypes;
import haxe.ds.StringMap;
import Reflect;
@:dox(hide)
class Boot {
@:keep public static function init():Void {
#if std_encoding_utf8
cs.system.Console.InputEncoding = new cs.system.text.UTF8Encoding();
cs.system.Console.OutputEncoding = new cs.system.text.UTF8Encoding();
#end
cs.Lib.applyCultureChanges();
}
}

View File

@ -0,0 +1,55 @@
/*
* 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;
/**
The type argument must be a value type. Any value type except Nullable_1<T>
can be specified.
It is intended to be used as a native cs type parameter constraint, when
using `@:nativeGen`. This constraint won't have any effect on Haxe code.
If used as a real type, the underlying type will be `Dynamic`.
**/
@:coreType abstract CsStruct from Dynamic {}
/**
The type argument must be a reference type. This constraint applies also to
any class, interface, delegate, or array type.
It is intended to be used as a native cs type parameter constraint, when
using `@:nativeGen`. This constraint won't have any effect on Haxe code.
If used as a real type, the underlying type will be `Dynamic`.
**/
@:coreType abstract CsClass from Dynamic {}
#if (cs_ver >= "7.3")
/**
The type argument must not be a reference type and must not contain any
reference type members at any level of nesting.
It is intended to be used as a native cs type parameter constraint, when
using `@:nativeGen`. This constraint won't have any effect on Haxe code.
If used as a real type, the underlying type will be `Dynamic`.
**/
@:coreType abstract CsUnmanaged from Dynamic {}
#end

View File

@ -0,0 +1,114 @@
/*
* 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;
/**
Use this type to have access to the bitwise operators of C# enums that have a `cs.system.FlagsAttribute` attribute.
Usage example:
```haxe
import cs.system.reflection.BindingFlags;
var binding = new Flags(BindingFlags.Public) | BindingFlags.Static | BindingFlags.NonPublic;
```
**/
abstract Flags<T:EnumValue>(T) from T to T {
/**
Creates a new `Flags` type with an optional initial value. If no initial value was specified,
the default enum value for an empty flags attribute is specified
**/
extern inline public function new(?initial:T)
this = initial == null ? cast null : initial;
/**
Accessible through the bitwise OR operator (`|`). Returns a new `Flags` type with the flags
passed at `flags` added to it.
**/
@:op(A | B) extern inline public function add(flags:Flags<T>):Flags<T> {
return new Flags(underlying() | flags.underlying());
}
/**
Accessible through the bitwise AND operator (`&`). Returns a new `Flags` type with
the flags that are set on both `this` and `flags`
**/
@:op(A & B) extern inline public function bitAnd(flags:Flags<T>):Flags<T> {
return new Flags(underlying() & flags.underlying());
}
/**
Accessible through the bitwise XOR operator (`^`).
**/
@:op(A ^ B) extern inline public function bitXor(flags:Flags<T>):Flags<T> {
return new Flags(underlying() & flags.underlying());
}
/**
Accesible through the bitwise negation operator (`~`). Returns a new `Flags` type
with all unset flags as set - but the ones that are set already.
**/
@:op(~A) extern inline public function bitNeg():Flags<T> {
return new Flags(~underlying());
}
/**
Returns a new `Flags` type with all flags set by `flags` unset
**/
extern inline public function remove(flags:Flags<T>):Flags<T> {
return new Flags(underlying() & ~flags.underlying());
}
/**
Returns whether `flag` is present on `this` type
**/
extern inline public function has(flag:T):Bool {
return underlying() & new Flags(flag).underlying() != null;
}
/**
Returns whether `this` type has any flag set by `flags` also set
**/
extern inline public function hasAny(flags:Flags<T>):Bool {
return underlying() & flags.underlying() != null;
}
/**
Returns whether `this` type has all flags set by `flags` also set
**/
extern inline public function hasAll(flags:Flags<T>):Bool {
return underlying() & flags.underlying() == flags.underlying();
}
extern inline private function underlying():EnumUnderlying<T>
return this;
}
@:coreType private abstract EnumUnderlying<T> from T to T {
@:op(A | B) public static function or<T>(lhs:EnumUnderlying<T>, rhs:EnumUnderlying<T>):T;
@:op(A ^ B) public static function xor<T>(lhs:EnumUnderlying<T>, rhs:EnumUnderlying<T>):T;
@:op(A & B) public static function and<T>(lhs:EnumUnderlying<T>, rhs:EnumUnderlying<T>):T;
@:op(~A) public static function bneg<T>(t:EnumUnderlying<T>):T;
}

View File

@ -0,0 +1,296 @@
/*
* 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;
import cs.system.Type;
/**
Platform-specific C# Library. Provides some platform-specific functions for the C# target,
such as conversion from haxe types to native types and vice-versa.
**/
class Lib {
private static var decimalSeparator:String;
/**
Changes the current culture settings to allow a consistent cross-target behavior.
Currently the only change made is in regard to the decimal separator, which is always set to "."
**/
public static function applyCultureChanges():Void {
var ci = new cs.system.globalization.CultureInfo(cs.system.threading.Thread.CurrentThread.CurrentCulture.Name, true);
decimalSeparator = ci.NumberFormat.NumberDecimalSeparator;
ci.NumberFormat.NumberDecimalSeparator = ".";
cs.system.threading.Thread.CurrentThread.CurrentCulture = ci;
}
/**
Reverts the culture changes to the default settings.
**/
public static function revertDefaultCulture():Void {
var ci = new cs.system.globalization.CultureInfo(cs.system.threading.Thread.CurrentThread.CurrentCulture.Name, true);
cs.system.threading.Thread.CurrentThread.CurrentCulture = ci;
}
/**
Returns a native array from the supplied Array. This native array is unsafe to be written on,
as it may or may not be linked to the actual Array implementation.
If equalLengthRequired is true, the result might be a copy of an array with the correct size.
**/
extern inline public static function nativeArray<T>(arr:Array<T>, equalLengthRequired:Bool):NativeArray<T> {
var ret = new cs.NativeArray(arr.length);
#if erase_generics
for (i in 0...arr.length)
ret[i] = arr[i];
#else
p_nativeArray(arr, ret);
#end
return ret;
}
#if !erase_generics
static function p_nativeArray<T>(arr:Array<T>, ret:cs.system.Array):Void {
var native:NativeArray<T> = untyped arr.__a;
var len = arr.length;
cs.system.Array.Copy(native, 0, ret, 0, len);
}
#end
/**
Provides support for the "as" keyword in C#.
If the object is not of the supplied type "T", it will return null instead of rasing an exception.
This function will not work with Value Types (such as Int, Float, Bool...)
**/
@:pure
extern public static inline function as<T>(obj:Dynamic, cl:Class<T>):T {
return untyped __as__(obj);
}
/**
Returns a Class<> equivalent to the native System.Type type.
Currently Haxe's Class<> is equivalent to System.Type, but this is an implementation detail.
This may change in the future, so use this function whenever you need to perform such conversion.
**/
public static inline function fromNativeType(t:cs.system.Type):Class<Dynamic> {
return untyped t;
}
/**
Returns a System.Type equivalent to the Haxe Class<> type.
Currently Haxe's Class<> is equivalent to System.Type, but this is an implementation detail.
This may change in the future, so use this function whenever you need to perform such conversion.
**/
public static inline function toNativeType(cl:Class<Dynamic>):Type {
return untyped cl;
}
/**
Returns a System.Type equivalent to the Haxe Enum<> type.
**/
public static inline function toNativeEnum(cl:Enum<Dynamic>):Type {
return untyped cl;
}
/**
Gets the native System.Type from the supplied object. Will throw an exception in case of null being passed.
[deprecated] - use `getNativeType` instead
**/
@:deprecated('The function `nativeType` is deprecated and will be removed in later versions. Please use `getNativeType` instead')
public static inline function nativeType(obj:Dynamic):Type {
return untyped obj.GetType();
}
/**
Gets the native System.Type from the supplied object. Will throw an exception in case of null being passed.
**/
public static inline function getNativeType(obj:Dynamic):Type {
return untyped obj.GetType();
}
#if erase_generics
inline private static function mkDynamic<T>(native:NativeArray<T>):NativeArray<Dynamic> {
var ret = new cs.NativeArray<Dynamic>(native.Length);
for (i in 0...native.Length)
ret[i] = native[i];
return ret;
}
#end
/**
Returns a Haxe Array of a native Array.
Unless `erase_generics` is defined, it won't copy the contents of the native array,
so unless any operation triggers an array resize, all changes made to the Haxe array
will affect the native array argument.
**/
inline public static function array<T>(native:cs.NativeArray<T>):Array<T> {
#if erase_generics
var dyn:NativeArray<Dynamic> = mkDynamic(native);
return @:privateAccess Array.ofNative(dyn);
#else
return @:privateAccess Array.ofNative(native);
#end
}
/**
Allocates a new Haxe Array with a predetermined size
**/
inline public static function arrayAlloc<T>(size:Int):Array<T> {
return @:privateAccess Array.alloc(size);
}
/**
Rethrow an exception. This is useful when manually filtering an exception in order
to keep the previous exception stack.
**/
extern inline public static function rethrow(e:Dynamic):Void {
throw untyped __rethrow__;
}
/**
Creates a "checked" block, which throws exceptions for overflows.
Usage:
cs.Lib.checked({
var x = 1000;
while(true)
{
x *= x;
}
});
This method only exists at compile-time, so it can't be called via reflection.
**/
extern public static inline function checked<V>(block:V):Void {
untyped __checked__(block);
}
/**
Ensures that one thread does not enter a critical section of code while another thread
is in the critical section. If another thread attempts to enter a locked code, it
will wait, block, until the object is released.
This method only exists at compile-time, so it can't be called via reflection.
**/
extern public static inline function lock<O, V>(obj:O, block:V):Void {
untyped __lock__(obj, block);
}
// Unsafe code manipulation
#if unsafe
/**
Marks its parameters as fixed objects inside the defined block.
The first variable declarations that use cs.Lib.pointerOfArray() will be the fixed definitions.
Usage:
cs.Lib.fixed({
var obj1 = cs.Lib.pointerOfArray(someArray);
var obj2 = cs.Lib.pointerOfArray(someArray2);
var obj3 = cs.Lib.pointerOfArray(someArray3);
//from now on, obj1, obj2 and obj3 are fixed
//we cannot change obj1, obj2 or obj3 variables like this:
//obj1++;
});
This method only exists at compile-time, so it can't be called via reflection.
**/
extern public static inline function fixed<V>(block:V):Void {
untyped __fixed__(block);
}
/**
Marks the contained block as an unsafe block, meaning that it can contain unsafe code.
Usage:
cs.Lib.unsafe({
//unsafe code is allowed inside here
});
This method only exists at compile-time, so it can't be called via reflection.
**/
extern public static inline function unsafe<V>(block:V):Void {
untyped __unsafe__(block);
}
/**
Gets the pointer to the address of current local. Equivalent to the "&" operator in C#
Usage:
var x:Int = 0;
cs.Lib.unsafe({
var addr = cs.Lib.addressOf(x);
x[0] = 42;
});
trace(x); //42
This method only exists at compile-time, so it can't be called via reflection.
Warning: This method will only work if a local variable is passed as an argument.
**/
extern public static inline function addressOf<T>(variable:T):cs.Pointer<T> {
return untyped __addressOf__(variable);
}
/**
Gets the value of the pointer address.
Usage:
var x:Int = 0;
cs.Lib.unsafe({
var addr = cs.Lib.addressOf(x);
trace(cs.Lib.valueOf(addr)); //0
addr[0] = 42;
trace(cs.Lib.valueOf(addr)); //42
});
trace(x); //42
This method only exists at compile-time, so it can't be called via reflection.
**/
extern public static inline function valueOf<T>(pointer:cs.Pointer<T>):T {
return untyped __valueOf__(pointer);
}
/**
Transforms a managed native array into a Pointer. Must be inside a fixed statement
Usage:
var x:cs.NativeArray<Int> = new cs.NativeArray(1);
cs.Lib.unsafe({
cs.Lib.fixed({
var addr = cs.Lib.pointerOfArray(x);
trace(cs.Lib.valueOf(addr)); //0
addr[0] = 42;
trace(cs.Lib.valueOf(addr)); //42
});
});
trace(x[0]); //42
This method only exists at compile-time, so it can't be called via reflection.
**/
extern public static inline function pointerOfArray<T>(array:cs.NativeArray<T>):cs.Pointer<T> {
return untyped __ptr__(array);
}
/**
Returns the byte size of the given struct. Only works with structs and basic types.
**/
extern public static inline function sizeof(struct:Class<Dynamic>):Int {
return untyped __sizeof__(struct);
}
#end
}

View File

@ -0,0 +1,78 @@
/*
* 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;
import haxe.extern.Rest;
/**
Represents a C# fixed-size Array (`T[]`)
**/
extern class NativeArray<T> extends cs.system.Array implements ArrayAccess<T> {
/**
Creates a new array with the specified elements.
Usage:
```haxe
var elements = NativeArray.make(1,2,3,4,5,6);
```
**/
static function make<T>(elements:Rest<T>):NativeArray<T>;
/**
Allocates a new array with size `len`
**/
function new(len:Int):Void;
/**
Alias to array's `Length` property. Returns the size of the array
**/
var length(get, never):Int;
extern inline private function get_length():Int
return this.Length;
static function Reverse(arr:cs.system.Array):Void;
/**
Returns an iterator so it's possible to use `for` with C#'s `NativeArray`
**/
extern inline function iterator():NativeArrayIterator<T>
return new NativeArrayIterator(this);
}
@:dce private class NativeArrayIterator<T> {
public var arr(default, null):NativeArray<T>;
public var idx(default, null):UInt;
inline public function new(arr) {
this.arr = arr;
this.idx = 0;
}
inline public function hasNext():Bool
return this.idx < this.arr.Length;
inline public function next():T {
return this.arr[this.idx++];
}
}

View File

@ -0,0 +1,33 @@
/*
* 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;
/**
This type represents "out" types for C# function parameters.
It only has effect on function parameters, and conversion to/from the referenced type is automatic.
Note: Using this type should be considered a bad practice unless overriding a native function is needed.
**/
@:analyzer(no_local_dce)
@:semantics(reference)
typedef Out<T> = T;

View File

@ -0,0 +1,133 @@
/*
* 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;
import cs.StdTypes.Int64;
/**
This type represents pointer types for C# function parameters. It should only
be used inside an unsafe context (not checked by the Haxe compiler)
C# code:
int[] src;
fixed (int* pSrc = src)
{
...
}
Haxe code:
var src:NativeArray<Int>;
cs.Lib.fixed({
var pSrc:cs.Pointer<Int> = cs.Lib.pointerOfArray(src);
...
});
**/
#if !unsafe
#error "You need to define 'unsafe' to be able to use unsafe code in hxcs"
#else
@:runtimeValue @:coreType abstract Pointer<T> from Int64 from PointerAccess<T> to PointerAccess<T> {
@:op(A + B) public static function addIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A + B) public static function addp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A * B) public static function mulIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A * B) public static function mulp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A % B) public static function modIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A % B) public static function modp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A - B) public static function subIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A - B) public static function subp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A / B) public static function divIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A / B) public static function divp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A | B) public static function orIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A | B) public static function orp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A ^ B) public static function xorIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A ^ B) public static function xorp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A & B) public static function andIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A & B) public static function andp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A << B) public static function shlIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A << B) public static function shlp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A >> B) public static function shrIp<T>(lhs:Pointer<T>, rhs:Int):Pointer<T>;
@:op(A >> B) public static function shrp<T>(lhs:Pointer<T>, rhs:Int64):Pointer<T>;
@:op(A > B) public static function gtp<T>(lhs:Pointer<T>, rhs:Pointer<T>):Bool;
@:op(A >= B) public static function gtep<T>(lhs:Pointer<T>, rhs:Pointer<T>):Bool;
@:op(A < B) public static function ltp<T>(lhs:Pointer<T>, rhs:Pointer<T>):Bool;
@:op(A <= B) public static function ltep<T>(lhs:Pointer<T>, rhs:Pointer<T>):Bool;
@:op(~A) public static function bnegp<T>(t:Pointer<T>):Pointer<T>;
@:op(A++) public static function prepp<T>(t:Pointer<T>):Pointer<T>;
@:op(A--) public static function prenn<T>(t:Pointer<T>):Pointer<T>;
@:op(++A) public static function postpp<T>(t:Pointer<T>):Pointer<T>;
@:op(--A) public static function postnn<T>(t:Pointer<T>):Pointer<T>;
/**
Returns a `cs.PointerAccess` type, which in turn allows the underlying Pointer's
fields to be accessed.
**/
// @:analyzer(no_simplification)
public var acc(get, never):PointerAccess<T>;
// @:analyzer(no_simplification)
extern inline private function get_acc():PointerAccess<T>
return (cast this : PointerAccess<T>);
// backwards compatibility
inline public function add(i:Int):Pointer<T> {
return this + i;
}
@:arrayAccess public static function getIp<T>(p:Pointer<T>, at:Int):T;
@:arrayAccess public static function setIp<T>(p:Pointer<T>, at:Int, val:T):T;
@:arrayAccess public static function getp<T>(p:Pointer<T>, at:Int64):T;
@:arrayAccess public static function setp<T>(p:Pointer<T>, at:Int64, val:T):T;
}
@:forward abstract PointerAccess<T>(T) {}
#end

View File

@ -0,0 +1,32 @@
/*
* 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;
/**
This type represents "ref" types for C# function parameters.
It only has effect on function parameters, and conversion to/from the referenced type is automatic.
Note: Using this type should be considered a bad practice unless overriding a native function is needed.
**/
@:semantics(reference)
typedef Ref<T> = T;

View File

@ -0,0 +1,153 @@
/*
* 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;
@:notNull @:runtimeValue @:coreType extern abstract Int8 to Int {}
@:notNull @:runtimeValue @:coreType extern abstract Int16 to Int {}
@:notNull @:runtimeValue @:coreType extern abstract Char16 from Int {}
@:notNull @:runtimeValue @:coreType extern abstract UInt8 to Int from Int {}
@:notNull @:runtimeValue @:coreType extern abstract UInt16 to Int {}
@:notNull @:runtimeValue @:coreType extern abstract Int64 from Int from Float {
@:op(A + B) public static function addI(lhs:Int64, rhs:Int):Int64;
@:op(A + B) public static function add(lhs:Int64, rhs:Int64):Int64;
@:op(A * B) public static function mulI(lhs:Int64, rhs:Int):Int64;
@:op(A * B) public static function mul(lhs:Int64, rhs:Int64):Int64;
@:op(A % B) public static function modI(lhs:Int64, rhs:Int):Int64;
@:op(A % B) public static function mod(lhs:Int64, rhs:Int64):Int64;
@:op(A - B) public static function subI(lhs:Int64, rhs:Int):Int64;
@:op(A - B) public static function sub(lhs:Int64, rhs:Int64):Int64;
@:op(A / B) public static function divI(lhs:Int64, rhs:Int):Int64;
@:op(A / B) public static function div(lhs:Int64, rhs:Int64):Int64;
@:op(A | B) public static function orI(lhs:Int64, rhs:Int):Int64;
@:op(A | B) public static function or(lhs:Int64, rhs:Int64):Int64;
@:op(A ^ B) public static function xorI(lhs:Int64, rhs:Int):Int64;
@:op(A ^ B) public static function xor(lhs:Int64, rhs:Int64):Int64;
@:op(A & B) public static function andI(lhs:Int64, rhs:Int):Int64;
@:op(A & B) public static function and(lhs:Int64, rhs:Int64):Int64;
@:op(A << B) public static function shlI(lhs:Int64, rhs:Int):Int64;
@:op(A << B) public static function shl(lhs:Int64, rhs:Int64):Int64;
@:op(A >> B) public static function shrI(lhs:Int64, rhs:Int):Int64;
@:op(A >> B) public static function shr(lhs:Int64, rhs:Int64):Int64;
@:op(A > B) public static function gt(lhs:Int64, rhs:Int64):Bool;
@:op(A >= B) public static function gte(lhs:Int64, rhs:Int64):Bool;
@:op(A < B) public static function lt(lhs:Int64, rhs:Int64):Bool;
@:op(A <= B) public static function lte(lhs:Int64, rhs:Int64):Bool;
@:op(~A) public static function bneg(t:Int64):Int64;
@:op(-A) public static function neg(t:Int64):Int64;
@:op(++A) public static function preIncrement(t:Int64):Int64;
@:op(A++) public static function postIncrement(t:Int64):Int64;
@:op(--A) public static function preDecrement(t:Int64):Int64;
@:op(A--) public static function postDecrement(t:Int64):Int64;
}
@:notNull @:runtimeValue @:coreType extern abstract UInt64 from Int from Int64 from Float from haxe.Int64 {
@:op(A + B) public static function addI(lhs:UInt64, rhs:Int):UInt64;
@:op(A + B) public static function add(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A * B) public static function mulI(lhs:UInt64, rhs:Int):UInt64;
@:op(A * B) public static function mul(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A % B) public static function modI(lhs:UInt64, rhs:Int):UInt64;
@:op(A % B) public static function mod(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A - B) public static function subI(lhs:UInt64, rhs:Int):UInt64;
@:op(A - B) public static function sub(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A / B) public static function divI(lhs:UInt64, rhs:Int):UInt64;
@:op(A / B) public static function div(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A | B) public static function orI(lhs:UInt64, rhs:Int):UInt64;
@:op(A | B) public static function or(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A ^ B) public static function xorI(lhs:UInt64, rhs:Int):UInt64;
@:op(A ^ B) public static function xor(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A & B) public static function andI(lhs:UInt64, rhs:Int):UInt64;
@:op(A & B) public static function and(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A << B) public static function shlI(lhs:UInt64, rhs:Int):UInt64;
@:op(A << B) public static function shl(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A >> B) public static function shrI(lhs:UInt64, rhs:Int):UInt64;
@:op(A >> B) public static function shr(lhs:UInt64, rhs:UInt64):UInt64;
@:op(A > B) public static function gt(lhs:UInt64, rhs:UInt64):Bool;
@:op(A >= B) public static function gte(lhs:UInt64, rhs:UInt64):Bool;
@:op(A < B) public static function lt(lhs:UInt64, rhs:UInt64):Bool;
@:op(A <= B) public static function lte(lhs:UInt64, rhs:UInt64):Bool;
@:op(~A) public static function bneg(t:UInt64):UInt64;
@:op(-A) public static function neg(t:UInt64):UInt64;
@:op(++A) public static function preIncrement(t:UInt64):UInt64;
@:op(A++) public static function postIncrement(t:UInt64):UInt64;
@:op(--A) public static function preDecrement(t:UInt64):UInt64;
@:op(A--) public static function postDecrement(t:UInt64):UInt64;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C)2005-2021 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;
import haxe.Rest;
/**
Generate C# syntax not directly supported by Haxe.
Use only at low-level when specific target-specific code-generation is required.
**/
@:noClosure
extern class Syntax {
/**
Inject `code` directly into generated source.
`code` must be a string constant.
Additional `args` are supported to provide code interpolation, for example:
```haxe
Syntax.code("System.Console.WriteLine({0} + {1})", "hi", 42);
```
will generate
```haxe
System.Console.WriteLine("hi" + 42);
```
Emits a compilation error if the count of `args` does not match the count of placeholders in `code`.
**/
static function code(code:String, args:Rest<Dynamic>):Dynamic;
/**
Inject `code` directly into generated source.
The same as `cs.Syntax.code` except this one does not provide code interpolation.
**/
static function plainCode(code:String):Dynamic;
}

View File

@ -0,0 +1,479 @@
/*
* 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 cs.NativeArray;
import haxe.iterators.ArrayKeyValueIterator;
#if core_api_serialize
@:meta(System.Serializable)
#end
final class Array<T> implements ArrayAccess<T> {
public var length(default, null):Int;
private var __a:NativeArray<T>;
@:skipReflection static var __hx_toString_depth = 0;
@:skipReflection static inline final __hx_defaultCapacity = 4;
#if erase_generics
inline private static function ofNative<X>(native:NativeArray<Dynamic>):Array<X> {
return new Array(native);
}
#else
inline private static function ofNative<X>(native:NativeArray<X>):Array<X> {
return new Array(native);
}
#end
inline private static function alloc<Y>(size:Int):Array<Y> {
return new Array(new NativeArray(size));
}
@:overload public function new():Void {
this.length = 0;
this.__a = new NativeArray(0);
}
#if erase_generics
@:overload private function new(native:NativeArray<Dynamic>) {
this.length = native.Length;
this.__a = untyped native;
}
#else
@:overload private function new(native:NativeArray<T>) {
this.length = native.Length;
this.__a = native;
}
#end
public function concat(a:Array<T>):Array<T> {
var len = length + a.length;
var retarr = new NativeArray(len);
cs.system.Array.Copy(__a, 0, retarr, 0, length);
cs.system.Array.Copy(a.__a, 0, retarr, length, a.length);
return ofNative(retarr);
}
private function concatNative(a:NativeArray<T>):Void {
var __a = __a;
var len = length + a.Length;
if (__a.Length >= len) {
cs.system.Array.Copy(a, 0, __a, length, length);
} else {
var newarr = new NativeArray(len);
cs.system.Array.Copy(__a, 0, newarr, 0, length);
cs.system.Array.Copy(a, 0, newarr, length, a.Length);
this.__a = newarr;
}
this.length = len;
}
public function indexOf(x:T, ?fromIndex:Int):Int {
var len = length, i:Int = (fromIndex == null) ? 0 : fromIndex;
if (i < 0) {
i += len;
if (i < 0)
i = 0;
} else if (i >= len) {
return -1;
}
return cs.system.Array.IndexOf(__a, x, i, len - i);
}
public function lastIndexOf(x:T, ?fromIndex:Int):Int {
var len = length, i:Int = (fromIndex == null) ? len - 1 : fromIndex;
if (i >= len) {
i = len - 1;
} else if (i < 0) {
i += len;
if (i < 0)
return -1;
}
return cs.system.Array.LastIndexOf(__a, x, i, i + 1);
}
public function join(sep:String):String {
var buf = new StringBuf();
var i = -1;
var first = true;
var length = length;
while (++i < length) {
if (first)
first = false;
else
buf.add(sep);
buf.add(__a[i]);
}
return buf.toString();
}
public function pop():Null<T> {
var __a = __a;
var length = length;
if (length > 0) {
var val = __a[--length];
__a[length] = null;
this.length = length;
return val;
} else {
return null;
}
}
public function push(x:T):Int {
if (length >= __a.Length) {
var newLen = length == 0 ? __hx_defaultCapacity : (length << 1);
var newarr = new NativeArray(newLen);
__a.CopyTo(newarr, 0);
this.__a = newarr;
}
__a[length] = x;
return ++length;
}
public function reverse():Void {
var i = 0;
var l = this.length;
var a = this.__a;
var half = l >> 1;
l -= 1;
while (i < half) {
var tmp = a[i];
a[i] = a[l - i];
a[l - i] = tmp;
i += 1;
}
}
public function shift():Null<T> {
var l = this.length;
if (l == 0)
return null;
var a = this.__a;
var x = a[0];
l -= 1;
cs.system.Array.Copy(a, 1, a, 0, length - 1);
a[l] = null;
this.length = l;
return x;
}
public function slice(pos:Int, ?end:Int):Array<T> {
if (pos < 0) {
pos = this.length + pos;
if (pos < 0)
pos = 0;
}
if (end == null)
end = this.length;
else if (end < 0)
end = this.length + end;
if (end > this.length)
end = this.length;
var len = end - pos;
if (len < 0)
return new Array();
var newarr = new NativeArray(len);
cs.system.Array.Copy(__a, pos, newarr, 0, len);
return ofNative(newarr);
}
public function sort(f:T->T->Int):Void {
if (length == 0)
return;
quicksort(0, length - 1, f);
}
private function quicksort(lo:Int, hi:Int, f:T->T->Int):Void {
var buf = __a;
var i = lo, j = hi;
var p = buf[(i + j) >> 1];
while (i <= j) {
while (i < hi && f(buf[i], p) < 0)
i++;
while (j > lo && f(buf[j], p) > 0)
j--;
if (i <= j) {
var t = buf[i];
buf[i++] = buf[j];
buf[j--] = t;
}
}
if (lo < j)
quicksort(lo, j, f);
if (i < hi)
quicksort(i, hi, f);
}
public function splice(pos:Int, len:Int):Array<T> {
if (len < 0)
return new Array();
if (pos < 0) {
pos = this.length + pos;
if (pos < 0)
pos = 0;
}
if (pos > this.length) {
pos = 0;
len = 0;
} else if (pos + len > this.length) {
len = this.length - pos;
if (len < 0)
len = 0;
}
var a = this.__a;
var ret = new NativeArray(len);
cs.system.Array.Copy(a, pos, ret, 0, len);
var ret = ofNative(ret);
var end = pos + len;
cs.system.Array.Copy(a, end, a, pos, this.length - end);
this.length -= len;
while (--len >= 0)
a[this.length + len] = null;
return ret;
}
private function spliceVoid(pos:Int, len:Int):Void {
if (len < 0)
return;
if (pos < 0) {
pos = this.length + pos;
if (pos < 0)
pos = 0;
}
if (pos > this.length) {
pos = 0;
len = 0;
} else if (pos + len > this.length) {
len = this.length - pos;
if (len < 0)
len = 0;
}
var a = this.__a;
var end = pos + len;
cs.system.Array.Copy(a, end, a, pos, this.length - end);
this.length -= len;
while (--len >= 0)
a[this.length + len] = null;
}
public function toString():String {
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
function __hx_toString():String {
var ret = new StringBuf();
var a = __a;
ret.add("[");
var first = true;
for (i in 0...length) {
if (first)
first = false;
else
ret.add(",");
ret.add(a[i]);
}
ret.add("]");
return ret.toString();
}
public function unshift(x:T):Void {
var __a = __a;
var length = length;
if (length >= __a.Length) {
var newLen = (length << 1) + 1;
var newarr = new NativeArray(newLen);
cs.system.Array.Copy(__a, 0, newarr, 1, length);
this.__a = newarr;
} else {
cs.system.Array.Copy(__a, 0, __a, 1, length);
}
this.__a[0] = x;
++this.length;
}
public function insert(pos:Int, x:T):Void {
var l = this.length;
if (pos < 0) {
pos = l + pos;
if (pos < 0)
pos = 0;
}
if (pos >= l) {
this.push(x);
return;
} else if (pos == 0) {
this.unshift(x);
return;
}
if (l >= __a.Length) {
var newLen = (length << 1) + 1;
var newarr = new NativeArray(newLen);
cs.system.Array.Copy(__a, 0, newarr, 0, pos);
newarr[pos] = x;
cs.system.Array.Copy(__a, pos, newarr, pos + 1, l - pos);
this.__a = newarr;
++this.length;
} else {
var __a = __a;
cs.system.Array.Copy(__a, pos, __a, pos + 1, l - pos);
cs.system.Array.Copy(__a, 0, __a, 0, pos);
__a[pos] = x;
++this.length;
}
}
public function remove(x:T):Bool {
var __a = __a;
var i = -1;
var length = length;
while (++i < length) {
if (__a[i] == x) {
cs.system.Array.Copy(__a, i + 1, __a, i, length - i - 1);
__a[--this.length] = null;
return true;
}
}
return false;
}
public inline function map<S>(f:T->S):Array<S> {
var ret = alloc(length);
for (i in 0...length)
ret.__unsafe_set(i, f(__unsafe_get(i)));
return ret;
}
public function contains(x:T):Bool {
var __a = __a;
var i = -1;
var length = length;
while (++i < length) {
if (__a[i] == x)
return true;
}
return false;
}
public inline function filter(f:T->Bool):Array<T> {
var ret = [];
for (i in 0...length) {
var elt = __unsafe_get(i);
if (f(elt))
ret.push(elt);
}
return ret;
}
public function copy():Array<T> {
var len = length;
var __a = __a;
var newarr = new NativeArray(len);
cs.system.Array.Copy(__a, 0, newarr, 0, len);
return ofNative(newarr);
}
public inline function iterator():haxe.iterators.ArrayIterator<T> {
return new haxe.iterators.ArrayIterator(this);
}
public inline function keyValueIterator() : ArrayKeyValueIterator<T>
{
return new ArrayKeyValueIterator(this);
}
public function resize(len:Int):Void {
if (length < len) {
if (__a.length < len) {
cs.system.Array.Resize(__a, len);
}
this.length = len;
} else if (length > len) {
spliceVoid(len, length - len);
}
}
private function __get(idx:Int):T {
return if ((cast idx : UInt) >= length) null else __a[idx];
}
private function __set(idx:Int, v:T):T {
var idx:UInt = idx;
var __a = __a;
if (idx >= __a.Length) {
var len = idx + 1;
if (idx == __a.Length)
len = (idx << 1) + 1;
var newArr = new NativeArray<T>(len);
__a.CopyTo(newArr, 0);
this.__a = __a = newArr;
}
if (idx >= length)
this.length = idx + 1;
return __a[idx] = v;
}
private inline function __unsafe_get(idx:Int):T {
return __a[idx];
}
private inline function __unsafe_set(idx:Int, val:T):T {
return __a[idx] = val;
}
}

View File

@ -0,0 +1,162 @@
/*
* 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 cs.system.DateTime;
import cs.system.DateTimeKind;
import cs.system.TimeSpan;
import haxe.Int64;
#if core_api_serialize
@:meta(System.Serializable)
#end
@:coreApi class Date {
@:readOnly private static var epochTicks:Int64 = new DateTime(1970, 1, 1).Ticks;
private var date:DateTime;
private var dateUTC:DateTime;
@:overload public function new(year:Int, month:Int, day:Int, hour:Int, min:Int, sec:Int):Void {
if (day <= 0)
day = 1;
if (year <= 0)
year = 1;
date = new DateTime(year, month + 1, day, hour, min, sec, DateTimeKind.Local);
dateUTC = date.ToUniversalTime();
}
@:overload private function new(native:DateTime) {
if (native.Kind == DateTimeKind.Utc) {
dateUTC = native;
date = dateUTC.ToLocalTime();
} else {
date = native;
dateUTC = date.ToUniversalTime();
}
}
public inline function getTime():Float {
#if (net_ver < 35)
return cast(cs.system.TimeZone.CurrentTimeZone.ToUniversalTime(date).Ticks - epochTicks, Float) / cast(TimeSpan.TicksPerMillisecond, Float);
#else
return cast(cs.system.TimeZoneInfo.ConvertTimeToUtc(date).Ticks - epochTicks, Float) / cast(TimeSpan.TicksPerMillisecond, Float);
#end
}
public inline function getHours():Int {
return date.Hour;
}
public inline function getMinutes():Int {
return date.Minute;
}
public inline function getSeconds():Int {
return date.Second;
}
public inline function getFullYear():Int {
return date.Year;
}
public inline function getMonth():Int {
return date.Month - 1;
}
public inline function getDate():Int {
return date.Day;
}
public inline function getDay():Int {
return cast(date.DayOfWeek, Int);
}
public inline function getUTCHours():Int {
return dateUTC.Hour;
}
public inline function getUTCMinutes():Int {
return dateUTC.Minute;
}
public inline function getUTCSeconds():Int {
return dateUTC.Second;
}
public inline function getUTCFullYear():Int {
return dateUTC.Year;
}
public inline function getUTCMonth():Int {
return dateUTC.Month - 1;
}
public inline function getUTCDate():Int {
return dateUTC.Day;
}
public inline function getUTCDay():Int {
return cast(dateUTC.DayOfWeek, Int);
}
public inline function getTimezoneOffset():Int {
return Std.int((cast(dateUTC.Ticks - date.Ticks, Float) / cast(TimeSpan.TicksPerMillisecond, Float)) / 60000.);
}
public function toString():String {
return date.ToString("yyyy-MM-dd HH\\:mm\\:ss");
}
static public inline function now():Date {
return new Date(DateTime.Now);
}
static public inline function fromTime(t:Float):Date {
#if (net_ver < 35)
return new Date(cs.system.TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(cast(t * cast(TimeSpan.TicksPerMillisecond, Float), Int64) + epochTicks)));
#else
return new Date(cs.system.TimeZoneInfo.ConvertTimeFromUtc(new DateTime(cast(t * cast(TimeSpan.TicksPerMillisecond, Float), Int64) + epochTicks),
cs.system.TimeZoneInfo.Local));
#end
}
static public function fromString(s:String):Date {
switch (s.length) {
case 8: // hh:mm:ss
var k = s.split(":");
return new Date(new DateTime(1970, 1, 1, Std.parseInt(k[0]), Std.parseInt(k[1]), Std.parseInt(k[2]), DateTimeKind.Utc));
case 10: // YYYY-MM-DD
var k = s.split("-");
return new Date(new DateTime(Std.parseInt(k[0]), Std.parseInt(k[1]), Std.parseInt(k[2]), 0, 0, 0, DateTimeKind.Local));
case 19: // YYYY-MM-DD hh:mm:ss
var k = s.split(" ");
var y = k[0].split("-");
var t = k[1].split(":");
return new Date(new DateTime(Std.parseInt(y[0]), Std.parseInt(y[1]), Std.parseInt(y[2]), Std.parseInt(t[0]), Std.parseInt(t[1]), Std.parseInt(t[2]), DateTimeKind.Local));
default:
throw "Invalid date format : " + s;
}
}
private static inline function fromNative(d:cs.system.DateTime):Date {
return new Date(d);
}
}

View File

@ -0,0 +1,135 @@
/*
* 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 cs.system.text.regularexpressions.Regex;
import cs.system.text.regularexpressions.Match;
import cs.system.text.regularexpressions.RegexOptions;
import cs.system.text.regularexpressions.*;
@:coreApi final class EReg {
private var regex:Regex;
private var m:Match;
private var isGlobal:Bool;
private var cur:String;
public function new(r:String, opt:String):Void {
var opts:Int = cast CultureInvariant;
for (i in 0...opt.length)
untyped {
switch (cast(opt[i], Int)) {
case 'i'.code:
opts |= cast(IgnoreCase, Int);
case 'g'.code:
isGlobal = true;
case 'm'.code:
opts |= cast(Multiline, Int);
#if (!unity && !unity_std_target)
case 'c'.code:
opts |= cast(Compiled, Int);
#end
}
}
this.regex = new Regex(r, cast(opts, RegexOptions));
}
public function match(s:String):Bool {
m = regex.Match(s);
cur = s;
return m.Success;
}
public function matched(n:Int):String {
if (m == null || cast(n, UInt) > m.Groups.Count)
throw "EReg::matched";
if (!m.Groups[n].Success)
return null;
return m.Groups[n].Value;
}
public function matchedLeft():String {
return untyped cur.Substring(0, m.Index);
}
public function matchedRight():String {
return untyped cur.Substring(m.Index + m.Length);
}
public function matchedPos():{pos:Int, len:Int} {
return {pos: m.Index, len: m.Length};
}
public function matchSub(s:String, pos:Int, len:Int = -1):Bool {
m = if (len < 0) regex.Match(s, pos) else regex.Match(s, pos, len);
cur = s;
return m.Success;
}
public function split(s:String):Array<String> {
if (isGlobal)
return cs.Lib.array(regex.Split(s));
var m = regex.Match(s);
if (!m.Success)
return [s];
return untyped [s.Substring(0, m.Index), s.Substring(m.Index + m.Length)];
}
inline function start(group:Int):Int {
return m.Groups[group].Index;
}
inline function len(group:Int):Int {
return m.Groups[group].Length;
}
public function replace(s:String, by:String):String {
return (isGlobal) ? regex.Replace(s, by) : regex.Replace(s, by, 1);
}
public function map(s:String, f:EReg->String):String {
var offset = 0;
var buf = new StringBuf();
do {
if (offset >= s.length)
break;
else if (!matchSub(s, offset)) {
buf.add(s.substr(offset));
break;
}
var p = matchedPos();
buf.add(s.substr(offset, p.pos - offset));
buf.add(f(this));
if (p.len == 0) {
buf.add(s.substr(p.pos, 1));
offset = p.pos + 1;
} else
offset = p.pos + p.len;
} while (isGlobal);
if (!isGlobal && offset > 0 && offset < s.length)
buf.add(s.substr(offset));
return buf.toString();
}
public static inline function escape(s:String):String {
return Regex.Escape(s);
}
}

View File

@ -0,0 +1,134 @@
/*
* 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.
*/
@:coreApi @:nativeGen class Math {
@:readOnly
private static var rand = new cs.system.Random();
@:readOnly
public static var PI(default, null) = cs.system.Math.PI;
@:readOnly
public static var NaN(default, null) = cs.system.Double.NaN;
@:readOnly
public static var NEGATIVE_INFINITY(default, null) = cs.system.Double.NegativeInfinity;
@:readOnly
public static var POSITIVE_INFINITY(default, null) = cs.system.Double.PositiveInfinity;
public static inline function abs(v:Float):Float {
return cs.system.Math.Abs(v);
}
public static inline function min(a:Float, b:Float):Float {
return cs.system.Math.Min(a, b);
}
public static inline function max(a:Float, b:Float):Float {
return cs.system.Math.Max(a, b);
}
public static inline function sin(v:Float):Float {
return cs.system.Math.Sin(v);
}
public static inline function cos(v:Float):Float {
return cs.system.Math.Cos(v);
}
public static inline function atan2(y:Float, x:Float):Float {
return cs.system.Math.Atan2(y, x);
}
public static inline function tan(v:Float):Float {
return cs.system.Math.Tan(v);
}
public static inline function exp(v:Float):Float {
return cs.system.Math.Exp(v);
}
public static inline function log(v:Float):Float {
return cs.system.Math.Log(v);
}
public static inline function sqrt(v:Float):Float {
return cs.system.Math.Sqrt(v);
}
public static inline function fround(v:Float):Float {
return cs.system.Math.Floor(v + 0.5);
}
public static inline function ffloor(v:Float):Float {
return cs.system.Math.Floor(v);
}
public static inline function fceil(v:Float):Float {
return cs.system.Math.Ceiling(v);
}
public static function round(v:Float):Int {
var vint = Std.int(v);
var dec = v - vint;
if (dec >= 1 || dec <= -1)
return vint; // overflow
if (dec >= .5)
return vint + 1;
if (dec < -.5)
return vint - 1;
return vint;
}
public static inline function floor(v:Float):Int {
return Std.int(cs.system.Math.Floor(v));
}
public static inline function ceil(v:Float):Int {
return Std.int(cs.system.Math.Ceiling(v));
}
public static inline function atan(v:Float):Float {
return cs.system.Math.Atan(v);
}
public static inline function asin(v:Float):Float {
return cs.system.Math.Asin(v);
}
public static inline function acos(v:Float):Float {
return cs.system.Math.Acos(v);
}
public static inline function pow(v:Float, exp:Float):Float {
return cs.system.Math.Pow(v, exp);
}
public static inline function random():Float {
return rand.NextDouble();
}
public static inline function isFinite(f:Float):Bool {
return !cs.system.Double.IsInfinity(f) && !cs.system.Double.IsNaN(f);
}
public static inline function isNaN(f:Float):Bool {
return cs.system.Double.IsNaN(f);
}
}

View File

@ -0,0 +1,162 @@
/*
* 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 cs.internal.Function;
import cs.system.reflection.*;
import cs.internal.*;
import cs.internal.HxObject;
import cs.internal.Runtime;
import cs.Flags;
import cs.Lib;
import cs.system.Object;
import cs.system.reflection.*;
@:coreApi class Reflect {
public static function hasField(o:Dynamic, field:String):Bool {
var ihx:IHxObject = Lib.as(o, IHxObject);
if (ihx != null)
return untyped ihx.__hx_getField(field, FieldLookup.hash(field), false, true, false) != Runtime.undefined;
return Runtime.slowHasField(o, field);
}
@:keep
public static function field(o:Dynamic, field:String):Dynamic {
var ihx:IHxObject = Lib.as(o, IHxObject);
if (ihx != null)
return untyped ihx.__hx_getField(field, FieldLookup.hash(field), false, false, false);
return Runtime.slowGetField(o, field, false);
}
@:keep
public static function setField(o:Dynamic, field:String, value:Dynamic):Void {
var ihx:IHxObject = Lib.as(o, IHxObject);
if (ihx != null)
untyped ihx.__hx_setField(field, FieldLookup.hash(field), value, false);
else
Runtime.slowSetField(o, field, value);
}
public static function getProperty(o:Dynamic, field:String):Dynamic {
var ihx:IHxObject = Lib.as(o, IHxObject);
if (ihx != null)
return untyped ihx.__hx_getField(field, FieldLookup.hash(field), false, false, true);
if (Runtime.slowHasField(o, "get_" + field))
return Runtime.slowCallField(o, "get_" + field, null);
return Runtime.slowGetField(o, field, false);
}
public static function setProperty(o:Dynamic, field:String, value:Dynamic):Void {
var ihx:IHxObject = Lib.as(o, IHxObject);
if (ihx != null)
untyped ihx.__hx_setField(field, FieldLookup.hash(field), value, true);
else if (Runtime.slowHasField(o, 'set_$field'))
Runtime.slowCallField(o, 'set_$field', cs.NativeArray.make(value));
else
Runtime.slowSetField(o, field, value);
}
public static function callMethod(o:Dynamic, func:haxe.Constraints.Function, args:Array<Dynamic>):Dynamic {
var args = cs.Lib.nativeArray(args, true);
return untyped cast(func, Function).__hx_invokeDynamic(args);
}
@:keep
public static function fields(o:Dynamic):Array<String> {
var ihx = Lib.as(o, IHxObject);
if (ihx != null) {
var ret = [];
untyped ihx.__hx_getFields(ret);
return ret;
} else if (Std.isOfType(o, cs.system.Type)) {
return Type.getClassFields(o);
} else {
return instanceFields(untyped o.GetType());
}
}
private static function instanceFields(c:Class<Dynamic>):Array<String> {
var c = cs.Lib.toNativeType(c);
var ret = [];
var mis = c.GetFields(new cs.Flags(BindingFlags.Public) | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
for (i in 0...mis.Length) {
var i = mis[i];
ret.push(i.Name);
}
return ret;
}
inline public static function isFunction(f:Dynamic):Bool {
return Std.isOfType(f, Function);
}
public static function compare<T>(a:T, b:T):Int {
return cs.internal.Runtime.compare(a, b);
}
@:access(cs.internal.Closure)
public static function compareMethods(f1:Dynamic, f2:Dynamic):Bool {
if (f1 == f2)
return true;
if (Std.isOfType(f1, Closure) && Std.isOfType(f2, Closure)) {
var f1c:Closure = cast f1;
var f2c:Closure = cast f2;
return Runtime.refEq(f1c.obj, f2c.obj) && f1c.field == f2c.field;
}
return false;
}
public static function isObject(v:Dynamic):Bool {
return v != null && !(Std.isOfType(v, HxEnum) || Std.isOfType(v, Function) || Std.isOfType(v, cs.system.ValueType));
}
public static function isEnumValue(v:Dynamic):Bool {
return v != null && (Std.isOfType(v, HxEnum) || Std.isOfType(v, cs.system.Enum));
}
public static function deleteField(o:Dynamic, field:String):Bool {
var ihx = Lib.as(o, DynamicObject);
if (ihx != null)
return untyped ihx.__hx_deleteField(field, FieldLookup.hash(field));
return false;
}
public static function copy<T>(o:Null<T>):Null<T> {
if (o == null)
return null;
var o2:Dynamic = {};
for (f in Reflect.fields(o))
Reflect.setField(o2, f, Reflect.field(o, f));
return cast o2;
}
@:overload(function(f:Array<Dynamic>->Void):Dynamic {})
public static function makeVarArgs(f:Array<Dynamic>->Dynamic):Dynamic {
return new VarArgsFunction(f);
}
}

View File

@ -0,0 +1,192 @@
/*
* 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 cs.Boot;
import cs.Lib;
@:coreApi @:nativeGen class Std {
@:deprecated('Std.is is deprecated. Use Std.isOfType instead.')
public static inline function is(v:Dynamic, t:Dynamic):Bool {
return isOfType(v, t);
}
public static function isOfType(v:Dynamic, t:Dynamic):Bool {
if (v == null)
return false;
if (t == null)
return false;
var clt = cs.Lib.as(t, cs.system.Type);
if (clt == null)
return false;
switch (clt.ToString()) {
case "System.Double":
return untyped __cs__('{0} is double || {0} is int', v);
case "System.Int32":
return cs.internal.Runtime.isInt(v);
case "System.Boolean":
return untyped __cs__('{0} is bool', v);
case "System.Object":
return true;
}
var vt = cs.Lib.getNativeType(v);
if (clt.IsAssignableFrom(vt))
return true;
#if !erase_generics
for (iface in clt.GetInterfaces()) {
var g = cs.internal.Runtime.getGenericAttr(iface);
if (g != null && g.generic == clt) {
return iface.IsAssignableFrom(vt);
}
}
#end
return false;
}
public static function string(s:Dynamic):String {
if (s == null)
return "null";
if (Std.isOfType(s, Bool))
return cast(s, Bool) ? "true" : "false";
return s.ToString();
}
public static function int(x:Float):Int {
return cast x;
}
public static function parseInt(x:String):Null<Int> {
if (x == null)
return null;
var base = 10;
var len = x.length;
var foundCount = 0;
var sign = 0;
var firstDigitIndex = 0;
var lastDigitIndex = -1;
var previous = 0;
for(i in 0...len) {
var c = StringTools.fastCodeAt(x, i);
switch c {
case _ if((c > 8 && c < 14) || c == 32):
if(foundCount > 0) {
return null;
}
continue;
case '-'.code if(foundCount == 0):
sign = -1;
case '+'.code if(foundCount == 0):
sign = 1;
case '0'.code if(foundCount == 0 || (foundCount == 1 && sign != 0)):
case 'x'.code | 'X'.code if(previous == '0'.code && ((foundCount == 1 && sign == 0) || (foundCount == 2 && sign != 0))):
base = 16;
case _ if('0'.code <= c && c <= '9'.code):
case _ if(base == 16 && (('a'.code <= c && c <= 'z'.code) || ('A'.code <= c && c <= 'Z'.code))):
case _:
break;
}
if((foundCount == 0 && sign == 0) || (foundCount == 1 && sign != 0)) {
firstDigitIndex = i;
}
foundCount++;
lastDigitIndex = i;
previous = c;
}
if(firstDigitIndex <= lastDigitIndex) {
var digits = x.substring(firstDigitIndex, lastDigitIndex + 1);
return try {
(sign == -1 ? -1 : 1) * cs.system.Convert.ToInt32(digits, base);
} catch(e:cs.system.FormatException) {
null;
}
}
return null;
}
public static function parseFloat(x:String):Float {
if (x == null)
return Math.NaN;
x = StringTools.ltrim(x);
var found = false,
hasDot = false,
hasSign = false,
hasE = false,
hasESign = false,
hasEData = false;
var i = -1;
inline function getch(i:Int):Int
return cast((untyped x : cs.system.String)[i]);
while (++i < x.length) {
var chr = getch(i);
if (chr >= '0'.code && chr <= '9'.code) {
if (hasE) {
hasEData = true;
}
found = true;
} else
switch (chr) {
case 'e'.code | 'E'.code if (!hasE):
hasE = true;
case '.'.code if (!hasDot):
hasDot = true;
case '-'.code, '+'.code if (!found && !hasSign):
hasSign = true;
case '-'.code | '+'.code if (found && !hasESign && hasE && !hasEData):
hasESign = true;
case _:
break;
}
}
if (hasE && !hasEData) {
i--;
if (hasESign)
i--;
}
if (i != x.length) {
x = x.substr(0, i);
}
return try cs.system.Double.Parse(x, cs.system.globalization.CultureInfo.InvariantCulture) catch (e:Dynamic) Math.NaN;
}
extern inline public static function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
return cs.Lib.as(value, c);
}
@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
extern inline public static function instance<T:{}, S:T>(value:T, c:Class<S>):S {
return downcast(value, c);
}
public static function random(x:Int):Int {
if (x <= 0)
return 0;
return untyped Math.rand.Next(x);
}
}

View File

@ -0,0 +1,67 @@
/*
* 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 cs.StdTypes;
@:coreApi extern class String implements ArrayAccess<Char16> {
@:overload private static function Compare(s1:String, s2:String):Int;
@:overload private static function Compare(s1:String, s2:String, kind:cs.system.StringComparison):Int;
private static function CompareOrdinal(s1:String, s2:String):Int;
var length(default, null):Int;
function new(string:String):Void;
function toUpperCase():String;
function toLowerCase():String;
function charAt(index:Int):String;
function charCodeAt(index:Int):Null<Int>;
function indexOf(str:String, ?startIndex:Int):Int;
function lastIndexOf(str:String, ?startIndex:Int):Int;
function split(delimiter:String):Array<String>;
function substr(pos:Int, ?len:Int):String;
function substring(startIndex:Int, ?endIndex:Int):String;
function toString():String;
static function fromCharCode(code:Int):String;
private function IndexOf(value:String, startIndex:Int, comparisonType:cs.system.StringComparison):Int;
private function Replace(oldValue:String, newValue:String):String;
private function StartsWith(value:String):Bool;
private function EndsWith(value:String):Bool;
private function TrimStart():String;
private function TrimEnd():String;
private function Trim():String;
private function CompareTo(obj:Dynamic):Int;
@:overload(function(startIndex:Int):String {})
private function Substring(startIndex:Int, length:Int):String;
}

View File

@ -0,0 +1,60 @@
/*
* 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 cs.system.text.StringBuilder;
@:coreApi
class StringBuf {
private var b:StringBuilder;
public var length(get, never):Int;
public inline function new():Void {
b = new StringBuilder();
}
inline function get_length():Int {
return b.Length;
}
public inline function add<T>(x:T):Void {
b.Append(Std.string(x));
}
public inline function addSub(s:String, pos:Int, ?len:Int):Void {
b.Append(s, pos, (len == null) ? (s.length - pos) : len);
}
public function addChar(c:Int):Void
untyped {
if (c >= 0x10000) {
b.Append(cast((c >> 10) + 0xD7C0, cs.StdTypes.Char16));
b.Append(cast((c & 0x3FF) + 0xDC00, cs.StdTypes.Char16));
} else {
b.Append(cast(c, cs.StdTypes.Char16));
}
}
public inline function toString():String {
return b.ToString();
}
}

View File

@ -0,0 +1,180 @@
/*
* 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 sys.io.Process;
import cs.system.Environment;
import cs.system.threading.Thread;
@:coreApi
class Sys {
private static var _env:haxe.ds.StringMap<String>;
private static var _args:Array<String>;
public static inline function print(v:Dynamic):Void {
cs.system.Console.Write(v);
}
public static inline function println(v:Dynamic):Void {
cs.system.Console.WriteLine(v);
}
public static function args():Array<String> {
if (_args == null) {
var ret = cs.Lib.array(Environment.GetCommandLineArgs());
ret.shift();
_args = ret;
}
return _args.copy();
}
public static inline function getEnv(s:String):String {
return Environment.GetEnvironmentVariable(s);
}
public static function putEnv(s:String, v:String):Void {
Environment.SetEnvironmentVariable(s, v);
if (_env != null)
_env.set(s, v);
}
public static function environment():Map<String, String> {
if (_env == null) {
var e = _env = new haxe.ds.StringMap();
var nenv = Environment.GetEnvironmentVariables().GetEnumerator();
while (nenv.MoveNext()) {
e.set(nenv.Key, nenv.Value);
}
}
return _env;
}
public static inline function sleep(seconds:Float):Void {
Thread.Sleep(Std.int(seconds * 1000));
}
public static function setTimeLocale(loc:String):Bool {
// TODO C#
return false;
}
public static inline function getCwd():String {
return cs.system.io.Directory.GetCurrentDirectory();
}
public static inline function setCwd(s:String):Void {
cs.system.io.Directory.SetCurrentDirectory(s);
}
public static function systemName():String {
// doing a switch with strings since MacOS might not be available
switch (Environment.OSVersion.Platform + "") {
case "Unix":
return "Linux";
case "Xbox":
return "Xbox";
case "MacOSX":
return "Mac";
default:
var ver = cast(Environment.OSVersion.Platform, Int);
if (ver == 4 || ver == 6 || ver == 128)
return "Linux";
return "Windows";
}
}
public static function command(cmd:String, ?args:Array<String>):Int {
var proc = Process.createNativeProcess(cmd, args);
proc.add_OutputDataReceived(new cs.system.diagnostics.DataReceivedEventHandler(function(p, evtArgs) {
var data = evtArgs.Data;
if (data != null && data != "")
println(data);
}));
var stderr = stderr();
proc.add_ErrorDataReceived(new cs.system.diagnostics.DataReceivedEventHandler(function(p, evtArgs) {
var data = evtArgs.Data;
if (data != null && data != "")
stderr.writeString(data + "\n");
}));
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
var exitCode = proc.ExitCode;
proc.Dispose();
return exitCode;
}
public static inline function exit(code:Int):Void {
Environment.Exit(code);
}
@:readOnly static var epochTicks = new cs.system.DateTime(1970, 1, 1).Ticks;
public static function time():Float {
return cast((cs.system.DateTime.UtcNow.Ticks - epochTicks), Float) / cast(cs.system.TimeSpan.TicksPerSecond, Float);
}
public static inline function cpuTime():Float {
return Environment.TickCount / 1000;
}
@:deprecated("Use programPath instead") public static inline function executablePath():String {
return cs.system.reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
}
public static function programPath():String {
return cs.system.reflection.Assembly.GetExecutingAssembly().Location;
}
public static function getChar(echo:Bool):Int {
#if !(Xbox || CF || MF) // Xbox, Compact Framework, Micro Framework
return cast(cs.system.Console.ReadKey(!echo).KeyChar, Int);
#else
return -1;
#end
}
public static inline function stdin():haxe.io.Input {
#if !(Xbox || CF || MF)
return new cs.io.NativeInput(cs.system.Console.OpenStandardInput());
#else
return null;
#end
}
public static inline function stdout():haxe.io.Output {
#if !(Xbox || CF || MF)
return new cs.io.NativeOutput(cs.system.Console.OpenStandardOutput());
#else
return null;
#end
}
public static inline function stderr():haxe.io.Output {
#if !(Xbox || CF || MF)
return new cs.io.NativeOutput(cs.system.Console.OpenStandardError());
#else
return null;
#end
}
}

View File

@ -0,0 +1,344 @@
/*
* 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 cs.Lib;
import cs.internal.HxObject;
import cs.internal.Runtime;
import cs.internal.Function;
import cs.Flags;
import cs.system.Object;
import cs.system.reflection.*;
using StringTools;
enum ValueType {
TNull;
TInt;
TFloat;
TBool;
TObject;
TFunction;
TClass(c:Class<Dynamic>);
TEnum(e:Enum<Dynamic>);
TUnknown;
}
@:coreApi class Type {
public static function getClass<T>(o:T):Class<T> {
if (Object.ReferenceEquals(o, null) || Std.isOfType(o, DynamicObject) || Std.isOfType(o, cs.system.Type))
return null;
return cast cs.Lib.getNativeType(o);
}
public static function getEnum(o:EnumValue):Enum<Dynamic> {
if (Std.isOfType(o, HxEnum))
return cast cs.Lib.getNativeType(o).BaseType; // enum constructors are subclasses of an enum type
else if (Std.isOfType(o, cs.system.Enum))
return cast cs.Lib.getNativeType(o);
return null;
}
public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic> {
var base = Lib.toNativeType(c).BaseType;
if (Object.ReferenceEquals(base, null) || base.ToString() == "haxe.lang.HxObject" || base.ToString() == "System.Object")
return null;
return Lib.fromNativeType(base);
}
public static function getClassName(c:Class<Dynamic>):String {
var ret = Lib.toNativeType(c).ToString();
#if no_root
if (ret.length > 10 && StringTools.startsWith(ret, "haxe.root."))
ret = ret.substr(10);
#end
return switch (ret) {
// TODO: are those really needed?
case "System.Int32": "Int";
case "System.Double": "Float";
case "System.String": "String";
case "System.Boolean": "Bool";
case "System.Object": "Dynamic";
case "System.Type": "Class";
default: cast(ret, cs.system.String).Split(cs.NativeArray.make(("`".code : cs.StdTypes.Char16)))[0];
}
}
public static function getEnumName(e:Enum<Dynamic>):String {
var ret = Lib.toNativeType(cast e).ToString();
#if no_root
if (ret.length > 10 && StringTools.startsWith(ret, "haxe.root."))
ret = ret.substr(10);
#end
return ret;
}
public static function resolveClass(name:String):Class<Dynamic> {
#if no_root
if (name.indexOf(".") == -1)
name = "haxe.root." + name;
#end
var t = cs.system.Type._GetType(name);
#if !CF
if (Object.ReferenceEquals(t, null)) {
var all = cs.system.AppDomain.CurrentDomain.GetAssemblies().GetEnumerator();
while (all.MoveNext()) {
var t2:cs.system.reflection.Assembly = all.Current;
t = t2.GetType(name);
if (!Object.ReferenceEquals(t, null))
break;
}
}
#end
if (Object.ReferenceEquals(t, null)) {
switch (name) {
case #if no_root "haxe.root.Int" #else "Int" #end:
return cast Int;
case #if no_root "haxe.root.Float" #else "Float" #end:
return cast Float;
case #if no_root "haxe.root.Class" #else "Class" #end:
return cast Class;
case #if no_root "haxe.root.Dynamic" #else "Dynamic" #end:
return cast Dynamic;
case #if no_root "haxe.root.String" #else "String" #end:
return cast String;
case #if no_root "haxe.root.Bool" #else "Bool" #end:
return cast Bool;
default:
return null;
}
#if !erase_generics
}
else if (t.IsInterface && cast(IGenericObject, cs.system.Type).IsAssignableFrom(t)) {
for (attr in t.GetCustomAttributes(true)) {
var g = cs.Lib.as(attr, cs.internal.HxObject.GenericInterface);
if (g != null)
return Lib.fromNativeType(g.generic);
}
return Lib.fromNativeType(t);
#end
} else {
return Lib.fromNativeType(t);
}
}
public static function resolveEnum(name:String):Enum<Dynamic> {
var t = Lib.toNativeType(resolveClass(name));
if (!Object.ReferenceEquals(t, null)
&& untyped t.BaseType.Equals(Lib.toNativeType(cs.system.Enum)) || Lib.toNativeType(HxEnum).IsAssignableFrom(t))
return cast t;
return null;
}
public static function createInstance<T>(cl:Class<T>, args:Array<Dynamic>):T {
if (Object.ReferenceEquals(cl, String))
return args[0];
var t = Lib.toNativeType(cl);
if (t.IsInterface) {
// may be generic
t = Lib.toNativeType(resolveClass(getClassName(cl)));
}
var ctors = t.GetConstructors();
return Runtime.callMethod(null, cast ctors, ctors.Length, cs.Lib.nativeArray(args, true));
}
// cache empty constructor arguments so we don't allocate it on each createEmptyInstance call
@:protected @:readOnly static var __createEmptyInstance_EMPTY_ARGS = cs.NativeArray.make((cs.internal.Runtime.EmptyObject.EMPTY : Any));
public static function createEmptyInstance<T>(cl:Class<T>):T {
var t = Lib.toNativeType(cl);
if (cs.system.Object.ReferenceEquals(t, String))
#if erase_generics
return untyped "";
#else
return untyped __cs__("(T)(object){0}", "");
#end
var res = try cs.system.Activator.CreateInstance(t,
__createEmptyInstance_EMPTY_ARGS) catch (_:cs.system.MissingMemberException) cs.system.Activator.CreateInstance(t);
#if erase_generics
return res;
#else
return untyped __cs__("(T){0}", res);
#end
}
public static function createEnum<T>(e:Enum<T>, constr:String, ?params:Array<Dynamic>):T {
if (params == null || params.length == 0) {
var ret = cs.internal.Runtime.slowGetField(e, constr, true);
if (Reflect.isFunction(ret))
throw 'Constructor $constr needs parameters';
return ret;
} else {
return cs.internal.Runtime.slowCallField(e, constr, cs.Lib.nativeArray(params, true));
}
}
public static function createEnumIndex<T>(e:Enum<T>, index:Int, ?params:Array<Dynamic>):T {
var constr = getEnumConstructs(e);
return createEnum(e, constr[index], params);
}
public static function getInstanceFields(c:Class<Dynamic>):Array<String> {
if (c == String)
return cs.internal.StringExt.StringRefl.fields;
var c = cs.Lib.toNativeType(c);
var ret = [];
var mis = c.GetMembers(new cs.Flags(BindingFlags.Public) | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
for (i in 0...mis.Length) {
var i = mis[i];
if (Std.isOfType(i, PropertyInfo))
continue;
var n = i.Name;
if (!n.startsWith('__hx_') && n.fastCodeAt(0) != '.'.code) {
switch (n) {
case 'Equals' | 'ToString' | 'GetHashCode' | 'GetType':
case _:
ret.push(n);
}
}
}
return ret;
}
public static function getClassFields(c:Class<Dynamic>):Array<String> {
if (Object.ReferenceEquals(c, String)) {
return ['fromCharCode'];
}
var ret = [];
var infos = Lib.toNativeType(c).GetMembers(new Flags(BindingFlags.Public) | BindingFlags.Static);
for (i in 0...infos.Length) {
var name = infos[i].Name;
if (!name.startsWith('__hx_')) {
ret.push(name);
}
}
return ret;
}
public static function getEnumConstructs(e:Enum<Dynamic>):Array<String> {
var t = cs.Lib.as(e, cs.system.Type);
var f = t.GetField("__hx_constructs", new cs.Flags(BindingFlags.Static) | BindingFlags.NonPublic);
if (f != null) {
var values:cs.system.Array = f.GetValue(null);
var copy = new cs.NativeArray(values.Length);
cs.system.Array.Copy(values, copy, values.Length);
return cs.Lib.array(copy);
} else
return cs.Lib.array(cs.system.Enum.GetNames(t));
}
public static function typeof(v:Dynamic):ValueType {
if (v == null)
return ValueType.TNull;
var t = cs.Lib.as(v, cs.system.Type);
if (!Object.ReferenceEquals(t, null)) {
// class type
return ValueType.TObject;
}
t = v.GetType();
if (t.IsEnum)
return ValueType.TEnum(cast t);
if (Std.isOfType(v, HxEnum))
return ValueType.TEnum(cast t.BaseType); // enum constructors are subclasses of an enum type
if (t.IsValueType) {
var vc = Std.downcast(v, cs.system.IConvertible);
if (vc != null) {
switch (vc.GetTypeCode()) {
case cs.system.TypeCode.Boolean:
return ValueType.TBool;
case cs.system.TypeCode.Double:
var d:Float = vc.ToDouble(null);
if (d >= cs.system.Int32.MinValue && d <= cs.system.Int32.MaxValue && d == vc.ToInt32(null))
return ValueType.TInt;
else
return ValueType.TFloat;
case cs.system.TypeCode.Int32:
return ValueType.TInt;
default:
return ValueType.TClass(cast t);
}
} else {
return ValueType.TClass(cast t);
}
}
if (Std.isOfType(v, IHxObject)) {
if (Std.isOfType(v, DynamicObject))
return ValueType.TObject;
return ValueType.TClass(cast t);
} else if (Std.isOfType(v, Function)) {
return ValueType.TFunction;
} else {
return ValueType.TClass(cast t);
}
}
@:ifFeature("has_enum")
public static function enumEq<T>(a:T, b:T):Bool {
if (a == null)
return b == null;
else if (b == null)
return false;
else
return untyped a.Equals(b);
}
public static function enumConstructor(e:EnumValue):String {
return Std.isOfType(e, cs.system.Enum) ? cast(e, cs.system.Enum).ToString() : cast(e, HxEnum).getTag();
}
public static function enumParameters(e:EnumValue):Array<Dynamic> {
return Std.isOfType(e, cs.system.Enum) ? [] : cast(e, HxEnum).getParams();
}
@:ifFeature("has_enum")
@:pure
public static function enumIndex(e:EnumValue):Int {
if (Std.isOfType(e, cs.system.Enum)) {
var values = cs.system.Enum.GetValues(Lib.getNativeType(e));
return cs.system.Array.IndexOf(values, e);
} else {
return @:privateAccess cast(e, HxEnum)._hx_index;
}
}
public static function allEnums<T>(e:Enum<T>):Array<T> {
var ctors = getEnumConstructs(e);
var ret = [];
for (ctor in ctors) {
var v = Reflect.field(e, ctor);
if (Std.isOfType(v, e))
ret.push(v);
}
return ret;
}
}

View File

@ -0,0 +1,118 @@
package haxe;
import cs.system.Exception as CsException;
import cs.system.diagnostics.StackTrace;
@:coreApi
class Exception extends NativeException {
public var message(get,never):String;
public var stack(get,never):CallStack;
public var previous(get,never):Null<Exception>;
public var native(get,never):Any;
@:noCompletion var __exceptionStack:Null<CallStack>;
@:noCompletion var __nativeStack:StackTrace;
@:noCompletion var __ownStack:Bool;
@:noCompletion @:ifFeature("haxe.Exception.get_stack") var __skipStack:Int = 0;
@:noCompletion var __nativeException:CsException;
@:noCompletion var __previousException:Null<Exception>;
static public function caught(value:Any):Exception {
if(Std.isOfType(value, Exception)) {
return value;
} else if(Std.isOfType(value, CsException)) {
return new Exception((value:CsException).Message, null, value);
} else {
return new ValueException(value, null, value);
}
}
static public function thrown(value:Any):Any {
if(Std.isOfType(value, Exception)) {
return (value:Exception).native;
} else if(Std.isOfType(value, CsException)) {
return value;
} else {
var e = new ValueException(value);
e.__shiftStack();
return e;
}
}
public function new(message:String, ?previous:Exception, ?native:Any) {
super(message, previous);
this.__previousException = previous;
if(native != null && Std.isOfType(native, CsException)) {
__nativeException = native;
if(__nativeException.StackTrace == null) {
__nativeStack = new StackTrace(1, true);
__ownStack = true;
} else {
__nativeStack = new StackTrace(__nativeException, true);
__ownStack = false;
}
} else {
__nativeException = cast this;
__nativeStack = new StackTrace(1, true);
__ownStack = true;
}
}
public function unwrap():Any {
return __nativeException;
}
public function toString():String {
return message;
}
public function details():String {
return inline CallStack.exceptionToString(this);
}
@:noCompletion
@:ifFeature("haxe.Exception.get_stack")
inline function __shiftStack():Void {
if(__ownStack) __skipStack++;
}
function get_message():String {
return this.Message;
}
function get_previous():Null<Exception> {
return __previousException;
}
final function get_native():Any {
return __nativeException;
}
function get_stack():CallStack {
return switch __exceptionStack {
case null:
__exceptionStack = NativeStackTrace.toHaxe(__nativeStack, __skipStack);
case s: s;
}
}
}
@:dox(hide)
@:nativeGen
@:noCompletion
@:native('System.Exception')
private extern class NativeException {
@:noCompletion private function new(message:String, innerException:NativeException):Void;
@:noCompletion @:skipReflection private final Data:cs.system.collections.IDictionary;
@:noCompletion @:skipReflection private var HelpLink:String;
@:noCompletion @:skipReflection private final InnerException:cs.system.Exception;
@:noCompletion @:skipReflection private final Message:String;
@:noCompletion @:skipReflection private var Source:String;
@:noCompletion @:skipReflection private final StackTrace:String;
@:noCompletion @:skipReflection private final TargetSite:cs.system.reflection.MethodBase;
@:overload @:noCompletion @:skipReflection private function GetBaseException():cs.system.Exception;
@:overload @:noCompletion @:skipReflection private function GetObjectData(info:cs.system.runtime.serialization.SerializationInfo, context:cs.system.runtime.serialization.StreamingContext):Void;
@:overload @:noCompletion @:skipReflection private function GetType():cs.system.Type;
@:overload @:noCompletion @:skipReflection private function ToString():cs.system.String;
}

View File

@ -0,0 +1,242 @@
/*
* 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 haxe;
using haxe.Int64;
import haxe.Int64Helper;
private typedef __Int64 = cs.StdTypes.Int64;
@:coreApi
@:transitive
abstract Int64(__Int64) from __Int64 to __Int64 {
public static inline function make(high:Int32, low:Int32):Int64
return new Int64((cast(high, __Int64) << 32) | (cast(low, __Int64) & (untyped __cs__('0xffffffffL') : Int64)));
private inline function new(x:__Int64)
this = x;
private var val(get, set):__Int64;
inline function get_val():__Int64
return this;
inline function set_val(x:__Int64):__Int64
return this = x;
public var high(get, never):Int32;
inline function get_high():Int32
return cast(this >> 32);
public var low(get, never):Int32;
inline function get_low():Int32
return cast this;
public inline function copy():Int64
return new Int64(this);
@:from public static inline function ofInt(x:Int):Int64
return cast x;
public static inline function toInt(x:Int64):Int {
if (x.val < 0x80000000 || x.val > 0x7FFFFFFF)
throw "Overflow";
return cast x.val;
}
@:deprecated('haxe.Int64.is() is deprecated. Use haxe.Int64.isInt64() instead')
inline public static function is(val:Dynamic):Bool
return Std.isOfType(val, cs.system.Int64);
inline public static function isInt64(val:Dynamic):Bool
return Std.isOfType(val, cs.system.Int64);
public static inline function getHigh(x:Int64):Int32
return cast(x.val >> 32);
public static inline function getLow(x:Int64):Int32
return cast(x.val);
public static inline function isNeg(x:Int64):Bool
return x.val < 0;
public static inline function isZero(x:Int64):Bool
return x.val == 0;
public static inline function compare(a:Int64, b:Int64):Int {
if (a.val < b.val)
return -1;
if (a.val > b.val)
return 1;
return 0;
}
public static inline function ucompare(a:Int64, b:Int64):Int {
if (a.val < 0)
return (b.val < 0) ? compare(a, b) : 1;
return (b.val < 0) ? -1 : compare(a, b);
}
public static inline function toStr(x:Int64):String
return '${x.val}';
public static inline function divMod(dividend:Int64, divisor:Int64):{quotient:Int64, modulus:Int64}
return {quotient: dividend / divisor, modulus: dividend % divisor};
private inline function toString():String
return '$this';
public static function parseString(sParam:String):Int64 {
return Int64Helper.parseString(sParam);
}
public static function fromFloat(f:Float):Int64 {
return Int64Helper.fromFloat(f);
}
@:op(-A) public static function neg(x:Int64):Int64
return -x.val;
@:op(++A) private inline function preIncrement():Int64
return ++this;
@:op(A++) private inline function postIncrement():Int64
return this++;
@:op(--A) private inline function preDecrement():Int64
return --this;
@:op(A--) private inline function postDecrement():Int64
return this--;
@:op(A + B) public static inline function add(a:Int64, b:Int64):Int64
return a.val + b.val;
@:op(A + B) @:commutative private static inline function addInt(a:Int64, b:Int):Int64
return a.val + b;
@:op(A - B) public static inline function sub(a:Int64, b:Int64):Int64
return a.val - b.val;
@:op(A - B) private static inline function subInt(a:Int64, b:Int):Int64
return a.val - b;
@:op(A - B) private static inline function intSub(a:Int, b:Int64):Int64
return a - b.val;
@:op(A * B) public static inline function mul(a:Int64, b:Int64):Int64
return a.val * b.val;
@:op(A * B) @:commutative private static inline function mulInt(a:Int64, b:Int):Int64
return a.val * b;
@:op(A / B) public static inline function div(a:Int64, b:Int64):Int64
return a.val / b.val;
@:op(A / B) private static inline function divInt(a:Int64, b:Int):Int64
return a.val / b;
@:op(A / B) private static inline function intDiv(a:Int, b:Int64):Int64
return a / b.val;
@:op(A % B) public static inline function mod(a:Int64, b:Int64):Int64
return a.val % b.val;
@:op(A % B) private static inline function modInt(a:Int64, b:Int):Int64
return a.val % b;
@:op(A % B) private static inline function intMod(a:Int, b:Int64):Int64
return a % b.val;
@:op(A == B) public static inline function eq(a:Int64, b:Int64):Bool
return a.val == b.val;
@:op(A == B) @:commutative private static inline function eqInt(a:Int64, b:Int):Bool
return a.val == b;
@:op(A != B) public static inline function neq(a:Int64, b:Int64):Bool
return a.val != b.val;
@:op(A != B) @:commutative private static inline function neqInt(a:Int64, b:Int):Bool
return a.val != b;
@:op(A < B) private static inline function lt(a:Int64, b:Int64):Bool
return a.val < b.val;
@:op(A < B) private static inline function ltInt(a:Int64, b:Int):Bool
return a.val < b;
@:op(A < B) private static inline function intLt(a:Int, b:Int64):Bool
return a < b.val;
@:op(A <= B) private static inline function lte(a:Int64, b:Int64):Bool
return a.val <= b.val;
@:op(A <= B) private static inline function lteInt(a:Int64, b:Int):Bool
return a.val <= b;
@:op(A <= B) private static inline function intLte(a:Int, b:Int64):Bool
return a <= b.val;
@:op(A > B) private static inline function gt(a:Int64, b:Int64):Bool
return a.val > b.val;
@:op(A > B) private static inline function gtInt(a:Int64, b:Int):Bool
return a.val > b;
@:op(A > B) private static inline function intGt(a:Int, b:Int64):Bool
return a > b.val;
@:op(A >= B) private static inline function gte(a:Int64, b:Int64):Bool
return a.val >= b.val;
@:op(A >= B) private static inline function gteInt(a:Int64, b:Int):Bool
return a.val >= b;
@:op(A >= B) private static inline function intGte(a:Int, b:Int64):Bool
return a >= b.val;
@:op(~A) private static inline function complement(x:Int64):Int64
return ~x.val;
@:op(A & B) public static inline function and(a:Int64, b:Int64):Int64
return a.val & b.val;
@:op(A | B) public static inline function or(a:Int64, b:Int64):Int64
return a.val | b.val;
@:op(A ^ B) public static inline function xor(a:Int64, b:Int64):Int64
return a.val ^ b.val;
@:op(A << B) public static inline function shl(a:Int64, b:Int):Int64
return a.val << b;
@:op(A >> B) public static inline function shr(a:Int64, b:Int):Int64
return a.val >> b;
@:op(A >>> B) public static inline function ushr(a:Int64, b:Int):Int64
return cast((a.val : cs.StdTypes.UInt64) >> b);
}

View File

@ -0,0 +1,60 @@
package haxe;
import haxe.CallStack.StackItem;
import cs.system.diagnostics.StackTrace;
/**
Do not use manually.
**/
@:dox(hide)
@:noCompletion
class NativeStackTrace {
@:meta(System.ThreadStaticAttribute)
static var exception:Null<cs.system.Exception>;
@:ifFeature('haxe.NativeStackTrace.exceptionStack')
static public inline function saveStack(e:Any):Void {
exception = e;
}
static public inline function callStack():StackTrace {
return new StackTrace(1, true);
}
static public function exceptionStack():Null<StackTrace> {
return switch exception {
case null: null;
case e: new StackTrace(e, true);
}
}
static public function toHaxe(native:Null<StackTrace>, skip:Int = 0):Array<StackItem> {
var stack = [];
if(native == null) {
return stack;
}
var cnt = 0;
for (i in 0...native.FrameCount) {
var frame = native.GetFrame(i);
var m = frame.GetMethod();
if (m == null) {
continue;
}
if(skip > cnt++) {
continue;
}
var method = StackItem.Method(m.ReflectedType.ToString(), m.Name);
var fileName = frame.GetFileName();
var lineNumber = frame.GetFileLineNumber();
if (fileName != null || lineNumber >= 0)
stack.push(FilePos(method, fileName, lineNumber));
else
stack.push(method);
}
return stack;
}
}

View File

@ -0,0 +1,70 @@
/*
* 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 haxe;
@:coreApi class Resource {
@:keep static var content:Array<String>;
static var paths:Map<String, String>;
@:keep static function getPaths():Map<String, String> {
if (paths != null)
return paths;
var p = new Map();
var all = cs.Lib.toNativeType(haxe.Resource).Assembly.GetManifestResourceNames();
for (i in 0...all.Length) {
var path = all[i];
var name = path.substr(path.indexOf("Resources.") + 10);
p.set(name, path);
}
return paths = p;
}
public static inline function listNames():Array<String> {
return content.copy();
}
@:access(haxe.io.Path.escape)
public static function getString(name:String):String {
name = haxe.io.Path.escape(name, true);
var path = getPaths().get(name);
if (path == null)
return null;
var str = cs.Lib.toNativeType(haxe.Resource).Assembly.GetManifestResourceStream(path);
if (str != null)
return new cs.io.NativeInput(str).readAll().toString();
return null;
}
@:access(haxe.io.Path.escape)
public static function getBytes(name:String):haxe.io.Bytes {
name = haxe.io.Path.escape(name, true);
var path = getPaths().get(name);
if (path == null)
return null;
var str = cs.Lib.toNativeType(haxe.Resource).Assembly.GetManifestResourceStream(path);
if (str != null)
return new cs.io.NativeInput(str).readAll();
return null;
}
}

View File

@ -0,0 +1,54 @@
package haxe;
import haxe.iterators.RestIterator;
import haxe.iterators.RestKeyValueIterator;
import cs.NativeArray;
import cs.system.Array as CsArray;
private typedef NativeRest<T> = #if erase_generics NativeArray<Dynamic> #else NativeArray<T> #end;
@:coreApi
abstract Rest<T>(NativeRest<T>) {
public var length(get,never):Int;
inline function get_length():Int
return this.Length;
@:from static public inline function of<T>(array:Array<T>):Rest<T>
return new Rest(@:privateAccess array.__a);
inline function new(a:NativeRest<T>):Void
this = a;
@:arrayAccess inline function get(index:Int):T
return (this[index] : T); // typecheck, otherwise it will be inlined as Dynamic with `-D erase-generics`
@:to public function toArray():Array<T> {
var result = new NativeRest(this.Length);
CsArray.Copy(this, 0, result, 0, this.Length);
return @:privateAccess Array.ofNative(result);
}
public inline function iterator():RestIterator<T>
return new RestIterator<T>(this);
public inline function keyValueIterator():RestKeyValueIterator<T>
return new RestKeyValueIterator<T>(this);
public function append(item:T):Rest<T> {
var result = new NativeRest(this.Length + 1);
CsArray.Copy(this, 0, result, 0, this.Length);
result[this.Length] = item;
return new Rest(result);
}
public function prepend(item:T):Rest<T> {
var result = new NativeRest(this.Length + 1);
CsArray.Copy(this, 0, result, 1, this.Length);
result[0] = item;
return new Rest(result);
}
public function toString():String {
return toArray().toString();
}
}

View File

@ -0,0 +1,528 @@
/*
* 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 haxe.ds;
import cs.NativeArray;
/*
* This IntMap implementation is based on khash (https://github.com/attractivechaos/klib/blob/master/khash.h)
* Copyright goes to Attractive Chaos <attractor@live.co.uk> and his contributors
*
* Thanks also to Jonas Malaco Filho for his Haxe-written IntMap code inspired by Python tables.
* (https://jonasmalaco.com/fossil/test/jonas-haxe/artifact/887b53126e237d6c68951111d594033403889304)
*/
@:coreApi class IntMap<T> implements haxe.Constraints.IMap<Int, T> {
private static inline var HASH_UPPER = 0.7;
private var flags:NativeArray<Int>;
private var _keys:NativeArray<Int>;
private var vals:NativeArray<T>;
private var nBuckets:Int;
private var size:Int;
private var nOccupied:Int;
private var upperBound:Int;
#if !no_map_cache
private var cachedKey:Int;
private var cachedIndex:Int;
#end
public function new():Void {
#if !no_map_cache
cachedIndex = -1;
#end
}
public function set(key:Int, value:T):Void {
var targetIndex:Int;
if (nOccupied >= upperBound) {
if (nBuckets > (size << 1)) {
resize(nBuckets - 1); // clear "deleted" elements
} else {
resize(nBuckets + 1);
}
}
var flags = flags, _keys = _keys;
{
var mask = nBuckets - 1,
hashedKey = hash(key),
curIndex = hashedKey & mask;
var delKey = -1, curFlag = 0;
// to speed things up, don't loop if the first bucket is already free
if (isEmpty(getFlag(flags, curIndex))) {
targetIndex = curIndex;
} else {
var inc = getInc(hashedKey, mask), last = curIndex;
while (!(_keys[curIndex] == key || isEmpty(curFlag = getFlag(flags, curIndex)))) {
if (delKey == -1 && isDel(curFlag)) {
delKey = curIndex;
}
curIndex = (curIndex + inc) & mask;
#if debug
assert(curIndex != last);
#end
}
if (delKey != -1 && isEmpty(getFlag(flags, curIndex))) {
targetIndex = delKey;
} else {
targetIndex = curIndex;
}
}
}
var flag = getFlag(flags, targetIndex);
if (isEmpty(flag)) {
_keys[targetIndex] = key;
vals[targetIndex] = value;
setIsBothFalse(flags, targetIndex);
size++;
nOccupied++;
} else if (isDel(flag)) {
_keys[targetIndex] = key;
vals[targetIndex] = value;
setIsBothFalse(flags, targetIndex);
size++;
} else {
#if debug
assert(_keys[targetIndex] == key);
#end
vals[targetIndex] = value;
}
}
final private function lookup(key:Int):Int {
if (nBuckets != 0) {
var flags = flags, _keys = _keys;
var mask = nBuckets - 1,
k = hash(key),
index = k & mask,
curFlag = -1,
inc = getInc(k, mask), /* inc == 1 for linear probing */
last = index;
do {
if (_keys[index] == key) {
if (isEmpty(curFlag = getFlag(flags, index))) {
index = (index + inc) & mask;
continue;
} else if (isDel(curFlag)) {
return -1;
} else {
return index;
}
} else {
index = (index + inc) & mask;
}
} while (index != last);
}
return -1;
}
public function get(key:Int):Null<T> {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return vals[idx];
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return vals[idx];
}
return null;
}
private function getDefault(key:Int, def:T):T {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return vals[idx];
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return vals[idx];
}
return def;
}
public function exists(key:Int):Bool {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return true;
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return true;
}
return false;
}
public function remove(key:Int):Bool {
var idx = -1;
#if !no_map_cache
if (!(cachedKey == key && ((idx = cachedIndex) != -1)))
#end
{
idx = lookup(key);
}
if (idx == -1) {
return false;
} else {
#if !no_map_cache
if (cachedKey == key) {
cachedIndex = -1;
}
#end
if (!isEither(getFlag(flags, idx))) {
setIsDelTrue(flags, idx);
--size;
vals[idx] = null;
// we do NOT reset the keys here, as unlike StringMap, we check for keys equality
// and stop if we find a key that is equal to the one we're looking for
// setting this to 0 will allow the hash to contain duplicate `0` keys
// (see #6457)
// _keys[idx] = 0;
}
return true;
}
}
final private function resize(newNBuckets:Int):Void {
// This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets.
var newFlags = null;
var j = 1;
{
newNBuckets = roundUp(newNBuckets);
if (newNBuckets < 4)
newNBuckets = 4;
if (size >= (newNBuckets * HASH_UPPER + 0.5))
/* requested size is too small */ {
j = 0;
} else { /* hash table size to be changed (shrink or expand); rehash */
var nfSize = flagsSize(newNBuckets);
newFlags = new NativeArray(nfSize);
for (i in 0...nfSize) {
newFlags[i] = 0xaaaaaaaa; // isEmpty = true; isDel = false
}
if (nBuckets < newNBuckets) // expand
{
var k = new NativeArray(newNBuckets);
if (_keys != null) {
arrayCopy(_keys, 0, k, 0, nBuckets);
}
_keys = k;
var v = new NativeArray(newNBuckets);
if (vals != null) {
arrayCopy(vals, 0, v, 0, nBuckets);
}
vals = v;
} // otherwise shrink
}
}
if (j != 0) { // rehashing is required
#if !no_map_cache
// resetting cache
cachedKey = 0;
cachedIndex = -1;
#end
j = -1;
var nBuckets = nBuckets, _keys = _keys, vals = vals, flags = flags;
var newMask = newNBuckets - 1;
while (++j < nBuckets) {
if (!isEither(getFlag(flags, j))) {
var key = _keys[j];
var val = vals[j];
// do not set keys as 0 - see comment about #6457
// _keys[j] = 0;
vals[j] = cast null;
setIsDelTrue(flags, j);
while (true)
/* kick-out process; sort of like in Cuckoo hashing */ {
var k = hash(key);
var inc = getInc(k, newMask);
var i = k & newMask;
while (!isEmpty(getFlag(newFlags, i))) {
i = (i + inc) & newMask;
}
setIsEmptyFalse(newFlags, i);
if (i < nBuckets && !isEither(getFlag(flags, i)))
/* kick out the existing element */ {
{
var tmp = _keys[i];
_keys[i] = key;
key = tmp;
} {
var tmp = vals[i];
vals[i] = val;
val = tmp;
}
setIsDelTrue(flags, i); /* mark it as deleted in the old hash table */
} else { /* write the element and jump out of the loop */
_keys[i] = key;
vals[i] = val;
break;
}
}
}
}
if (nBuckets > newNBuckets)
/* shrink the hash table */ {
{
var k = new NativeArray(newNBuckets);
arrayCopy(_keys, 0, k, 0, newNBuckets);
this._keys = k;
} {
var v = new NativeArray(newNBuckets);
arrayCopy(vals, 0, v, 0, newNBuckets);
this.vals = v;
}
}
this.flags = newFlags;
this.nBuckets = newNBuckets;
this.nOccupied = size;
this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5);
}
}
public inline function keys():Iterator<Int> {
return new IntMapKeyIterator(this);
}
public inline function iterator():Iterator<T> {
return new IntMapValueIterator(this);
}
@:runtime public inline function keyValueIterator():KeyValueIterator<Int, T> {
return new haxe.iterators.MapKeyValueIterator(this);
}
public function copy():IntMap<T> {
var copied = new IntMap<T>();
for (key in keys())
copied.set(key, get(key));
return copied;
}
public function toString():String {
var s = new StringBuf();
s.add("{");
var it = keys();
for (i in it) {
s.add(i);
s.add(" => ");
s.add(Std.string(get(i)));
if (it.hasNext())
s.add(", ");
}
s.add("}");
return s.toString();
}
public function clear():Void {
flags = null;
_keys = null;
vals = null;
nBuckets = 0;
size = 0;
nOccupied = 0;
upperBound = 0;
#if !no_map_cache
cachedKey = 0;
cachedIndex = -1;
#end
}
private static inline function assert(x:Bool):Void {
#if debug
if (!x)
throw "assert failed";
#end
}
private static inline function defaultK():Int
return 0;
private static inline function arrayCopy(sourceArray:cs.system.Array, sourceIndex:Int, destinationArray:cs.system.Array, destinationIndex:Int,
length:Int):Void {
cs.system.Array.Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length);
}
private static inline function getInc(k:Int, mask:Int):Int {
return (((k) >> 3 ^ (k) << 3) | 1) & (mask);
}
private static inline function hash(i:Int):Int {
return i;
}
// flags represents a bit array with 2 significant bits for each index
// one bit for deleted (1), one for empty (2)
// so what this function does is:
// * gets the integer with (flags / 16)
// * shifts those bits to the right ((flags % 16) * 2) places
// * masks it with 0b11
private static inline function getFlag(flags:NativeArray<Int>, i:Int):Int {
return ((flags[i >> 4] >>> ((i & 0xf) << 1)) & 3);
}
private static inline function isDel(flag:Int):Bool {
return (flag & 1) != 0;
}
private static inline function isEmpty(flag:Int):Bool {
return (flag & 2) != 0;
}
private static inline function isEither(flag:Int):Bool {
return flag != 0;
}
private static inline function setIsDelFalse(flags:NativeArray<Int>, i:Int):Void {
flags[i >> 4] &= ~(1 << ((i & 0xf) << 1));
}
private static inline function setIsEmptyFalse(flags:NativeArray<Int>, i:Int):Void {
flags[i >> 4] &= ~(2 << ((i & 0xf) << 1));
}
private static inline function setIsBothFalse(flags:NativeArray<Int>, i:Int):Void {
flags[i >> 4] &= ~(3 << ((i & 0xf) << 1));
}
private static inline function setIsDelTrue(flags:NativeArray<Int>, i:Int):Void {
flags[i >> 4] |= 1 << ((i & 0xf) << 1);
}
private static inline function roundUp(x:Int):Int {
--x;
x |= (x) >>> 1;
x |= (x) >>> 2;
x |= (x) >>> 4;
x |= (x) >>> 8;
x |= (x) >>> 16;
return ++x;
}
private static inline function flagsSize(m:Int):Int {
return ((m) < 16 ? 1 : (m) >> 4);
}
}
@:access(haxe.ds.IntMap)
private final class IntMapKeyIterator<T> {
var m:IntMap<T>;
var i:Int;
var len:Int;
public function new(m:IntMap<T>) {
this.i = 0;
this.m = m;
this.len = m.nBuckets;
}
public function hasNext():Bool {
for (j in i...len) {
if (!IntMap.isEither(IntMap.getFlag(m.flags, j))) {
i = j;
return true;
}
}
return false;
}
public function next():Int {
var ret = m._keys[i];
#if !no_map_cache
m.cachedIndex = i;
m.cachedKey = ret;
#end
i++;
return ret;
}
}
@:access(haxe.ds.IntMap)
private final class IntMapValueIterator<T> {
var m:IntMap<T>;
var i:Int;
var len:Int;
public function new(m:IntMap<T>) {
this.i = 0;
this.m = m;
this.len = m.nBuckets;
}
public function hasNext():Bool {
for (j in i...len) {
if (!IntMap.isEither(IntMap.getFlag(m.flags, j))) {
i = j;
return true;
}
}
return false;
}
public inline function next():T {
return m.vals[i++];
}
}

View File

@ -0,0 +1,539 @@
/*
* 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 haxe.ds;
import cs.NativeArray;
@:coreApi class ObjectMap<K:{}, V> implements haxe.Constraints.IMap<K, V> {
extern private static inline var HASH_UPPER = 0.77;
extern private static inline var FLAG_EMPTY = 0;
extern private static inline var FLAG_DEL = 1;
/**
* This is the most important structure here and the reason why it's so fast.
* It's an array of all the hashes contained in the table. These hashes cannot be 0 nor 1,
* which stand for "empty" and "deleted" states.
*
* The lookup algorithm will keep looking until a 0 or the key wanted is found;
* The insertion algorithm will do the same but will also break when FLAG_DEL is found;
*/
private var hashes:NativeArray<HashType>;
private var _keys:NativeArray<K>;
private var vals:NativeArray<V>;
private var nBuckets:Int;
private var size:Int;
private var nOccupied:Int;
private var upperBound:Int;
#if !no_map_cache
private var cachedKey:K;
private var cachedIndex:Int;
#end
#if DEBUG_HASHTBL
private var totalProbes:Int;
private var probeTimes:Int;
private var sameHash:Int;
private var maxProbe:Int;
#end
public function new():Void {
#if !no_map_cache
cachedIndex = -1;
#end
}
public function set(key:K, value:V):Void {
var x:Int, k:Int;
if (nOccupied >= upperBound) {
if (nBuckets > (size << 1))
resize(nBuckets - 1); // clear "deleted" elements
else
resize(nBuckets + 2);
}
var hashes = hashes, keys = _keys, hashes = hashes;
{
var mask = (nBuckets == 0) ? 0 : nBuckets - 1;
var site = x = nBuckets;
k = hash(key);
var i = k & mask, nProbes = 0;
var delKey = -1;
// for speed up
if (isEmpty(hashes[i])) {
x = i;
} else {
// var inc = getInc(k, mask);
var last = i, flag;
while (!(isEmpty(flag = hashes[i]) || (flag == k && _keys[i] == key))) {
if (isDel(flag) && delKey == -1)
delKey = i;
i = (i + ++nProbes) & mask;
#if DEBUG_HASHTBL
probeTimes++;
if (i == last)
throw "assert";
#end
}
if (isEmpty(flag) && delKey != -1)
x = delKey;
else
x = i;
}
#if DEBUG_HASHTBL
if (nProbes > maxProbe)
maxProbe = nProbes;
totalProbes++;
#end
}
var flag = hashes[x];
if (isEmpty(flag)) {
keys[x] = key;
vals[x] = value;
hashes[x] = k;
size++;
nOccupied++;
} else if (isDel(flag)) {
keys[x] = key;
vals[x] = value;
hashes[x] = k;
size++;
} else {
assert(_keys[x] == key);
vals[x] = value;
}
#if !no_map_cache
cachedIndex = x;
cachedKey = key;
#end
}
private final function lookup(key:K):Int {
if (nBuckets != 0) {
var hashes = hashes, keys = _keys;
var mask = nBuckets - 1, hash = hash(key), k = hash, nProbes = 0;
var i = k & mask;
var last = i, flag;
// var inc = getInc(k, mask);
while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != k || keys[i] != key)) {
i = (i + ++nProbes) & mask;
#if DEBUG_HASHTBL
probeTimes++;
if (i == last)
throw "assert";
#end
}
#if DEBUG_HASHTBL
if (nProbes > maxProbe)
maxProbe = nProbes;
totalProbes++;
#end
return isEither(flag) ? -1 : i;
}
return -1;
}
final function resize(newNBuckets:Int):Void {
// This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets.
var newHash = null;
var j = 1;
{
newNBuckets = roundUp(newNBuckets);
if (newNBuckets < 4)
newNBuckets = 4;
if (size >= (newNBuckets * HASH_UPPER + 0.5))
/* requested size is too small */ {
j = 0;
} else { /* hash table size to be changed (shrink or expand); rehash */
var nfSize = newNBuckets;
newHash = new NativeArray(nfSize);
if (nBuckets < newNBuckets) // expand
{
var k = new NativeArray(newNBuckets);
if (_keys != null)
arrayCopy(_keys, 0, k, 0, nBuckets);
_keys = k;
var v = new NativeArray(newNBuckets);
if (vals != null)
arrayCopy(vals, 0, v, 0, nBuckets);
vals = v;
} // otherwise shrink
}
}
if (j != 0) { // rehashing is required
#if !no_map_cache
// resetting cache
cachedKey = null;
cachedIndex = -1;
#end
j = -1;
var nBuckets = nBuckets,
_keys = _keys,
vals = vals,
hashes = hashes;
var newMask = newNBuckets - 1;
while (++j < nBuckets) {
var k;
if (!isEither(k = hashes[j])) {
var key = _keys[j];
var val = vals[j];
_keys[j] = null;
vals[j] = cast null;
hashes[j] = FLAG_DEL;
while (true)
/* kick-out process; sort of like in Cuckoo hashing */ {
var nProbes = 0;
// var inc = getInc(k, newMask);
var i = k & newMask;
while (!isEmpty(newHash[i]))
i = (i + ++nProbes) & newMask;
newHash[i] = k;
if (i < nBuckets && !isEither(k = hashes[i]))
/* kick out the existing element */ {
{
var tmp = _keys[i];
_keys[i] = key;
key = tmp;
} {
var tmp = vals[i];
vals[i] = val;
val = tmp;
}
hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */
} else { /* write the element and jump out of the loop */
_keys[i] = key;
vals[i] = val;
break;
}
}
}
}
if (nBuckets > newNBuckets)
/* shrink the hash table */ {
{
var k = new NativeArray(newNBuckets);
arrayCopy(_keys, 0, k, 0, newNBuckets);
this._keys = k;
} {
var v = new NativeArray(newNBuckets);
arrayCopy(vals, 0, v, 0, newNBuckets);
this.vals = v;
}
}
this.hashes = newHash;
this.nBuckets = newNBuckets;
this.nOccupied = size;
this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5);
}
}
public function get(key:K):Null<V> {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return vals[idx];
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return vals[idx];
}
return null;
}
private function getDefault(key:K, def:V):V {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return vals[idx];
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return vals[idx];
}
return def;
}
public function exists(key:K):Bool {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return true;
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return true;
}
return false;
}
public function remove(key:K):Bool {
var idx = -1;
#if !no_map_cache
if (!(cachedKey == key && ((idx = cachedIndex) != -1)))
#end
{
idx = lookup(key);
}
if (idx == -1) {
return false;
} else {
#if !no_map_cache
if (cachedKey == key)
cachedIndex = -1;
#end
hashes[idx] = FLAG_DEL;
_keys[idx] = null;
vals[idx] = null;
--size;
return true;
}
}
public function keys():Iterator<K> {
return new ObjectMapKeyIterator(this);
}
public function iterator():Iterator<V> {
return new ObjectMapValueIterator(this);
}
@:runtime public inline function keyValueIterator():KeyValueIterator<K, V> {
return new haxe.iterators.MapKeyValueIterator(this);
}
public function copy():ObjectMap<K, V> {
var copied = new ObjectMap<K, V>();
for (key in keys())
copied.set(key, get(key));
return copied;
}
public function toString():String {
var s = new StringBuf();
s.add("{");
var it = keys();
for (i in it) {
s.add(Std.string(i));
s.add(" => ");
s.add(Std.string(get(i)));
if (it.hasNext())
s.add(", ");
}
s.add("}");
return s.toString();
}
public function clear():Void {
hashes = null;
_keys = null;
vals = null;
nBuckets = 0;
size = 0;
nOccupied = 0;
upperBound = 0;
#if !no_map_cache
cachedKey = null;
cachedIndex = -1;
#end
#if DEBUG_HASHTBL
totalProbes = 0;
probeTimes = 0;
sameHash = 0;
maxProbe = 0;
#end
}
extern private static inline function roundUp(x:Int):Int {
--x;
x |= (x) >>> 1;
x |= (x) >>> 2;
x |= (x) >>> 4;
x |= (x) >>> 8;
x |= (x) >>> 16;
return ++x;
}
extern private static inline function getInc(k:Int, mask:Int):Int // return 1 for linear probing
return (((k) >> 3 ^ (k) << 3) | 1) & (mask);
extern private static inline function isEither(v:HashType):Bool
return (v & 0xFFFFFFFE) == 0;
extern private static inline function isEmpty(v:HashType):Bool
return v == FLAG_EMPTY;
extern private static inline function isDel(v:HashType):Bool
return v == FLAG_DEL;
// guarantee: Whatever this function is, it will never return 0 nor 1
extern private static inline function hash<K>(s:K):HashType {
var k:Int = untyped s.GetHashCode();
// k *= 357913941;
// k ^= k << 24;
// k += ~357913941;
// k ^= k >> 31;
// k ^= k << 31;
k = (k + 0x7ed55d16) + (k << 12);
k = (k ^ 0xc761c23c) ^ (k >> 19);
k = (k + 0x165667b1) + (k << 5);
k = (k + 0xd3a2646c) ^ (k << 9);
k = (k + 0xfd7046c5) + (k << 3);
k = (k ^ 0xb55a4f09) ^ (k >> 16);
var ret = k;
if (isEither(ret)) {
if (ret == 0)
ret = 2;
else
ret = 0xFFFFFFFF;
}
return ret;
}
extern private static inline function arrayCopy(sourceArray:cs.system.Array, sourceIndex:Int, destinationArray:cs.system.Array, destinationIndex:Int,
length:Int):Void
cs.system.Array.Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length);
extern private static inline function assert(x:Bool):Void {
#if DEBUG_HASHTBL
if (!x)
throw "assert failed";
#end
}
}
@:access(haxe.ds.ObjectMap)
private final class ObjectMapKeyIterator<T:{}, V> {
var m:ObjectMap<T, V>;
var i:Int;
var len:Int;
public function new(m:ObjectMap<T, V>) {
this.i = 0;
this.m = m;
this.len = m.nBuckets;
}
public function hasNext():Bool {
for (j in i...len) {
if (!ObjectMap.isEither(m.hashes[j])) {
i = j;
return true;
}
}
return false;
}
public function next():T {
var ret = m._keys[i];
#if !no_map_cache
m.cachedIndex = i;
m.cachedKey = ret;
#end
i = i + 1;
return ret;
}
}
@:access(haxe.ds.ObjectMap)
private final class ObjectMapValueIterator<K:{}, T> {
var m:ObjectMap<K, T>;
var i:Int;
var len:Int;
public function new(m:ObjectMap<K, T>) {
this.i = 0;
this.m = m;
this.len = m.nBuckets;
}
public function hasNext():Bool {
for (j in i...len) {
if (!ObjectMap.isEither(m.hashes[j])) {
i = j;
return true;
}
}
return false;
}
public inline function next():T {
var ret = m.vals[i];
i = i + 1;
return ret;
}
}
private typedef HashType = Int;

View File

@ -0,0 +1,531 @@
/*
* 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 haxe.ds;
import cs.NativeArray;
@:coreApi class StringMap<T> implements haxe.Constraints.IMap<String, T> {
extern private static inline var HASH_UPPER = 0.77;
extern private static inline var FLAG_EMPTY = 0;
extern private static inline var FLAG_DEL = 1;
/**
* This is the most important structure here and the reason why it's so fast.
* It's an array of all the hashes contained in the table. These hashes cannot be 0 nor 1,
* which stand for "empty" and "deleted" states.
*
* The lookup algorithm will keep looking until a 0 or the key wanted is found;
* The insertion algorithm will do the same but will also break when FLAG_DEL is found;
*/
private var hashes:NativeArray<HashType>;
private var _keys:NativeArray<String>;
private var vals:NativeArray<T>;
private var nBuckets:Int;
private var size:Int;
private var nOccupied:Int;
private var upperBound:Int;
#if !no_map_cache
private var cachedKey:String;
private var cachedIndex:Int;
#end
#if DEBUG_HASHTBL
private var totalProbes:Int;
private var probeTimes:Int;
private var sameHash:Int;
private var maxProbe:Int;
#end
public function new():Void {
#if !no_map_cache
cachedIndex = -1;
#end
}
public function set(key:String, value:T):Void {
var x:Int, k:Int;
if (nOccupied >= upperBound) {
if (nBuckets > (size << 1)) {
resize(nBuckets - 1); // clear "deleted" elements
} else {
resize(nBuckets + 2);
}
}
var hashes = hashes, keys = _keys, hashes = hashes;
{
var mask = (nBuckets == 0) ? 0 : nBuckets - 1;
var site = x = nBuckets;
k = hash(key);
var i = k & mask, nProbes = 0;
var delKey = -1;
// to speed things up, don't loop if the first bucket is already free
if (isEmpty(hashes[i])) {
x = i;
} else {
var last = i, flag;
while (!(isEmpty(flag = hashes[i]) || (flag == k && _keys[i] == key))) {
if (isDel(flag) && delKey == -1) {
delKey = i;
}
i = (i + ++nProbes) & mask;
#if DEBUG_HASHTBL
probeTimes++;
if (i == last)
throw "assert";
#end
}
if (isEmpty(flag) && delKey != -1) {
x = delKey;
} else {
x = i;
}
}
#if DEBUG_HASHTBL
if (nProbes > maxProbe)
maxProbe = nProbes;
totalProbes++;
#end
}
var flag = hashes[x];
if (isEmpty(flag)) {
keys[x] = key;
vals[x] = value;
hashes[x] = k;
size++;
nOccupied++;
} else if (isDel(flag)) {
keys[x] = key;
vals[x] = value;
hashes[x] = k;
size++;
} else {
assert(_keys[x] == key);
vals[x] = value;
}
#if !no_map_cache
cachedIndex = x;
cachedKey = key;
#end
}
private final function lookup(key:String):Int {
if (nBuckets != 0) {
var hashes = hashes, keys = _keys;
var mask = nBuckets - 1, hash = hash(key), k = hash, nProbes = 0;
var i = k & mask;
var last = i, flag;
// if we hit an empty bucket, it means we're done
while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != k || keys[i] != key)) {
i = (i + ++nProbes) & mask;
#if DEBUG_HASHTBL
probeTimes++;
if (i == last)
throw "assert";
#end
}
#if DEBUG_HASHTBL
if (nProbes > maxProbe)
maxProbe = nProbes;
totalProbes++;
#end
return isEither(flag) ? -1 : i;
}
return -1;
}
final function resize(newNBuckets:Int):Void {
// This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets.
var newHash = null;
var j = 1;
{
newNBuckets = roundUp(newNBuckets);
if (newNBuckets < 4)
newNBuckets = 4;
if (size >= (newNBuckets * HASH_UPPER + 0.5))
/* requested size is too small */ {
j = 0;
} else { /* hash table size to be changed (shrink or expand); rehash */
var nfSize = newNBuckets;
newHash = new NativeArray(nfSize);
if (nBuckets < newNBuckets) // expand
{
var k = new NativeArray(newNBuckets);
if (_keys != null)
arrayCopy(_keys, 0, k, 0, nBuckets);
_keys = k;
var v = new NativeArray(newNBuckets);
if (vals != null)
arrayCopy(vals, 0, v, 0, nBuckets);
vals = v;
} // otherwise shrink
}
}
if (j != 0) { // rehashing is required
// resetting cache
#if !no_map_cache
cachedKey = null;
cachedIndex = -1;
#end
j = -1;
var nBuckets = nBuckets,
_keys = _keys,
vals = vals,
hashes = hashes;
var newMask = newNBuckets - 1;
while (++j < nBuckets) {
var k;
if (!isEither(k = hashes[j])) {
var key = _keys[j];
var val = vals[j];
_keys[j] = null;
vals[j] = cast null;
hashes[j] = FLAG_DEL;
while (true)
/* kick-out process; sort of like in Cuckoo hashing */ {
var nProbes = 0;
var i = k & newMask;
while (!isEmpty(newHash[i])) {
i = (i + ++nProbes) & newMask;
}
newHash[i] = k;
if (i < nBuckets && !isEither(k = hashes[i]))
/* kick out the existing element */ {
{ // inlined swap
var tmp = _keys[i];
_keys[i] = key;
key = tmp;
} { // inlined swap
var tmp = vals[i];
vals[i] = val;
val = tmp;
}
hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */
} else { /* write the element and jump out of the loop */
_keys[i] = key;
vals[i] = val;
break;
}
}
}
}
if (nBuckets > newNBuckets)
/* shrink the hash table */ {
{ // inlined swap
var k = new NativeArray(newNBuckets);
arrayCopy(_keys, 0, k, 0, newNBuckets);
this._keys = k;
} { // inlined swap
var v = new NativeArray(newNBuckets);
arrayCopy(vals, 0, v, 0, newNBuckets);
this.vals = v;
}
}
this.hashes = newHash;
this.nBuckets = newNBuckets;
this.nOccupied = size;
this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5);
}
}
public function get(key:String):Null<T> {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return vals[idx];
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return vals[idx];
}
return null;
}
private function getDefault(key:String, def:T):T {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return vals[idx];
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return vals[idx];
}
return def;
}
public function exists(key:String):Bool {
var idx = -1;
#if !no_map_cache
if (cachedKey == key && ((idx = cachedIndex) != -1)) {
return true;
}
#end
idx = lookup(key);
if (idx != -1) {
#if !no_map_cache
cachedKey = key;
cachedIndex = idx;
#end
return true;
}
return false;
}
public function remove(key:String):Bool {
var idx = -1;
#if !no_map_cache
if (!(cachedKey == key && ((idx = cachedIndex) != -1)))
#end
{
idx = lookup(key);
}
if (idx == -1) {
return false;
} else {
#if !no_map_cache
if (cachedKey == key) {
cachedIndex = -1;
}
#end
hashes[idx] = FLAG_DEL;
_keys[idx] = null;
vals[idx] = null;
--size;
return true;
}
}
public inline function keys():Iterator<String> {
return new StringMapKeyIterator(this);
}
public inline function iterator():Iterator<T> {
return new StringMapValueIterator(this);
}
@:runtime public inline function keyValueIterator():KeyValueIterator<String, T> {
return new haxe.iterators.MapKeyValueIterator(this);
}
public function copy():StringMap<T> {
var copied = new StringMap<T>();
for (key in keys())
copied.set(key, get(key));
return copied;
}
public function toString():String {
var s = new StringBuf();
s.add("{");
var it = keys();
for (i in it) {
s.add(i);
s.add(" => ");
s.add(Std.string(get(i)));
if (it.hasNext())
s.add(", ");
}
s.add("}");
return s.toString();
}
public function clear():Void {
hashes = null;
_keys = null;
vals = null;
nBuckets = 0;
size = 0;
nOccupied = 0;
upperBound = 0;
#if !no_map_cache
cachedKey = null;
cachedIndex = -1;
#end
#if DEBUG_HASHTBL
totalProbes = 0;
probeTimes = 0;
sameHash = 0;
maxProbe = 0;
#end
}
extern private static inline function roundUp(x:Int):Int {
--x;
x |= (x) >>> 1;
x |= (x) >>> 2;
x |= (x) >>> 4;
x |= (x) >>> 8;
x |= (x) >>> 16;
return ++x;
}
extern private static inline function isEither(v:HashType):Bool
return (v & 0xFFFFFFFE) == 0;
extern private static inline function isEmpty(v:HashType):Bool
return v == FLAG_EMPTY;
extern private static inline function isDel(v:HashType):Bool
return v == FLAG_DEL;
// guarantee: Whatever this function is, it will never return 0 nor 1
extern private static inline function hash(s:String):HashType {
var k:Int = untyped s.GetHashCode();
// k *= 357913941;
// k ^= k << 24;
// k += ~357913941;
// k ^= k >> 31;
// k ^= k << 31;
k = (k + 0x7ed55d16) + (k << 12);
k = (k ^ 0xc761c23c) ^ (k >> 19);
k = (k + 0x165667b1) + (k << 5);
k = (k + 0xd3a2646c) ^ (k << 9);
k = (k + 0xfd7046c5) + (k << 3);
k = (k ^ 0xb55a4f09) ^ (k >> 16);
var ret = k;
if (isEither(ret)) {
if (ret == 0)
ret = 2;
else
ret = 0xFFFFFFFF;
}
return ret;
}
extern private static inline function arrayCopy(sourceArray:cs.system.Array, sourceIndex:Int, destinationArray:cs.system.Array, destinationIndex:Int,
length:Int):Void
cs.system.Array.Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length);
extern private static inline function assert(x:Bool):Void {
#if DEBUG_HASHTBL
if (!x)
throw "assert failed";
#end
}
}
private typedef HashType = Int;
@:access(haxe.ds.StringMap)
private final class StringMapKeyIterator<T> {
var m:StringMap<T>;
var i:Int;
var len:Int;
public function new(m:StringMap<T>) {
this.m = m;
this.i = 0;
this.len = m.nBuckets;
}
public function hasNext():Bool {
for (j in i...len) {
if (!StringMap.isEither(m.hashes[j])) {
i = j;
return true;
}
}
return false;
}
public function next():String {
var ret = m._keys[i];
#if !no_map_cache
m.cachedIndex = i;
m.cachedKey = ret;
#end
i++;
return ret;
}
}
@:access(haxe.ds.StringMap)
private final class StringMapValueIterator<T> {
var m:StringMap<T>;
var i:Int;
var len:Int;
public function new(m:StringMap<T>) {
this.m = m;
this.i = 0;
this.len = m.nBuckets;
}
public function hasNext():Bool {
for (j in i...len) {
if (!StringMap.isEither(m.hashes[j])) {
i = j;
return true;
}
}
return false;
}
public inline function next():T {
return m.vals[i++];
}
}

View File

@ -0,0 +1,125 @@
/*
* 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 sys;
import cs.system.io.DirectoryInfo;
import cs.system.io.File;
import cs.system.io.Directory;
import cs.system.io.FileInfo;
@:coreApi
class FileSystem {
public static function exists(path:String):Bool {
return (File.Exists(path) || Directory.Exists(path));
}
public static function rename(path:String, newPath:String):Void {
Directory.Move(path, newPath);
}
@:access(Date.fromNative)
public static function stat(path:String):FileStat {
if (File.Exists(path)) {
var fi = new FileInfo(path);
return {
gid: 0, // C# doesn't let you get this info
uid: 0, // same
atime: Date.fromNative(fi.LastAccessTime),
mtime: Date.fromNative(fi.LastWriteTime),
ctime: Date.fromNative(fi.CreationTime),
size: cast(fi.Length, Int), // TODO: maybe change to Int64 for Haxe 3?
dev: 0, // FIXME: not sure what that is
ino: 0, // FIXME: not sure what that is
nlink: 0, // FIXME: not sure what that is
rdev: 0, // FIXME: not sure what that is
mode: 0 // FIXME: not sure what that is
};
} else if (Directory.Exists(path)) {
var fi = new DirectoryInfo(path);
return {
gid: 0, // C# doesn't let you get this info
uid: 0, // same
atime: Date.fromNative(fi.LastAccessTime),
mtime: Date.fromNative(fi.LastWriteTime),
ctime: Date.fromNative(fi.CreationTime),
size: 0, // TODO: maybe change to Int64 for Haxe 3?
dev: 0, // FIXME: not sure what that is
ino: 0, // FIXME: not sure what that is
nlink: 0, // FIXME: not sure what that is
rdev: 0, // FIXME: not sure what that is
mode: 0 // FIXME: not sure what that is
};
} else {
throw "Path '" + path + "' doesn't exist";
}
}
public static function fullPath(relPath:String):String {
return new FileInfo(relPath).FullName;
}
public static function absolutePath(relPath:String):String {
if (haxe.io.Path.isAbsolute(relPath))
return relPath;
return haxe.io.Path.join([Sys.getCwd(), relPath]);
}
public static function isDirectory(path:String):Bool {
var isdir = Directory.Exists(path);
if (isdir != File.Exists(path))
return isdir;
throw "Path '" + path + "' doesn't exist";
}
public static function createDirectory(path:String):Void {
Directory.CreateDirectory(path);
}
public static function deleteFile(path:String):Void {
if (!File.Exists(path))
throw "Path '" + path + "' doesn't exist";
File.Delete(path);
}
public static function deleteDirectory(path:String):Void {
if (!Directory.Exists(path))
throw "Path '" + path + "' doesn't exist";
Directory.Delete(path);
}
public static function readDirectory(path:String):Array<String> {
var ret = Directory.GetFileSystemEntries(path);
if (ret.Length > 0) {
var fst = ret[0];
var sep = "/";
if (fst.lastIndexOf(sep) < fst.lastIndexOf("\\"))
sep = "\\";
for (i in 0...ret.Length) {
var path = ret[i];
ret[i] = path.substr(path.lastIndexOf(sep) + 1);
}
}
return cs.Lib.array(ret);
}
}

View File

@ -0,0 +1,59 @@
/*
* 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 sys.db;
class Sqlite {
static var type:Class<cs.system.data.IDbConnection>;
public static function open(file:String):sys.db.Connection {
var cnxString = 'Data Source=$file';
if (type == null) {
var t = null;
var assemblies = cs.system.AppDomain.CurrentDomain.GetAssemblies();
for (i in 0...assemblies.Length) {
var a = assemblies[i];
t = a.GetType('Mono.Data.Sqlite.SqliteConnection');
if (t == null)
t = a.GetType('System.Data.SQLite.SQLiteConnection');
if (t != null) {
break;
}
}
if (t == null) {
var asm = cs.system.reflection.Assembly.Load('Mono.Data.Sqlite');
t = asm.GetType('Mono.Data.Sqlite.SqliteConnection');
}
if (t != null)
type = cast cs.Lib.fromNativeType(t);
}
if (type == null) {
throw "No ADO.NET SQLite provider was found!";
}
var ret = Type.createInstance(type, [cnxString]);
ret.Open();
return cs.db.AdoNet.create(ret, 'SQLite');
}
}

View File

@ -0,0 +1,95 @@
/*
* 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 sys.io;
@:coreApi
class File {
public static function getContent(path:String):String {
var f = read(path, false);
var ret = f.readAll().toString();
f.close();
return ret;
}
public static function saveContent(path:String, content:String):Void {
var f = write(path, false);
f.writeString(content);
f.close();
}
public static function getBytes(path:String):haxe.io.Bytes {
var f = read(path, true);
var ret = f.readAll();
f.close();
return ret;
}
public static function saveBytes(path:String, bytes:haxe.io.Bytes):Void {
var f = write(path, true);
f.writeBytes(bytes, 0, bytes.length);
f.close();
}
public static function read(path:String, binary:Bool = true):FileInput {
#if std_buffer // standardize 4kb buffers
var stream = new cs.system.io.FileStream(path, Open, Read, ReadWrite, 4096);
#else
var stream = new cs.system.io.FileStream(path, Open, Read, ReadWrite);
#end
return @:privateAccess new FileInput(stream);
}
public static function write(path:String, binary:Bool = true):FileOutput {
#if std_buffer // standardize 4kb buffers
var stream = new cs.system.io.FileStream(path, Create, Write, ReadWrite, 4096);
#else
var stream = new cs.system.io.FileStream(path, Create, Write, ReadWrite);
#end
return @:privateAccess new FileOutput(stream);
}
public static function append(path:String, binary:Bool = true):FileOutput {
#if std_buffer // standardize 4kb buffers
var stream = new cs.system.io.FileStream(path, Append, Write, ReadWrite, 4096);
#else
var stream = new cs.system.io.FileStream(path, Append, Write, ReadWrite);
#end
return @:privateAccess new FileOutput(stream);
}
public static function update(path:String, binary:Bool = true):FileOutput {
if (!FileSystem.exists(path)) {
write(path).close();
}
#if std_buffer // standardize 4kb buffers
var stream = new cs.system.io.FileStream(path, OpenOrCreate, Write, ReadWrite, 4096);
#else
var stream = new cs.system.io.FileStream(path, OpenOrCreate, Write, ReadWrite);
#end
return @:privateAccess new FileOutput(stream);
}
public static function copy(srcPath:String, dstPath:String):Void {
cs.system.io.File.Copy(srcPath, dstPath, true);
}
}

View File

@ -0,0 +1,29 @@
/*
* 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 sys.io;
class FileInput extends cs.io.NativeInput {
function new(stream:cs.system.io.FileStream) {
super(stream);
}
}

View File

@ -0,0 +1,29 @@
/*
* 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 sys.io;
class FileOutput extends cs.io.NativeOutput {
function new(stream:cs.system.io.FileStream) {
super(stream);
}
}

View File

@ -0,0 +1,127 @@
/*
* 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 sys.io;
import haxe.io.BytesInput;
import cs.system.io.StreamReader;
import cs.system.io.StreamWriter;
import cs.system.diagnostics.Process as NativeProcess;
import cs.system.diagnostics.ProcessStartInfo as NativeStartInfo;
@:coreApi
class Process {
public var stdout(default, null):haxe.io.Input;
public var stderr(default, null):haxe.io.Input;
public var stdin(default, null):haxe.io.Output;
private var native:NativeProcess;
public function new(cmd:String, ?args:Array<String>, ?detached:Bool):Void {
if (detached)
throw "Detached process is not supported on this platform";
this.native = createNativeProcess(cmd, args);
native.Start();
this.stdout = new cs.io.NativeInput(native.StandardOutput.BaseStream);
this.stderr = new cs.io.NativeInput(native.StandardError.BaseStream);
this.stdin = new cs.io.NativeOutput(native.StandardInput.BaseStream);
}
@:allow(Sys)
private static function createNativeProcess(cmd:String, ?args:Array<String>):NativeProcess {
var native = new NativeProcess();
native.StartInfo.CreateNoWindow = true;
native.StartInfo.RedirectStandardError = native.StartInfo.RedirectStandardInput = native.StartInfo.RedirectStandardOutput = true;
if (args != null) {
// mono 4.2.1 on Windows doesn't support relative path correctly
if (cmd.indexOf("/") != -1 || cmd.indexOf("\\") != -1)
cmd = sys.FileSystem.fullPath(cmd);
native.StartInfo.FileName = cmd;
native.StartInfo.UseShellExecute = false;
native.StartInfo.Arguments = buildArgumentsString(args);
} else {
switch (Sys.systemName()) {
case "Windows":
native.StartInfo.FileName = switch (Sys.getEnv("COMSPEC")) {
case null: "cmd.exe";
case var comspec: comspec;
}
native.StartInfo.Arguments = '/C "$cmd"';
case _:
native.StartInfo.FileName = "/bin/sh";
native.StartInfo.Arguments = buildArgumentsString(["-c", cmd]);
}
native.StartInfo.UseShellExecute = false;
}
return native;
}
private static function buildArgumentsString(args:Array<String>):String {
return switch (Sys.systemName()) {
case "Windows":
[
for (a in args)
haxe.SysTools.quoteWinArg(a, false)
].join(" ");
case _:
// mono uses a slightly different quoting/escaping rule...
// https://bugzilla.xamarin.com/show_bug.cgi?id=19296
[
for (arg in args) {
var b = new StringBuf();
b.add('"');
for (i in 0...arg.length) {
var c = arg.charCodeAt(i);
switch (c) {
case '"'.code | '\\'.code:
b.addChar('\\'.code);
case _: // pass
}
b.addChar(c);
}
b.add('"');
b.toString();
}
].join(" ");
}
}
public function getPid():Int {
return native.Id;
}
public function exitCode(block:Bool = true):Null<Int> {
if (block == false && !native.HasExited)
return null;
native.WaitForExit();
return native.ExitCode;
}
public function close():Void {
native.Close();
}
public function kill():Void {
native.Kill();
}
}

View File

@ -0,0 +1,75 @@
/*
* 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 sys.net;
import cs.system.Array;
import cs.system.net.Dns;
import cs.system.net.IPAddress;
import cs.system.net.IPHostEntry;
import cs.system.net.sockets.AddressFamily;
import haxe.io.Bytes;
import haxe.io.BytesInput;
@:coreapi
class Host {
public var hostEntry(default, null):IPHostEntry;
public var ipAddress(default, null):IPAddress;
public var host(default, null):String;
public var ip(get, null):Int;
private function get_ip():Int {
return new BytesInput(Bytes.ofData(ipAddress.GetAddressBytes())).readInt32();
}
public function new(name:String):Void {
host = name;
try{
hostEntry = Dns.GetHostEntry(host);
for (i in 0...hostEntry.AddressList.Length) {
if (hostEntry.AddressList[i].AddressFamily == InterNetwork) {
ipAddress = hostEntry.AddressList[i];
break;
}
}
}catch (e:Dynamic){
ipAddress = IPAddress.Any;
if (!IPAddress.TryParse(host, ipAddress)){
throw "Unknown host.";
}
}
}
public function toString():String {
return ipAddress.ToString();
}
public function reverse():String {
return hostEntry.HostName;
}
static public function localhost():String {
return Dns.GetHostName();
}
}

View File

@ -0,0 +1,190 @@
/*
* 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 sys.net;
import cs.NativeArray;
import cs.system.collections.ArrayList;
import cs.system.net.IPEndPoint;
import cs.system.net.sockets.AddressFamily;
import cs.system.net.sockets.NetworkStream;
import cs.system.net.sockets.ProtocolType;
import cs.system.net.sockets.SocketFlags;
import cs.system.net.sockets.SocketShutdown;
import cs.system.net.sockets.SocketType;
import cs.system.threading.Thread;
import cs.system.net.sockets.Socket in NativeSocket;
import cs.types.UInt8;
import haxe.io.Bytes;
import haxe.io.Error;
import haxe.io.Input;
import haxe.io.Output;
@:coreApi
class Socket {
private var sock:NativeSocket = null;
public var input(default, null):haxe.io.Input;
public var output(default, null):haxe.io.Output;
public var custom:Dynamic;
/**
Creates a new unconnected socket.
**/
public function new():Void {
init();
}
private function init():Void {
sock = new NativeSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Blocking = true;
}
public function close():Void {
sock.Close();
input = null;
output = null;
}
public function read():String {
return input.readAll().toString();
}
public function write(content:String):Void {
output.writeString(content);
}
public function connect(host:Host, port:Int):Void {
sock.Connect(host.ipAddress, port);
if (sock.Connected) {
this.output = new cs.io.NativeOutput(new NetworkStream(sock));
this.input = new cs.io.NativeInput(new NetworkStream(sock));
} else {
throw "Connection failed.";
}
}
public function listen(connections:Int):Void {
sock.Listen(connections);
}
public function shutdown(read:Bool, write:Bool):Void {
if (read && write) {
sock.Shutdown(SocketShutdown.Both);
input = null;
output = null;
} else if (read) {
sock.Shutdown(SocketShutdown.Receive);
input = null;
} else if (write) {
sock.Shutdown(SocketShutdown.Send);
output = null;
}
}
public function bind(host:Host, port:Int):Void {
sock = new NativeSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(new IPEndPoint(host.ipAddress, port));
}
public function accept():Socket {
var r = new Socket();
r.sock = sock.Accept();
r.output = new cs.io.NativeOutput(new NetworkStream(r.sock));
r.input = new cs.io.NativeInput(new NetworkStream(r.sock));
return r;
}
public function peer():{host:Host, port:Int} {
var remoteIP = cast(sock.RemoteEndPoint, IPEndPoint);
return {host: new Host(remoteIP.Address.ToString()), port: remoteIP.Port};
}
public function host():{host:Host, port:Int} {
var localIP = cast(sock.LocalEndPoint, IPEndPoint);
return {host: new Host(localIP.Address.ToString()), port: localIP.Port};
}
public function setTimeout(timeout:Float):Void {
sock.ReceiveTimeout = sock.SendTimeout = Math.round(timeout * 1000);
}
public function waitForRead():Void {
var end = Date.now().getTime() + ((sock.ReceiveTimeout <= 0) ? Math.POSITIVE_INFINITY : sock.ReceiveTimeout);
while (sock.Available == 0 && Date.now().getTime() < end) {
Thread.Sleep(5);
}
}
public function setBlocking(b:Bool):Void {
sock.Blocking = b;
}
public function setFastSend(b:Bool):Void {
sock.NoDelay = b;
}
static public function select(read:Array<Socket>, write:Array<Socket>, others:Array<Socket>,
?timeout:Float):{read:Array<Socket>, write:Array<Socket>, others:Array<Socket>} {
var map:Map<Int, Socket> = new Map();
inline function addSockets(sockets:Array<Socket>) {
if (sockets != null)
for (s in sockets)
map[s.sock.Handle.ToInt32()] = s;
}
inline function getRaw(sockets:Array<Socket>):ArrayList {
var a = new ArrayList(sockets == null ? 0 : sockets.length);
if (sockets != null)
for (s in sockets) {
a.Add(s.sock);
}
return a;
}
inline function getOriginal(result:ArrayList) {
var a:Array<Socket> = [];
for (i in 0...result.Count) {
var s:NativeSocket = result[i];
a.push(map[s.Handle.ToInt32()]);
}
return a;
}
addSockets(read);
addSockets(write);
addSockets(others);
// unwrap Sockets into native sockets
var rawRead:ArrayList = getRaw(read),
rawWrite:ArrayList = getRaw(write),
rawOthers:ArrayList = getRaw(others);
var microsec = timeout == null ? -1 : Std.int(timeout * 1000000);
NativeSocket.Select(rawRead, rawWrite, rawOthers, microsec);
// convert native sockets back to Socket objects
return {
read: getOriginal(rawRead),
write: getOriginal(rawWrite),
others: getOriginal(rawOthers),
}
}
}

View File

@ -0,0 +1,99 @@
/*
* 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 sys.net;
import haxe.extern.Rest;
import sys.net.Socket;
import cs.NativeArray;
import cs.system.collections.ArrayList;
import cs.system.net.IPEndPoint;
import cs.system.net.EndPoint;
import cs.system.net.IPAddress;
import cs.system.net.sockets.AddressFamily;
import cs.system.net.sockets.NetworkStream;
import cs.system.net.sockets.ProtocolType;
import cs.system.net.sockets.SocketFlags;
import cs.system.net.sockets.SocketShutdown;
import cs.system.net.sockets.SocketType;
import cs.system.threading.Thread;
import cs.system.net.sockets.Socket in NativeSocket;
import cs.types.UInt8;
import cs.Ref;
import haxe.io.Bytes;
import haxe.io.Error;
import haxe.io.Input;
import haxe.io.Output;
@:coreapi
class UdpSocket extends Socket {
public function new() {
super();
}
override private function init():Void {
sock = new NativeSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
override public function bind(host:Host, port:Int):Void {
sock = new NativeSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
var endpoint:IPEndPoint = new IPEndPoint(host.ipAddress, port);
sock.Bind(endpoint);
}
public function sendTo(buf:haxe.io.Bytes, pos:Int, len:Int, addr:Address):Int {
var data = new NativeArray<UInt8>(len);
var indices:NativeArray<Int>;
for (i in 0...len) {
indices = NativeArray.make(i);
data.SetValue(cast buf.get(pos + i), indices);
}
var host = addr.getHost();
var ip:IPAddress = IPAddress.Parse(host.toString());
var endpoint:IPEndPoint = new IPEndPoint(ip, addr.port);
return this.sock.SendTo(data, endpoint);
}
public function readFrom(buf:haxe.io.Bytes, pos:Int, len:Int, addr:Address):Int {
var endpoint:EndPoint = cast new IPEndPoint(IPAddress.Any, 0);
var data:NativeArray<UInt8> = new NativeArray(len);
var length:Int = -1;
try {
length = this.sock.ReceiveFrom(data, endpoint);
} catch (e:Dynamic) {
return length;
}
var ipEndpoint:IPEndPoint = cast endpoint;
addr.host = ipEndpoint.Address.Address.high;
addr.port = ipEndpoint.Port;
var i:Int = 0;
for (each in data.iterator()) {
buf.set(pos + i, each);
i += 1;
}
return length;
}
public function setBroadcast(b:Bool):Void {
sock.EnableBroadcast = b;
}
}

View File

@ -0,0 +1,60 @@
/*
* 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 sys.thread;
import cs.system.threading.ManualResetEvent;
import cs.Lib;
@:coreApi class Deque<T> {
final storage:Array<T> = [];
final lockObj = {};
final addEvent = new ManualResetEvent(false);
public function new():Void {}
public function add(i:T):Void {
Lib.lock(lockObj, {
storage.push(i);
addEvent.Set();
});
}
public function push(i:T):Void {
Lib.lock(lockObj, {
storage.unshift(i);
addEvent.Set();
});
}
public function pop(block:Bool):Null<T> {
do {
Lib.lock(lockObj, {
if (storage.length > 0) {
return storage.shift();
}
addEvent.Reset();
});
} while (block && addEvent.WaitOne());
return null;
}
}

View 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 sys.thread;
import haxe.Timer;
import cs.Lib;
import cs.system.threading.ManualResetEvent;
class Lock {
final lockObj = {};
final releaseEvent = new ManualResetEvent(false);
var waitCount = 1; // initially locked
var releaseCount = 0;
public function new():Void {}
public function wait(?timeout:Float):Bool {
var myTicket;
// Get a ticket in queue
Lib.lock(lockObj, {
myTicket = waitCount;
waitCount++;
if (myTicket <= releaseCount) {
return true;
}
releaseEvent.Reset();
});
if (timeout == null) {
do {
releaseEvent.WaitOne();
if (myTicket <= releaseCount) {
return true;
}
} while (true);
} else {
var timeoutStamp = Timer.stamp() + timeout;
do {
var secondsLeft = timeoutStamp - Timer.stamp();
if (secondsLeft <= 0 || !releaseEvent.WaitOne(Std.int(secondsLeft * 1000))) {
// Timeout. Do not occupy a place in queue anymore
release();
return false;
}
if (myTicket <= releaseCount) {
return true;
}
} while (true);
}
}
public function release():Void {
Lib.lock(lockObj, {
releaseCount++;
releaseEvent.Set();
});
}
}

View File

@ -0,0 +1,43 @@
/*
* 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 sys.thread;
import cs.system.threading.Mutex as NativeMutex;
class Mutex {
final native = new NativeMutex();
public function new():Void {}
public function acquire():Void {
native.WaitOne();
}
public function tryAcquire():Bool {
return native.WaitOne(0);
}
public function release():Void {
native.ReleaseMutex();
}
}

View File

@ -0,0 +1,184 @@
/*
* 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 sys.thread;
import cs.system.threading.Thread as NativeThread;
import cs.system.threading.Mutex as NativeMutex;
import cs.system.WeakReference;
import cs.Lib;
private typedef ThreadImpl = HaxeThread;
abstract Thread(ThreadImpl) from ThreadImpl {
public var events(get,never):EventLoop;
inline function new(thread:HaxeThread) {
this = thread;
}
public static function create(job:Void->Void):Thread {
var hx:Null<HaxeThread> = null;
var native = new NativeThread(job);
native.IsBackground = true;
hx = HaxeThread.allocate(native, false);
native.Start();
return new Thread(hx);
}
public static inline function runWithEventLoop(job:()->Void):Void {
HaxeThread.runWithEventLoop(job);
}
public static inline function createWithEventLoop(job:()->Void):Thread {
var hx:Null<HaxeThread> = null;
var native = new NativeThread(() -> {
job();
if(hx == null) {
HaxeThread.get(NativeThread.CurrentThread).events.loop();
} else {
hx.events.loop();
}
});
native.IsBackground = true;
hx = HaxeThread.allocate(native, true);
native.Start();
return new Thread(hx);
}
public static inline function current():Thread {
return new Thread(HaxeThread.get(NativeThread.CurrentThread));
}
public static function readMessage(block:Bool):Dynamic {
return current().readMessageImpl(block);
}
public inline function sendMessage(msg:Dynamic):Void {
this.sendMessage(msg);
}
inline function readMessageImpl(block:Bool):Dynamic {
return this.readMessage(block);
}
function get_events():EventLoop {
if(this.events == null)
throw new NoEventLoopException();
return this.events;
}
@:keep
static function processEvents():Void {
HaxeThread.get(NativeThread.CurrentThread).events.loop();
}
}
private class HaxeThread {
static var mainNativeThread:NativeThread;
static var mainHaxeThread:HaxeThread;
static var threads:Map<Int, WeakReference>;
static var threadsMutex:NativeMutex;
static var allocateCount:Int;
static function __init__() {
threads = new Map();
threadsMutex = new NativeMutex();
allocateCount = 0;
mainNativeThread = NativeThread.CurrentThread;
mainHaxeThread = new HaxeThread(NativeThread.CurrentThread);
mainHaxeThread.events = new EventLoop();
}
public final native:NativeThread;
public var events(default,null):Null<EventLoop>;
final messages = new Deque<Dynamic>();
public static function get(native:NativeThread):HaxeThread {
if(native == mainNativeThread) {
return mainHaxeThread;
}
var native = NativeThread.CurrentThread;
var key = native.ManagedThreadId;
threadsMutex.WaitOne();
var ref = threads.get(key);
threadsMutex.ReleaseMutex();
if (ref == null || !ref.IsAlive) {
return allocate(native, false);
}
return ref.Target;
}
public static function allocate(native:NativeThread, withEventLoop:Bool):HaxeThread {
threadsMutex.WaitOne();
allocateCount++;
inline function cleanup() {
if (allocateCount % 100 == 0) {
for (key => ref in threads) {
if (!ref.IsAlive) {
threads.remove(key);
}
}
}
}
var hx = new HaxeThread(native);
if(withEventLoop)
hx.events = new EventLoop();
var ref = new WeakReference(hx);
cleanup();
threads.set(native.ManagedThreadId, ref);
threadsMutex.ReleaseMutex();
return hx;
}
public static function runWithEventLoop(job:()->Void):Void {
var thread = get(NativeThread.CurrentThread);
if(thread.events == null) {
thread.events = new EventLoop();
try {
job();
thread.events.loop();
thread.events = null;
} catch(e) {
thread.events = null;
throw e;
}
} else {
job();
}
}
function new(native:NativeThread) {
this.native = native;
}
public inline function readMessage(block:Bool):Dynamic {
return messages.pop(block);
}
public function sendMessage(msg:Dynamic):Void {
messages.add(msg);
}
}

View File

@ -0,0 +1,45 @@
/*
* 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 sys.thread;
import cs.system.threading.Thread as NativeThread;
import cs.system.LocalDataStoreSlot;
class Tls<T> {
public var value(get, set):T;
final slot:LocalDataStoreSlot;
public function new():Void {
slot = NativeThread.GetNamedDataSlot('__hx__Tls');
}
function get_value():T {
return NativeThread.GetData(slot);
}
function set_value(value:T):T {
NativeThread.SetData(slot, value);
return value;
}
}

View File

@ -0,0 +1,354 @@
/*
* 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.db;
import sys.db.*;
import cs.system.data.*;
class AdoNet {
public static function create(cnx:IDbConnection, dbName:String):Connection {
return new AdoConnection(cnx, dbName);
}
}
private class AdoConnection implements Connection {
private static var ids = 0;
private var id:Int;
private var cnx:IDbConnection;
// escape handling
private var escapeRegex:EReg;
private var escapes:Array<IDbDataParameter>;
private var name:String;
private var command:IDbCommand;
private var transaction:IDbTransaction;
public function new(cnx, name:String) {
this.id = cs.system.threading.Interlocked.Increment(ids);
this.cnx = cnx;
this.name = name;
this.escapes = [];
this.command = cnx.CreateCommand();
this.escapeRegex = ~/@HX_ESCAPE(\d+)_(\d+)/;
}
public function close():Void {
cnx.Close();
}
public function escape(s:String):String {
var param = command.CreateParameter();
var name = "@HX_ESCAPE" + id + "_" + escapes.push(param) + "";
param.ParameterName = name;
param.Value = s;
return name;
}
public function quote(s:String):String {
var param = command.CreateParameter();
var name = "@HX_ESCAPE" + id + "_" + escapes.push(param) + "";
param.ParameterName = name;
param.Value = s;
return name;
}
public function addValue(s:StringBuf, v:Dynamic) {
if (Std.isOfType(v, Date)) {
v = Std.string(v);
} else if (Std.isOfType(v, haxe.io.Bytes)) {
var bt:haxe.io.Bytes = v;
v = bt.getData();
}
var param = command.CreateParameter();
var name = "@HX_ESCAPE" + id + "_" + escapes.push(param) + "";
param.ParameterName = name;
param.Value = v;
s.add(name);
}
public function lastInsertId():Int {
var ret = cnx.CreateCommand();
ret.CommandText = switch (name) {
case 'SQLite':
'SELECT last_insert_rowid()';
case _:
'SELECT @@IDENTITY';
}
ret.CommandType = CommandType.Text;
var r = cast ret.ExecuteScalar();
ret.Dispose();
return r;
}
public function dbName():String {
return name;
}
public function startTransaction():Void {
if (this.transaction != null)
throw 'Transaction already active';
this.transaction = cnx.BeginTransaction();
}
public function commit():Void {
if (this.transaction == null)
throw 'No transaction was initiated';
this.transaction.Commit();
}
public function rollback():Void {
if (this.transaction == null)
throw 'No transaction was initiated';
this.transaction.Rollback();
}
private static function getFirstStatement(s:String) {
var buf = new StringBuf();
var hasData = false;
var chr = 0, i = 0;
inline function getch()
return chr = StringTools.fastCodeAt(s, i++);
while (!StringTools.isEof(getch())) {
inline function peek() {
var c = StringTools.fastCodeAt(s, i);
if (StringTools.isEof(c))
break;
return c;
}
switch (chr) {
case ' '.code | '\t'.code | '\n'.code:
if (hasData)
return buf.toString();
case '-'.code if (peek() == '-'.code):
if (hasData)
return buf.toString();
while (!StringTools.isEof(getch())) {
if (chr == '\n'.code)
break;
}
case '#'.code:
if (hasData)
return buf.toString();
while (!StringTools.isEof(getch())) {
if (chr == '\n'.code)
break;
}
case '/'.code if (peek() == '*'.code):
i++;
if (hasData)
return buf.toString();
while (!StringTools.isEof(getch())) {
if (chr == '*'.code && peek() == '/'.code) {
i++;
break;
}
}
case _:
hasData = true;
buf.addChar(chr);
}
}
return buf.toString();
}
public function request(s:String):ResultSet {
var newst = new StringBuf();
// cycle through the request string, adding any @HX_ESCAPE reference to the command
var ret:ResultSet = null;
var r = escapeRegex;
var myid = id + "", escapes = escapes, elen = escapes.length;
var cmd = this.command;
try {
while (r.match(s)) {
var id = r.matched(1);
#if debug
if (id != myid)
throw "Request quotes are only valid for one single request; They can't be cached.";
#end
newst.add(r.matchedLeft());
var eid = Std.parseInt(r.matched(2));
#if debug
if (eid == null || eid > elen)
throw "Invalid request quote ID " + eid;
#end
cmd.Parameters.Add(escapes[eid - 1]);
newst.add(escapes[eid - 1].ParameterName);
s = r.matchedRight();
}
newst.add(s);
s = newst.toString();
cmd.CommandText = s;
var stmt = getFirstStatement(s).toLowerCase();
if (stmt == 'select') {
ret = new AdoResultSet(cmd.ExecuteReader());
} else {
cmd.ExecuteNonQuery();
ret = EmptyResultSet.empty;
}
if (escapes.length != 0)
this.escapes = [];
this.id = cs.system.threading.Interlocked.Increment(ids);
cmd.Dispose();
this.command = cnx.CreateCommand();
return ret;
} catch (e:Dynamic) {
if (escapes.length != 0)
this.escapes = [];
this.id = cs.system.threading.Interlocked.Increment(ids);
try {
cmd.Dispose();
} catch (e:Dynamic) {}
this.command = cnx.CreateCommand();
cs.Lib.rethrow(e);
}
return null;
}
}
private class AdoResultSet implements ResultSet {
public var length(get, null):Int;
public var nfields(get, null):Int;
private var reader:IDataReader;
private var didNext:Bool;
private var names:Array<String>;
private var types:Array<Class<Dynamic>>;
public function new(reader) {
this.reader = reader;
this.names = [for (i in 0...reader.FieldCount) reader.GetName(i)];
this.types = [for (i in 0...names.length) cs.Lib.fromNativeType(reader.GetFieldType(i))];
}
private function get_length() {
return reader.Depth;
}
private function get_nfields() {
return names.length;
}
public function hasNext():Bool {
didNext = true;
return reader.Read();
}
public function next():Dynamic {
if (!didNext && !hasNext())
return null;
didNext = false;
var ret = {}, names = names, types = types;
for (i in 0...names.length) {
var name = names[i], t = types[i], val:Dynamic = null;
if (reader.IsDBNull(i)) {
val = null;
} else if (t == cs.system.Single) {
val = reader.GetDouble(i);
} else if (t == cs.system.DateTime || t == cs.system.TimeSpan) {
var d = reader.GetDateTime(i);
if (d != null)
val = @:privateAccess Date.fromNative(d);
} else if (t == cs.system.DBNull) {
val = null;
} else if (t == cs.system.Byte) {
var v2:cs.StdTypes.UInt8 = reader.GetValue(i);
val = cast(v2, Int);
} else if (Std.string(t) == 'System.Byte[]') {
val = haxe.io.Bytes.ofData(reader.GetValue(i));
} else {
val = reader.GetValue(i);
}
if (Std.isOfType(val, cs.system.DBNull))
val = null;
Reflect.setField(ret, name, val);
}
return ret;
}
public function results():List<Dynamic> {
var l = new List();
while (hasNext())
l.add(next());
return l;
}
public function getResult(n:Int):String {
return reader.GetString(n);
}
public function getIntResult(n:Int):Int {
return reader.GetInt32(n);
}
public function getFloatResult(n:Int):Float {
return reader.GetDouble(n);
}
public function getFieldsNames():Null<Array<String>> {
return names;
}
}
private class EmptyResultSet implements ResultSet {
public static var empty = new EmptyResultSet();
public function new() {}
public var length(get, null):Int;
public var nfields(get, null):Int;
private function get_length() {
return 0;
}
private function get_nfields() {
return 0;
}
public function hasNext():Bool
return false;
public function next():Dynamic
return null;
public function results():List<Dynamic>
return new List();
public function getResult(n:Int):String
return null;
public function getIntResult(n:Int):Int
return 0;
public function getFloatResult(n:Int):Float
return 0;
public function getFieldsNames():Null<Array<String>>
return null;
}

View 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;
}
}

View 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;
}
}
}

View 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();
}
}

View 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;
}
}

View 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;
}
}

View 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;
}

View 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);
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.io;
import haxe.Int64;
import haxe.io.Bytes;
import haxe.io.Eof;
import haxe.io.Error;
import haxe.io.Input;
class NativeInput extends Input {
public var canSeek(get, never):Bool;
var stream:cs.system.io.Stream;
var _eof:Bool;
public function new(stream) {
this.stream = stream;
this._eof = false;
if (!stream.CanRead)
throw "Write-only stream";
}
override public function readByte():Int {
var ret = stream.ReadByte();
if (ret == -1) {
_eof = true;
throw new Eof();
}
return ret;
}
override public function readBytes(s:Bytes, pos:Int, len:Int):Int {
if (pos < 0 || len < 0 || pos + len > s.length)
throw Error.OutsideBounds;
var ret = 0;
var data = s.getData();
try {
ret = stream.Read(data, pos, len);
} catch (e: Dynamic) {}
if (ret == 0) {
_eof = true;
throw new Eof();
}
return ret;
}
override public function close():Void {
stream.Close();
}
private inline function get_canSeek():Bool {
return stream.CanSeek;
}
public function seek(p:Int, pos:sys.io.FileSeek):Void {
_eof = false;
var pos = switch (pos) {
case SeekBegin: cs.system.io.SeekOrigin.Begin;
case SeekCur: cs.system.io.SeekOrigin.Current;
case SeekEnd: cs.system.io.SeekOrigin.End;
};
stream.Seek(cast(p, Int64), pos);
}
public function tell():Int {
return cast(stream.Position, Int);
}
public inline function eof():Bool {
return _eof;
}
}

View File

@ -0,0 +1,74 @@
/*
* 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.io;
import haxe.Int64;
import haxe.io.Bytes;
import haxe.io.Output;
class NativeOutput extends Output {
var canSeek(get, never):Bool;
var stream:cs.system.io.Stream;
public function new(stream) {
this.stream = stream;
if (!stream.CanWrite)
throw "Read-only stream";
}
override public function writeByte(c:Int):Void {
stream.WriteByte(cast c);
}
override public function close():Void {
stream.Close();
}
override public function flush():Void {
stream.Flush();
}
override public function prepare(nbytes:Int):Void {
// TODO see if implementation is correct
stream.SetLength(haxe.Int64.add(stream.Length, cast(nbytes, Int64)));
}
private inline function get_canSeek():Bool {
return stream.CanSeek;
}
public function seek(p:Int, pos:sys.io.FileSeek):Void {
var pos = switch (pos) {
case SeekBegin: cs.system.io.SeekOrigin.Begin;
case SeekCur: cs.system.io.SeekOrigin.Current;
case SeekEnd: cs.system.io.SeekOrigin.End;
};
stream.Seek(cast(p, Int64), pos);
}
public function tell():Int {
return cast(stream.Position, Int);
}
}

View File

@ -0,0 +1,25 @@
/*
* 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.types;
typedef Char16 = cs.StdTypes.Char16;

View File

@ -0,0 +1,25 @@
/*
* 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.types;
typedef Int16 = cs.StdTypes.Int16;

View File

@ -0,0 +1,25 @@
/*
* 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.types;
typedef Int64 = cs.StdTypes.Int64;

View File

@ -0,0 +1,25 @@
/*
* 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.types;
typedef Int8 = cs.StdTypes.Int8;

View File

@ -0,0 +1,25 @@
/*
* 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.types;
typedef UInt16 = cs.StdTypes.UInt16;

View File

@ -0,0 +1,25 @@
/*
* 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.types;
typedef UInt64 = cs.StdTypes.UInt64;

View File

@ -0,0 +1,25 @@
/*
* 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.types;
typedef UInt8 = cs.StdTypes.UInt8;