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,113 @@
/*
* 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 cpp.NativeSys;
@:buildXml('<include name="${HXCPP}/src/hx/libs/std/Build.xml"/>')
@:coreApi
class FileSystem {
public static function exists(path:String):Bool {
return NativeSys.sys_exists(makeCompatiblePath(path));
}
public static function rename(path:String, newPath:String):Void {
NativeSys.sys_rename(path, newPath);
}
public static function stat(path:String):FileStat {
var s:FileStat = NativeSys.sys_stat(makeCompatiblePath(path));
if (s == null)
return {
gid: 0,
uid: 0,
atime: Date.fromTime(0),
mtime: Date.fromTime(0),
ctime: Date.fromTime(0),
dev: 0,
ino: 0,
nlink: 0,
rdev: 0,
size: 0,
mode: 0
};
s.atime = Date.fromTime(1000.0 * (untyped s.atime));
s.mtime = Date.fromTime(1000.0 * (untyped s.mtime));
s.ctime = Date.fromTime(1000.0 * (untyped s.ctime));
return s;
}
public static function fullPath(relPath:String):String {
return NativeSys.file_full_path(relPath);
}
public static function absolutePath(relPath:String):String {
if (haxe.io.Path.isAbsolute(relPath))
return relPath;
return haxe.io.Path.join([Sys.getCwd(), relPath]);
}
inline static function kind(path:String):String {
return NativeSys.sys_file_type(makeCompatiblePath(path));
}
public static function isDirectory(path:String):Bool {
return kind(path) == "dir";
}
public static function createDirectory(path:String):Void {
var path = haxe.io.Path.addTrailingSlash(path);
var _p = null;
var parts = [];
while (path != (_p = haxe.io.Path.directory(path))) {
parts.unshift(path);
path = _p;
}
for (part in parts) {
if (part.charCodeAt(part.length - 1) != ":".code && !exists(part) && !NativeSys.sys_create_dir(part, 493))
throw "Could not create directory:" + part;
}
}
public static function deleteFile(path:String):Void {
NativeSys.file_delete(path);
}
public static function deleteDirectory(path:String):Void {
NativeSys.sys_remove_dir(path);
}
public static function readDirectory(path:String):Array<String> {
return NativeSys.sys_read_dir(path);
}
private static inline function makeCompatiblePath(path:String):String {
return if (path.charCodeAt(1) == ":".code && path.length <= 3) {
haxe.io.Path.addTrailingSlash(path);
} else if (path == "/") {
"/";
} else {
haxe.io.Path.removeTrailingSlashes(path);
}
}
}

View File

@ -0,0 +1,228 @@
/*
* 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;
@:keep
private class D {
@:native("_hx_mysql_connect")
extern public static function connect(params:Dynamic):Dynamic;
@:native("_hx_mysql_select_db")
extern public static function select_db(handle:Dynamic, db:String):Void;
@:native("_hx_mysql_request")
extern public static function request(handle:Dynamic, req:String):Dynamic;
@:native("_hx_mysql_close")
extern public static function close(handle:Dynamic):Dynamic;
@:native("_hx_mysql_escape")
extern public static function escape(handle:Dynamic, str:String):String;
@:native("_hx_mysql_result_get_length")
extern public static function result_get_length(handle:Dynamic):Int;
@:native("_hx_mysql_result_get_nfields")
extern public static function result_get_nfields(handle:Dynamic):Int;
@:native("_hx_mysql_result_next")
extern public static function result_next(handle:Dynamic):Dynamic;
@:native("_hx_mysql_result_get")
extern public static function result_get(handle:Dynamic, i:Int):String;
@:native("_hx_mysql_result_get_int")
extern public static function result_get_int(handle:Dynamic, i:Int):Int;
@:native("_hx_mysql_result_get_float")
extern public static function result_get_float(handle:Dynamic, i:Int):Float;
@:native("_hx_mysql_result_get_fields_names")
extern public static function result_fields_names(handle:Dynamic):Array<String>;
@:native("_hx_mysql_set_conversion")
extern public static function set_conv_funs(charsToBytes:cpp.Callable<Dynamic->Dynamic>, intToDate:cpp.Callable<Float->Dynamic>):Void;
public static function charsToBytes(data:Dynamic):Dynamic
return haxe.io.Bytes.ofData(data);
public static function secondsToDate(seconds:Float):Dynamic
return Date.fromTime(seconds * 1000);
}
private class MysqlResultSet implements sys.db.ResultSet {
public var length(get, null):Int;
public var nfields(get, null):Int;
private var __r:Dynamic;
private var cache:Dynamic;
public function new(r:Dynamic) {
__r = r;
}
private function get_length() {
return D.result_get_length(__r);
}
private function get_nfields() {
return D.result_get_nfields(__r);
}
public function hasNext() {
if (cache == null)
cache = next();
return (cache != null);
}
public function next():Dynamic {
var c = cache;
if (c != null) {
cache = null;
return c;
}
c = D.result_next(__r);
return c;
}
public function results():List<Dynamic> {
var l = new List();
while (hasNext())
l.add(next());
return l;
}
public function getResult(n:Int) {
return D.result_get(__r, n);
}
public function getIntResult(n:Int):Int {
return D.result_get_int(__r, n);
}
public function getFloatResult(n:Int):Float {
return D.result_get_float(__r, n);
}
public function getFieldsNames():Array<String> {
var a = D.result_fields_names(__r);
return a;
}
}
private class MysqlConnection implements sys.db.Connection {
private var __c:Dynamic;
public function new(c:Dynamic) {
__c = c;
D.set_conv_funs(cpp.Function.fromStaticFunction(D.charsToBytes), cpp.Function.fromStaticFunction(D.secondsToDate));
}
public function request(s:String):sys.db.ResultSet {
var r = D.request(this.__c, s);
return new MysqlResultSet(r);
}
public function close() {
D.close(__c);
}
public function escape(s:String) {
return D.escape(__c, s);
}
public function quote(s:String) {
return "'" + escape(s) + "'";
}
public function addValue(s:StringBuf, v:Dynamic) {
if (v == null) {
s.add(v);
} else if (Std.isOfType(v, Bool)) {
s.add(v ? 1 : 0);
} else {
var t:Int = untyped v.__GetType();
if (t == 0xff)
s.add(v);
else if (t == 2)
s.add(untyped v.__GetInt() ? "1".code : "0".code);
else {
s.addChar("'".code);
s.add(escape(Std.string(v)));
s.addChar("'".code);
}
}
}
public function lastInsertId() {
return request("SELECT LAST_INSERT_ID()").getIntResult(0);
}
public function dbName() {
return "MySQL";
}
public function startTransaction() {
request("START TRANSACTION");
}
public function commit() {
request("COMMIT");
}
public function rollback() {
request("ROLLBACK");
}
private static var __use_date = Date;
}
@:buildXml('<include name="${HXCPP}/src/hx/libs/mysql/Build.xml"/>')
@:coreApi class Mysql {
public static function connect(params:{
host:String,
?port:Int,
user:String,
pass:String,
?socket:String,
?database:String
}):sys.db.Connection {
var o = {
host: params.host,
port: if (params.port == null) 3306 else params.port,
user: params.user,
pass: params.pass,
socket: if (params.socket == null) null else params.socket
};
var c = D.connect(o);
if (params.database != null) {
try {
D.select_db(c, params.database);
} catch (e:Dynamic) {
D.close(c);
cpp.Lib.rethrow(e);
}
}
return new MysqlConnection(c);
}
}

View File

@ -0,0 +1,203 @@
/*
* 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;
private class SqliteConnection implements Connection {
var c:Dynamic;
public function new(file:String) {
c = _connect(file);
}
public function close() {
_close(c);
}
public function request(s:String):ResultSet {
try {
return new SqliteResultSet(_request(c, s));
} catch (e:String) {
throw "Error while executing " + s + " (" + e + ")";
}
}
public function escape(s:String) {
return s.split("'").join("''");
}
public function quote(s:String) {
if (s.indexOf("\000") >= 0) {
var hexChars = new Array<String>();
for (i in 0...s.length)
hexChars.push(StringTools.hex(StringTools.fastCodeAt(s, i), 2));
return "x'" + hexChars.join("") + "'";
}
return "'" + s.split("'").join("''") + "'";
}
public function addValue(s:StringBuf, v:Dynamic) {
if (v == null) {
s.add(v);
} else if (Std.isOfType(v, Bool)) {
s.add(v ? 1 : 0);
} else {
var t:Int = untyped v.__GetType();
if (t == 0xff)
s.add(v);
else if (t == 2)
s.add(untyped v.__GetInt());
else
s.add(quote(Std.string(v)));
}
}
public function lastInsertId():Int {
return _last_id(c);
}
public function dbName() {
return "SQLite";
}
public function startTransaction() {
request("BEGIN TRANSACTION");
}
public function commit() {
request("COMMIT");
}
public function rollback() {
request("ROLLBACK");
}
@:native("_hx_sqlite_connect")
extern public static function _connect(filename:String):Dynamic;
@:native("_hx_sqlite_request")
extern public static function _request(handle:Dynamic, req:String):Dynamic;
@:native("_hx_sqlite_close")
extern public static function _close(handle:Dynamic):Void;
@:native("_hx_sqlite_last_insert_id")
extern public static function _last_id(handle:Dynamic):Int;
}
private class SqliteResultSet implements ResultSet {
public var length(get, null):Int;
public var nfields(get, null):Int;
var r:Dynamic;
var cache:List<Dynamic>;
public function new(r:Dynamic) {
cache = new List();
this.r = r;
hasNext(); // execute the request
}
function get_length() {
if (nfields != 0) {
while (true) {
var c = result_next(r);
if (c == null)
break;
cache.add(c);
}
return cache.length;
}
return result_get_length(r);
}
function get_nfields() {
return result_get_nfields(r);
}
public function hasNext() {
var c = next();
if (c == null)
return false;
cache.push(c);
return true;
}
public function next():Dynamic {
var c = cache.pop();
if (c != null)
return c;
return result_next(r);
}
public function results():List<Dynamic> {
var l = new List();
while (true) {
var c = next();
if (c == null)
break;
l.add(c);
}
return l;
}
public function getResult(n:Int) {
return new String(result_get(r, n));
}
public function getIntResult(n:Int):Int {
return result_get_int(r, n);
}
public function getFloatResult(n:Int):Float {
return result_get_float(r, n);
}
public function getFieldsNames():Array<String> {
throw new haxe.exceptions.NotImplementedException();
}
@:native("_hx_sqlite_result_next")
extern public static function result_next(handle:Dynamic):Dynamic;
@:native("_hx_sqlite_result_get_length")
extern public static function result_get_length(handle:Dynamic):Int;
@:native("_hx_sqlite_result_get_nfields")
extern public static function result_get_nfields(handle:Dynamic):Int;
@:native("_hx_sqlite_result_get")
extern public static function result_get(handle:Dynamic, i:Int):String;
@:native("_hx_sqlite_result_get_int")
extern public static function result_get_int(handle:Dynamic, i:Int):Int;
@:native("_hx_sqlite_result_get_float")
extern public static function result_get_float(handle:Dynamic, i:Int):Float;
}
@:buildXml('<include name="${HXCPP}/src/hx/libs/sqlite/Build.xml"/>')
@:coreApi class Sqlite {
public static function open(file:String):Connection {
return new SqliteConnection(file);
}
}

View File

@ -0,0 +1,76 @@
/*
* 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 cpp.NativeFile;
@:coreApi
class File {
public static function getContent(path:String):String {
return NativeFile.file_contents_string(path);
}
public static function getBytes(path:String):haxe.io.Bytes {
var data = NativeFile.file_contents_bytes(path);
return haxe.io.Bytes.ofData(data);
}
public static function saveContent(path:String, content:String):Void {
var f = write(path);
f.writeString(content);
f.close();
}
public static function saveBytes(path:String, bytes:haxe.io.Bytes):Void {
var f = write(path);
f.write(bytes);
f.close();
}
public static function read(path:String, binary:Bool = true):FileInput {
return untyped new FileInput(NativeFile.file_open(path, (if (binary) "rb" else "r")));
}
public static function write(path:String, binary:Bool = true):FileOutput {
return untyped new FileOutput(NativeFile.file_open(path, (if (binary) "wb" else "w")));
}
public static function append(path:String, binary:Bool = true):FileOutput {
return untyped new FileOutput(NativeFile.file_open(path, (if (binary) "ab" else "a")));
}
public static function update(path:String, binary:Bool = true):FileOutput {
if (!FileSystem.exists(path)) {
write(path).close();
}
return untyped new FileOutput(NativeFile.file_open(path, (if (binary) "rb+" else "r+")));
}
public static function copy(srcPath:String, dstPath:String):Void {
var s = read(srcPath, true);
var d = write(dstPath, true);
d.writeInput(s);
s.close();
d.close();
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package sys.io;
import sys.io.FileSeek;
import cpp.NativeFile;
@:coreApi
class FileInput extends haxe.io.Input {
private var __f:Dynamic;
function new(f:Dynamic):Void {
__f = f;
}
public override function readByte():Int {
return try {
NativeFile.file_read_char(__f);
} catch (e:Dynamic) {
if (untyped e.__IsArray())
throw new haxe.io.Eof();
else
throw haxe.io.Error.Custom(e);
}
}
public override function readBytes(s:haxe.io.Bytes, p:Int, l:Int):Int {
return try {
NativeFile.file_read(__f, s.getData(), p, l);
} catch (e:Dynamic) {
if (untyped e.__IsArray())
throw new haxe.io.Eof();
else
throw haxe.io.Error.Custom(e);
}
}
public override function close():Void {
super.close();
NativeFile.file_close(__f);
}
public function seek(p:Int, pos:FileSeek):Void {
NativeFile.file_seek(__f, p, pos == SeekBegin ? 0 : pos == SeekCur ? 1 : 2);
}
public function tell():Int {
return NativeFile.file_tell(__f);
}
public function eof():Bool {
return NativeFile.file_eof(__f);
}
}

View File

@ -0,0 +1,63 @@
/*
* 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 sys.io.FileSeek;
import cpp.NativeFile;
@:coreApi
class FileOutput extends haxe.io.Output {
private var __f:Dynamic;
function new(f:Dynamic):Void {
__f = f;
}
public override function writeByte(c:Int):Void {
try
NativeFile.file_write_char(__f, c)
catch (e:Dynamic)
throw haxe.io.Error.Custom(e);
}
public override function writeBytes(s:haxe.io.Bytes, p:Int, l:Int):Int {
return try NativeFile.file_write(__f, s.getData(), p, l) catch (e:Dynamic) throw haxe.io.Error.Custom(e);
}
public override function flush():Void {
NativeFile.file_flush(__f);
}
public override function close():Void {
super.close();
NativeFile.file_close(__f);
}
public function seek(p:Int, pos:FileSeek):Void {
NativeFile.file_seek(__f, p, pos == SeekBegin ? 0 : pos == SeekCur ? 1 : 2);
}
public function tell():Int {
return NativeFile.file_tell(__f);
}
}

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;
import cpp.NativeProcess;
private class Stdin extends haxe.io.Output {
var p:Dynamic;
var buf:haxe.io.Bytes;
public function new(p:Dynamic) {
this.p = p;
buf = haxe.io.Bytes.alloc(1);
}
public override function close() {
super.close();
NativeProcess.process_stdin_close(p);
}
public override function writeByte(c) {
buf.set(0, c);
writeBytes(buf, 0, 1);
}
public override function writeBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
try {
return NativeProcess.process_stdin_write(p, buf.getData(), pos, len);
} catch (e:Dynamic) {
throw new haxe.io.Eof();
}
return 0;
}
}
private class Stdout extends haxe.io.Input {
var p:Dynamic;
var out:Bool;
var buf:haxe.io.Bytes;
public function new(p:Dynamic, out) {
this.p = p;
this.out = out;
buf = haxe.io.Bytes.alloc(1);
}
public override function readByte() {
if (readBytes(buf, 0, 1) == 0)
throw haxe.io.Error.Blocked;
return buf.get(0);
}
public override function readBytes(str:haxe.io.Bytes, pos:Int, len:Int):Int {
var result:Int;
try {
result = out ? NativeProcess.process_stdout_read(p, str.getData(), pos, len) : NativeProcess.process_stderr_read(p, str.getData(), pos, len);
} catch (e:Dynamic) {
throw new haxe.io.Eof();
}
if (result == 0)
throw new haxe.io.Eof();
return result;
}
}
@:coreApi
class Process {
var p:Dynamic;
public var stdout(default, null):haxe.io.Input;
public var stderr(default, null):haxe.io.Input;
public var stdin(default, null):haxe.io.Output;
public function new(cmd:String, ?args:Array<String>, ?detached:Bool):Void {
if (detached)
throw "Detached process is not supported on this platform";
p = try NativeProcess.process_run(cmd, args) catch (e:Dynamic) throw "Process creation failure : " + cmd;
stdin = new Stdin(p);
stdout = new Stdout(p, true);
stderr = new Stdout(p, false);
}
public function getPid():Int {
return NativeProcess.process_pid(p);
}
public function exitCode(block:Bool = true):Null<Int> {
if (block == false)
throw "Non blocking exitCode() not supported on this platform";
return NativeProcess.process_exit(p);
}
public function close():Void {
NativeProcess.process_close(p);
}
public function kill():Void {
NativeProcess.process_kill(p);
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package sys.net;
import cpp.NativeSocket;
@:coreApi
class Host {
public var host(default, null):String;
public var ip(default, null):Int;
private var ipv6(default, null):haxe.io.BytesData;
public function new(name:String):Void {
host = name;
try {
ip = NativeSocket.host_resolve(name);
} catch (e:Dynamic) {
ipv6 = NativeSocket.host_resolve_ipv6(name);
}
}
public function toString():String {
return ipv6 == null ? NativeSocket.host_to_string(ip) : NativeSocket.host_to_string_ipv6(ipv6);
}
public function reverse():String {
return ipv6 == null ? NativeSocket.host_reverse(ip) : NativeSocket.host_reverse_ipv6(ipv6);
}
public static function localhost():String {
return NativeSocket.host_local();
}
static function __init__():Void {
NativeSocket.socket_init();
}
}

View File

@ -0,0 +1,273 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package sys.net;
import haxe.io.Error;
import cpp.NativeSocket;
import cpp.NativeString;
import cpp.Pointer;
private class SocketInput extends haxe.io.Input {
var __s:Dynamic;
public function new(s:Dynamic) {
__s = s;
}
public override function readByte() {
return try {
NativeSocket.socket_recv_char(__s);
} catch (e:Dynamic) {
if (e == "Blocking")
throw Blocked;
else if (__s == null)
throw Custom(e);
else
throw new haxe.io.Eof();
}
}
public override function readBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
var r;
if (__s == null)
throw "Invalid handle";
try {
r = NativeSocket.socket_recv(__s, buf.getData(), pos, len);
} catch (e:Dynamic) {
if (e == "Blocking")
throw Blocked;
else
throw Custom(e);
}
if (r == 0)
throw new haxe.io.Eof();
return r;
}
public override function close() {
super.close();
if (__s != null)
NativeSocket.socket_close(__s);
}
}
private class SocketOutput extends haxe.io.Output {
var __s:Dynamic;
public function new(s:Dynamic) {
__s = s;
}
public override function writeByte(c:Int) {
if (__s == null)
throw "Invalid handle";
try {
NativeSocket.socket_send_char(__s, c);
} catch (e:Dynamic) {
if (e == "Blocking")
throw Blocked;
else
throw Custom(e);
}
}
public override function writeBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
return try {
NativeSocket.socket_send(__s, buf.getData(), pos, len);
} catch (e:Dynamic) {
if (e == "Blocking")
throw Blocked;
else if (e == "EOF")
throw new haxe.io.Eof();
else
throw Custom(e);
}
}
public override function close() {
super.close();
if (__s != null)
NativeSocket.socket_close(__s);
}
}
@:coreApi
class Socket {
private var __s:Dynamic;
// We need to keep these values so that we can restore
// them if we re-create the socket for ipv6 as in
// connect() and bind() below.
private var __timeout:Float = 0.0;
private var __blocking:Bool = true;
private var __fastSend:Bool = false;
public var input(default, null):haxe.io.Input;
public var output(default, null):haxe.io.Output;
public var custom:Dynamic;
public function new():Void {
init();
}
private function init():Void {
if (__s == null)
__s = NativeSocket.socket_new(false);
// Restore these values if they changed. This can happen
// in connect() and bind() if using an ipv6 address.
setTimeout(__timeout);
setBlocking(__blocking);
setFastSend(__fastSend);
input = new SocketInput(__s);
output = new SocketOutput(__s);
}
public function close():Void {
NativeSocket.socket_close(__s);
untyped {
var input:SocketInput = cast input;
var output:SocketOutput = cast output;
input.__s = null;
output.__s = null;
}
input.close();
output.close();
}
public function read():String {
var bytes:haxe.io.BytesData = NativeSocket.socket_read(__s);
if (bytes == null)
return "";
var arr:Array<cpp.Char> = cast bytes;
return NativeString.fromPointer(Pointer.ofArray(arr));
}
public function write(content:String):Void {
NativeSocket.socket_write(__s, haxe.io.Bytes.ofString(content).getData());
}
public function connect(host:Host, port:Int):Void {
try {
if (host.ip == 0 && host.host != "0.0.0.0") {
// hack, hack, hack
var ipv6:haxe.io.BytesData = Reflect.field(host, "ipv6");
if (ipv6 != null) {
close();
__s = NativeSocket.socket_new_ip(false, true);
init();
NativeSocket.socket_connect_ipv6(__s, ipv6, port);
} else
throw "Unresolved host";
} else
NativeSocket.socket_connect(__s, host.ip, port);
} catch (s:String) {
if (s == "Invalid socket handle")
throw "Failed to connect on " + host.toString() + ":" + port;
else if (s == "Blocking") {
// Do nothing, this is not a real error, it simply indicates
// that a non-blocking connect is in progress
} else
cpp.Lib.rethrow(s);
}
}
public function listen(connections:Int):Void {
NativeSocket.socket_listen(__s, connections);
}
public function shutdown(read:Bool, write:Bool):Void {
NativeSocket.socket_shutdown(__s, read, write);
}
public function bind(host:Host, port:Int):Void {
if (host.ip == 0 && host.host != "0.0.0.0") {
var ipv6:haxe.io.BytesData = Reflect.field(host, "ipv6");
if (ipv6 != null) {
close();
__s = NativeSocket.socket_new_ip(false, true);
init();
NativeSocket.socket_bind_ipv6(__s, ipv6, port);
} else
throw "Unresolved host";
} else
NativeSocket.socket_bind(__s, host.ip, port);
}
public function accept():Socket {
var c = NativeSocket.socket_accept(__s);
var s = Type.createEmptyInstance(Socket);
s.__s = c;
s.input = new SocketInput(c);
s.output = new SocketOutput(c);
return s;
}
public function peer():{host:Host, port:Int} {
var a:Dynamic = NativeSocket.socket_peer(__s);
if (a == null) {
return null;
}
var h = new Host("127.0.0.1");
untyped h.ip = a[0];
return {host: h, port: a[1]};
}
public function host():{host:Host, port:Int} {
var a:Dynamic = NativeSocket.socket_host(__s);
if (a == null) {
return null;
}
var h = new Host("127.0.0.1");
untyped h.ip = a[0];
return {host: h, port: a[1]};
}
public function setTimeout(timeout:Float):Void {
__timeout = timeout;
NativeSocket.socket_set_timeout(__s, timeout);
}
public function waitForRead():Void {
select([this], null, null, null);
}
public function setBlocking(b:Bool):Void {
__blocking = b;
NativeSocket.socket_set_blocking(__s, b);
}
public function setFastSend(b:Bool):Void {
__fastSend = b;
NativeSocket.socket_set_fast_send(__s, b);
}
public static function select(read:Array<Socket>, write:Array<Socket>, others:Array<Socket>,
?timeout:Float):{read:Array<Socket>, write:Array<Socket>, others:Array<Socket>} {
var neko_array = NativeSocket.socket_select(read, write, others, timeout);
if (neko_array == null)
throw "Select error";
return @:fixed {
read:neko_array[0], write:neko_array[1], others:neko_array[2]
};
}
}

View 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 sys.net;
import haxe.io.Error;
import cpp.NativeSocket;
@:coreApi
class UdpSocket extends Socket {
private override function init():Void {
__s = NativeSocket.socket_new(true);
super.init();
}
public function sendTo(buf:haxe.io.Bytes, pos:Int, len:Int, addr:Address):Int {
return try {
NativeSocket.socket_send_to(__s, buf.getData(), pos, len, addr);
} catch (e:Dynamic) {
if (e == "Blocking")
throw Blocked;
else
throw Custom(e);
}
}
public function readFrom(buf:haxe.io.Bytes, pos:Int, len:Int, addr:Address):Int {
var r;
try {
r = NativeSocket.socket_recv_from(__s, buf.getData(), pos, len, addr);
} catch (e:Dynamic) {
if (e == "Blocking")
throw Blocked;
else
throw Custom(e);
}
if (r == 0)
throw new haxe.io.Eof();
return r;
}
public function setBroadcast(b:Bool):Void {
NativeSocket.socket_set_broadcast(__s, b);
}
}

View File

@ -0,0 +1,136 @@
/*
* 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.ssl;
import cpp.NativeSsl;
@:coreApi
class Certificate {
var __h:Null<Certificate>;
var __x:Dynamic;
@:allow(sys.ssl.Socket)
function new(x:Dynamic, ?h:Certificate) {
__x = x;
__h = h;
}
public static function loadFile(file:String):Certificate {
return new Certificate(NativeSsl.cert_load_file(file));
}
public static function loadPath(path:String):Certificate {
return new Certificate(NativeSsl.cert_load_path(path));
}
public static function fromString(str:String):Certificate {
return new Certificate(NativeSsl.cert_add_pem(null, str));
}
public static function loadDefaults():Certificate {
var x = NativeSsl.cert_load_defaults();
if (x != null)
return new Certificate(x);
var defPaths = null;
switch (Sys.systemName()) {
case "Linux":
defPaths = [
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
"/etc/ssl/certs", // SLES10/SLES11
"/system/etc/security/cacerts" // Android
];
case "BSD":
defPaths = [
"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
"/etc/ssl/cert.pem", // OpenBSD
"/etc/openssl/certs/ca-certificates.crt", // NetBSD
];
case "Android":
defPaths = ["/system/etc/security/cacerts"];
default:
}
if (defPaths != null) {
for (path in defPaths) {
if (sys.FileSystem.exists(path)) {
if (sys.FileSystem.isDirectory(path))
return loadPath(path);
else
return loadFile(path);
}
}
}
return null;
}
public var commonName(get, null):Null<String>;
public var altNames(get, null):Array<String>;
public var notBefore(get, null):Date;
public var notAfter(get, null):Date;
function get_commonName():Null<String> {
return subject("CN");
}
function get_altNames():Array<String> {
return NativeSsl.cert_get_altnames(__x);
}
public function subject(field:String):Null<String> {
return NativeSsl.cert_get_subject(__x, field);
}
public function issuer(field:String):Null<String> {
return NativeSsl.cert_get_issuer(__x, field);
}
function get_notBefore():Date {
var a = NativeSsl.cert_get_notbefore(__x);
return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
}
function get_notAfter():Date {
var a = NativeSsl.cert_get_notafter(__x);
return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
}
public function next():Null<Certificate> {
var n = NativeSsl.cert_get_next(__x);
return n == null ? null : new Certificate(n, __h == null ? this : __h);
}
public function add(pem:String):Void {
NativeSsl.cert_add_pem(__x, pem);
}
public function addDER(der:haxe.io.Bytes):Void {
NativeSsl.cert_add_der(__x, der.getData());
}
static function __init__():Void {
NativeSsl.init();
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.ssl;
import cpp.NativeSsl;
@:coreApi
class Digest {
public static function make(data:haxe.io.Bytes, alg:DigestAlgorithm):haxe.io.Bytes {
return haxe.io.Bytes.ofData(NativeSsl.dgst_make(data.getData(), alg));
}
public static function sign(data:haxe.io.Bytes, privKey:Key, alg:DigestAlgorithm):haxe.io.Bytes {
return haxe.io.Bytes.ofData(NativeSsl.dgst_sign(data.getData(), @:privateAccess privKey.__k, alg));
}
public static function verify(data:haxe.io.Bytes, signature:haxe.io.Bytes, pubKey:Key, alg:DigestAlgorithm):Bool {
return NativeSsl.dgst_verify(data.getData(), signature.getData(), @:privateAccess pubKey.__k, alg);
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.ssl;
import cpp.NativeSsl;
private typedef PKEY = Dynamic;
@:coreApi
class Key {
private var __k:PKEY;
private function new(k:PKEY) {
__k = k;
}
public static function loadFile(file:String, ?isPublic:Bool, ?pass:String):Key {
var data = sys.io.File.getBytes(file);
var str = cpp.Lib.stringReference(data);
if (str.indexOf("-----BEGIN ") >= 0)
return readPEM(str, isPublic == true, pass);
else
return readDER(data, isPublic == true);
}
public static function readPEM(data:String, isPublic:Bool, ?pass:String):Key {
return new Key(NativeSsl.key_from_pem(data, isPublic, pass));
}
public static function readDER(data:haxe.io.Bytes, isPublic:Bool):Key {
return new Key(NativeSsl.key_from_der(data.getData(), isPublic));
}
static function __init__():Void {
NativeSsl.init();
}
}

View File

@ -0,0 +1,297 @@
/*
* 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.ssl;
import cpp.NativeSocket;
import cpp.NativeSsl;
private typedef SocketHandle = Dynamic;
private typedef CONF = Dynamic;
private typedef SSL = Dynamic;
private class SocketInput extends haxe.io.Input {
@:allow(sys.ssl.Socket) private var __s:Socket;
public function new(s:Socket) {
this.__s = s;
}
public override function readByte() {
return try {
__s.handshake();
NativeSsl.ssl_recv_char(@:privateAccess __s.ssl);
} catch (e:Dynamic) {
if (e == "Blocking")
throw haxe.io.Error.Blocked;
else if (__s == null)
throw haxe.io.Error.Custom(e);
else
throw new haxe.io.Eof();
}
}
public override function readBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
var r:Int;
if (__s == null)
throw "Invalid handle";
try {
__s.handshake();
r = NativeSsl.ssl_recv(@:privateAccess __s.ssl, buf.getData(), pos, len);
} catch (e:Dynamic) {
if (e == "Blocking")
throw haxe.io.Error.Blocked;
else
throw haxe.io.Error.Custom(e);
}
if (r == 0)
throw new haxe.io.Eof();
return r;
}
public override function close() {
super.close();
if (__s != null)
__s.close();
}
}
private class SocketOutput extends haxe.io.Output {
@:allow(sys.ssl.Socket) private var __s:Socket;
public function new(s:Socket) {
this.__s = s;
}
public override function writeByte(c:Int) {
if (__s == null)
throw "Invalid handle";
try {
__s.handshake();
NativeSsl.ssl_send_char(@:privateAccess __s.ssl, c);
} catch (e:Dynamic) {
if (e == "Blocking")
throw haxe.io.Error.Blocked;
else
throw haxe.io.Error.Custom(e);
}
}
public override function writeBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
return try {
__s.handshake();
NativeSsl.ssl_send(@:privateAccess __s.ssl, buf.getData(), pos, len);
} catch (e:Dynamic) {
if (e == "Blocking")
throw haxe.io.Error.Blocked;
else
throw haxe.io.Error.Custom(e);
}
}
public override function close() {
super.close();
if (__s != null)
__s.close();
}
}
@:coreApi
class Socket extends sys.net.Socket {
public static var DEFAULT_VERIFY_CERT:Null<Bool> = true;
public static var DEFAULT_CA:Null<Certificate>;
private var conf:CONF;
private var ssl:SSL;
public var verifyCert:Null<Bool>;
private var caCert:Null<Certificate>;
private var hostname:String;
private var ownCert:Null<Certificate>;
private var ownKey:Null<Key>;
private var altSNIContexts:Null<Array<{match:String->Bool, key:Key, cert:Certificate}>>;
private var sniCallback:Dynamic;
private var handshakeDone:Bool;
private override function init():Void {
__s = NativeSocket.socket_new(false);
input = new SocketInput(this);
output = new SocketOutput(this);
if (DEFAULT_VERIFY_CERT && DEFAULT_CA == null) {
try {
DEFAULT_CA = Certificate.loadDefaults();
} catch (e:Dynamic) {}
}
caCert = DEFAULT_CA;
verifyCert = DEFAULT_VERIFY_CERT;
}
public override function connect(host:sys.net.Host, port:Int):Void {
try {
conf = buildSSLConfig(false);
ssl = NativeSsl.ssl_new(conf);
handshakeDone = false;
NativeSsl.ssl_set_socket(ssl, __s);
if (hostname == null)
hostname = host.host;
if (hostname != null)
NativeSsl.ssl_set_hostname(ssl, hostname);
NativeSocket.socket_connect(__s, host.ip, port);
handshake();
} catch (s:String) {
if (s == "Invalid socket handle")
throw "Failed to connect on " + host.host + ":" + port;
else
cpp.Lib.rethrow(s);
} catch (e:Dynamic) {
cpp.Lib.rethrow(e);
}
}
public function handshake():Void {
if (!handshakeDone) {
try {
NativeSsl.ssl_handshake(ssl);
handshakeDone = true;
} catch (e:Dynamic) {
if (e == "Blocking")
throw haxe.io.Error.Blocked;
else
cpp.Lib.rethrow(e);
}
}
}
public function setCA(cert:Certificate):Void {
caCert = cert;
}
public function setHostname(name:String):Void {
hostname = name;
}
public function setCertificate(cert:Certificate, key:Key):Void {
ownCert = cert;
ownKey = key;
}
public override function read():String {
handshake();
var b = NativeSsl.ssl_read(ssl);
if (b == null)
return "";
return haxe.io.Bytes.ofData(b).toString();
}
public override function write(content:String):Void {
handshake();
NativeSsl.ssl_write(ssl, haxe.io.Bytes.ofString(content).getData());
}
public override function close():Void {
if (ssl != null)
NativeSsl.ssl_close(ssl);
if (conf != null)
NativeSsl.conf_close(conf);
if (altSNIContexts != null)
sniCallback = null;
NativeSocket.socket_close(__s);
var input:SocketInput = cast input;
var output:SocketOutput = cast output;
@:privateAccess input.__s = output.__s = null;
input.close();
output.close();
}
public function addSNICertificate(cbServernameMatch:String->Bool, cert:Certificate, key:Key):Void {
if (altSNIContexts == null)
altSNIContexts = [];
altSNIContexts.push({match: cbServernameMatch, cert: cert, key: key});
}
public override function bind(host:sys.net.Host, port:Int):Void {
conf = buildSSLConfig(true);
NativeSocket.socket_bind(__s, host.ip, port);
}
public override function accept():Socket {
var c = NativeSocket.socket_accept(__s);
var ssl = NativeSsl.ssl_new(conf);
NativeSsl.ssl_set_socket(ssl, c);
var s = Type.createEmptyInstance(sys.ssl.Socket);
s.__s = c;
s.ssl = ssl;
s.input = new SocketInput(s);
s.output = new SocketOutput(s);
s.handshakeDone = false;
return s;
}
public function peerCertificate():sys.ssl.Certificate {
var x = NativeSsl.ssl_get_peer_certificate(ssl);
return x == null ? null : new sys.ssl.Certificate(x);
}
private function buildSSLConfig(server:Bool):CONF {
var conf:CONF = NativeSsl.conf_new(server);
if (ownCert != null && ownKey != null)
NativeSsl.conf_set_cert(conf, @:privateAccess ownCert.__x, @:privateAccess ownKey.__k);
if (altSNIContexts != null) {
sniCallback = function(servername) {
var servername = new String(cast servername);
for (c in altSNIContexts) {
if (c.match(servername))
return @:privateAccess {
key:c.key.__k, cert:c.cert.__x
};
}
if (ownKey != null && ownCert != null)
return @:privateAccess {
key:ownKey.__k, cert:ownCert.__x
};
return null;
}
NativeSsl.conf_set_servername_callback(conf, sniCallback);
}
if (caCert != null)
NativeSsl.conf_set_ca(conf, caCert == null ? null : @:privateAccess caCert.__x);
if (verifyCert == null)
NativeSsl.conf_set_verify(conf, 2);
else
NativeSsl.conf_set_verify(conf, verifyCert ? 1 : 0);
return conf;
}
static function __init__():Void {
NativeSsl.init();
}
}

View File

@ -0,0 +1,44 @@
/*
* 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
class Deque<T> {
var q:Dynamic;
public function new() {
q = untyped __global__.__hxcpp_deque_create();
}
public function add(i:T):Void {
untyped __global__.__hxcpp_deque_add(q, i);
}
public function push(i:T):Void {
untyped __global__.__hxcpp_deque_push(q, i);
}
public function pop(block:Bool):Null<T> {
return untyped __global__.__hxcpp_deque_pop(q, block);
}
}

View File

@ -0,0 +1,40 @@
/*
* 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
class Lock {
var l:Dynamic;
public function new() {
l = untyped __global__.__hxcpp_lock_create();
}
public function wait(?timeout:Float = -1):Bool {
return untyped __global__.__hxcpp_lock_wait(l, timeout);
}
public function release():Void {
untyped __global__.__hxcpp_lock_release(l);
}
}

View File

@ -0,0 +1,44 @@
/*
* 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
class Mutex {
var m:Dynamic;
public function new() {
m = untyped __global__.__hxcpp_mutex_create();
}
public function acquire():Void {
untyped __global__.__hxcpp_mutex_acquire(m);
}
public function tryAcquire():Bool {
return untyped __global__.__hxcpp_mutex_try(m);
}
public function release():Void {
untyped __global__.__hxcpp_mutex_release(m);
}
}

View File

@ -0,0 +1,189 @@
/*
* 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;
private typedef ThreadImpl = HaxeThread;
abstract Thread(ThreadImpl) from ThreadImpl {
public var events(get,never):EventLoop;
public inline function sendMessage(msg:Dynamic):Void {
this.sendMessage(msg);
}
public static inline function current():Thread {
return HaxeThread.current();
}
public static inline function create(job:()->Void):Thread {
return HaxeThread.create(job, false);
}
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 function readMessage(block:Bool):Dynamic {
return HaxeThread.readMessage(block);
}
function get_events():EventLoop {
if(this.events == null)
throw new NoEventLoopException();
return this.events;
}
@:keep
static public function processEvents() {
HaxeThread.current().events.loop();
}
}
@:callable
@:coreType
private abstract NativeThreadHandle {}
private typedef ThreadHandle = NativeThreadHandle;
private class HaxeThread {
static var threads:Array<{thread:HaxeThread, handle:ThreadHandle}>;
static var threadsMutex:Mutex;
static var mainThreadHandle:ThreadHandle;
static var mainThread:HaxeThread;
static function __init__() {
threads = [];
threadsMutex = new Mutex();
mainThreadHandle = currentHandle();
mainThread = new HaxeThread(currentHandle());
mainThread.events = new EventLoop();
}
public var events(default,null):Null<EventLoop>;
public var handle:ThreadHandle;
final messages = new Deque<Dynamic>();
static public function current():HaxeThread {
var handle = currentHandle();
if(handle == mainThreadHandle) {
return mainThread;
}
threadsMutex.acquire();
var thread = null;
for(item in threads) {
if(item.handle == handle) {
thread = item.thread;
break;
}
}
if(thread == null) {
thread = new HaxeThread(handle);
threads.push({thread:thread, handle:handle});
}
threadsMutex.release();
return thread;
}
public static function create(job:()->Void, withEventLoop:Bool):Thread {
var item = {handle:null, thread:new HaxeThread(null)};
threadsMutex.acquire();
var index = threads.push(item);
threadsMutex.release();
if(withEventLoop)
item.thread.events = new EventLoop();
item.handle = createHandle(() -> {
if(item.thread.handle == null) {
item.handle = currentHandle();
item.thread.handle = item.handle;
}
try {
job();
if(withEventLoop)
item.thread.events.loop();
} catch(e) {
dropThread(item, index);
throw e;
}
dropThread(item, index);
});
item.thread.handle = item.handle;
return item.thread;
}
public static function runWithEventLoop(job:()->Void):Void {
var thread = current();
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();
}
}
static function dropThread(item, probableIndex:Int) {
threadsMutex.acquire();
if(threads[probableIndex] == item) {
threads.splice(probableIndex, 1);
} else {
for(i => item2 in threads) {
if(item2 == item) {
threads.splice(i, 1);
break;
}
}
}
threadsMutex.release();
}
function new(h:ThreadHandle):Void {
handle = h;
}
public inline function sendMessage(msg:Dynamic):Void {
messages.add(msg);
}
static #if !scriptable inline #end function currentHandle():ThreadHandle {
return untyped __global__.__hxcpp_thread_current();
}
static #if !scriptable inline #end function createHandle(callb:Void->Void):ThreadHandle {
return untyped __global__.__hxcpp_thread_create(callb);
}
public static #if !scriptable inline #end function readMessage(block:Bool):Dynamic {
return current().messages.pop(block);
}
}

View File

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