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,147 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package sys;
@:coreApi
@:access(Sys)
class FileSystem {
public static function exists(path:String):Bool {
return sys_exists(Sys.getPath(makeCompatiblePath(path)));
}
public static function rename(path:String, newPath:String):Void {
if (!sys_rename(Sys.getPath(path), Sys.getPath(newPath)))
throw new Sys.SysError("Failed to rename " + path + " to " + newPath);
}
public static function stat(path:String):FileStat {
var values = sys_stat(Sys.getPath(makeCompatiblePath(path)));
if (values == null)
throw new Sys.SysError("Failed to stat " + path);
return {
gid: values[0],
uid: values[1],
atime: @:privateAccess Date.fromInt(values[2]),
mtime: @:privateAccess Date.fromInt(values[3]),
ctime: @:privateAccess Date.fromInt(values[4]),
size: values[5],
dev: values[6],
ino: values[7],
nlink: values[8],
rdev: values[9],
mode: values[10],
};
}
public static function fullPath(relPath:String):String {
return Sys.makePath(sys_full_path(Sys.getPath(relPath)));
}
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 {
return sys_is_dir(Sys.getPath(makeCompatiblePath(path)));
}
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))
if (!sys_create_dir(Sys.getPath(part), 493))
throw new Sys.SysError("Failed to create directory " + part);
}
}
public static function deleteFile(path:String):Void {
if (!sys_delete(Sys.getPath(path)))
throw new Sys.SysError("Can't delete file " + path);
}
public static function deleteDirectory(path:String):Void {
if (!sys_remove_dir(Sys.getPath(path)))
throw new Sys.SysError("Can't delete directory " + path);
}
public static function readDirectory(path:String):Array<String> {
var content = sys_read_dir(Sys.getPath(path));
if (content == null)
throw new Sys.SysError("Failed to read directory " + path);
return [for (c in content) Sys.makePath(c)];
}
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);
}
}
@:hlNative("std", "sys_read_dir") static function sys_read_dir(path:hl.Bytes):hl.NativeArray<hl.Bytes> {
return null;
}
@:hlNative("std", "sys_create_dir") static function sys_create_dir(path:hl.Bytes, rights:Int):Bool {
return false;
}
@:hlNative("std", "sys_is_dir") static function sys_is_dir(path:hl.Bytes):Bool {
return false;
}
@:hlNative("std", "sys_stat") static function sys_stat(path:hl.Bytes):hl.NativeArray<Int> {
return null;
}
@:hlNative("std", "sys_rename") static function sys_rename(path:hl.Bytes, to:hl.Bytes):Bool {
return true;
}
@:hlNative("std", "sys_delete") static function sys_delete(path:hl.Bytes):Bool {
return true;
};
@:hlNative("std", "sys_full_path") static function sys_full_path(path:hl.Bytes):hl.Bytes {
return null;
}
@:hlNative("std", "sys_remove_dir") static function sys_remove_dir(path:hl.Bytes):Bool {
return true;
}
@:hlNative("std", "sys_exists") static function sys_exists(path:hl.Bytes):Bool {
return true;
}
}

View File

