Update Files

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

View File

@ -0,0 +1,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());
}
}

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

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

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

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

View File

@ -0,0 +1,94 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package 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);
}
}
}

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

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

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

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

View File

@ -0,0 +1,78 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package 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();
}
});
}
}

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

View File

@ -0,0 +1,190 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package sys.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

View File

@ -0,0 +1,43 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package sys.thread;
// @: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;
}
}