forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
502
Kha/Tools/macos/std/java/_std/Array.hx
Normal file
502
Kha/Tools/macos/std/java/_std/Array.hx
Normal file
@ -0,0 +1,502 @@
|
||||
/*
|
||||
* 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 java.lang.System;
|
||||
import java.NativeArray;
|
||||
import haxe.iterators.ArrayKeyValueIterator;
|
||||
|
||||
@:classCode('
|
||||
public Array(T[] _native)
|
||||
{
|
||||
this.__a = _native;
|
||||
this.length = _native.length;
|
||||
}
|
||||
')
|
||||
@:coreApi 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;
|
||||
|
||||
@:functionCode('
|
||||
return new Array<X>(_native);
|
||||
')
|
||||
private static function ofNative<X>(native:NativeArray<X>):Array<X> {
|
||||
var a = new Array();
|
||||
a.length = native.length;
|
||||
a.__a = native;
|
||||
return a;
|
||||
}
|
||||
|
||||
@:functionCode('
|
||||
return new Array<Y>((Y[]) ((java.lang.Object)new java.lang.Object[size]));
|
||||
')
|
||||
private static function alloc<Y>(size:Int):Array<Y> {
|
||||
var a = new Array();
|
||||
a.length = size;
|
||||
a.__a = new java.NativeArray(size);
|
||||
return a;
|
||||
}
|
||||
|
||||
#if jvm
|
||||
function getNative():NativeArray<T> {
|
||||
var a = new NativeArray(length);
|
||||
System.arraycopy(__a, 0, a, 0, length);
|
||||
return a;
|
||||
}
|
||||
#end
|
||||
|
||||
public function new():Void {
|
||||
this.length = 0;
|
||||
this.__a = new NativeArray(0);
|
||||
}
|
||||
|
||||
public function concat(a:Array<T>):Array<T> {
|
||||
var length = length;
|
||||
var len = length + a.length;
|
||||
var retarr = new NativeArray(len);
|
||||
System.arraycopy(__a, 0, retarr, 0, length);
|
||||
System.arraycopy(a.__a, 0, retarr, length, a.length);
|
||||
|
||||
return ofNative(retarr);
|
||||
}
|
||||
|
||||
private function concatNative(a:NativeArray<T>):Void {
|
||||
var __a = __a;
|
||||
var length = length;
|
||||
var len = length + a.length;
|
||||
if (__a.length >= len) {
|
||||
System.arraycopy(a, 0, __a, length, length);
|
||||
} else {
|
||||
var newarr = new NativeArray(len);
|
||||
System.arraycopy(__a, 0, newarr, 0, length);
|
||||
System.arraycopy(a, 0, newarr, length, a.length);
|
||||
|
||||
this.__a = newarr;
|
||||
}
|
||||
|
||||
this.length = len;
|
||||
}
|
||||
|
||||
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 {
|
||||
var length = length;
|
||||
if (length >= __a.length) {
|
||||
var newLen = length == 0 ? __hx_defaultCapacity : (length << 1);
|
||||
var newarr = new NativeArray(newLen);
|
||||
System.arraycopy(__a, 0, newarr, 0, __a.length);
|
||||
|
||||
this.__a = newarr;
|
||||
}
|
||||
|
||||
__a[length] = x;
|
||||
return ++this.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;
|
||||
System.arraycopy(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);
|
||||
System.arraycopy(__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);
|
||||
System.arraycopy(a, pos, ret, 0, len);
|
||||
var ret = ofNative(ret);
|
||||
|
||||
var end = pos + len;
|
||||
System.arraycopy(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;
|
||||
System.arraycopy(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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
System.arraycopy(__a, 0, newarr, 1, length);
|
||||
|
||||
this.__a = newarr;
|
||||
} else {
|
||||
System.arraycopy(__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);
|
||||
System.arraycopy(__a, 0, newarr, 0, pos);
|
||||
newarr[pos] = x;
|
||||
System.arraycopy(__a, pos, newarr, pos + 1, l - pos);
|
||||
|
||||
this.__a = newarr;
|
||||
++this.length;
|
||||
} else {
|
||||
var __a = __a;
|
||||
System.arraycopy(__a, pos, __a, pos + 1, l - pos);
|
||||
System.arraycopy(__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) {
|
||||
System.arraycopy(__a, i + 1, __a, i, length - i - 1);
|
||||
__a[--this.length] = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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 function indexOf(x:T, ?fromIndex:Int):Int {
|
||||
var len = length, a = __a, i:Int = (fromIndex == null) ? 0 : fromIndex;
|
||||
if (i < 0) {
|
||||
i += len;
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
}
|
||||
while (i < len) {
|
||||
if (a[i] == x)
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function lastIndexOf(x:T, ?fromIndex:Int):Int {
|
||||
var len = length,
|
||||
a = __a,
|
||||
i:Int = (fromIndex == null) ? len - 1 : fromIndex;
|
||||
if (i >= len)
|
||||
i = len - 1;
|
||||
else if (i < 0)
|
||||
i += len;
|
||||
while (i >= 0) {
|
||||
if (a[i] == x)
|
||||
return i;
|
||||
i--;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function copy():Array<T> {
|
||||
var len = length;
|
||||
var __a = __a;
|
||||
var newarr = new NativeArray(len);
|
||||
System.arraycopy(__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) {
|
||||
var newArr = new NativeArray<T>(len);
|
||||
if (length > 0)
|
||||
System.arraycopy(__a, 0, newArr, 0, length);
|
||||
this.__a = __a = newArr;
|
||||
}
|
||||
this.length = len;
|
||||
} else if (length > len) {
|
||||
spliceVoid(len, length - len);
|
||||
}
|
||||
}
|
||||
|
||||
public inline function map<S>(f:T->S):Array<S> {
|
||||
var ret = alloc(length);
|
||||
for (i in 0...length)
|
||||
ret.__set(i, f(__get(i)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public inline function filter(f:T->Bool):Array<T> {
|
||||
var ret = [];
|
||||
for (i in 0...length) {
|
||||
var elt = __get(i);
|
||||
if (f(elt))
|
||||
ret.push(elt);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private function __get(idx:Int):T {
|
||||
var __a = __a;
|
||||
if (idx >= __a.length || idx < 0)
|
||||
return null;
|
||||
|
||||
return __a[idx];
|
||||
}
|
||||
|
||||
private function __set(idx:Int, v:T):#if jvm Void #else T #end
|
||||
{
|
||||
var __a = __a;
|
||||
if (idx >= __a.length) {
|
||||
var newl = idx + 1;
|
||||
if (idx == __a.length)
|
||||
newl = (idx << 1) + 1;
|
||||
var newArr = new NativeArray<T>(newl);
|
||||
if (length > 0)
|
||||
System.arraycopy(__a, 0, newArr, 0, length);
|
||||
this.__a = __a = newArr;
|
||||
}
|
||||
|
||||
if (idx >= length)
|
||||
this.length = idx + 1;
|
||||
|
||||
#if !jvm return #end __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;
|
||||
}
|
||||
}
|
147
Kha/Tools/macos/std/java/_std/Date.hx
Normal file
147
Kha/Tools/macos/std/java/_std/Date.hx
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import haxe.Int64;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@:coreApi class Date {
|
||||
private var date:Calendar;
|
||||
private var dateUTC:Calendar;
|
||||
|
||||
public function new(year:Int, month:Int, day:Int, hour:Int, min:Int, sec:Int):Void {
|
||||
date = new GregorianCalendar(year, month, day, hour, min, sec);
|
||||
dateUTC = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
||||
dateUTC.setTimeInMillis(date.getTimeInMillis());
|
||||
}
|
||||
|
||||
public inline function getTime():Float {
|
||||
return cast date.getTimeInMillis();
|
||||
}
|
||||
|
||||
public inline function getHours():Int {
|
||||
return date.get(Calendar.HOUR_OF_DAY);
|
||||
}
|
||||
|
||||
public inline function getMinutes():Int {
|
||||
return date.get(Calendar.MINUTE);
|
||||
}
|
||||
|
||||
public inline function getSeconds():Int {
|
||||
return date.get(Calendar.SECOND);
|
||||
}
|
||||
|
||||
public inline function getFullYear():Int {
|
||||
return date.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
public inline function getMonth():Int {
|
||||
return date.get(Calendar.MONTH);
|
||||
}
|
||||
|
||||
public inline function getDate():Int {
|
||||
return date.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
public inline function getDay():Int {
|
||||
// SUNDAY in Java == 1, MONDAY == 2, ...
|
||||
return cast date.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
}
|
||||
|
||||
public inline function getUTCHours():Int {
|
||||
return dateUTC.get(Calendar.HOUR_OF_DAY);
|
||||
}
|
||||
|
||||
public inline function getUTCMinutes():Int {
|
||||
return dateUTC.get(Calendar.MINUTE);
|
||||
}
|
||||
|
||||
public inline function getUTCSeconds():Int {
|
||||
return dateUTC.get(Calendar.SECOND);
|
||||
}
|
||||
|
||||
public inline function getUTCFullYear():Int {
|
||||
return dateUTC.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
public inline function getUTCMonth():Int {
|
||||
return dateUTC.get(Calendar.MONTH);
|
||||
}
|
||||
|
||||
public inline function getUTCDate():Int {
|
||||
return dateUTC.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
public inline function getUTCDay():Int {
|
||||
// SUNDAY in Java == 1, MONDAY == 2, ...
|
||||
return cast dateUTC.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
}
|
||||
|
||||
public inline function getTimezoneOffset():Int {
|
||||
return -Std.int(date.get(Calendar.ZONE_OFFSET) / 60000);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
var m = getMonth() + 1;
|
||||
var d = getDate();
|
||||
var h = getHours();
|
||||
var mi = getMinutes();
|
||||
var s = getSeconds();
|
||||
return getFullYear() + "-" + (if (m < 10) "0" + m else "" + m) + "-" + (if (d < 10) "0" + d else "" + d) + " "
|
||||
+ (if (h < 10) "0" + h else "" + h) + ":" + (if (mi < 10) "0" + mi else "" + mi) + ":" + (if (s < 10) "0" + s else "" + s);
|
||||
}
|
||||
|
||||
static public function now():Date {
|
||||
var d = new Date(0, 0, 0, 0, 0, 0);
|
||||
d.date = Calendar.getInstance();
|
||||
d.dateUTC.setTimeInMillis(d.date.getTimeInMillis());
|
||||
return d;
|
||||
}
|
||||
|
||||
static public function fromTime(t:Float):Date {
|
||||
var d = new Date(0, 0, 0, 0, 0, 0);
|
||||
d.date.setTimeInMillis(cast t);
|
||||
d.dateUTC.setTimeInMillis(cast t);
|
||||
return d;
|
||||
}
|
||||
|
||||
static public function fromString(s:String):Date {
|
||||
switch (s.length) {
|
||||
case 8: // hh:mm:ss
|
||||
var k = s.split(":");
|
||||
return Date.fromTime(Std.parseInt(k[0]) * 3600000. + Std.parseInt(k[1]) * 60000. + Std.parseInt(k[2]) * 1000.);
|
||||
case 10: // YYYY-MM-DD
|
||||
var k = s.split("-");
|
||||
return new Date(Std.parseInt(k[0]), Std.parseInt(k[1]) - 1, Std.parseInt(k[2]), 0, 0, 0);
|
||||
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(Std.parseInt(y[0]), Std.parseInt(y[1]) - 1, Std.parseInt(y[2]), Std.parseInt(t[0]), Std.parseInt(t[1]), Std.parseInt(t[2]));
|
||||
default:
|
||||
throw "Invalid date format : " + s;
|
||||
}
|
||||
}
|
||||
}
|
192
Kha/Tools/macos/std/java/_std/EReg.hx
Normal file
192
Kha/Tools/macos/std/java/_std/EReg.hx
Normal 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 java.util.regex.*;
|
||||
|
||||
using StringTools;
|
||||
|
||||
@:coreApi class EReg {
|
||||
private var pattern:String;
|
||||
private var matcher:Matcher;
|
||||
private var cur:String;
|
||||
private var isGlobal:Bool;
|
||||
|
||||
public function new(r:String, opt:String) {
|
||||
var flags = 0;
|
||||
for (i in 0...opt.length) {
|
||||
switch (StringTools.fastCodeAt(opt, i)) {
|
||||
case 'i'.code:
|
||||
flags |= Pattern.CASE_INSENSITIVE;
|
||||
case 'm'.code:
|
||||
flags |= Pattern.MULTILINE;
|
||||
case 's'.code:
|
||||
flags |= Pattern.DOTALL;
|
||||
case 'g'.code:
|
||||
isGlobal = true;
|
||||
}
|
||||
}
|
||||
|
||||
flags |= Pattern.UNICODE_CASE;
|
||||
#if !android // see https://github.com/HaxeFoundation/haxe/issues/7632
|
||||
flags |= Pattern.UNICODE_CHARACTER_CLASS;
|
||||
#end
|
||||
matcher = Pattern.compile(convert(r), flags).matcher("");
|
||||
pattern = r;
|
||||
}
|
||||
|
||||
private static function convert(r:String):String {
|
||||
// some references of the implementation:
|
||||
// http://stackoverflow.com/questions/809647/java-vs-javascript-regex-problem
|
||||
// http://stackoverflow.com/questions/4788413/how-to-convert-javascript-regex-to-safe-java-regex
|
||||
// Some necessary changes:
|
||||
//
|
||||
// \0 -> \x00
|
||||
// \v -> \x0b
|
||||
// [^] -> [\s\S]
|
||||
// unescaped ', " -> \', \"
|
||||
/* FIXME
|
||||
var pat = new StringBuf();
|
||||
var len = r.length;
|
||||
var i = 0;
|
||||
while (i < len)
|
||||
{
|
||||
var c = StringTools.fastCodeAt(r, i++);
|
||||
switch(c)
|
||||
{
|
||||
case '\\'.code: //escape-sequence
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public function match(s:String):Bool {
|
||||
cur = s;
|
||||
matcher = matcher.reset(s);
|
||||
return matcher.find();
|
||||
}
|
||||
|
||||
public function matched(n:Int):String {
|
||||
if (n == 0)
|
||||
return matcher.group();
|
||||
else
|
||||
return matcher.group(n);
|
||||
}
|
||||
|
||||
public function matchedLeft():String {
|
||||
return untyped cur.substring(0, matcher.start());
|
||||
}
|
||||
|
||||
public function matchedRight():String {
|
||||
return untyped cur.substring(matcher.end(), cur.length);
|
||||
}
|
||||
|
||||
public function matchedPos():{pos:Int, len:Int} {
|
||||
var start = matcher.start();
|
||||
return {pos: start, len: matcher.end() - start};
|
||||
}
|
||||
|
||||
public function matchSub(s:String, pos:Int, len:Int = -1):Bool {
|
||||
matcher = matcher.reset(len < 0 ? s : s.substr(0, pos + len));
|
||||
cur = s;
|
||||
return matcher.find(pos);
|
||||
}
|
||||
|
||||
public function split(s:String):Array<String> {
|
||||
if (isGlobal) {
|
||||
var ret = [];
|
||||
matcher.reset(s);
|
||||
matcher = matcher.useAnchoringBounds(false).useTransparentBounds(true);
|
||||
var copyOffset = 0;
|
||||
while (true) {
|
||||
if (!matcher.find()) {
|
||||
ret.push(s.substring(copyOffset, s.length));
|
||||
break;
|
||||
}
|
||||
ret.push(s.substring(copyOffset, matcher.start()));
|
||||
var nextStart = matcher.end();
|
||||
copyOffset = nextStart;
|
||||
if (nextStart == matcher.regionStart()) {
|
||||
nextStart++; // zero-length match - shift region one forward
|
||||
}
|
||||
if (nextStart >= s.length) {
|
||||
ret.push("");
|
||||
break;
|
||||
}
|
||||
matcher.region(nextStart, s.length);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
var m = matcher;
|
||||
m.reset(s);
|
||||
if (m.find()) {
|
||||
return untyped [s.substring(0, m.start()), s.substring(m.end(), s.length)];
|
||||
} else {
|
||||
return [s];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline function start(group:Int):Int {
|
||||
return matcher.start(group);
|
||||
}
|
||||
|
||||
inline function len(group:Int):Int {
|
||||
return matcher.end(group) - matcher.start(group);
|
||||
}
|
||||
|
||||
public function replace(s:String, by:String):String {
|
||||
matcher.reset(s);
|
||||
by = by.replace("\\", "\\\\").replace("$$", "\\$");
|
||||
return isGlobal ? matcher.replaceAll(by) : matcher.replaceFirst(by);
|
||||
}
|
||||
|
||||
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 Pattern.quote(s);
|
||||
}
|
||||
}
|
55
Kha/Tools/macos/std/java/_std/Math.hx
Normal file
55
Kha/Tools/macos/std/java/_std/Math.hx
Normal 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.
|
||||
*/
|
||||
@:coreApi
|
||||
@:native("java.lang.Math") extern class Math {
|
||||
static var PI(default, null):Float;
|
||||
static var NaN(default, null):Float;
|
||||
static var NEGATIVE_INFINITY(default, null):Float;
|
||||
static var POSITIVE_INFINITY(default, null):Float;
|
||||
|
||||
static function abs(v:Float):Float;
|
||||
static function min(a:Float, b:Float):Float;
|
||||
static function max(a:Float, b:Float):Float;
|
||||
static function sin(v:Float):Float;
|
||||
static function cos(v:Float):Float;
|
||||
static function atan2(y:Float, x:Float):Float;
|
||||
static function tan(v:Float):Float;
|
||||
static function exp(v:Float):Float;
|
||||
static function log(v:Float):Float;
|
||||
static function sqrt(v:Float):Float;
|
||||
static function round(v:Float):Int;
|
||||
static function floor(v:Float):Int;
|
||||
static function ceil(v:Float):Int;
|
||||
static function atan(v:Float):Float;
|
||||
inline static function fround(v:Float):Float {
|
||||
return ffloor(v + 0.5);
|
||||
}
|
||||
static function ffloor(v:Float):Float;
|
||||
static function fceil(v:Float):Float;
|
||||
static function asin(v:Float):Float;
|
||||
static function acos(v:Float):Float;
|
||||
static function pow(v:Float, exp:Float):Float;
|
||||
static function random():Float;
|
||||
|
||||
static function isFinite(f:Float):Bool;
|
||||
static function isNaN(f:Float):Bool;
|
||||
}
|
145
Kha/Tools/macos/std/java/_std/Reflect.hx
Normal file
145
Kha/Tools/macos/std/java/_std/Reflect.hx
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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 java.internal.Function;
|
||||
import java.internal.HxObject;
|
||||
import java.internal.Runtime;
|
||||
import java.Boot;
|
||||
|
||||
@:coreApi class Reflect {
|
||||
public static function hasField(o:Dynamic, field:String):Bool {
|
||||
if (Std.isOfType(o, IHxObject)) {
|
||||
return untyped (o : IHxObject).__hx_getField(field, false, true, false) != Runtime.undefined;
|
||||
}
|
||||
return Runtime.slowHasField(o, field);
|
||||
}
|
||||
|
||||
@:keep
|
||||
public static function field(o:Dynamic, field:String):Dynamic {
|
||||
if (Std.isOfType(o, IHxObject)) {
|
||||
return untyped (o : IHxObject).__hx_getField(field, false, false, false);
|
||||
}
|
||||
return Runtime.slowGetField(o, field, false);
|
||||
}
|
||||
|
||||
@:keep
|
||||
public static function setField(o:Dynamic, field:String, value:Dynamic):Void {
|
||||
if (Std.isOfType(o, IHxObject)) {
|
||||
untyped (o : IHxObject).__hx_setField(field, value, false);
|
||||
} else {
|
||||
Runtime.slowSetField(o, field, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getProperty(o:Dynamic, field:String):Dynamic {
|
||||
if (o == null || field == null) {
|
||||
return null;
|
||||
}
|
||||
if (Std.isOfType(o, IHxObject)) {
|
||||
return untyped (o : IHxObject).__hx_getField(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 {
|
||||
if (Std.isOfType(o, IHxObject)) {
|
||||
untyped (o : IHxObject).__hx_setField(field, value, true);
|
||||
} else if (Runtime.slowHasField(o, "set_" + field)) {
|
||||
Runtime.slowCallField(o, "set_" + field, java.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 = java.Lib.nativeArray(args, true);
|
||||
return untyped (func : Function).__hx_invokeDynamic(args);
|
||||
}
|
||||
|
||||
@:keep
|
||||
public static function fields(o:Dynamic):Array<String> {
|
||||
if (Std.isOfType(o, IHxObject)) {
|
||||
var ret:Array<String> = [];
|
||||
untyped (o : IHxObject).__hx_getFields(ret);
|
||||
return ret;
|
||||
} else if (Std.isOfType(o, java.lang.Class)) {
|
||||
return Type.getClassFields(cast o);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public static function isFunction(f:Dynamic):Bool {
|
||||
return Std.isOfType(f, Function);
|
||||
}
|
||||
|
||||
public static function compare<T>(a:T, b:T):Int {
|
||||
return Runtime.compare(a, b);
|
||||
}
|
||||
|
||||
@:access(java.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, java.lang.Enum)
|
||||
|| Std.isOfType(v, java.lang.Number)
|
||||
|| Std.isOfType(v, java.lang.Boolean.BooleanClass));
|
||||
}
|
||||
|
||||
public static function isEnumValue(v:Dynamic):Bool {
|
||||
return v != null && (Std.isOfType(v, HxEnum) || Std.isOfType(v, java.lang.Enum));
|
||||
}
|
||||
|
||||
public static function deleteField(o:Dynamic, field:String):Bool {
|
||||
return (Std.isOfType(o, DynamicObject) && (o : DynamicObject).__hx_deleteField(field));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
177
Kha/Tools/macos/std/java/_std/Std.hx
Normal file
177
Kha/Tools/macos/std/java/_std/Std.hx
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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 java.Boot;
|
||||
import java.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:java.lang.Class<Dynamic> = cast t;
|
||||
if (clt == null)
|
||||
return false;
|
||||
var name:String = clt.getName();
|
||||
|
||||
switch (name) {
|
||||
case "double", "java.lang.Double":
|
||||
return untyped __java__('haxe.lang.Runtime.isDouble(v)');
|
||||
case "int", "java.lang.Integer":
|
||||
return untyped __java__('haxe.lang.Runtime.isInt(v)');
|
||||
case "boolean", "java.lang.Boolean":
|
||||
return untyped __java__('v instanceof java.lang.Boolean');
|
||||
case "java.lang.Object":
|
||||
return true;
|
||||
}
|
||||
|
||||
var clv:java.lang.Class<Dynamic> = untyped __java__('v.getClass()');
|
||||
|
||||
return clt.isAssignableFrom(clv);
|
||||
}
|
||||
|
||||
public static function string(s:Dynamic):String {
|
||||
return cast(s, String) + "";
|
||||
}
|
||||
|
||||
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 + (base == 16 ? 2 : 0), lastDigitIndex + 1);
|
||||
return try {
|
||||
(sign == -1 ? -1 : 1) * java.lang.Integer.parseInt(digits, base);
|
||||
} catch(e:java.lang.NumberFormatException) {
|
||||
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._charAt(i) : java.StdTypes.Char16);
|
||||
|
||||
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 java.lang.Double.DoubleClass.parseDouble(x) catch (e:Dynamic) Math.NaN;
|
||||
}
|
||||
|
||||
inline public static function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
|
||||
return Std.isOfType(value, c) ? cast value : null;
|
||||
}
|
||||
|
||||
@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
|
||||
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 Std.int(Math.random() * x);
|
||||
}
|
||||
}
|
58
Kha/Tools/macos/std/java/_std/String.hx
Normal file
58
Kha/Tools/macos/std/java/_std/String.hx
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 extern class String implements java.lang.CharSequence {
|
||||
var length(default, null):Int;
|
||||
|
||||
@:overload(function(b:haxe.io.BytesData, offset:Int, length:Int, charsetName:String):Void {})
|
||||
@:overload(function(b:haxe.io.BytesData, offset:Int, length:Int):Void {})
|
||||
@:overload(function(b:java.NativeArray<java.StdTypes.Char16>):Void {})
|
||||
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;
|
||||
|
||||
private function compareTo(anotherString:String):Int;
|
||||
|
||||
private function codePointAt(idx:Int):Int;
|
||||
|
||||
@:overload(function():haxe.io.BytesData {})
|
||||
private function getBytes(encoding:String):haxe.io.BytesData;
|
||||
|
||||
static function fromCharCode(code:Int):String;
|
||||
}
|
59
Kha/Tools/macos/std/java/_std/StringBuf.hx
Normal file
59
Kha/Tools/macos/std/java/_std/StringBuf.hx
Normal 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.
|
||||
*/
|
||||
@:coreApi
|
||||
class StringBuf {
|
||||
private var b:java.lang.StringBuilder;
|
||||
|
||||
public var length(get, never):Int;
|
||||
|
||||
public function new():Void {
|
||||
b = new java.lang.StringBuilder();
|
||||
}
|
||||
|
||||
inline function get_length():Int {
|
||||
return b.length();
|
||||
}
|
||||
|
||||
public function add<T>(x:T):Void {
|
||||
if (Std.isOfType(x, Int)) {
|
||||
var x:Int = cast x;
|
||||
var xd:Dynamic = x;
|
||||
b.append(xd);
|
||||
} else {
|
||||
b.append(x);
|
||||
}
|
||||
}
|
||||
|
||||
public function addSub(s:String, pos:Int, ?len:Int):Void {
|
||||
var l:Int = (len == null) ? s.length - pos : len;
|
||||
b.append(s, pos, pos + l);
|
||||
}
|
||||
|
||||
public function addChar(c:Int):Void
|
||||
untyped {
|
||||
b.appendCodePoint(c);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return b.toString();
|
||||
}
|
||||
}
|
164
Kha/Tools/macos/std/java/_std/Sys.hx
Normal file
164
Kha/Tools/macos/std/java/_std/Sys.hx
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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 java.lang.System;
|
||||
import sys.io.Process;
|
||||
|
||||
using haxe.Int64;
|
||||
|
||||
@:coreApi class Sys {
|
||||
private static var _args:java.NativeArray<String>;
|
||||
private static var _env:haxe.ds.StringMap<String>;
|
||||
private static var _sysName:String;
|
||||
|
||||
public static inline function print(v:Dynamic):Void {
|
||||
java.lang.System.out.print(v);
|
||||
}
|
||||
|
||||
public static inline function println(v:Dynamic):Void {
|
||||
java.lang.System.out.println(v);
|
||||
}
|
||||
|
||||
public static function args():Array<String> {
|
||||
if (_args == null)
|
||||
return [];
|
||||
return java.Lib.array(_args);
|
||||
}
|
||||
|
||||
public static function getEnv(s:String):String {
|
||||
return java.lang.System.getenv(s);
|
||||
}
|
||||
|
||||
public static function putEnv(s:String, v:String):Void {
|
||||
// java offers no support for it (!)
|
||||
throw new haxe.exceptions.NotImplementedException("Not implemented in this platform");
|
||||
}
|
||||
|
||||
public static function environment():Map<String, String> {
|
||||
if (_env != null)
|
||||
return _env;
|
||||
var _env = _env = new haxe.ds.StringMap();
|
||||
for (mv in java.lang.System.getenv().entrySet()) {
|
||||
_env.set(mv.getKey(), mv.getValue());
|
||||
}
|
||||
|
||||
return _env;
|
||||
}
|
||||
|
||||
public static function sleep(seconds:Float):Void {
|
||||
try
|
||||
java.lang.Thread.sleep(cast seconds * 1000)
|
||||
catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
public static function setTimeLocale(loc:String):Bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getCwd():String {
|
||||
return new java.io.File(".").getAbsolutePath().substr(0, -1);
|
||||
}
|
||||
|
||||
public static function setCwd(s:String):Void {
|
||||
// java offers no support for it (!)
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
public static function systemName():String {
|
||||
if (_sysName != null)
|
||||
return _sysName;
|
||||
var sname = System.getProperty("os.name").toLowerCase();
|
||||
if (sname.indexOf("win") >= 0)
|
||||
return _sysName = "Windows";
|
||||
if (sname.indexOf("mac") >= 0)
|
||||
return _sysName = "Mac";
|
||||
if (sname.indexOf("nux") >= 0)
|
||||
return _sysName = "Linux";
|
||||
if (sname.indexOf("nix") >= 0)
|
||||
return _sysName = "BSD";
|
||||
|
||||
return _sysName = System.getProperty("os.name");
|
||||
}
|
||||
|
||||
public static function command(cmd:String, ?args:Array<String>):Int {
|
||||
var pb = Process.createProcessBuilder(cmd, args);
|
||||
#if java6
|
||||
pb.redirectErrorStream(true);
|
||||
#else
|
||||
pb.redirectOutput(java.lang.ProcessBuilder.ProcessBuilder_Redirect.INHERIT);
|
||||
pb.redirectError(java.lang.ProcessBuilder.ProcessBuilder_Redirect.INHERIT);
|
||||
#end
|
||||
var proc = pb.start();
|
||||
#if java6
|
||||
var reader = new java.io.NativeInput(proc.getInputStream());
|
||||
try {
|
||||
while (true) {
|
||||
var ln = reader.readLine();
|
||||
Sys.println(ln);
|
||||
}
|
||||
} catch (e:haxe.io.Eof) {}
|
||||
#end
|
||||
proc.waitFor();
|
||||
var exitCode = proc.exitValue();
|
||||
proc.destroy();
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public static function exit(code:Int):Void {
|
||||
System.exit(code);
|
||||
}
|
||||
|
||||
public static function time():Float {
|
||||
return cast(System.currentTimeMillis(), Float) / 1000;
|
||||
}
|
||||
|
||||
public static function cpuTime():Float {
|
||||
return cast(System.nanoTime(), Float) / 1000000000;
|
||||
}
|
||||
|
||||
@:deprecated("Use programPath instead") public static function executablePath():String {
|
||||
return getCwd();
|
||||
}
|
||||
|
||||
public static function programPath():String {
|
||||
return java.Lib.toNativeType(Sys).getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
|
||||
}
|
||||
|
||||
public static function getChar(echo:Bool):Int {
|
||||
// TODO
|
||||
return throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
public static function stdin():haxe.io.Input {
|
||||
var _in:java.io.InputStream = Reflect.field(System, "in");
|
||||
return new java.io.NativeInput(_in);
|
||||
}
|
||||
|
||||
public static function stdout():haxe.io.Output {
|
||||
return new java.io.NativeOutput(System.out);
|
||||
}
|
||||
|
||||
public static function stderr():haxe.io.Output {
|
||||
return new java.io.NativeOutput(System.err);
|
||||
}
|
||||
}
|
370
Kha/Tools/macos/std/java/_std/Type.hx
Normal file
370
Kha/Tools/macos/std/java/_std/Type.hx
Normal file
@ -0,0 +1,370 @@
|
||||
/*
|
||||
* 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 java.internal.HxObject;
|
||||
|
||||
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 (o == null || Std.isOfType(o, DynamicObject) || Std.isOfType(o, java.lang.Class)) {
|
||||
return null;
|
||||
}
|
||||
return cast java.Lib.getNativeType(o);
|
||||
}
|
||||
|
||||
public static function getEnum(o:EnumValue):Enum<Dynamic> {
|
||||
if (Std.isOfType(o, java.lang.Enum) || Std.isOfType(o, HxEnum)) {
|
||||
return untyped o.getClass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic> {
|
||||
var c = java.Lib.toNativeType(c);
|
||||
var cl:java.lang.Class<Dynamic> = c == null ? null : untyped c.getSuperclass();
|
||||
if (cl != null && cl.getName() != "haxe.lang.HxObject" && cl.getName() != "java.lang.Object") {
|
||||
return cast cl;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getClassName(c:Class<Dynamic>):String {
|
||||
var c:java.lang.Class<Dynamic> = cast c;
|
||||
var name:String = c.getName();
|
||||
if (name.startsWith("haxe.root."))
|
||||
return name.substr(10);
|
||||
if (name.startsWith("java.lang"))
|
||||
name = name.substr(10);
|
||||
|
||||
return switch (name) {
|
||||
case "int", "Integer": "Int";
|
||||
case "double", "Double": "Float";
|
||||
case "Object": "Dynamic";
|
||||
default: name;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getEnumName(e:Enum<Dynamic>):String {
|
||||
var c:java.lang.Class<Dynamic> = cast e;
|
||||
var ret:String = c.getName();
|
||||
if (ret.startsWith("haxe.root."))
|
||||
return ret.substr(10);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static function resolveClass(name:String):Class<Dynamic> {
|
||||
try {
|
||||
if (name.indexOf(".") == -1) {
|
||||
name = "haxe.root." + name;
|
||||
}
|
||||
return cast java.lang.Class.forName(name);
|
||||
} catch (e:java.lang.ClassNotFoundException) {
|
||||
return untyped switch (name) {
|
||||
case "haxe.root.Int": Int;
|
||||
case "haxe.root.Float": Float;
|
||||
case "haxe.root.String": String;
|
||||
case "haxe.root.Math": java.lang.Math;
|
||||
case "haxe.root.Class": java.lang.Class;
|
||||
case "haxe.root.Dynamic": java.lang.Object;
|
||||
case _: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@:functionCode('
|
||||
if ("Bool".equals(name)) return boolean.class;
|
||||
Class r = resolveClass(name);
|
||||
if (r != null && (r.getSuperclass() == java.lang.Enum.class || haxe.lang.Enum.class.isAssignableFrom(r)))
|
||||
return r;
|
||||
return null;
|
||||
')
|
||||
public static function resolveEnum(name:String):Enum<Dynamic>
|
||||
untyped {
|
||||
if (name == "Bool")
|
||||
return Bool;
|
||||
return resolveClass(name);
|
||||
}
|
||||
|
||||
public static function createInstance<T>(cl:Class<T>, args:Array<Dynamic>):T {
|
||||
var nargs = args.length,
|
||||
callArguments = new java.NativeArray<Dynamic>(nargs);
|
||||
|
||||
var ctors = java.Lib.toNativeType(cl).getConstructors(),
|
||||
totalCtors = ctors.length,
|
||||
validCtors = 0;
|
||||
|
||||
for (i in 0...totalCtors) {
|
||||
var ctor = ctors[i];
|
||||
var ptypes = ctor.getParameterTypes();
|
||||
if (ptypes.length != nargs && !ctor.isVarArgs()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var argNum = -1, valid = true;
|
||||
for (arg in args) {
|
||||
argNum++;
|
||||
var expectedType = argNum < ptypes.length ? ptypes[argNum] : ptypes[ptypes.length - 1]; // varags
|
||||
var isDynamic = Std.isOfType(arg, DynamicObject) && expectedType.isAssignableFrom(java.Lib.getNativeType(arg));
|
||||
var argType = Type.getClass(arg);
|
||||
|
||||
if (arg == null || isDynamic || (argType != null && expectedType.isAssignableFrom(java.Lib.toNativeType(argType)))) {
|
||||
callArguments[argNum] = arg;
|
||||
} else if(expectedType.getName() == 'boolean' && (cast argType:java.lang.Class<Dynamic>).getName() == 'java.lang.Boolean') {
|
||||
callArguments[argNum] = (cast arg : java.lang.Boolean).booleanValue();
|
||||
} else if (Std.isOfType(arg, java.lang.Number)) {
|
||||
var name = expectedType.getName();
|
||||
switch (name) {
|
||||
case 'double' | 'java.lang.Double':
|
||||
callArguments[argNum] = (cast arg : java.lang.Number).doubleValue();
|
||||
case 'int' | 'java.lang.Integer':
|
||||
callArguments[argNum] = (cast arg : java.lang.Number).intValue();
|
||||
case 'float' | 'java.lang.Float':
|
||||
callArguments[argNum] = (cast arg : java.lang.Number).floatValue();
|
||||
case 'byte' | 'java.lang.Byte':
|
||||
callArguments[argNum] = (cast arg : java.lang.Number).byteValue();
|
||||
case 'short' | 'java.lang.Short':
|
||||
callArguments[argNum] = (cast arg : java.lang.Number).shortValue();
|
||||
case _:
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// the current constructor was found and it is valid - call it
|
||||
ctor.setAccessible(true);
|
||||
return cast ctor.newInstance(callArguments);
|
||||
}
|
||||
|
||||
throw 'Could not find any constructor that matches the provided arguments for class $cl';
|
||||
}
|
||||
|
||||
// cache empty constructor arguments so we don't allocate it on each createEmptyInstance call
|
||||
@:protected @:readOnly static var __createEmptyInstance_EMPTY_TYPES = java.NativeArray.make(java.Lib.toNativeEnum(java.internal.Runtime.EmptyObject));
|
||||
@:protected @:readOnly static var __createEmptyInstance_EMPTY_ARGS = java.NativeArray.make(java.internal.Runtime.EmptyObject.EMPTY);
|
||||
|
||||
public static function createEmptyInstance<T>(cl:Class<T>):T {
|
||||
var t = java.Lib.toNativeType(cl);
|
||||
try {
|
||||
var ctor = t.getConstructor(__createEmptyInstance_EMPTY_TYPES);
|
||||
return ctor.newInstance(__createEmptyInstance_EMPTY_ARGS);
|
||||
} catch (_:java.lang.NoSuchMethodException) {
|
||||
return t.newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
public static function createEnum<T>(e:Enum<T>, constr:String, ?params:Array<Dynamic>):T {
|
||||
if (params == null || params.length == 0) {
|
||||
var ret:Dynamic = java.internal.Runtime.slowGetField(e, constr, true);
|
||||
if (Std.isOfType(ret, java.internal.Function)) {
|
||||
throw "Constructor " + constr + " needs parameters";
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
var params = java.Lib.nativeArray(params, true);
|
||||
return java.internal.Runtime.slowCallField(e, constr, params);
|
||||
}
|
||||
}
|
||||
|
||||
public static function createEnumIndex<T>(e:Enum<T>, index:Int, ?params:Array<Dynamic>):T {
|
||||
var constr = getEnumConstructs(e);
|
||||
return createEnum(e, constr[index], params);
|
||||
}
|
||||
|
||||
@:functionCode('
|
||||
if (c == java.lang.String.class)
|
||||
{
|
||||
return haxe.lang.StringRefl.fields;
|
||||
}
|
||||
|
||||
Array<String> ret = new Array<String>();
|
||||
for (java.lang.reflect.Field f : c.getFields())
|
||||
{
|
||||
java.lang.String fname = f.getName();
|
||||
if (!java.lang.reflect.Modifier.isStatic(f.getModifiers()) && !fname.startsWith("__hx_"))
|
||||
ret.push(fname);
|
||||
}
|
||||
|
||||
for (java.lang.reflect.Method m : c.getMethods())
|
||||
{
|
||||
if (m.getDeclaringClass() == java.lang.Object.class)
|
||||
continue;
|
||||
java.lang.String mname = m.getName();
|
||||
if (!java.lang.reflect.Modifier.isStatic(m.getModifiers()) && !mname.startsWith("__hx_"))
|
||||
ret.push(mname);
|
||||
}
|
||||
|
||||
return ret;
|
||||
')
|
||||
public static function getInstanceFields(c:Class<Dynamic>):Array<String> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@:functionCode('
|
||||
Array<String> ret = new Array<String>();
|
||||
if (c == java.lang.String.class)
|
||||
{
|
||||
ret.push("fromCharCode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (java.lang.reflect.Field f : c.getDeclaredFields())
|
||||
{
|
||||
java.lang.String fname = f.getName();
|
||||
if (java.lang.reflect.Modifier.isStatic(f.getModifiers()) && !fname.startsWith("__hx_"))
|
||||
ret.push(fname);
|
||||
}
|
||||
|
||||
for (java.lang.reflect.Method m : c.getDeclaredMethods())
|
||||
{
|
||||
if (m.getDeclaringClass() == java.lang.Object.class)
|
||||
continue;
|
||||
java.lang.String mname = m.getName();
|
||||
if (java.lang.reflect.Modifier.isStatic(m.getModifiers()) && !mname.startsWith("__hx_"))
|
||||
ret.push(mname);
|
||||
}
|
||||
|
||||
return ret;
|
||||
')
|
||||
public static function getClassFields(c:Class<Dynamic>):Array<String> {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getEnumConstructs(e:Enum<Dynamic>):Array<String> {
|
||||
if (Reflect.hasField(e, "__hx_constructs")) {
|
||||
var ret:Array<String> = java.Lib.array(untyped e.__hx_constructs);
|
||||
return ret.copy();
|
||||
}
|
||||
var vals:java.NativeArray<java.lang.Enum<Dynamic>> = untyped e.values(),
|
||||
ret = [];
|
||||
for (i in 0...vals.length)
|
||||
ret[i] = vals[i].name();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@:functionCode('
|
||||
if (v == null) return ValueType.TNull;
|
||||
|
||||
if (v instanceof haxe.lang.IHxObject) {
|
||||
haxe.lang.IHxObject vobj = (haxe.lang.IHxObject) v;
|
||||
java.lang.Class cl = vobj.getClass();
|
||||
if (v instanceof haxe.lang.DynamicObject)
|
||||
return ValueType.TObject;
|
||||
else
|
||||
return ValueType.TClass(cl);
|
||||
} else if (v instanceof java.lang.Number) {
|
||||
java.lang.Number n = (java.lang.Number) v;
|
||||
if (n.intValue() == n.doubleValue())
|
||||
return ValueType.TInt;
|
||||
else
|
||||
return ValueType.TFloat;
|
||||
} else if (v instanceof haxe.lang.Function) {
|
||||
return ValueType.TFunction;
|
||||
} else if (v instanceof java.lang.Enum || v instanceof haxe.lang.Enum) {
|
||||
return ValueType.TEnum(v.getClass());
|
||||
} else if (v instanceof java.lang.Boolean) {
|
||||
return ValueType.TBool;
|
||||
} else if (v instanceof java.lang.Class) {
|
||||
return ValueType.TObject;
|
||||
} else {
|
||||
return ValueType.TClass(v.getClass());
|
||||
}
|
||||
')
|
||||
public static function typeof(v:Dynamic):ValueType
|
||||
untyped {
|
||||
return null;
|
||||
}
|
||||
|
||||
@:functionCode('
|
||||
if (a instanceof haxe.lang.Enum)
|
||||
return a.equals(b);
|
||||
else
|
||||
return haxe.lang.Runtime.eq(a, b);
|
||||
')
|
||||
public static function enumEq<T>(a:T, b:T):Bool
|
||||
untyped {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
@:functionCode('
|
||||
if (e instanceof java.lang.Enum)
|
||||
return ((java.lang.Enum) e).name();
|
||||
else
|
||||
return ((haxe.lang.Enum) e).getTag();
|
||||
')
|
||||
public static function enumConstructor(e:EnumValue):String
|
||||
untyped {
|
||||
return null;
|
||||
}
|
||||
|
||||
@:functionCode('
|
||||
return ( e instanceof java.lang.Enum ) ? new haxe.root.Array() : ((haxe.lang.Enum) e).getParams();
|
||||
')
|
||||
public static function enumParameters(e:EnumValue):Array<Dynamic>
|
||||
untyped {
|
||||
return null;
|
||||
}
|
||||
|
||||
@:ifFeature("has_enum")
|
||||
@:functionCode('
|
||||
if (e instanceof java.lang.Enum)
|
||||
return ((java.lang.Enum) e).ordinal();
|
||||
else
|
||||
return ((haxe.lang.Enum) e).index;
|
||||
')
|
||||
public static function enumIndex(e:EnumValue):Int
|
||||
untyped {
|
||||
return e.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;
|
||||
}
|
||||
}
|
112
Kha/Tools/macos/std/java/_std/haxe/Exception.hx
Normal file
112
Kha/Tools/macos/std/java/_std/haxe/Exception.hx
Normal file
@ -0,0 +1,112 @@
|
||||
package haxe;
|
||||
|
||||
import java.NativeArray;
|
||||
import java.lang.Throwable;
|
||||
import java.lang.RuntimeException;
|
||||
import java.lang.StackTraceElement;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
@: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 __nativeException:Throwable;
|
||||
@:noCompletion var __previousException:Null<Exception>;
|
||||
|
||||
static function caught(value:Any):Exception {
|
||||
if(Std.isOfType(value, Exception)) {
|
||||
return value;
|
||||
} else if(Std.isOfType(value, Throwable)) {
|
||||
return new Exception((value:Throwable).getMessage(), null, value);
|
||||
} else {
|
||||
return new ValueException(value, null, value);
|
||||
}
|
||||
}
|
||||
|
||||
static function thrown(value:Any):Any {
|
||||
if(Std.isOfType(value, Exception)) {
|
||||
var native = (value:Exception).__nativeException;
|
||||
return Std.isOfType(native, RuntimeException) ? native : value;
|
||||
} else if(Std.isOfType(value, RuntimeException)) {
|
||||
return value;
|
||||
} else if(Std.isOfType(value, Throwable)) {
|
||||
return new Exception((value:Throwable).getMessage(), null, value);
|
||||
} else {
|
||||
var e = new ValueException(value);
|
||||
var stack = e.getStackTrace();
|
||||
if(stack.length > 1) {
|
||||
e.setStackTrace(java.util.Arrays.copyOfRange(stack, 1, stack.length));
|
||||
}
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
public function new(message:String, ?previous:Exception, ?native:Any) {
|
||||
super(message, cast previous);
|
||||
__previousException = previous;
|
||||
if(native != null && Std.isOfType(native, Throwable)) {
|
||||
__nativeException = native;
|
||||
setStackTrace(__nativeException.getStackTrace());
|
||||
} else {
|
||||
__nativeException = cast this;
|
||||
}
|
||||
}
|
||||
|
||||
function unwrap():Any {
|
||||
return __nativeException;
|
||||
}
|
||||
|
||||
override public function toString():String {
|
||||
return message;
|
||||
}
|
||||
|
||||
public function details():String {
|
||||
return inline CallStack.exceptionToString(this);
|
||||
}
|
||||
|
||||
function get_message():String {
|
||||
return this.getMessage();
|
||||
}
|
||||
|
||||
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(__nativeException.getStackTrace());
|
||||
case s: s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@:dox(hide)
|
||||
@:noCompletion
|
||||
@:native('java.lang.RuntimeException')
|
||||
private extern class NativeException {
|
||||
@:noCompletion private function new(?message:String, ?cause:Throwable):Void;
|
||||
|
||||
@:noCompletion @:skipReflection private function addSuppressed (param1:Throwable):Void;
|
||||
@:noCompletion @:skipReflection private function fillInStackTrace ():Throwable;
|
||||
@:noCompletion @:skipReflection private function getCause ():Throwable;
|
||||
@:noCompletion @:skipReflection private function getLocalizedMessage ():String;
|
||||
@:noCompletion @:skipReflection private function getMessage ():String;
|
||||
@:noCompletion @:skipReflection private function getStackTrace ():NativeArray<StackTraceElement>;
|
||||
@:noCompletion @:skipReflection private function getSuppressed ():NativeArray<Throwable>;
|
||||
@:noCompletion @:skipReflection private function initCause (param1:Throwable):Throwable;
|
||||
@:noCompletion @:skipReflection @:overload private function printStackTrace (param1:PrintWriter):Void;
|
||||
@:noCompletion @:skipReflection @:overload private function printStackTrace ():Void;
|
||||
@:noCompletion @:skipReflection @:overload private function printStackTrace (param1:PrintStream):Void;
|
||||
@:noCompletion @:skipReflection private function setStackTrace (param1:NativeArray<StackTraceElement>):Void;
|
||||
@:noCompletion @:skipReflection private function toString ():String;
|
||||
}
|
247
Kha/Tools/macos/std/java/_std/haxe/Int64.hx
Normal file
247
Kha/Tools/macos/std/java/_std/haxe/Int64.hx
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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 = java.StdTypes.Int64;
|
||||
|
||||
@:coreApi
|
||||
@:transitive
|
||||
abstract Int64(__Int64) from __Int64 to __Int64 {
|
||||
#if jvm
|
||||
extern public static function make(high:Int32, low:Int32):Int64;
|
||||
#else
|
||||
public static inline function make(high:Int32, low:Int32):Int64
|
||||
return new Int64(((cast high : __Int64) << 32) | ((cast low : __Int64) & (untyped __java__('0xffffffffL') : Int64)));
|
||||
#end
|
||||
|
||||
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;
|
||||
|
||||
@:deprecated('haxe.Int64.is() is deprecated. Use haxe.Int64.isInt64() instead')
|
||||
inline public static function is(val:Dynamic):Bool
|
||||
return Std.isOfType(val, java.lang.Long.LongClass);
|
||||
|
||||
inline public static function isInt64(val:Dynamic):Bool
|
||||
return Std.isOfType(val, java.lang.Long.LongClass);
|
||||
|
||||
public static inline function toInt(x:Int64):Int {
|
||||
if (x.val < 0x80000000 || x.val > 0x7FFFFFFF)
|
||||
throw "Overflow";
|
||||
return cast x.val;
|
||||
}
|
||||
|
||||
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 {
|
||||
// can this be done?: return new Int64( java.lang.Long.LongClass.parseLong( sParam ) );
|
||||
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 a.val >>> b;
|
||||
}
|
55
Kha/Tools/macos/std/java/_std/haxe/NativeStackTrace.hx
Normal file
55
Kha/Tools/macos/std/java/_std/haxe/NativeStackTrace.hx
Normal file
@ -0,0 +1,55 @@
|
||||
package haxe;
|
||||
|
||||
import java.NativeArray;
|
||||
import java.lang.ThreadLocal;
|
||||
import java.lang.Throwable;
|
||||
import java.lang.Thread;
|
||||
import java.lang.StackTraceElement;
|
||||
import haxe.CallStack.StackItem;
|
||||
|
||||
/**
|
||||
Do not use manually.
|
||||
**/
|
||||
@:dox(hide)
|
||||
@:noCompletion
|
||||
class NativeStackTrace {
|
||||
static var exception = new ThreadLocal<Throwable>();
|
||||
|
||||
@:ifFeature('haxe.NativeStackTrace.exceptionStack')
|
||||
static public inline function saveStack(e:Throwable):Void {
|
||||
exception.set(e);
|
||||
}
|
||||
|
||||
static public function callStack():NativeArray<StackTraceElement> {
|
||||
var stack = Thread.currentThread().getStackTrace();
|
||||
return stack.length <= 3 ? stack : java.util.Arrays.copyOfRange(stack, 3, stack.length);
|
||||
}
|
||||
|
||||
static public function exceptionStack():NativeArray<StackTraceElement> {
|
||||
return switch exception.get() {
|
||||
case null: new NativeArray(0);
|
||||
case e: e.getStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
static public function toHaxe(native:NativeArray<StackTraceElement>, skip:Int = 0):Array<StackItem> {
|
||||
var stack = [];
|
||||
for (i in 0...native.length) {
|
||||
if(skip > i) {
|
||||
continue;
|
||||
}
|
||||
var el = native[i];
|
||||
var className = el.getClassName();
|
||||
var methodName = el.getMethodName();
|
||||
var fileName = el.getFileName();
|
||||
var lineNumber = el.getLineNumber();
|
||||
var method = Method(className, methodName);
|
||||
if (fileName != null || lineNumber >= 0) {
|
||||
stack.push(FilePos(method, fileName, lineNumber));
|
||||
} else {
|
||||
stack.push(method);
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
}
|
51
Kha/Tools/macos/std/java/_std/haxe/Resource.hx
Normal file
51
Kha/Tools/macos/std/java/_std/haxe/Resource.hx
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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>;
|
||||
|
||||
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 stream = cast(Resource, java.lang.Class<Dynamic>).getResourceAsStream("/" + name);
|
||||
if (stream == null)
|
||||
return null;
|
||||
var stream = new java.io.NativeInput(stream);
|
||||
return stream.readAll().toString();
|
||||
}
|
||||
|
||||
@:access(haxe.io.Path.escape)
|
||||
public static function getBytes(name:String):haxe.io.Bytes {
|
||||
name = haxe.io.Path.escape(name, true);
|
||||
var stream = cast(Resource, java.lang.Class<Dynamic>).getResourceAsStream("/" + name);
|
||||
if (stream == null)
|
||||
return null;
|
||||
var stream = new java.io.NativeInput(stream);
|
||||
return stream.readAll();
|
||||
}
|
||||
}
|
64
Kha/Tools/macos/std/java/_std/haxe/Rest.hx
Normal file
64
Kha/Tools/macos/std/java/_std/haxe/Rest.hx
Normal file
@ -0,0 +1,64 @@
|
||||
package haxe;
|
||||
|
||||
import haxe.iterators.RestIterator;
|
||||
import haxe.iterators.RestKeyValueIterator;
|
||||
import java.NativeArray;
|
||||
import java.lang.System;
|
||||
import java.lang.Object;
|
||||
import java.util.Arrays;
|
||||
|
||||
private typedef NativeRest<T> = NativeArray<Object>;
|
||||
|
||||
@:coreApi
|
||||
abstract Rest<T>(NativeRest<T>) {
|
||||
public var length(get,never):Int;
|
||||
inline function get_length():Int
|
||||
return this.length;
|
||||
|
||||
@:from static public function of<T>(array:Array<T>):Rest<T> {
|
||||
var native = @:privateAccess array.__a;
|
||||
var result:NativeRest<T>;
|
||||
#if jvm
|
||||
result = (cast native:Object).clone();
|
||||
#else
|
||||
result = new NativeRest<T>(native.length);
|
||||
for(i in 0...native.length)
|
||||
result[i] = cast native[i];
|
||||
#end
|
||||
return new Rest(result);
|
||||
}
|
||||
|
||||
inline function new(a:NativeRest<T>):Void
|
||||
this = a;
|
||||
|
||||
@:arrayAccess inline function get(index:Int):T
|
||||
return cast this[index];
|
||||
|
||||
@:to public function toArray():Array<T> {
|
||||
return [for(i in 0...this.length) cast this[i]];
|
||||
}
|
||||
|
||||
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<T>(this.length + 1);
|
||||
System.arraycopy(this, 0, result, 0, this.length);
|
||||
result[this.length] = cast item;
|
||||
return new Rest(result);
|
||||
}
|
||||
|
||||
public function prepend(item:T):Rest<T> {
|
||||
var result = new NativeRest<T>(this.length + 1);
|
||||
System.arraycopy(this, 0, result, 1, this.length);
|
||||
result[0] = cast item;
|
||||
return new Rest(result);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return toArray().toString();
|
||||
}
|
||||
}
|
42
Kha/Tools/macos/std/java/_std/haxe/crypto/Md5.hx
Normal file
42
Kha/Tools/macos/std/java/_std/haxe/crypto/Md5.hx
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.crypto;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import haxe.io.BytesData;
|
||||
import java.security.MessageDigest;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@:coreApi
|
||||
class Md5 {
|
||||
public static function encode(s:String):String {
|
||||
return Bytes.ofData(digest((cast s : java.NativeString).getBytes(StandardCharsets.UTF_8))).toHex();
|
||||
}
|
||||
|
||||
public static function make(b:haxe.io.Bytes):haxe.io.Bytes {
|
||||
return Bytes.ofData(digest(b.getData()));
|
||||
}
|
||||
|
||||
inline static function digest(b:BytesData):BytesData {
|
||||
return MessageDigest.getInstance("MD5").digest(b);
|
||||
}
|
||||
}
|
42
Kha/Tools/macos/std/java/_std/haxe/crypto/Sha1.hx
Normal file
42
Kha/Tools/macos/std/java/_std/haxe/crypto/Sha1.hx
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.crypto;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import haxe.io.BytesData;
|
||||
import java.security.MessageDigest;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@:coreApi
|
||||
class Sha1 {
|
||||
public static function encode(s:String):String {
|
||||
return Bytes.ofData(digest((cast s : java.NativeString).getBytes(StandardCharsets.UTF_8))).toHex();
|
||||
}
|
||||
|
||||
public static function make(b:haxe.io.Bytes):haxe.io.Bytes {
|
||||
return Bytes.ofData(digest(b.getData()));
|
||||
}
|
||||
|
||||
inline static function digest(b:BytesData):BytesData {
|
||||
return MessageDigest.getInstance("SHA-1").digest(b);
|
||||
}
|
||||
}
|
42
Kha/Tools/macos/std/java/_std/haxe/crypto/Sha256.hx
Normal file
42
Kha/Tools/macos/std/java/_std/haxe/crypto/Sha256.hx
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.crypto;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import haxe.io.BytesData;
|
||||
import java.security.MessageDigest;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@:coreApi
|
||||
class Sha256 {
|
||||
public static function encode(s:String):String {
|
||||
return Bytes.ofData(digest((cast s : java.NativeString).getBytes(StandardCharsets.UTF_8))).toHex();
|
||||
}
|
||||
|
||||
public static function make(b:haxe.io.Bytes):haxe.io.Bytes {
|
||||
return Bytes.ofData(digest(b.getData()));
|
||||
}
|
||||
|
||||
inline static function digest(b:BytesData):BytesData {
|
||||
return MessageDigest.getInstance("SHA-256").digest(b);
|
||||
}
|
||||
}
|
523
Kha/Tools/macos/std/java/_std/haxe/ds/IntMap.hx
Normal file
523
Kha/Tools/macos/std/java/_std/haxe/ds/IntMap.hx
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
* 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 java.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;
|
||||
}
|
||||
}
|
||||
|
||||
private final 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;
|
||||
}
|
||||
}
|
||||
|
||||
private 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 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();
|
||||
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:Dynamic, sourceIndex:Int, destinationArray:Dynamic, destinationIndex:Int, length:Int):Void
|
||||
java.lang.System.arraycopy(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++];
|
||||
}
|
||||
}
|
538
Kha/Tools/macos/std/java/_std/haxe/ds/ObjectMap.hx
Normal file
538
Kha/Tools/macos/std/java/_std/haxe/ds/ObjectMap.hx
Normal file
@ -0,0 +1,538 @@
|
||||
/*
|
||||
* 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 java.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 && (cast keys[i] : java.lang.Object).equals(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 || !((cast keys[i] : java.lang.Object).equals(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;
|
||||
}
|
||||
|
||||
@:private 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 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();
|
||||
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(s:Dynamic):HashType {
|
||||
var k:Int = (cast s : java.lang.Object).hashCode();
|
||||
// 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:Dynamic, sourceIndex:Int, destinationArray:Dynamic, destinationIndex:Int, length:Int):Void
|
||||
java.lang.System.arraycopy(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;
|
533
Kha/Tools/macos/std/java/_std/haxe/ds/StringMap.hx
Normal file
533
Kha/Tools/macos/std/java/_std/haxe/ds/StringMap.hx
Normal file
@ -0,0 +1,533 @@
|
||||
/*
|
||||
* 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 java.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;
|
||||
}
|
||||
|
||||
@:private 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 */ {
|
||||
{
|
||||
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: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);
|
||||
}
|
||||
|
||||
@:runtime public inline function keyValueIterator():KeyValueIterator<String, T> {
|
||||
return new haxe.iterators.MapKeyValueIterator(this);
|
||||
}
|
||||
|
||||
public inline function iterator():Iterator<T> {
|
||||
return new StringMapValueIterator(this);
|
||||
}
|
||||
|
||||
public function copy():StringMap<T> {
|
||||
var copied = new StringMap();
|
||||
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 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(s:String):HashType {
|
||||
var k:Int = (cast s : java.NativeString).hashCode();
|
||||
// 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:Dynamic, sourceIndex:Int, destinationArray:Dynamic, destinationIndex:Int, length:Int):Void
|
||||
java.lang.System.arraycopy(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++];
|
||||
}
|
||||
}
|
582
Kha/Tools/macos/std/java/_std/haxe/ds/WeakMap.hx
Normal file
582
Kha/Tools/macos/std/java/_std/haxe/ds/WeakMap.hx
Normal file
@ -0,0 +1,582 @@
|
||||
/*
|
||||
* 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 java.NativeArray;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
|
||||
@:coreApi class WeakMap<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 entries:NativeArray<Entry<K, V>>;
|
||||
|
||||
// weak map specific
|
||||
private var queue:ReferenceQueue<K>;
|
||||
|
||||
private var nBuckets:Int;
|
||||
private var size:Int;
|
||||
private var nOccupied:Int;
|
||||
private var upperBound:Int;
|
||||
|
||||
#if !no_map_cache
|
||||
private var cachedEntry:Entry<K, V>;
|
||||
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
|
||||
queue = new ReferenceQueue();
|
||||
}
|
||||
|
||||
@:analyzer(ignore)
|
||||
private function cleanupRefs():Void {
|
||||
var x:Dynamic = null, nOccupied = nOccupied;
|
||||
while ((x = queue.poll()) != null) {
|
||||
// even if not found on hashtable (already removed), release value
|
||||
var x:Entry<K, V> = cast x;
|
||||
x.value = null;
|
||||
|
||||
// lookup index
|
||||
if (nOccupied != 0) {
|
||||
var mask = nBuckets - 1, hash = x.hash, nProbes = 0;
|
||||
var i = hash & mask;
|
||||
var last = i, flag;
|
||||
while (!isEmpty(flag = hashes[i]) && (isDel(flag) || flag != hash || entries[i] != x)) {
|
||||
i = (i + ++nProbes) & mask;
|
||||
}
|
||||
|
||||
if (entries[i] == x) {
|
||||
#if !no_map_cache
|
||||
if (cachedIndex == i) {
|
||||
cachedIndex = -1;
|
||||
cachedEntry = null;
|
||||
}
|
||||
#end
|
||||
entries[i] = null;
|
||||
hashes[i] = FLAG_DEL;
|
||||
--size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function set(key:K, value:V):Void {
|
||||
cleanupRefs();
|
||||
var x:Int, k:Int;
|
||||
if (nOccupied >= upperBound) {
|
||||
if (nBuckets > (size << 1))
|
||||
resize(nBuckets - 1); // clear "deleted" elements
|
||||
else
|
||||
resize(nBuckets + 2);
|
||||
}
|
||||
|
||||
k = hash(key);
|
||||
var hashes = hashes, entries = entries;
|
||||
{
|
||||
var mask = (nBuckets == 0) ? 0 : nBuckets - 1;
|
||||
var site = x = nBuckets;
|
||||
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 && entries[i].keyEquals(key)))) {
|
||||
if (delKey == -1 && isDel(flag))
|
||||
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], entry = new Entry(key, value, k, queue);
|
||||
if (isEmpty(flag)) {
|
||||
entries[x] = entry;
|
||||
hashes[x] = k;
|
||||
size++;
|
||||
nOccupied++;
|
||||
} else if (isDel(flag)) {
|
||||
entries[x] = entry;
|
||||
hashes[x] = k;
|
||||
size++;
|
||||
} else {
|
||||
assert(entries[x].keyEquals(key));
|
||||
entries[x] = entry;
|
||||
}
|
||||
|
||||
#if !no_map_cache
|
||||
cachedIndex = x;
|
||||
cachedEntry = entry;
|
||||
#end
|
||||
}
|
||||
|
||||
private final function lookup(key:K):Int {
|
||||
if (nBuckets != 0) {
|
||||
var hashes = hashes, entries = entries;
|
||||
|
||||
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 || !entries[i].keyEquals(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;
|
||||
}
|
||||
|
||||
@:private 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 e = new NativeArray(newNBuckets);
|
||||
if (entries != null)
|
||||
arrayCopy(entries, 0, e, 0, nBuckets);
|
||||
entries = e;
|
||||
} // otherwise shrink
|
||||
}
|
||||
}
|
||||
|
||||
if (j != 0) { // rehashing is required
|
||||
// resetting cache
|
||||
#if !no_map_cache
|
||||
cachedEntry = null;
|
||||
cachedIndex = -1;
|
||||
#end
|
||||
|
||||
j = -1;
|
||||
var nBuckets = nBuckets, entries = entries, hashes = hashes;
|
||||
|
||||
var newMask = newNBuckets - 1;
|
||||
while (++j < nBuckets) {
|
||||
var k;
|
||||
if (!isEither(k = hashes[j])) {
|
||||
var entry = entries[j];
|
||||
|
||||
entries[j] = 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 */ {
|
||||
{
|
||||
var tmp = entries[i];
|
||||
entries[i] = entry;
|
||||
entry = tmp;
|
||||
}
|
||||
|
||||
hashes[i] = FLAG_DEL; /* mark it as deleted in the old hash table */
|
||||
} else { /* write the element and jump out of the loop */
|
||||
entries[i] = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nBuckets > newNBuckets)
|
||||
/* shrink the hash table */ {
|
||||
{
|
||||
var e = new NativeArray(newNBuckets);
|
||||
arrayCopy(entries, 0, e, 0, newNBuckets);
|
||||
this.entries = e;
|
||||
}
|
||||
}
|
||||
|
||||
this.hashes = newHash;
|
||||
this.nBuckets = newNBuckets;
|
||||
this.nOccupied = size;
|
||||
this.upperBound = Std.int(newNBuckets * HASH_UPPER + .5);
|
||||
}
|
||||
}
|
||||
|
||||
public function get(key:K):Null<V> {
|
||||
cleanupRefs();
|
||||
var idx = -1;
|
||||
#if !no_map_cache
|
||||
if (cachedEntry != null && cachedEntry.keyEquals(key) && ((idx = cachedIndex) != -1)) {
|
||||
return cachedEntry.value;
|
||||
}
|
||||
#end
|
||||
|
||||
idx = lookup(key);
|
||||
if (idx != -1) {
|
||||
var entry = entries[idx];
|
||||
#if !no_map_cache
|
||||
cachedEntry = entry;
|
||||
cachedIndex = idx;
|
||||
#end
|
||||
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getDefault(key:K, def:V):V {
|
||||
cleanupRefs();
|
||||
var idx = -1;
|
||||
#if !no_map_cache
|
||||
if (cachedEntry != null && cachedEntry.keyEquals(key) && ((idx = cachedIndex) != -1)) {
|
||||
return cachedEntry.value;
|
||||
}
|
||||
#end
|
||||
|
||||
idx = lookup(key);
|
||||
if (idx != -1) {
|
||||
var entry = entries[idx];
|
||||
#if !no_map_cache
|
||||
cachedEntry = entry;
|
||||
cachedIndex = idx;
|
||||
#end
|
||||
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
public function exists(key:K):Bool {
|
||||
cleanupRefs();
|
||||
var idx = -1;
|
||||
#if !no_map_cache
|
||||
if (cachedEntry != null && cachedEntry.keyEquals(key) && ((idx = cachedIndex) != -1)) {
|
||||
return true;
|
||||
}
|
||||
#end
|
||||
|
||||
idx = lookup(key);
|
||||
if (idx != -1) {
|
||||
var entry = entries[idx];
|
||||
#if !no_map_cache
|
||||
cachedEntry = entry;
|
||||
cachedIndex = idx;
|
||||
#end
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function remove(key:K):Bool {
|
||||
cleanupRefs();
|
||||
var idx = -1;
|
||||
#if !no_map_cache
|
||||
if (!(cachedEntry != null && cachedEntry.keyEquals(key) && ((idx = cachedIndex) != -1)))
|
||||
#end
|
||||
{
|
||||
idx = lookup(key);
|
||||
}
|
||||
|
||||
if (idx == -1) {
|
||||
return false;
|
||||
} else {
|
||||
#if !no_map_cache
|
||||
if (cachedEntry != null && cachedEntry.keyEquals(key)) {
|
||||
cachedIndex = -1;
|
||||
cachedEntry = null;
|
||||
}
|
||||
#end
|
||||
|
||||
hashes[idx] = FLAG_DEL;
|
||||
entries[idx] = null;
|
||||
--size;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public inline function keys():Iterator<K> {
|
||||
cleanupRefs();
|
||||
return new WeakMapKeyIterator(this);
|
||||
}
|
||||
|
||||
public inline function iterator():Iterator<V> {
|
||||
cleanupRefs();
|
||||
return new WeakMapValueIterator(this);
|
||||
}
|
||||
|
||||
public inline function keyValueIterator():KeyValueIterator<K, V> {
|
||||
return new haxe.iterators.MapKeyValueIterator(this);
|
||||
}
|
||||
|
||||
public function copy():WeakMap<K, V> {
|
||||
var copied = new WeakMap();
|
||||
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;
|
||||
entries = null;
|
||||
queue = new ReferenceQueue();
|
||||
nBuckets = 0;
|
||||
size = 0;
|
||||
nOccupied = 0;
|
||||
upperBound = 0;
|
||||
#if !no_map_cache
|
||||
cachedEntry = 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(s:Dynamic):HashType {
|
||||
var k:Int = untyped s.hashCode();
|
||||
// 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:Dynamic, sourceIndex:Int, destinationArray:Dynamic, destinationIndex:Int, length:Int):Void
|
||||
java.lang.System.arraycopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length);
|
||||
|
||||
extern private static inline function assert(x:Bool):Void {
|
||||
#if DEBUG_HASHTBL
|
||||
if (!x)
|
||||
throw "assert failed";
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
private class Entry<K, V> extends WeakReference<K> {
|
||||
public var value:V;
|
||||
public var hash(default, null):Int;
|
||||
|
||||
public function new(key:K, value:V, hash:Int, queue:ReferenceQueue<K>) {
|
||||
super(key, queue);
|
||||
this.value = value;
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
final inline public function keyEquals(k:K):Bool {
|
||||
return k != null && untyped k.equals(get());
|
||||
}
|
||||
}
|
||||
|
||||
@:access(haxe.ds.WeakMap)
|
||||
private final class WeakMapKeyIterator<T:{}, V> {
|
||||
var m:WeakMap<T, V>;
|
||||
var i:Int;
|
||||
var len:Int;
|
||||
var lastKey:T;
|
||||
|
||||
public function new(m:WeakMap<T, V>) {
|
||||
this.i = 0;
|
||||
this.m = m;
|
||||
this.len = m.nBuckets;
|
||||
}
|
||||
|
||||
public function hasNext():Bool {
|
||||
for (j in i...len) {
|
||||
if (!WeakMap.isEither(m.hashes[j])) {
|
||||
var entry = m.entries[j], last = entry.get();
|
||||
if (last != null) {
|
||||
#if !no_map_cache
|
||||
m.cachedIndex = i;
|
||||
m.cachedEntry = entry;
|
||||
#end
|
||||
lastKey = last; // keep a strong reference to the key while iterating, so it doesn't get collected
|
||||
i = j;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
lastKey = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function next():T {
|
||||
i = i + 1;
|
||||
return lastKey;
|
||||
}
|
||||
}
|
||||
|
||||
@:access(haxe.ds.WeakMap)
|
||||
private final class WeakMapValueIterator<K:{}, T> {
|
||||
var m:WeakMap<K, T>;
|
||||
var i:Int;
|
||||
var len:Int;
|
||||
|
||||
public function new(m:WeakMap<K, T>) {
|
||||
this.i = 0;
|
||||
this.m = m;
|
||||
this.len = m.nBuckets;
|
||||
}
|
||||
|
||||
public function hasNext():Bool {
|
||||
for (j in i...len) {
|
||||
if (!WeakMap.isEither(m.hashes[j]) && m.entries[j].get() != null) {
|
||||
i = j;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public inline function next():T {
|
||||
var ret = m.entries[i];
|
||||
i = i + 1;
|
||||
return ret.value;
|
||||
}
|
||||
}
|
||||
|
||||
private typedef HashType = Int;
|
82
Kha/Tools/macos/std/java/_std/haxe/zip/Compress.hx
Normal file
82
Kha/Tools/macos/std/java/_std/haxe/zip/Compress.hx
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.zip;
|
||||
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
class Compress {
|
||||
var deflater:Deflater;
|
||||
var mode:Int;
|
||||
var finish:Bool = false;
|
||||
|
||||
public function new(level:Int) {
|
||||
throw new haxe.exceptions.NotImplementedException("Not implemented for this platform"); // FIXME: Add unit tests for Compress/Uncompress and check current implementation
|
||||
this.deflater = new Deflater(level);
|
||||
this.mode = Deflater.NO_FLUSH;
|
||||
}
|
||||
|
||||
public function execute(src:haxe.io.Bytes, srcPos:Int, dst:haxe.io.Bytes, dstPos:Int):{done:Bool, read:Int, write:Int} {
|
||||
deflater.setInput(src.getData(), srcPos, src.length - srcPos);
|
||||
if (finish)
|
||||
deflater.finish();
|
||||
finish = false;
|
||||
|
||||
var written = deflater.deflate(dst.getData(), dstPos, dst.length - dstPos);
|
||||
var read = deflater.getTotalIn();
|
||||
return {done: deflater.finished(), read: read, write: written};
|
||||
}
|
||||
|
||||
public function setFlushMode(f:FlushMode) {
|
||||
this.mode = switch (f) {
|
||||
case NO:
|
||||
Deflater.NO_FLUSH;
|
||||
case SYNC:
|
||||
Deflater.SYNC_FLUSH;
|
||||
case FULL:
|
||||
Deflater.FULL_FLUSH;
|
||||
case FINISH:
|
||||
this.finish = true;
|
||||
Deflater.FULL_FLUSH;
|
||||
case BLOCK:
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public function close() {
|
||||
deflater.end();
|
||||
}
|
||||
|
||||
public static function run(s:haxe.io.Bytes, level:Int):haxe.io.Bytes {
|
||||
var deflater = new java.util.zip.Deflater(level);
|
||||
deflater.setInput(s.getData());
|
||||
var outputStream = new java.io.ByteArrayOutputStream(s.length);
|
||||
deflater.finish();
|
||||
var buffer = haxe.io.Bytes.alloc(1024).getData();
|
||||
while (!deflater.finished()) {
|
||||
var count = deflater.deflate(buffer);
|
||||
outputStream.write(buffer, 0, count);
|
||||
}
|
||||
outputStream.close();
|
||||
return haxe.io.Bytes.ofData(outputStream.toByteArray());
|
||||
}
|
||||
}
|
64
Kha/Tools/macos/std/java/_std/haxe/zip/Uncompress.hx
Normal file
64
Kha/Tools/macos/std/java/_std/haxe/zip/Uncompress.hx
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.zip;
|
||||
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
class Uncompress {
|
||||
final inflater:Inflater;
|
||||
|
||||
public function new(?windowBits:Int) {
|
||||
inflater = new Inflater(windowBits != null && windowBits < 0);
|
||||
}
|
||||
|
||||
public function execute(src:haxe.io.Bytes, srcPos:Int, dst:haxe.io.Bytes, dstPos:Int):{done:Bool, read:Int, write:Int} {
|
||||
inflater.setInput(src.getData(), srcPos, src.length - srcPos);
|
||||
inflater.inflate(dst.getData(), dstPos, dst.length - dstPos);
|
||||
return {
|
||||
done: inflater.finished(),
|
||||
read: Int64.toInt(inflater.getBytesRead()),
|
||||
write: Int64.toInt(inflater.getBytesWritten())
|
||||
};
|
||||
}
|
||||
|
||||
public function setFlushMode(f:FlushMode) {}
|
||||
|
||||
public function close() {
|
||||
inflater.end();
|
||||
}
|
||||
|
||||
public static function run(src:haxe.io.Bytes, ?bufsize:Int):haxe.io.Bytes {
|
||||
var decompresser = new java.util.zip.Inflater();
|
||||
var buf = haxe.io.Bytes.alloc(bufsize == null ? src.length : bufsize).getData();
|
||||
|
||||
var out = new java.io.ByteArrayOutputStream(src.length);
|
||||
decompresser.setInput(src.getData(), 0, src.length);
|
||||
|
||||
while (!decompresser.finished()) {
|
||||
var count = decompresser.inflate(buf);
|
||||
out.write(buf, 0, count);
|
||||
}
|
||||
out.close();
|
||||
return haxe.io.Bytes.ofData(out.toByteArray());
|
||||
}
|
||||
}
|
102
Kha/Tools/macos/std/java/_std/sys/FileSystem.hx
Normal file
102
Kha/Tools/macos/std/java/_std/sys/FileSystem.hx
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 java.io.File;
|
||||
import java.Lib;
|
||||
|
||||
@:coreApi
|
||||
class FileSystem {
|
||||
public static function exists(path:String):Bool {
|
||||
return new File(path).exists();
|
||||
}
|
||||
|
||||
public static function rename(path:String, newPath:String):Void {
|
||||
if (!new File(path).renameTo(new File(newPath))) {
|
||||
throw "Cannot rename " + path + " to " + newPath;
|
||||
}
|
||||
}
|
||||
|
||||
public static function stat(path:String):FileStat {
|
||||
var f = new File(path);
|
||||
if (!f.exists())
|
||||
throw "Path " + path + " doesn't exist";
|
||||
return {
|
||||
gid: 0, // java doesn't let you get this info
|
||||
uid: 0, // same
|
||||
atime: Date.now(), // same
|
||||
mtime: Date.fromTime(cast(f.lastModified(), Float)),
|
||||
ctime: Date.fromTime(cast(f.lastModified(), Float)), // same
|
||||
size: cast(f.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
|
||||
};
|
||||
}
|
||||
|
||||
public static function fullPath(relPath:String):String {
|
||||
try {
|
||||
return new File(relPath).getCanonicalPath();
|
||||
} catch (e:java.io.IOException) {
|
||||
throw new java.lang.RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
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 f = new File(path);
|
||||
if (!f.exists())
|
||||
throw "Path " + path + " doesn't exist";
|
||||
return f.isDirectory();
|
||||
}
|
||||
|
||||
public static function createDirectory(path:String):Void {
|
||||
var f = new File(path);
|
||||
if (!f.isDirectory() && !f.mkdirs())
|
||||
throw "Cannot create dir " + path;
|
||||
}
|
||||
|
||||
public static function deleteFile(path:String):Void {
|
||||
if (!new File(path).delete())
|
||||
throw "Cannot delete file " + path;
|
||||
}
|
||||
|
||||
public static function deleteDirectory(path:String):Void {
|
||||
if (!new File(path).delete())
|
||||
throw "Cannot delete directory " + path;
|
||||
}
|
||||
|
||||
public static function readDirectory(path:String):Array<String> {
|
||||
var f = new File(path);
|
||||
if (!f.exists())
|
||||
throw "Path " + path + " doesn't exist";
|
||||
return Lib.array(f.list());
|
||||
}
|
||||
}
|
56
Kha/Tools/macos/std/java/_std/sys/db/Mysql.hx
Normal file
56
Kha/Tools/macos/std/java/_std/sys/db/Mysql.hx
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 Mysql {
|
||||
static var init = false;
|
||||
|
||||
public static function connect(params:{
|
||||
host:String,
|
||||
?port:Int,
|
||||
user:String,
|
||||
pass:String,
|
||||
?socket:String,
|
||||
?database:String
|
||||
}):sys.db.Connection {
|
||||
if (!init) {
|
||||
java.lang.Class.forName("com.mysql.jdbc.Driver");
|
||||
init = true;
|
||||
}
|
||||
var url = new StringBuf();
|
||||
url.add('jdbc:mysql:');
|
||||
if (params.socket != null) {
|
||||
url.add(params.socket);
|
||||
} else {
|
||||
url.add('//');
|
||||
url.add(params.host);
|
||||
if (params.port != null)
|
||||
url.add(':${params.port}');
|
||||
}
|
||||
if (params.database != null) {
|
||||
url.add('/${params.database}');
|
||||
}
|
||||
var cnx = java.sql.DriverManager.getConnection(url.toString(), params.user, params.pass);
|
||||
return java.db.Jdbc.create(cnx);
|
||||
}
|
||||
}
|
42
Kha/Tools/macos/std/java/_std/sys/db/Sqlite.hx
Normal file
42
Kha/Tools/macos/std/java/_std/sys/db/Sqlite.hx
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 init = false;
|
||||
|
||||
public static function open(file:String):sys.db.Connection {
|
||||
if (!init) {
|
||||
try
|
||||
java.lang.Class.forName("org.sqlite.JDBC")
|
||||
catch (e:Dynamic)
|
||||
throw e;
|
||||
init = true;
|
||||
}
|
||||
try {
|
||||
var cnx = java.sql.DriverManager.getConnection("jdbc:sqlite:" + file);
|
||||
return java.db.Jdbc.create(cnx);
|
||||
} catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
}
|
120
Kha/Tools/macos/std/java/_std/sys/io/File.hx
Normal file
120
Kha/Tools/macos/std/java/_std/sys/io/File.hx
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 {
|
||||
try {
|
||||
return @:privateAccess new FileInput(new java.io.RandomAccessFile(new java.io.File(path), "r"));
|
||||
} catch (e:Dynamic) {
|
||||
// swallow checked exceptions
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function write(path:String, binary:Bool = true):FileOutput {
|
||||
var f = new java.io.File(path);
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
|
||||
try {
|
||||
return @:privateAccess new FileOutput(new java.io.RandomAccessFile(f, "rw"));
|
||||
} catch (e:Dynamic) {
|
||||
// swallow checked exceptions
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function append(path:String, binary:Bool = true):FileOutput {
|
||||
var f = new java.io.File(path);
|
||||
|
||||
try {
|
||||
var ra = new java.io.RandomAccessFile(f, "rw");
|
||||
if (f.exists()) {
|
||||
ra.seek(f.length());
|
||||
}
|
||||
return @:privateAccess new FileOutput(ra);
|
||||
} catch (e:Dynamic) {
|
||||
// swallow checked exceptions
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function update(path:String, binary:Bool = true):FileOutput {
|
||||
var f = new java.io.File(path);
|
||||
|
||||
try {
|
||||
var ra = new java.io.RandomAccessFile(f, "rw");
|
||||
return @:privateAccess new FileOutput(ra);
|
||||
} catch (e:Dynamic) {
|
||||
// swallow checked exceptions
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function copy(srcPath:String, dstPath:String):Void {
|
||||
var r:FileInput = null;
|
||||
var w:FileOutput = null;
|
||||
try {
|
||||
r = read(srcPath);
|
||||
w = write(dstPath);
|
||||
w.writeInput(r);
|
||||
r.close();
|
||||
w.close();
|
||||
} catch (e:Dynamic) {
|
||||
if (r != null)
|
||||
r.close();
|
||||
if (w != null)
|
||||
w.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
111
Kha/Tools/macos/std/java/_std/sys/io/FileInput.hx
Normal file
111
Kha/Tools/macos/std/java/_std/sys/io/FileInput.hx
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.Int64;
|
||||
import haxe.io.Bytes;
|
||||
import haxe.io.Eof;
|
||||
import haxe.io.Input;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
class FileInput extends Input {
|
||||
var f:java.io.RandomAccessFile;
|
||||
var _eof:Bool;
|
||||
|
||||
function new(f) {
|
||||
this.f = f;
|
||||
this._eof = false;
|
||||
}
|
||||
|
||||
override public function close() {
|
||||
try
|
||||
f.close()
|
||||
catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
override public function readByte():Int {
|
||||
try {
|
||||
return f.readUnsignedByte();
|
||||
} catch (e:EOFException) {
|
||||
|
||||
_eof = true;
|
||||
throw new Eof();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
|
||||
override public function readBytes(s:Bytes, pos:Int, len:Int):Int {
|
||||
var ret = 0;
|
||||
try {
|
||||
ret = f.read(s.getData(), pos, len);
|
||||
} catch (e:EOFException) {
|
||||
|
||||
_eof = true;
|
||||
throw new Eof();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
_eof = true;
|
||||
throw new Eof();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public function seek(p:Int, pos:FileSeek):Void {
|
||||
_eof = false;
|
||||
try {
|
||||
switch (pos) {
|
||||
case SeekBegin:
|
||||
f.seek(cast p);
|
||||
case SeekCur:
|
||||
f.seek(haxe.Int64.add(f.getFilePointer(), cast(p, Int64)));
|
||||
case SeekEnd:
|
||||
f.seek(haxe.Int64.add(f.length(), cast p));
|
||||
}
|
||||
} catch (e:EOFException) {
|
||||
|
||||
_eof = true;
|
||||
throw new Eof();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
|
||||
public function tell():Int {
|
||||
try {
|
||||
return cast f.getFilePointer();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
|
||||
public inline function eof():Bool {
|
||||
return _eof;
|
||||
}
|
||||
}
|
94
Kha/Tools/macos/std/java/_std/sys/io/FileOutput.hx
Normal file
94
Kha/Tools/macos/std/java/_std/sys/io/FileOutput.hx
Normal 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 sys.io;
|
||||
|
||||
import haxe.io.Bytes;
|
||||
import haxe.io.Eof;
|
||||
import haxe.io.Output;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
class FileOutput extends Output {
|
||||
var f:java.io.RandomAccessFile;
|
||||
|
||||
function new(f) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
override public function close() {
|
||||
try
|
||||
f.close()
|
||||
catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
override public function writeByte(c:Int):Void {
|
||||
try {
|
||||
this.f.write(c);
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
|
||||
override public function write(s:Bytes):Void {
|
||||
try {
|
||||
this.f.write(s.getData());
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
|
||||
override public function writeBytes(s:Bytes, pos:Int, len:Int):Int {
|
||||
try {
|
||||
this.f.write(s.getData(), pos, len);
|
||||
return len;
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
|
||||
public function seek(p:Int, pos:FileSeek):Void {
|
||||
try {
|
||||
switch (pos) {
|
||||
case SeekBegin:
|
||||
f.seek(cast p);
|
||||
case SeekCur:
|
||||
f.seek(haxe.Int64.add(f.getFilePointer(), cast(p, haxe.Int64)));
|
||||
case SeekEnd:
|
||||
f.seek(haxe.Int64.add(f.length(), cast p));
|
||||
}
|
||||
} catch (e:EOFException) {
|
||||
throw new Eof();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
|
||||
public function tell():Int {
|
||||
try {
|
||||
return cast f.getFilePointer();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
}
|
176
Kha/Tools/macos/std/java/_std/sys/io/Process.hx
Normal file
176
Kha/Tools/macos/std/java/_std/sys/io/Process.hx
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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.SysTools;
|
||||
import haxe.io.Bytes;
|
||||
import haxe.io.BytesInput;
|
||||
import haxe.io.Eof;
|
||||
import java.io.IOException;
|
||||
import java.io.EOFException;
|
||||
import java.NativeArray;
|
||||
|
||||
@: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 proc:java.lang.Process;
|
||||
|
||||
@:allow(Sys)
|
||||
private static function createProcessBuilder(cmd:String, ?args:Array<String>):java.lang.ProcessBuilder {
|
||||
var sysName = Sys.systemName();
|
||||
var pargs;
|
||||
if (args == null) {
|
||||
var cmdStr = cmd;
|
||||
switch (sysName) {
|
||||
case "Windows":
|
||||
pargs = new NativeArray(3);
|
||||
pargs[0] = cmd = switch (Sys.getEnv("COMSPEC")) {
|
||||
case null: "cmd.exe";
|
||||
case var comspec: comspec;
|
||||
}
|
||||
pargs[1] = '/C';
|
||||
pargs[2] = '"$cmdStr"';
|
||||
case _:
|
||||
pargs = new NativeArray(3);
|
||||
pargs[0] = cmd = "/bin/sh";
|
||||
pargs[1] = "-c";
|
||||
pargs[2] = cmdStr;
|
||||
}
|
||||
} else {
|
||||
pargs = new NativeArray(args.length + 1);
|
||||
switch (sysName) {
|
||||
case "Windows":
|
||||
pargs[0] = SysTools.quoteWinArg(cmd, false);
|
||||
for (i in 0...args.length) {
|
||||
pargs[i + 1] = SysTools.quoteWinArg(args[i], false);
|
||||
}
|
||||
case _:
|
||||
pargs[0] = cmd;
|
||||
for (i in 0...args.length) {
|
||||
pargs[i + 1] = args[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new java.lang.ProcessBuilder(pargs);
|
||||
}
|
||||
|
||||
public function new(cmd:String, ?args:Array<String>, ?detached:Bool):Void {
|
||||
if (detached)
|
||||
throw "Detached process is not supported on this platform";
|
||||
var p = proc = createProcessBuilder(cmd, args).start();
|
||||
stderr = new ProcessInput(p.getErrorStream());
|
||||
stdout = new ProcessInput(p.getInputStream());
|
||||
stdin = new java.io.NativeOutput(p.getOutputStream());
|
||||
}
|
||||
|
||||
public function getPid():Int {
|
||||
if (Reflect.hasField(proc, "pid"))
|
||||
return Reflect.field(proc, "pid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function exitCode(block:Bool = true):Null<Int> {
|
||||
if (block == false) {
|
||||
try {
|
||||
return proc.exitValue();
|
||||
} catch (e:Dynamic) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
cast(stdout, ProcessInput).bufferContents();
|
||||
cast(stderr, ProcessInput).bufferContents();
|
||||
try {
|
||||
proc.waitFor();
|
||||
} catch (e:Dynamic) {
|
||||
throw e;
|
||||
}
|
||||
return proc.exitValue();
|
||||
}
|
||||
|
||||
public function close():Void {
|
||||
proc.destroy();
|
||||
}
|
||||
|
||||
public function kill():Void {
|
||||
proc.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
private class ProcessInput extends java.io.NativeInput {
|
||||
private var chained:BytesInput;
|
||||
|
||||
public function bufferContents():Void {
|
||||
if (chained != null)
|
||||
return;
|
||||
var b = this.readAll();
|
||||
chained = new BytesInput(b);
|
||||
}
|
||||
|
||||
override public function readByte():Int {
|
||||
if (chained != null)
|
||||
return chained.readByte();
|
||||
var ret = 0;
|
||||
try {
|
||||
ret = stream.read();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
if (ret == -1)
|
||||
throw new Eof();
|
||||
return ret;
|
||||
}
|
||||
|
||||
override public function readBytes(s:Bytes, pos:Int, len:Int):Int {
|
||||
if (chained != null)
|
||||
return chained.readBytes(s, pos, len);
|
||||
|
||||
var ret = -1;
|
||||
try {
|
||||
ret = stream.read(s.getData(), pos, len);
|
||||
} catch (e:EOFException) {
|
||||
|
||||
throw new Eof();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
throw new Eof();
|
||||
return ret;
|
||||
}
|
||||
|
||||
override public function close():Void {
|
||||
if (chained != null)
|
||||
chained.close();
|
||||
try {
|
||||
stream.close();
|
||||
} catch (e:IOException) {
|
||||
throw haxe.io.Error.Custom(e);
|
||||
}
|
||||
}
|
||||
}
|
58
Kha/Tools/macos/std/java/_std/sys/net/Host.hx
Normal file
58
Kha/Tools/macos/std/java/_std/sys/net/Host.hx
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 java.net.InetAddress;
|
||||
|
||||
class Host {
|
||||
public var host(default, null):String;
|
||||
public var ip(default, null):Int;
|
||||
|
||||
@:allow(sys.net) private var wrapped:InetAddress;
|
||||
|
||||
public function new(name:String):Void {
|
||||
host = name;
|
||||
try
|
||||
this.wrapped = InetAddress.getByName(name)
|
||||
catch (e:Dynamic)
|
||||
throw e;
|
||||
var rawIp = wrapped.getAddress();
|
||||
// network byte order assumed
|
||||
this.ip = cast(rawIp[3], Int) | (cast(rawIp[2], Int) << 8) | (cast(rawIp[1], Int) << 16) | (cast(rawIp[0], Int) << 24);
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return wrapped.getHostAddress();
|
||||
}
|
||||
|
||||
public function reverse():String {
|
||||
return wrapped.getHostName();
|
||||
}
|
||||
|
||||
public static function localhost():String {
|
||||
try {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
} catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
}
|
164
Kha/Tools/macos/std/java/_std/sys/net/Socket.hx
Normal file
164
Kha/Tools/macos/std/java/_std/sys/net/Socket.hx
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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 java.net.InetSocketAddress;
|
||||
|
||||
@:coreApi
|
||||
class Socket {
|
||||
public var input(default, null):haxe.io.Input;
|
||||
public var output(default, null):haxe.io.Output;
|
||||
|
||||
public var custom:Dynamic;
|
||||
|
||||
private var sock:java.net.Socket;
|
||||
private var server:java.net.ServerSocket;
|
||||
private var boundAddr:java.net.SocketAddress;
|
||||
|
||||
public function new():Void {
|
||||
create();
|
||||
}
|
||||
|
||||
private function create():Void {
|
||||
this.sock = new java.net.Socket();
|
||||
try {
|
||||
this.server = new java.net.ServerSocket();
|
||||
} catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
public function close():Void {
|
||||
try {
|
||||
if (sock != null)
|
||||
this.sock.close();
|
||||
if (server != null)
|
||||
this.server.close();
|
||||
} catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
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 {
|
||||
try {
|
||||
sock.connect(new InetSocketAddress(host.wrapped, port));
|
||||
this.output = new java.io.NativeOutput(sock.getOutputStream());
|
||||
this.input = new java.io.NativeInput(sock.getInputStream());
|
||||
} catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
public function listen(connections:Int):Void {
|
||||
if (boundAddr == null)
|
||||
throw "You must bind the Socket to an address!";
|
||||
try
|
||||
server.bind(boundAddr, connections)
|
||||
catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
public function shutdown(read:Bool, write:Bool):Void {
|
||||
try {
|
||||
if (read)
|
||||
sock.shutdownInput();
|
||||
if (write)
|
||||
sock.shutdownOutput();
|
||||
} catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
public function bind(host:Host, port:Int):Void {
|
||||
if (boundAddr != null) {
|
||||
if (server.isBound())
|
||||
throw "Already bound";
|
||||
}
|
||||
this.boundAddr = new java.net.InetSocketAddress(host.wrapped, port);
|
||||
}
|
||||
|
||||
public function accept():Socket {
|
||||
var ret = try server.accept() catch (e:Dynamic) throw e;
|
||||
|
||||
var s = new Socket();
|
||||
s.sock = ret;
|
||||
s.output = new java.io.NativeOutput(ret.getOutputStream());
|
||||
s.input = new java.io.NativeInput(ret.getInputStream());
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public function peer():{host:Host, port:Int} {
|
||||
var rem = sock.getInetAddress();
|
||||
if (rem == null)
|
||||
return null;
|
||||
|
||||
var host = new Host(null);
|
||||
host.wrapped = rem;
|
||||
return {host: host, port: sock.getPort()};
|
||||
}
|
||||
|
||||
public function host():{host:Host, port:Int} {
|
||||
var local = sock.getLocalAddress();
|
||||
var host = new Host(null);
|
||||
host.wrapped = local;
|
||||
|
||||
if (boundAddr != null) {
|
||||
return {host: host, port: server.getLocalPort()};
|
||||
}
|
||||
|
||||
return {host: host, port: sock.getLocalPort()};
|
||||
}
|
||||
|
||||
public function setTimeout(timeout:Float):Void {
|
||||
try
|
||||
sock.setSoTimeout(Std.int(timeout * 1000))
|
||||
catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
public function waitForRead():Void {
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
public function setBlocking(b:Bool):Void {
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
public function setFastSend(b:Bool):Void {
|
||||
try
|
||||
sock.setTcpNoDelay(b)
|
||||
catch (e:Dynamic)
|
||||
throw e;
|
||||
}
|
||||
|
||||
public static function select(read:Array<Socket>, write:Array<Socket>, others:Array<Socket>,
|
||||
?timeout:Float):{read:Array<Socket>, write:Array<Socket>, others:Array<Socket>} {
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
return null;
|
||||
}
|
||||
}
|
51
Kha/Tools/macos/std/java/_std/sys/thread/Deque.hx
Normal file
51
Kha/Tools/macos/std/java/_std/sys/thread/Deque.hx
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 java.Lib;
|
||||
|
||||
@:coreApi
|
||||
@:native('haxe.java.vm.Deque')
|
||||
@:nativeGen class Deque<T> {
|
||||
var lbd:java.util.concurrent.LinkedBlockingDeque<T>;
|
||||
|
||||
public function new() {
|
||||
lbd = new java.util.concurrent.LinkedBlockingDeque<T>();
|
||||
}
|
||||
|
||||
public function add(i:T):Void {
|
||||
lbd.add(i);
|
||||
}
|
||||
|
||||
public function push(i:T):Void {
|
||||
lbd.push(i);
|
||||
}
|
||||
|
||||
public inline function pop(block:Bool):Null<T> {
|
||||
return if (block) {
|
||||
lbd.take();
|
||||
} else {
|
||||
lbd.poll();
|
||||
}
|
||||
}
|
||||
}
|
78
Kha/Tools/macos/std/java/_std/sys/thread/Lock.hx
Normal file
78
Kha/Tools/macos/std/java/_std/sys/thread/Lock.hx
Normal 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 sys.thread;
|
||||
|
||||
import java.Lib;
|
||||
import java.lang.System;
|
||||
|
||||
using haxe.Int64;
|
||||
|
||||
@:coreApi
|
||||
@:native('haxe.java.vm.Lock') class Lock {
|
||||
@:private @:volatile var releasedCount = 0;
|
||||
|
||||
public function new() {}
|
||||
|
||||
public function wait(?timeout:Float):Bool {
|
||||
var ret = false;
|
||||
java.Lib.lock(this, {
|
||||
if (--releasedCount < 0) {
|
||||
if (timeout == null) {
|
||||
// since .notify() is asynchronous, this `while` is needed
|
||||
// because there is a very remote possibility of release() awaking a thread,
|
||||
// but before it releases, another thread calls wait - and since the release count
|
||||
// is still positive, it will get the lock.
|
||||
while (releasedCount < 0) {
|
||||
try {
|
||||
(cast this : java.lang.Object).wait();
|
||||
} catch (e:java.lang.InterruptedException) {}
|
||||
}
|
||||
} else {
|
||||
var timeout:haxe.Int64 = cast timeout * 1000;
|
||||
var cur = System.currentTimeMillis(),
|
||||
max = cur.add(timeout);
|
||||
// see above comment about this while loop
|
||||
while (releasedCount < 0 && cur.compare(max) < 0) {
|
||||
try {
|
||||
var t = max.sub(cur);
|
||||
(cast this : java.lang.Object).wait(t);
|
||||
cur = System.currentTimeMillis();
|
||||
} catch (e:java.lang.InterruptedException) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = this.releasedCount >= 0;
|
||||
if (!ret)
|
||||
this.releasedCount++; // timed out
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
public function release():Void {
|
||||
untyped __lock__(this, {
|
||||
if (++releasedCount >= 0) {
|
||||
untyped this.notify();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
46
Kha/Tools/macos/std/java/_std/sys/thread/Mutex.hx
Normal file
46
Kha/Tools/macos/std/java/_std/sys/thread/Mutex.hx
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@:coreApi
|
||||
@:native('haxe.java.vm.Mutex') class Mutex {
|
||||
@:private var lock:ReentrantLock;
|
||||
|
||||
public function new() {
|
||||
this.lock = new ReentrantLock();
|
||||
}
|
||||
|
||||
public function tryAcquire():Bool {
|
||||
return this.lock.tryLock();
|
||||
}
|
||||
|
||||
public function acquire():Void {
|
||||
this.lock.lock();
|
||||
}
|
||||
|
||||
public function release():Void {
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
190
Kha/Tools/macos/std/java/_std/sys/thread/Thread.hx
Normal file
190
Kha/Tools/macos/std/java/_std/sys/thread/Thread.hx
Normal 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.thread;
|
||||
|
||||
import java.Lib;
|
||||
import java.lang.Runnable;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.Collections;
|
||||
import java.lang.Thread as JavaThread;
|
||||
import java.lang.System;
|
||||
import java.StdTypes.Int64 as Long;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
private typedef ThreadImpl = HaxeThread;
|
||||
|
||||
abstract Thread(ThreadImpl) from ThreadImpl {
|
||||
public var events(get,never):EventLoop;
|
||||
|
||||
inline function new(t:HaxeThread) {
|
||||
this = t;
|
||||
}
|
||||
|
||||
public static inline function create(job:()->Void):Thread {
|
||||
return HaxeThread.create(job, false);
|
||||
}
|
||||
|
||||
public static inline function current():Thread {
|
||||
return HaxeThread.get(JavaThread.currentThread());
|
||||
}
|
||||
|
||||
public static inline function runWithEventLoop(job:()->Void):Void {
|
||||
HaxeThread.runWithEventLoop(job);
|
||||
}
|
||||
|
||||
public static inline function createWithEventLoop(job:()->Void):Thread {
|
||||
return HaxeThread.create(job, true);
|
||||
}
|
||||
|
||||
public static inline function readMessage(block:Bool):Dynamic {
|
||||
return current().getHandle().readMessage(block);
|
||||
}
|
||||
|
||||
public inline function sendMessage(msg:Dynamic):Void {
|
||||
this.sendMessage(msg);
|
||||
}
|
||||
|
||||
inline function getHandle():HaxeThread {
|
||||
return this;
|
||||
}
|
||||
|
||||
function get_events():EventLoop {
|
||||
if(this.events == null)
|
||||
throw new NoEventLoopException();
|
||||
return this.events;
|
||||
}
|
||||
|
||||
@:keep //TODO: keep only if events are actually used
|
||||
static function processEvents():Void {
|
||||
current().getHandle().events.loop();
|
||||
}
|
||||
}
|
||||
|
||||
private class HaxeThread {
|
||||
static var nativeThreads:java.util.Map<JavaThread,HaxeThread>;
|
||||
static var mainJavaThread:JavaThread;
|
||||
static var mainHaxeThread:HaxeThread;
|
||||
|
||||
static function __init__() {
|
||||
nativeThreads = Collections.synchronizedMap(new WeakHashMap<JavaThread,HaxeThread>());
|
||||
mainJavaThread = JavaThread.currentThread();
|
||||
mainHaxeThread = new HaxeThread();
|
||||
mainHaxeThread.events = new EventLoop();
|
||||
}
|
||||
|
||||
public final messages = new LinkedBlockingDeque<Dynamic>();
|
||||
|
||||
public var events(default,null):Null<EventLoop>;
|
||||
|
||||
public static function create(job:()->Void, withEventLoop:Bool):HaxeThread {
|
||||
var hx = new HaxeThread();
|
||||
if(withEventLoop)
|
||||
hx.events = new EventLoop();
|
||||
var thread = new NativeHaxeThread(hx, job, withEventLoop);
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
return hx;
|
||||
}
|
||||
|
||||
public static function get(javaThread:JavaThread):HaxeThread {
|
||||
if(javaThread == mainJavaThread) {
|
||||
return mainHaxeThread;
|
||||
} else if(javaThread is NativeHaxeThread) {
|
||||
return (cast javaThread:NativeHaxeThread).haxeThread;
|
||||
} else {
|
||||
switch nativeThreads.get(javaThread) {
|
||||
case null:
|
||||
var hx = new HaxeThread();
|
||||
nativeThreads.put(javaThread, hx);
|
||||
return hx;
|
||||
case hx:
|
||||
return hx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function runWithEventLoop(job:()->Void):Void {
|
||||
var thread = get(JavaThread.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() {}
|
||||
|
||||
public function sendMessage(msg:Dynamic):Void {
|
||||
messages.add(msg);
|
||||
}
|
||||
|
||||
public function readMessage(block:Bool):Dynamic {
|
||||
return block ? messages.take() : messages.poll();
|
||||
}
|
||||
}
|
||||
|
||||
private class NativeHaxeThread extends java.lang.Thread {
|
||||
public final haxeThread:HaxeThread;
|
||||
final withEventLoop:Bool;
|
||||
|
||||
public function new(haxeThread:HaxeThread, job:()->Void, withEventLoop:Bool) {
|
||||
super(new Job(job));
|
||||
this.haxeThread = haxeThread;
|
||||
this.withEventLoop = withEventLoop;
|
||||
}
|
||||
|
||||
override overload public function run() {
|
||||
super.run();
|
||||
if(withEventLoop)
|
||||
haxeThread.events.loop();
|
||||
}
|
||||
}
|
||||
|
||||
#if jvm
|
||||
private abstract Job(Runnable) from Runnable to Runnable {
|
||||
public inline function new(job:()->Void) {
|
||||
this = cast job;
|
||||
}
|
||||
}
|
||||
#else
|
||||
private class Job implements Runnable {
|
||||
final job:()->Void;
|
||||
|
||||
public function new(job:()->Void) {
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
public function run() {
|
||||
job();
|
||||
}
|
||||
}
|
||||
#end
|
43
Kha/Tools/macos/std/java/_std/sys/thread/Tls.hx
Normal file
43
Kha/Tools/macos/std/java/_std/sys/thread/Tls.hx
Normal 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;
|
||||
|
||||
// @:coreApi // causes some overload error...
|
||||
@:native('haxe.java.vm.Tls') class Tls<T> {
|
||||
var t:java.lang.ThreadLocal<T>;
|
||||
|
||||
public var value(get, set):T;
|
||||
|
||||
public function new() {
|
||||
this.t = new java.lang.ThreadLocal();
|
||||
}
|
||||
|
||||
inline private function get_value():T {
|
||||
return t.get();
|
||||
}
|
||||
|
||||
inline private function set_value(v:T):T {
|
||||
t.set(v);
|
||||
return v;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user