@ -0,0 +1,36 @@
/*
* 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;
interface Connection {
function request(s:String):ResultSet;
function close():Void;
function escape(s:String):String;
function quote(s:String):String;
function addValue(s:StringBuf, v:Dynamic):Void;
function lastInsertId():Int;
function dbName():String;
function startTransaction():Void;
function commit():Void;
function rollback():Void;
}

View File

@ -0,0 +1,250 @@
/*
* 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 MysqlParams {
public var host:hl.Bytes;
public var user:hl.Bytes;
public var pass:hl.Bytes;
public var socket:hl.Bytes;
public var port:Int;
public function new() {}
}
private typedef ConnectionHandler = hl.Abstract<"mysql_cnx">;
private typedef ResultHandler = hl.Abstract<"mysql_result">;
@:hlNative("mysql")
private class MysqlResultSet implements sys.db.ResultSet {
public var length(get, null):Int;
public var nfields(get, null):Int;
private var r:ResultHandler;
private var cache:Dynamic;
function new(r) {
this.r = r;
}
private function get_length() {
return result_get_length(r);
}
private function get_nfields() {
return 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 = 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) {
var v = result_get(r, n);
if (v == null)
return null;
return @:privateAccess String.fromUTF8(v);
}
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> {
var a = result_get_fields_names(r);
return [for (v in a) @:privateAccess String.fromUTF8(v)];
}
static function result_get_length(r:ResultHandler):Int {
return 0;
}
static function result_get_nfields(r:ResultHandler):Int {
return 0;
}
static function result_next(r:ResultHandler):Dynamic {
return null;
}
static function result_get(r:ResultHandler, n:Int):hl.Bytes {
return null;
}
static function result_get_int(r:ResultHandler, n:Int):Int {
return 0;
}
static function result_get_float(r:ResultHandler, n:Int):Float {
return 0.;
}
static function result_get_fields_names(r:ResultHandler):hl.NativeArray<hl.Bytes> {
return null;
}
}
@:hlNative("mysql")
private class MysqlConnection implements Connection {
var h:ConnectionHandler;
function new(h) {
this.h = h;
}
public function close() {
if (h != null)
close_wrap(h);
h = null;
}
public function request(s:String) @:privateAccess {
var len = 0;
var b = s.bytes.utf16ToUtf8(0, len);
return new MysqlResultSet(request_wrap(h, b, len));
}
public function escape(s:String) @:privateAccess {
var len = 0;
var utf = s.bytes.utf16ToUtf8(0, len);
return String.fromUTF8(escape_wrap(h, utf, len));
}
public function quote(s:String) {
return "'" + escape(s) + "'";
}
public function addValue(s:StringBuf, v:Dynamic) {
if (v == null) {
s.add(null);
return;
}
var t = hl.Type.getDynamic(v).kind;
if (t == HI32 || t == HF64)
s.add(v);
else if (t == HBool)
s.addChar(if (v) "1".code else "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");
}
static function close_wrap(h:ConnectionHandler) {}
static function connect_wrap(p:MysqlParams):ConnectionHandler {
return null;
}
static function select_db_wrap(h:ConnectionHandler, db:hl.Bytes):Bool {
return false;
}
@:hlNative("mysql", "request")
static function request_wrap(h:ConnectionHandler, rq:hl.Bytes, rqLen:Int):ResultHandler {
return null;
}
@:hlNative("mysql", "escape")
static function escape_wrap(h:ConnectionHandler, str:hl.Bytes, len:Int):hl.Bytes {
return null;
}
static function setConvFuns(fstring:Dynamic, fbytes:Dynamic, fdate:Dynamic, fjson:Dynamic) {};
}
class Mysql {
static var INIT_DONE = false;
public static function connect(params:{
host:String,
?port:Int,
user:String,
pass:String,
?socket:String,
?database:String
}):sys.db.Connection@:privateAccess {
if (!INIT_DONE) {
INIT_DONE = true;
MysqlConnection.setConvFuns(function(v:hl.Bytes) return @:privateAccess String.fromUTF8(v),
function(v:hl.Bytes, len:Int) return new haxe.io.Bytes(v, len), function(t) return Date.fromTime(1000. * t),
function(v:hl.Bytes) return haxe.Json.parse(@:privateAccess String.fromUTF8(v)));
}
var p = new MysqlParams();
p.host = params.host == null ? null : params.host.toUtf8();
p.user = params.user.toUtf8();
p.pass = params.pass.toUtf8();
p.socket = params.socket == null ? null : params.socket.toUtf8();
p.port = params.port == null ? 3306 : params.port;
var cnx = new MysqlConnection(MysqlConnection.connect_wrap(p));
if (params.database != null && !MysqlConnection.select_db_wrap(cnx.h, params.database.toUtf8())) {
cnx.close();
throw "Failed to select database " + params.database;
}
return cnx;
}
}

View File

@ -0,0 +1,36 @@
/*
* 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;
interface ResultSet {
var length(get, null):Int;
var nfields(get, null):Int;
function hasNext():Bool;
function next():Dynamic;
function results():List<Dynamic>;
function getResult(n:Int):String;
function getIntResult(n:Int):Int;
function getFloatResult(n:Int):Float;
function getFieldsNames():Null<Array<String>>;
}

View File

@ -0,0 +1,283 @@
/*
* 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;
import haxe.crypto.BaseCode;
private typedef SqliteConnectionHandle = hl.Abstract<"sqlite_database">;
private typedef SqliteResultHandle = hl.Abstract<"sqlite_result">;
@:hlNative("sqlite")
private class SqliteLib {
public static function connect(path:hl.Bytes):SqliteConnectionHandle {
return null;
}
public static function close(c:SqliteConnectionHandle):Void {}
public static function request(c:SqliteConnectionHandle, sql:hl.Bytes):SqliteResultHandle {
return null;
}
public static function last_id(c:SqliteConnectionHandle):Int {
return 0;
}
public static function result_next(c:SqliteResultHandle):hl.NativeArray<Dynamic> {
return null;
}
public static function result_get(c:SqliteResultHandle, n:Int):Null<hl.Bytes> {
return null;
}
public static function result_get_int(c:SqliteResultHandle, n:Int):Null<Int> {
return 0;
}
public static function result_get_float(c:SqliteResultHandle, n:Int):Null<Float> {
return .0;
}
public static function result_get_length(c:SqliteResultHandle):Null<Int> {
return 0;
}
public static function result_get_nfields(c:SqliteResultHandle):Int {
return 0;
}
public static function result_get_fields(c:SqliteResultHandle):hl.NativeArray<hl.Bytes> {
return null;
}
}
@:access(Sys)
@:access(String)
private class SqliteConnection implements Connection {
var c:SqliteConnectionHandle;
public function new(file:String) {
c = SqliteLib.connect(file.bytes);
}
public function close():Void {
SqliteLib.close(c);
}
public function request(s:String):ResultSet {
try {
var r:SqliteResultHandle = SqliteLib.request(c, s.bytes);
return new SqliteResultSet(r);
} catch (e:String) {
throw 'Error while executing $s ($e)';
}
return null;
}
public function escape(s:String):String {
return s.split("'").join("''");
}
public function quote(s:String):String {
if (s.indexOf("\000") >= 0)
return "x'" + BaseCode.encode(s, "0123456789ABCDEF") + "'";
return "'" + s.split("'").join("''") + "'";
}
public function addValue(s:StringBuf, v:Dynamic):Void {
switch (Type.typeof(v)) {
case TNull, TInt:
s.add(v);
case TBool:
s.add(v ? 1 : 0);
case TClass(haxe.io.Bytes):
s.add("x'");
s.add((v : haxe.io.Bytes).toHex());
s.add("'");
case _:
s.add(quote(Std.string(v)));
}
}
public function lastInsertId():Int {
return SqliteLib.last_id(c);
}
public function dbName():String {
return "SQLite";
}
public function startTransaction():Void {
request("BEGIN TRANSACTION");
}
public function commit():Void {
request("COMMIT");
}
public function rollback():Void {
request("ROLLBACK");
}
}
@:access(String)
private class SqliteResultSet implements ResultSet {
public var length(get, null):Int;
public var nfields(get, null):Int;
var names:Array<String>;
var cache:List<Dynamic>;
var r:SqliteResultHandle;
public function new(r:SqliteResultHandle) {
cache = new List();
this.r = r;
hasNext(); // execute the request
}
function get_length():Int {
if (nfields != 0) {
while (true) {
var c = doNext();
if (c == null)
break;
cache.add(c);
}
return cache.length;
}
return SqliteLib.result_get_length(r);
}
function get_nfields():Int {
return SqliteLib.result_get_nfields(r);
}
public function hasNext():Bool {
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 doNext();
}
private function doNext():Dynamic {
var o:Dynamic = {};
var a = SqliteLib.result_next(r);
if (a == null)
return null;
var names = getFieldsNames();
var i = 0;
var l = names.length;
while (i < l) {
var n:String = names[i];
var v:Dynamic = a[i];
switch (hl.Type.getDynamic(v).kind) {
case hl.Type.TypeKind.HArray:
var pair:hl.NativeArray<Dynamic> = v;
var bytes:hl.Bytes = pair[0];
var len:Int = pair[1];
var data = new haxe.io.BytesData(bytes, len);
Reflect.setField(o, n, haxe.io.Bytes.ofData(data));
case hl.Type.TypeKind.HBytes:
Reflect.setField(o, n, String.fromUCS2(v));
default:
Reflect.setField(o, n, v);
}
i++;
}
return o;
}
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):String {
var bytes = SqliteLib.result_get(r, n);
if (bytes == null)
return null;
return String.fromUCS2(bytes);
}
public function getIntResult(n:Int):Int {
return SqliteLib.result_get_int(r, n);
}
public function getFloatResult(n:Int):Float {
return SqliteLib.result_get_float(r, n);
}
public function getFieldsNames():Array<String> {
if (this.names != null)
return this.names;
this.names = [];
var names = SqliteLib.result_get_fields(r);
var i = 0;
var l = names.length;
while (i < l) {
var name = String.fromUCS2(names[i]);
this.names.push(name);
i++;
}
return this.names;
}
}
@:coreApi class Sqlite {
public static function open(file:String):Connection {
return new SqliteConnection(file);
}
}

View File

@ -0,0 +1,106 @@
/*
* 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;
#if doc_gen
enum FileHandle {}
#else
typedef FileHandle = hl.Abstract<"hl_fdesc">;
#end
@:access(Sys)
@:coreApi class File {
public static function getContent(path:String):String {
var bytes = file_contents(Sys.getPath(path), null);
if (bytes == null)
throw new Sys.SysError("Can't read " + path);
return @:privateAccess String.fromUTF8(bytes);
}
public static function getBytes(path:String):haxe.io.Bytes {
var size = 0;
var bytes = file_contents(Sys.getPath(path), size);
if (bytes == null)
throw new Sys.SysError("Can't read " + path);
return @:privateAccess new haxe.io.Bytes(bytes, size);
}
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 {
var f = file_open(Sys.getPath(path), 0, binary);
if (f == null)
throw new Sys.SysError("Can't open " + path);
return @:privateAccess new FileInput(f);
}
public static function write(path:String, binary:Bool = true):FileOutput {
var f = file_open(Sys.getPath(path), 1, binary);
if (f == null)
throw new Sys.SysError("Can't open " + path + " for writing");
return @:privateAccess new FileOutput(f);
}
public static function append(path:String, binary:Bool = true):FileOutput {
var f = file_open(Sys.getPath(path), 2, binary);
if (f == null)
throw new Sys.SysError("Can't open " + path + " for append");
return @:privateAccess new FileOutput(f);
}
public static function update(path:String, binary:Bool = true):FileOutput {
if (!FileSystem.exists(path)) {
write(path).close();
}
var f = file_open(Sys.getPath(path), 3, binary);
if (f == null)
throw new Sys.SysError("Can't open " + path + " for update");
return @:privateAccess new FileOutput(f);
}
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();
}
@:hlNative("std", "file_open") static function file_open(path:hl.Bytes, mode:Int, binary:Bool):FileHandle {
return null;
}
@:hlNative("std", "file_contents") static function file_contents(path:hl.Bytes, size:hl.Ref<Int>):hl.Bytes {
return null;
}
}

View File

@ -0,0 +1,97 @@
/*
* 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.File;
@:coreApi class FileInput extends haxe.io.Input {
private var __f:FileHandle;
function new(f:FileHandle):Void {
__f = f;
}
public override function readByte():Int {
var c = file_read_char(__f);
if (c < 0)
throw new haxe.io.Eof();
return c;
}
public override function readBytes(s:haxe.io.Bytes, p:Int, l:Int):Int {
if (p < 0 || l < 0 || p + l > s.length)
throw haxe.io.Error.OutsideBounds;
var v = file_read(__f, s.getData(), p, l);
if (v <= 0)
throw new haxe.io.Eof();
return v;
}
public override function close():Void {
super.close();
file_close(__f);
__f = null;
}
public function seek(p:Int, pos:FileSeek):Void {
if (!file_seek(__f, p, switch (pos) {
case SeekBegin: 0;
case SeekCur: 1;
case SeekEnd: 2;
}))
throw haxe.io.Error.Custom("seek() failure");
}
public function tell():Int {
var p = file_tell(__f);
if (p < 0)
throw haxe.io.Error.Custom("tell() failure");
return p;
}
public function eof():Bool {
return file_eof(__f);
}
@:hlNative("std", "file_eof") static function file_eof(f:FileHandle):Bool {
return false;
}
@:hlNative("std", "file_read") static function file_read(f:FileHandle, bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
@:hlNative("std", "file_read_char") static function file_read_char(f:FileHandle):Int {
return 0;
}
@:hlNative("std", "file_close") static function file_close(f:FileHandle):Void {}
@:hlNative("std", "file_seek") static function file_seek(f:FileHandle, pos:Int, from:Int):Bool {
return true;
}
@:hlNative("std", "file_tell") static function file_tell(f:FileHandle):Int {
return 0;
}
}

View File

@ -0,0 +1,86 @@
/*
* 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.File;
@:coreApi class FileOutput extends haxe.io.Output {
private var __f:FileHandle;
function new(f:FileHandle):Void {
__f = f;
}
public override function writeByte(c:Int):Void {
if (!file_write_char(__f, c))
throw new haxe.io.Eof();
}
public override function writeBytes(s:haxe.io.Bytes, p:Int, l:Int):Int {
if (p < 0 || l < 0 || p + l > s.length)
throw haxe.io.Error.OutsideBounds;
var v = file_write(__f, s.getData(), p, l);
if (v <= 0)
throw new haxe.io.Eof();
return v;
}
public override function flush():Void {
if (!file_flush(__f))
throw haxe.io.Error.Custom("flush() failure");
}
public override function close():Void {
super.close();
@:privateAccess FileInput.file_close(__f);
__f = null;
}
public function seek(p:Int, pos:FileSeek):Void {
if (@:privateAccess !FileInput.file_seek(__f, p, switch (pos) {
case SeekBegin: 0;
case SeekCur: 1;
case SeekEnd: 2;
}))
throw haxe.io.Error.Custom("seek() failure");
}
public function tell():Int {
var p = @:privateAccess FileInput.file_tell(__f);
if (p < 0)
throw haxe.io.Error.Custom("tell() failure");
return p;
}
@:hlNative("std", "file_flush") static function file_flush(f:FileHandle):Bool {
return true;
}
@:hlNative("std", "file_write") static function file_write(f:FileHandle, bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
@:hlNative("std", "file_write_char") static function file_write_char(f:FileHandle, v:Int):Bool {
return true;
}
}

View File

@ -0,0 +1,201 @@
/*
* 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;
private typedef ProcessHandle = hl.Abstract<"hl_process">;
private class Stdin extends haxe.io.Output {
var p:Dynamic;
var buf:haxe.io.Bytes;
public function new(p) {
this.p = p;
buf = haxe.io.Bytes.alloc(1);
}
public override function close() {
super.close();
_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 {
var v = _stdin_write(p, buf.getData().bytes, pos, len);
if (v < 0)
throw new haxe.io.Eof();
return v;
}
@:hlNative("std", "process_stdin_write") static function _stdin_write(p:ProcessHandle, bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
@:hlNative("std", "process_stdin_close") static function _stdin_close(p:ProcessHandle):Bool {
return false;
}
}
private class Stdout extends haxe.io.Input {
var p:ProcessHandle;
var out:Bool;
var buf:haxe.io.Bytes;
public function new(p, 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 v = out ? _stdout_read(p, str.getData().bytes, pos, len) : _stderr_read(p, str.getData().bytes, pos, len);
if (v < 0)
throw new haxe.io.Eof();
return v;
}
@:hlNative("std", "process_stdout_read") static function _stdout_read(p:ProcessHandle, bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
@:hlNative("std", "process_stderr_read") static function _stderr_read(p:ProcessHandle, bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
}
@:access(Sys)
@:coreApi class Process {
var p:ProcessHandle;
public var stdout(default, null):haxe.io.Input;
public var stderr(default, null):haxe.io.Input;
public var stdin(default, null):haxe.io.Output;
static var isWin = Sys.systemName() == "Windows";
public function new(cmd:String, ?args:Array<String>, ?detached:Bool):Void {
var runCmd = cmd;
if (isWin) {
var b = new StringBuf();
if (args == null) {
var exe = Sys.getEnv("COMSPEC");
if (exe == null)
exe = "cmd.exe";
b.add("\"");
b.add(exe);
b.add("\" /C \"");
b.add(cmd);
b.addChar('"'.code);
} else {
b.addChar('"'.code);
b.add(cmd);
b.addChar('"'.code);
for (a in args) {
b.add(" \"");
var bsCount = 0;
for (i in 0...a.length) {
switch (StringTools.fastCodeAt(a, i)) {
case '"'.code:
for (i in 0...bsCount * 2)
b.addChar('\\'.code);
bsCount = 0;
b.add("\\\"");
case '\\'.code:
bsCount++;
case c:
for (i in 0...bsCount)
b.addChar('\\'.code);
bsCount = 0;
b.addChar(c);
}
}
// Add remaining backslashes, if any.
for (i in 0...bsCount * 2)
b.addChar('\\'.code);
b.addChar('"'.code);
}
args = null;
}
runCmd = b.toString();
}
@:privateAccess {
var aargs = null;
if (args != null) {
aargs = new hl.NativeArray<hl.Bytes>(args.length);
for (i in 0...args.length)
aargs[i] = Sys.getPath(args[i]);
}
p = _run(Sys.getPath(runCmd), aargs, detached);
}
if (p == null)
throw new Sys.SysError("Process creation failure : " + cmd);
stdin = new Stdin(p);
stdout = new Stdout(p, true);
stderr = new Stdout(p, false);
}
public function getPid():Int {
return _pid(p);
}
public function exitCode(block:Bool = true):Null<Int> {
var running = false;
var code = _exit(p, block == false ? new hl.Ref(running) : null);
if (block == false)
return running ? null : code;
return code;
}
public function close():Void {
_close(p);
}
public function kill():Void {
_kill(p);
}
@:hlNative("std", "process_run") static function _run(cmd:hl.Bytes, args:hl.NativeArray<hl.Bytes>, detached:Bool):ProcessHandle {
return null;
}
@:hlNative("std", "process_exit") static function _exit(p:ProcessHandle, running:hl.Ref<Bool>):Int {
return 0;
}
@:hlNative("std", "process_pid") static function _pid(p:ProcessHandle):Int {
return 0;
}
@:hlNative("std", "process_close") static function _close(p:ProcessHandle):Void {}
@:hlNative("std", "process_kill") static function _kill(p:ProcessHandle):Void {}
}

View File

@ -0,0 +1,65 @@
/*
* 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;
@:coreApi
class Host {
public var host(default, null):String;
public var ip(default, null):Int;
public function new(name:String):Void {
host = name;
ip = host_resolve(@:privateAccess name.bytes.utf16ToUtf8(0, null));
if (ip == -1)
throw new Sys.SysError("Unresolved host " + name);
}
public function toString():String {
return @:privateAccess String.fromUTF8(host_to_string(ip));
}
public function reverse():String {
return @:privateAccess String.fromUTF8(host_reverse(ip));
}
public static function localhost():String {
return @:privateAccess String.fromUTF8(host_local());
}
@:hlNative("std", "host_resolve") static function host_resolve(name:hl.Bytes):Int {
return 0;
}
@:hlNative("std", "host_reverse") static function host_reverse(host:Int):hl.Bytes {
return null;
}
@:hlNative("std", "host_to_string") static function host_to_string(host:Int):hl.Bytes {
return null;
}
@:hlNative("std", "host_local") static function host_local():hl.Bytes {
return null;
}
}

View File

@ -0,0 +1,334 @@
/*
* 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;
#if doc_gen
@:noDoc enum SocketHandle {}
#else
@:noDoc typedef SocketHandle = hl.Abstract<"hl_socket">;
#end
private class SocketOutput extends haxe.io.Output {
var sock:Socket;
public function new(s) {
this.sock = s;
}
public override function writeByte(c:Int) {
var k = socket_send_char(@:privateAccess sock.__s, c);
if (k < 0) {
if (k == -1)
throw Blocked;
throw new haxe.io.Eof();
}
}
public override function writeBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
if (pos < 0 || len < 0 || pos + len > buf.length)
throw haxe.io.Error.OutsideBounds;
var n = socket_send(@:privateAccess sock.__s, buf.getData().bytes, pos, len);
if (n < 0) {
if (n == -1)
throw Blocked;
throw new haxe.io.Eof();
}
return n;
}
public override function close() {
sock.close();
}
@:hlNative("std", "socket_send_char") static function socket_send_char(s:SocketHandle, c:Int):Int {
return 0;
}
@:hlNative("std", "socket_send") static function socket_send(s:SocketHandle, bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
}
private class SocketInput extends haxe.io.Input {
var sock:Socket;
public function new(s) {
sock = s;
}
public override function readByte():Int {
var c = socket_recv_char(@:privateAccess sock.__s);
if (c < 0) {
if (c == -1)
throw Blocked;
throw new haxe.io.Eof();
}
return c;
}
public override function readBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
if (pos < 0 || len < 0 || pos + len > buf.length)
throw haxe.io.Error.OutsideBounds;
var r = socket_recv(@:privateAccess sock.__s, buf.getData().bytes, pos, len);
if (r <= 0) {
if (r == -1)
throw Blocked;
throw new haxe.io.Eof();
}
return r;
}
public override function close() {
sock.close();
}
@:hlNative("std", "socket_recv") static function socket_recv(s:SocketHandle, bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
@:hlNative("std", "socket_recv_char") static function socket_recv_char(s:SocketHandle):Int {
return 0;
}
}
@:coreApi
@:keepInit
class Socket {
private var __s:SocketHandle;
public var input(default, null):haxe.io.Input;
public var output(default, null):haxe.io.Output;
public var custom:Dynamic;
static function __init__():Void {
socket_init();
}
public function new():Void {
init();
}
function init():Void {
if (__s == null)
__s = socket_new(false);
input = new SocketInput(this);
output = new SocketOutput(this);
}
public function close():Void {
if (__s != null) {
socket_close(__s);
__s = null;
}
}
public function read():String {
return input.readAll().toString();
}
public function write(content:String):Void {
output.writeString(content);
}
public function connect(host:Host, port:Int):Void {
if (!socket_connect(__s, host.ip, port))
throw new Sys.SysError("Failed to connect on " + host.toString() + ":" + port);
}
public function listen(connections:Int):Void {
if (!socket_listen(__s, connections))
throw new Sys.SysError("listen() failure");
}
public function shutdown(read:Bool, write:Bool):Void {
if (!socket_shutdown(__s, read, write))
throw new Sys.SysError("shutdown() failure");
}
public function bind(host:Host, port:Int):Void {
if (!socket_bind(__s, host.ip, port))
throw new Sys.SysError("Cannot bind socket on " + host + ":" + port);
}
public function accept():Socket {
var c = socket_accept(__s);
if (c == null)
return null;
var s:Socket = untyped $new(Socket);
s.__s = c;
s.input = new SocketInput(s);
s.output = new SocketOutput(s);
return s;
}
public function peer():{host:Host, port:Int} {
var ip = 0, port = 0;
if (!socket_peer(__s, ip, port))
return null;
var h:Host = untyped $new(Host);
@:privateAccess h.ip = ip;
return {host: h, port: port};
}
public function host():{host:Host, port:Int} {
var ip = 0, port = 0;
if (!socket_host(__s, ip, port))
return null;
var h:Host = untyped $new(Host);
@:privateAccess h.ip = ip;
return {host: h, port: port};
}
public function setTimeout(timeout:Float):Void {
if (!socket_set_timeout(__s, timeout))
throw new Sys.SysError("setTimeout() failure");
}
public function waitForRead():Void {
select([this], null, null, null);
}
public function setBlocking(b:Bool):Void {
if (!socket_set_blocking(__s, b))
throw new Sys.SysError("setBlocking() failure");
}
public function setFastSend(b:Bool):Void {
if (!socket_set_fast_send(__s, b))
throw new Sys.SysError("setFastSend() failure");
}
// TODO : use TLS when multithread added
static var tmp:hl.Bytes = null;
static var curTmpSize = 0;
static function makeArray(a:Array<Socket>):hl.NativeArray<SocketHandle> {
if (a == null)
return null;
var arr = new hl.NativeArray(a.length);
for (i in 0...a.length)
arr[i] = a[i].__s;
return arr;
}
static function outArray(a:hl.NativeArray<SocketHandle>, original:Array<Socket>):Array<Socket> {
var out = [];
if (a == null)
return out;
var i = 0, p = 0;
var max = original.length;
while (i < max) {
var sh = a[i++];
if (sh == null)
break;
while (original[p].__s != sh)
p++;
out.push(original[p++]);
}
return out;
}
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 sread = makeArray(read);
var swrite = makeArray(write);
var sothers = makeArray(others);
var tmpSize = 0;
if (sread != null)
tmpSize += socket_fd_size(sread.length);
if (swrite != null)
tmpSize += socket_fd_size(swrite.length);
if (sothers != null)
tmpSize += socket_fd_size(sothers.length);
if (tmpSize > curTmpSize) {
tmp = new hl.Bytes(tmpSize);
curTmpSize = tmpSize;
}
if (!socket_select(sread, swrite, sothers, tmp, curTmpSize, timeout == null ? -1 : timeout))
throw "Error while waiting on socket";
return {
read: outArray(sread, read),
write: outArray(swrite, write),
others: outArray(sothers, others),
};
}
@:hlNative("std", "socket_init") static function socket_init():Void {}
@:hlNative("std", "socket_new") static function socket_new(udp:Bool):SocketHandle {
return null;
}
@:hlNative("std", "socket_close") static function socket_close(s:SocketHandle):Void {}
@:hlNative("std", "socket_connect") static function socket_connect(s:SocketHandle, host:Int, port:Int):Bool {
return true;
}
@:hlNative("std", "socket_listen") static function socket_listen(s:SocketHandle, count:Int):Bool {
return true;
}
@:hlNative("std", "socket_bind") static function socket_bind(s:SocketHandle, host:Int, port:Int):Bool {
return true;
}
@:hlNative("std", "socket_accept") static function socket_accept(s:SocketHandle):SocketHandle {
return null;
}
@:hlNative("std", "socket_peer") static function socket_peer(s:SocketHandle, host:hl.Ref<Int>, port:hl.Ref<Int>):Bool {
return true;
}
@:hlNative("std", "socket_host") static function socket_host(s:SocketHandle, host:hl.Ref<Int>, port:hl.Ref<Int>):Bool {
return true;
}
@:hlNative("std", "socket_set_timeout") static function socket_set_timeout(s:SocketHandle, timeout:Float):Bool {
return true;
}
@:hlNative("std", "socket_shutdown") static function socket_shutdown(s:SocketHandle, read:Bool, write:Bool):Bool {
return true;
}
@:hlNative("std", "socket_set_blocking") static function socket_set_blocking(s:SocketHandle, b:Bool):Bool {
return true;
}
@:hlNative("std", "socket_set_fast_send") static function socket_set_fast_send(s:SocketHandle, b:Bool):Bool {
return true;
}
@:hlNative("std", "socket_fd_size") static function socket_fd_size(count:Int):Int {
return 0;
}
@:hlNative("std", "socket_select") static function socket_select(read:hl.NativeArray<SocketHandle>, write:hl.NativeArray<SocketHandle>,
other:hl.NativeArray<SocketHandle>, tmpData:hl.Bytes, tmpSize:Int, timeout:Float):Bool {
return false;
}
}

View File

@ -0,0 +1,81 @@
/*
* 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 sys.net.Socket;
import haxe.io.Error;
class UdpSocket extends Socket {
public function new() {
super();
}
override function init():Void {
__s = Socket.socket_new(true);
super.init();
}
public function sendTo(buf:haxe.io.Bytes, pos:Int, len:Int, addr:Address):Int {
if (pos < 0 || len < 0 || pos + len > buf.length)
throw OutsideBounds;
var ret = socket_send_to(__s, (buf : hl.Bytes).offset(pos), len, addr.host, addr.port);
if (ret < 0) {
if (ret == -1)
throw Blocked;
throw new haxe.io.Eof();
}
return ret;
}
public function readFrom(buf:haxe.io.Bytes, pos:Int, len:Int, addr:Address):Int {
var host = 0, port = 0;
if (pos < 0 || len < 0 || pos + len > buf.length)
throw OutsideBounds;
var ret = socket_recv_from(__s, (buf : hl.Bytes).offset(pos), len, host, port);
if (ret <= 0) {
if (ret == -1)
throw Blocked;
throw new haxe.io.Eof();
}
addr.host = host;
addr.port = port;
return ret;
}
public function setBroadcast(b:Bool):Void {
if (!socket_set_broadcast(__s, b))
throw new Sys.SysError("setBroadcast() failure");
}
@:hlNative("std", "socket_send_to") static function socket_send_to(s:SocketHandle, bytes:hl.Bytes, len:Int, host:Int, port:Int):Int {
return 0;
}
@:hlNative("std", "socket_set_broadcast") static function socket_set_broadcast(s:SocketHandle, b:Bool):Bool {
return true;
}
@:hlNative("std", "socket_recv_from") static function socket_recv_from(s:SocketHandle, bytes:hl.Bytes, len:Int, host:hl.Ref<Int>, port:hl.Ref<Int>):Int {
return 0;
}
}

View File

@ -0,0 +1,182 @@
/*
* 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 sys.ssl.Lib;
@:noDoc
typedef CertificatePtr = hl.Abstract<"hl_ssl_cert">;
@:coreApi
class Certificate {
var __h:Null<Certificate>;
var __x:CertificatePtr;
@:allow(sys.ssl.Socket)
function new(x:CertificatePtr, ?h:Certificate) {
__x = x;
__h = h;
}
public static function loadFile(file:String):Certificate {
return new Certificate(cert_load_file(@:privateAccess file.toUtf8()));
}
public static function loadPath(path:String):Certificate {
return new Certificate(cert_load_path(@:privateAccess path.toUtf8()));
}
public static function fromString(str:String):Certificate {
return new Certificate(cert_add_pem(null, @:privateAccess str.toUtf8()));
}
public static function loadDefaults():Certificate {
var x = 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> {
var a = cert_get_altnames(__x);
return [for (e in a) @:privateAccess String.fromUCS2(e)];
}
public function subject(field:String):Null<String> {
var s = cert_get_subject(__x, @:privateAccess field.toUtf8());
return s == null ? null : @:privateAccess String.fromUCS2(cast s);
}
public function issuer(field:String):Null<String> {
var s = cert_get_issuer(__x, @:privateAccess field.toUtf8());
return s == null ? null : @:privateAccess String.fromUCS2(cast s);
}
function get_notBefore():Date {
var a = 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 = 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 = cert_get_next(__x);
return n == null ? null : new Certificate(n, __h == null ? this : __h);
}
public function add(pem:String):Void {
cert_add_pem(__x, @:privateAccess pem.toUtf8());
}
public function addDER(der:haxe.io.Bytes):Void {
cert_add_der(__x, @:privateAccess der.b, @:privateAccess der.length);
}
@:hlNative("ssl", "cert_load_defaults") static function cert_load_defaults():CertificatePtr {
return null;
}
@:hlNative("ssl", "cert_load_file") static function cert_load_file(file:hl.Bytes):CertificatePtr {
return null;
}
@:hlNative("ssl", "cert_load_path") static function cert_load_path(path:hl.Bytes):CertificatePtr {
return null;
}
@:hlNative("ssl", "cert_get_subject") static function cert_get_subject(cert:CertificatePtr, obj:hl.Bytes):hl.Bytes {
return null;
}
@:hlNative("ssl", "cert_get_issuer") static function cert_get_issuer(cert:CertificatePtr, obj:hl.Bytes):hl.Bytes {
return null;
}
@:hlNative("ssl", "cert_get_altnames") static function cert_get_altnames(cert:CertificatePtr):hl.NativeArray<hl.Bytes> {
return null;
}
@:hlNative("ssl", "cert_get_notbefore") static function cert_get_notbefore(cert:CertificatePtr):hl.NativeArray<Int> {
return null;
}
@:hlNative("ssl", "cert_get_notafter") static function cert_get_notafter(cert:CertificatePtr):hl.NativeArray<Int> {
return null;
}
@:hlNative("ssl", "cert_get_next") static function cert_get_next(cert:CertificatePtr):Null<CertificatePtr> {
return null;
}
@:hlNative("ssl", "cert_add_pem") static function cert_add_pem(cert:Null<CertificatePtr>, data:hl.Bytes):CertificatePtr {
return null;
}
@:hlNative("ssl", "cert_add_der") static function cert_add_der(cert:Null<CertificatePtr>, data:hl.Bytes, len:Int):CertificatePtr {
return null;
}
}

View File

@ -0,0 +1,98 @@
/*
* 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;
private typedef ConfigPtr = hl.Abstract<"mbedtls_ssl_config">;
private typedef ContextPtr = hl.Abstract<"mbedtls_ssl_context">;
@:keep class SNICbResult {
public var cert:Certificate.CertificatePtr;
public var key:Key.KeyPtr;
public function new(cert:Certificate, key:Key) {
this.cert = @:privateAccess cert.__x;
this.key = @:privateAccess key.__k;
}
}
@:hlNative("ssl", "ssl_")
abstract Context(ContextPtr) {
public function new(config) {
this = ssl_new(config);
}
public function close():Void {}
public function handshake():Int {
return 0;
}
public function recvChar():Int {
return 0;
}
public function sendChar(c:Int):Int {
return 0;
}
public function getPeerCertificate():Certificate.CertificatePtr {
return null;
}
public function recv(bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
public function send(bytes:hl.Bytes, pos:Int, len:Int):Int {
return 0;
}
public function setSocket(socket:sys.net.Socket.SocketHandle):Void {}
public function setHostname(name:hl.Bytes):Void {}
@:hlNative("ssl", "ssl_new") static function ssl_new(conf:Config):ContextPtr {
return null;
}
}
@:hlNative("ssl", "conf_")
abstract Config(ConfigPtr) {
public function new(server:Bool) {
this = conf_new(server);
}
public function setCert(cert:Certificate.CertificatePtr, pkey:Key.KeyPtr):Void {}
public function setCa(ca:Certificate.CertificatePtr):Void {}
public function close():Void {}
public function setVerify(mode:Int):Void {}
public function setServernameCallback(cb:hl.Bytes->SNICbResult):Void {}
@:hlNative("ssl", "conf_new") static function conf_new(server:Bool):ConfigPtr {
return null;
}
}

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.ssl;
import sys.ssl.Lib;
@:coreApi
class Digest {
public static function make(data:haxe.io.Bytes, alg:DigestAlgorithm):haxe.io.Bytes {
var size = 0;
var b = @:privateAccess dgst_make(data.b, data.length, (alg : String).toUtf8(), size);
return @:privateAccess new haxe.io.Bytes(b, size);
}
public static function sign(data:haxe.io.Bytes, privKey:Key, alg:DigestAlgorithm):haxe.io.Bytes {
var size = 0;
var b = @:privateAccess dgst_sign(data.b, data.length, privKey.__k, (alg : String).toUtf8(), size);
return @:privateAccess new haxe.io.Bytes(b, size);
}
public static function verify(data:haxe.io.Bytes, signature:haxe.io.Bytes, pubKey:Key, alg:DigestAlgorithm):Bool {
return @:privateAccess dgst_verify(data.b, data.length, signature.b, signature.length, pubKey.__k, (alg : String).toUtf8());
}
@:hlNative("ssl", "dgst_make") static function dgst_make(data:hl.Bytes, len:Int, alg:hl.Bytes, size:hl.Ref<Int>):hl.Bytes {
return null;
}
@:hlNative("ssl", "dgst_sign") static function dgst_sign(data:hl.Bytes, len:Int, key:sys.ssl.Key.KeyPtr, alg:hl.Bytes, size:hl.Ref<Int>):hl.Bytes {
return null;
}
@:hlNative("ssl", "dgst_verify") static function dgst_verify(data:hl.Bytes, dlen:Int, sign:hl.Bytes, slen:Int, key:sys.ssl.Key.KeyPtr, alg:hl.Bytes):Bool {
return false;
}
}

View File

@ -0,0 +1,62 @@
/*
* 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 sys.ssl.Lib;
@:noDoc
typedef KeyPtr = hl.Abstract<"hl_ssl_pkey">;
@:coreApi
class Key {
private var __k:KeyPtr;
private function new(k:KeyPtr) {
__k = k;
}
public static function loadFile(file:String, ?isPublic:Bool, ?pass:String):Key {
var data = sys.io.File.getBytes(file);
var start = data.getString(0, 11);
if (start == "-----BEGIN ")
return readPEM(data.toString(), isPublic == true, pass);
else
return readDER(data, isPublic == true);
}
public static function readPEM(data:String, isPublic:Bool, ?pass:String):Key {
return new Key(key_from_pem(@:privateAccess data.toUtf8(), isPublic, pass == null ? null : @:privateAccess pass.toUtf8()));
}
public static function readDER(data:haxe.io.Bytes, isPublic:Bool):Key {
return new Key(key_from_der(@:privateAccess data.b, @:privateAccess data.length, isPublic));
}
@:hlNative("ssl", "key_from_pem") static function key_from_pem(data:hl.Bytes, pub:Bool, pass:Null<hl.Bytes>):KeyPtr {
return null;
}
@:hlNative("ssl", "key_from_der") static function key_from_der(data:hl.Bytes, len:Int, pub:Bool):KeyPtr {
return null;
}
}

View File

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

View File

@ -0,0 +1,255 @@
/*
* 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 sys.ssl.Lib;
import sys.ssl.Key.KeyPtr;
import sys.ssl.Certificate.CertificatePtr;
import sys.net.Socket.SocketHandle;
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() {
__s.handshake();
var r = @:privateAccess __s.ssl.recvChar();
if (r == -1)
throw haxe.io.Error.Blocked;
else if (r < 0)
throw new haxe.io.Eof();
return r;
}
public override function readBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
if (pos < 0 || len < 0 || ((pos + len) : UInt) > (buf.length : UInt))
throw haxe.io.Error.OutsideBounds;
__s.handshake();
var r = @:privateAccess __s.ssl.recv(buf, pos, len);
if (r == -1)
throw haxe.io.Error.Blocked;
else 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) {
__s.handshake();
var r = @:privateAccess __s.ssl.sendChar(c);
if (r == -1)
throw haxe.io.Error.Blocked;
else if (r < 0)
throw new haxe.io.Eof();
}
public override function writeBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
if (pos < 0 || len < 0 || ((pos + len) : UInt) > (buf.length : UInt))
throw haxe.io.Error.OutsideBounds;
__s.handshake();
var r = @:privateAccess __s.ssl.send(buf, pos, len);
if (r == -1)
throw haxe.io.Error.Blocked;
else if (r < 0)
throw new haxe.io.Eof();
return r;
}
public override function close() {
super.close();
if (__s != null)
__s.close();
}
}
@:coreApi @:access(sys.net.Socket)
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:Context.Config;
private var ssl:Context;
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:hl.Bytes->Context.SNICbResult;
private var handshakeDone:Bool;
private var isBlocking:Bool = true;
private override function init():Void {
__s = sys.net.Socket.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) {}
}
verifyCert = DEFAULT_VERIFY_CERT;
caCert = DEFAULT_CA;
}
public override function connect(host:sys.net.Host, port:Int):Void {
conf = buildConfig(false);
ssl = new Context(conf);
ssl.setSocket(__s);
handshakeDone = false;
if (hostname == null)
hostname = host.host;
if (hostname != null)
ssl.setHostname(@:privateAccess hostname.toUtf8());
if (!sys.net.Socket.socket_connect(__s, host.ip, port))
throw new Sys.SysError("Failed to connect on " + host.toString() + ":" + port);
if (isBlocking)
handshake();
}
public function handshake():Void {
if (!handshakeDone) {
var r = ssl.handshake();
if (r == 0)
handshakeDone = true;
else if (r == -1)
throw haxe.io.Error.Blocked;
else
throw new haxe.io.Eof();
}
}
override function setBlocking(b:Bool):Void {
super.setBlocking(b);
isBlocking = b;
}
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 close():Void {
if (ssl != null)
ssl.close();
if (conf != null)
conf.close();
if (altSNIContexts != null)
sniCallback = null;
sys.net.Socket.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 = buildConfig(true);
sys.net.Socket.socket_bind(__s, host.ip, port);
}
public override function accept():Socket {
var c = sys.net.Socket.socket_accept(__s);
if(c == null)
throw "Blocking";
var cssl = new Context(conf);
cssl.setSocket(c);
var s = Type.createEmptyInstance(sys.ssl.Socket);
s.__s = c;
s.ssl = cssl;
s.input = new SocketInput(s);
s.output = new SocketOutput(s);
s.handshakeDone = false;
return s;
}
public function peerCertificate():sys.ssl.Certificate {
var x = ssl.getPeerCertificate();
return x == null ? null : new sys.ssl.Certificate(x);
}
private function buildConfig(server:Bool):Context.Config {
var conf = new Context.Config(server);
if (ownCert != null && ownKey != null)
conf.setCert(@:privateAccess ownCert.__x, @:privateAccess ownKey.__k);
if (altSNIContexts != null) {
sniCallback = function(servername:hl.Bytes):Context.SNICbResult {
var servername = @:privateAccess String.fromUTF8(servername);
for (c in altSNIContexts) {
if (c.match(servername))
return new Context.SNICbResult(c.cert, c.key);
}
if (ownKey != null && ownCert != null)
return new Context.SNICbResult(ownCert, ownKey);
return null;
}
conf.setServernameCallback(sniCallback);
}
if (caCert != null)
conf.setCa(caCert == null ? null : @:privateAccess caCert.__x);
conf.setVerify(if (verifyCert) 1 else if (verifyCert == null) 2 else 0);
return conf;
}
}

View File

@ -0,0 +1,52 @@
/*
* 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;
#if doc_gen
@:coreApi extern class Deque<T> {
function new():Void;
function add(i:T):Void;
function push(i:T):Void;
function pop(block:Bool):Null<T>;
}
#else
@:hlNative("std", "deque_")
abstract Deque<T>(hl.Abstract<"hl_deque">) {
public function new() {
this = alloc();
}
public function add(i:T) {}
public function push(i:T) {}
public function pop(block:Bool):Null<T> {
return null;
}
static function alloc() {
return null;
}
}
#end

View File

@ -0,0 +1,87 @@
/*
* 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;
#if (hl_ver >= version("1.11.0"))
typedef LockHandle = hl.Abstract<"hl_lock">;
@:coreApi
@:hlNative("std")
class Lock {
var handle : LockHandle;
public function new() {
handle = lock_create();
}
public function wait( ?timeout : Float ) : Bool {
return lock_wait(handle, timeout);
}
public function release( ) : Void {
lock_release(handle);
}
static function lock_wait( handle : LockHandle, ?timeout : Float ) : Bool {
return false;
}
static function lock_release( handle : LockHandle ) : Void { }
static function lock_create( ) : LockHandle {
return null;
}
}
#else
@:coreApi
class Lock {
var deque:sys.thread.Deque<Bool>;
public function new():Void {
deque = new Deque<Null<Bool>>();
}
public function wait(?timeout:Float):Bool {
if (timeout == null) {
deque.pop(true);
return true;
}
var targetTime = haxe.Timer.stamp() + timeout;
do {
if (deque.pop(false) != null) {
return true;
}
} while (haxe.Timer.stamp() < targetTime);
return false;
}
public function release():Void {
deque.push(true);
}
}
#end

View File

@ -0,0 +1,52 @@
/*
* 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;
#if doc_gen
@:coreApi
extern class Mutex {
function new():Void;
function acquire():Void;
function tryAcquire():Bool;
function release():Void;
}
#else
abstract Mutex(hl.Abstract<"hl_mutex">) {
public function new() {
this = alloc(true);
}
@:hlNative("std", "mutex_acquire") public function acquire() {}
@:hlNative("std", "mutex_try_acquire") public function tryAcquire():Bool {
return false;
}
@:hlNative("std", "mutex_release") public function release() {}
@:hlNative("std", "mutex_alloc") public static function alloc(b:Bool) {
return null;
}
}
#end

View File

@ -0,0 +1,180 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package sys.thread;
private typedef ThreadImpl = HaxeThread;
abstract Thread(ThreadImpl) from ThreadImpl {
public var events(get,never):EventLoop;
public inline function sendMessage(msg:Dynamic) {
this.sendMessage(msg);
}
public static inline function readMessage(block = true):Dynamic {
return HaxeThread.current().readMessage(block);
}
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 current():Thread {
return HaxeThread.current();
}
function get_events():EventLoop {
if(this.events == null)
throw new NoEventLoopException();
return this.events;
}
@:keep
static public function processEvents() {
HaxeThread.current().events.loop();
}
}
private typedef ThreadHandle = hl.Abstract<"hl_thread">;
private class HaxeThread {
static var mainThreadHandle:ThreadHandle;
static var mainThread:HaxeThread;
static var threads:Array<{thread:HaxeThread, handle:ThreadHandle}>;
static var threadsMutex:Mutex;
static function __init__() {
mainThreadHandle = currentHandle();
threadsMutex = new Mutex();
threads = [];
mainThread = new HaxeThread();
mainThread.events = new EventLoop();
}
public var events(default,null):Null<EventLoop>;
final messages = new Deque();
static var ids = 0;
var id = ids++;
@:hlNative("std", "thread_create")
static function createHandle(callb:Void->Void):ThreadHandle {
return null;
}
@:hlNative("std", "thread_current")
static function currentHandle():ThreadHandle {
return null;
}
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();
threads.push({thread:thread, handle:handle});
}
threadsMutex.release();
return thread;
}
public static function create(callb:()->Void, withEventLoop:Bool):Thread {
var item = {handle:null, thread:new HaxeThread()};
threadsMutex.acquire();
threads.push(item);
threadsMutex.release();
if(withEventLoop)
item.thread.events = new EventLoop();
item.handle = createHandle(() -> {
if(item.handle == null) {
item.handle = currentHandle();
}
try {
callb();
if(withEventLoop)
item.thread.events.loop();
} catch(e) {
dropThread(item);
throw e;
}
dropThread(item);
});
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(deleteItem) {
threadsMutex.acquire();
for(i => item in threads) {
if(item == deleteItem) {
threads.splice(i, 1);
break;
}
}
threadsMutex.release();
}
public function readMessage(block:Bool):Dynamic {
return messages.pop(block);
}
public function new() {}
public function sendMessage(msg:Dynamic) {
messages.add(msg);
}
}

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.thread;
#if doc_gen
@:coreApi
extern class Tls<T> {
var value(get, set):T;
function new():Void;
}
#else
@:hlNative("std")
abstract Tls<T>(hl.Abstract<"hl_tls">) {
public var value(get, set):T;
public function new() {
this = tls_alloc(true);
}
function get_value():T {
return tls_get(this);
}
function set_value(v:T) {
tls_set(this, v);
return v;
}
static function tls_alloc(gcValue:Bool)
return null;
static function tls_get(t):Dynamic
return null;
static function tls_set(t, v:Dynamic) {}
}
#end