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,103 @@
package haxe;
import php.Throwable;
import php.NativeAssocArray;
import php.NativeIndexedArray;
@:coreApi
class Exception extends NativeException {
public var message(get,never):String;
public var stack(get,never):CallStack;
public var previous(get,never):Null<Exception>;
public var native(get,never):Any;
@:noCompletion var __exceptionStack:Null<CallStack>;
@:noCompletion var __nativeException:Throwable;
@:noCompletion var __skipStack:Int = 0;
@:noCompletion var __previousException:Null<Exception>;
static function caught(value:Any):Exception {
if(Std.isOfType(value, Exception)) {
return value;
} else if(Std.isOfType(value, Throwable)) {
return new Exception((value:Throwable).getMessage(), null, value);
} else {
return new ValueException(value, null, value);
}
}
static function thrown(value:Any):Any {
if(Std.isOfType(value, Exception)) {
return (value:Exception).native;
} else if(Std.isOfType(value, Throwable)) {
return value;
} else {
var e = new ValueException(value);
e.__skipStack = 1;
return e;
}
}
public function new(message:String, ?previous:Exception, ?native:Any) {
super(message, 0, previous);
this.__previousException = previous;
if(native != null && Std.isOfType(native, Throwable)) {
__nativeException = native;
} else {
__nativeException = cast this;
}
}
function unwrap():Any {
return __nativeException;
}
public function toString():String {
return message;
}
public function details():String {
return inline CallStack.exceptionToString(this);
}
function get_message():String {
return this.getMessage();
}
function get_previous():Null<Exception> {
return __previousException;
}
final function get_native():Any {
return __nativeException;
}
function get_stack():CallStack {
return switch __exceptionStack {
case null:
var nativeTrace = NativeStackTrace.complementTrace(__nativeException.getTrace(), native);
__exceptionStack = NativeStackTrace.toHaxe(nativeTrace, __skipStack);
case s: s;
}
}
}
@:dox(hide)
@:noCompletion
@:native('Exception')
private extern class NativeException {
@:noCompletion private function new(?message:String, ?code:Int, ?previous:NativeException):Void;
@:noCompletion private var code:Int;
@:noCompletion private var file:String;
@:noCompletion private var line:Int;
@:noCompletion final private function getPrevious():Throwable;
@:noCompletion private function getMessage():String;
@:noCompletion private function getCode():Int;
@:noCompletion private function getFile():String;
@:noCompletion private function getLine():Int;
@:noCompletion private function getTrace():NativeIndexedArray<NativeAssocArray<Dynamic>>;
@:noCompletion private function getTraceAsString():String;
@:noCompletion @:phpMagic private function __toString():String;
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe;
import php.*;
import haxe.format.JsonPrinter;
@:coreApi
class Json {
public static inline function parse(text:String):Dynamic {
#if haxeJSON
return haxe.format.JsonParser.parse(text);
#else
return phpJsonDecode(text);
#end
}
public static inline function stringify(value:Dynamic, ?replacer:(key:Dynamic, value:Dynamic) -> Dynamic, ?space:String):String {
#if haxeJSON
return JsonPrinter.print(value, replacer, space);
#else
return phpJsonEncode(value, replacer, space);
#end
}
static function phpJsonDecode(json:String):Dynamic {
var value = Global.json_decode(json);
if (value == null && Global.json_last_error() != Const.JSON_ERROR_NONE) {
throw Global.json_last_error_msg();
}
return convertAfterDecode(value);
}
static function convertAfterDecode(value:Dynamic):Dynamic {
if (Global.is_object(value)) {
var result = new NativeAssocArray();
var data = Syntax.array(value);
Syntax.foreach(data, function(fieldName:String, fieldValue:Dynamic) {
result[fieldName] = convertAfterDecode(fieldValue);
});
return Boot.createAnon(result);
}
if (Global.is_array(value)) {
var result = new NativeIndexedArray();
Syntax.foreach(value, function(index:Int, item:Dynamic) {
result[index] = convertAfterDecode(item);
});
return @:privateAccess Array.wrap(result);
}
return value;
}
static function phpJsonEncode(value:Dynamic, ?replacer:(key:Dynamic, value:Dynamic) -> Dynamic, ?space:String):String {
if (null != replacer || null != space) {
return JsonPrinter.print(value, replacer, space);
}
var json = Global.json_encode(convertBeforeEncode(value));
if (Global.json_last_error() != Const.JSON_ERROR_NONE) {
return throw Global.json_last_error_msg();
}
return json;
}
static function convertBeforeEncode(value:Dynamic):Dynamic {
if (Std.isOfType(value, Array)) {
var result = new NativeIndexedArray();
Syntax.foreach(value.arr, function(index:Int, item:Dynamic) {
result[index] = convertBeforeEncode(item);
});
return result;
}
if (Global.is_object(value)) {
var result = {};
Syntax.foreach(value, function(fieldName:String, fieldValue:Dynamic) {
Syntax.setField(result, fieldName, convertBeforeEncode(fieldValue));
});
return result;
}
if (Global.is_float(value) && !Global.is_finite(value)) {
return null;
}
return value;
}
}

View File

@ -0,0 +1,115 @@
package haxe;
import php.*;
import haxe.CallStack.StackItem;
private typedef NativeTrace = NativeIndexedArray<NativeAssocArray<Dynamic>>;
/**
Do not use manually.
**/
@:dox(hide)
@:noCompletion
@:allow(haxe.Exception)
class NativeStackTrace {
/**
If defined this function will be used to transform call stack entries.
@param String - generated php file name.
@param Int - Line number in generated file.
**/
static public var mapPosition:String->Int->Null<{?source:String, ?originalLine:Int}>;
static var lastExceptionTrace:Null<NativeTrace>;
@:ifFeature('haxe.NativeStackTrace.exceptionStack')
static public function saveStack(e:Throwable) {
var nativeTrace = e.getTrace();
// Reduce exception stack to the place where exception was caught
var currentTrace = Global.debug_backtrace(Const.DEBUG_BACKTRACE_IGNORE_ARGS);
var count = Global.count(currentTrace);
for (i in -(count - 1)...1) {
var exceptionEntry:NativeAssocArray<Dynamic> = Global.end(nativeTrace);
if (!Global.isset(exceptionEntry['file']) || !Global.isset(currentTrace[-i]['file'])) {
Global.array_pop(nativeTrace);
} else if (currentTrace[-i]['file'] == exceptionEntry['file'] && currentTrace[-i]['line'] == exceptionEntry['line']) {
Global.array_pop(nativeTrace);
} else {
break;
}
}
// Remove arguments from trace to avoid blocking some objects from GC
var count = Global.count(nativeTrace);
for (i in 0...count) {
nativeTrace[i]['args'] = new NativeArray();
}
lastExceptionTrace = complementTrace(nativeTrace, e);
}
static public inline function callStack():NativeTrace {
return Global.debug_backtrace(Const.DEBUG_BACKTRACE_IGNORE_ARGS);
}
static public function exceptionStack():NativeTrace {
return lastExceptionTrace == null ? new NativeIndexedArray() : lastExceptionTrace;
}
static public function toHaxe(native:NativeTrace, skip:Int = 0):Array<StackItem> {
var result = [];
var count = Global.count(native);
for (i in 0...count) {
if(skip > i) {
continue;
}
var entry = native[i];
var item = null;
if (i + 1 < count) {
var next = native[i + 1];
if (!Global.isset(next['function']))
next['function'] = '';
if (!Global.isset(next['class']))
next['class'] = '';
if ((next['function'] : String).indexOf('{closure}') >= 0) {
item = LocalFunction();
} else if (Global.strlen(next['class']) > 0 && Global.strlen(next['function']) > 0) {
var cls = Boot.getClassName(next['class']);
item = Method(cls, next['function']);
}
}
if (Global.isset(entry['file'])) {
if (mapPosition != null) {
var pos = mapPosition(entry['file'], entry['line']);
if (pos != null && pos.source != null && pos.originalLine != null) {
entry['file'] = pos.source;
entry['line'] = pos.originalLine;
}
}
result.push(FilePos(item, entry['file'], entry['line']));
} else if (item != null) {
result.push(item);
}
}
return result;
}
static function complementTrace(nativeTrace:NativeTrace, e:Throwable):NativeTrace {
var thrownAt = new NativeAssocArray<Dynamic>();
thrownAt['function'] = '';
thrownAt['line'] = e.getLine();
thrownAt['file'] = e.getFile();
thrownAt['class'] = '';
thrownAt['args'] = new NativeArray();
Global.array_unshift(nativeTrace, thrownAt);
return nativeTrace;
}
}

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 haxe;
import php.*;
import haxe.io.Bytes;
import haxe.crypto.Base64;
@:coreApi
class Resource {
static function cleanName(name:String):String {
return ~/[\\\/:?"*<>|]/.replace(name, '_');
}
static function getDir():String {
var pathToRoot = '/../..';
#if php_prefix
pathToRoot += '/..';
for (i in 0...Global.substr_count(Boot.getPrefix(), '\\')) {
pathToRoot += '/..';
}
#end
return Global.dirname(Const.__FILE__) + pathToRoot + "/res";
}
@:access(haxe.io.Path.escape)
static function getPath(name:String):String {
return getDir() + '/' + haxe.io.Path.escape(name);
}
@:access(haxe.io.Path.unescape)
public static function listNames():Array<String> {
var a = sys.FileSystem.readDirectory(getDir());
if (a[0] == '.')
a.shift();
if (a[0] == '..')
a.shift();
return a.map(function(s) return haxe.io.Path.unescape(s));
}
public static function getString(name:String):String {
var path = getPath(name);
return if (!sys.FileSystem.exists(path))
null;
else
sys.io.File.getContent(path);
}
public static function getBytes(name:String):haxe.io.Bytes {
var path = getPath(name);
return if (!sys.FileSystem.exists(path))
null;
else
sys.io.File.getBytes(path);
}
}

View File

@ -0,0 +1,50 @@
package haxe;
import php.*;
import haxe.iterators.RestIterator;
import haxe.iterators.RestKeyValueIterator;
private typedef NativeRest<T> = NativeIndexedArray<T>;
@:coreApi
@:semantics(value)
abstract Rest<T>(NativeRest<T>) {
public var length(get,never):Int;
inline function get_length():Int
return Global.count(this);
@:from
static public inline function of<T>(array:Array<T>):Rest<T>
return new Rest(@:privateAccess array.arr);
inline function new(a:NativeIndexedArray<T>):Void
this = a;
@:arrayAccess inline function get(index:Int):T
return this[index];
@:to public inline function toArray():Array<T>
return @:privateAccess Array.wrap(this);
public inline function iterator():RestIterator<T>
return new RestIterator<T>(this);
public inline function keyValueIterator():RestKeyValueIterator<T>
return new RestKeyValueIterator<T>(this);
public inline function append(item:T):Rest<T> {
var result = this;
result.push(item);
return new Rest(result);
}
public inline function prepend(item:T):Rest<T> {
var result = this;
Global.array_unshift(result, item);
return new Rest(result);
}
public function toString():String {
return inline Boot.stringifyNativeIndexedArray(this);
}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe;
import php.Global;
@:coreApi
@:deprecated('haxe.Utf8 is deprecated. Use UnicodeString instead.')
class Utf8 {
var __b:String;
public function new(?size:Int):Void {
__b = '';
}
public function addChar(c:Int):Void {
__b += uchr(c);
}
public function toString():String {
return __b;
}
public static function encode(s:String):String {
return Global.utf8_encode(s);
}
public static function decode(s:String):String {
return Global.utf8_decode(s);
}
public static function iter(s:String, chars:Int->Void):Void {
var len = length(s);
for (i in 0...len) {
chars(charCodeAt(s, i));
}
}
public static function charCodeAt(s:String, index:Int):Int {
return uord(sub(s, index, 1));
}
static function uchr(i:Int):String {
return Global.mb_convert_encoding(Global.pack('N', i), 'UTF-8', 'UCS-4BE');
}
static function uord(s:String):Int {
var c = Global.unpack('N', Global.mb_convert_encoding(s, 'UCS-4BE', 'UTF-8'));
return c[1];
}
public static function validate(s:String):Bool {
return Global.mb_check_encoding(s, enc);
}
public static function length(s:String):Int {
return Global.mb_strlen(s, enc);
}
public static function compare(a:String, b:String):Int {
return Global.strcmp(a, b);
}
public static function sub(s:String, pos:Int, len:Int):String {
return Global.mb_substr(s, pos, len, enc);
}
private static inline var enc = "UTF-8";
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.crypto;
import php.Global.*;
import php.Syntax;
import php.NativeArray;
import haxe.io.Bytes;
class Base64 {
public static var CHARS(default, null) = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
public static var BYTES(default, null) = haxe.io.Bytes.ofString(CHARS);
public static var URL_CHARS(default, null) = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
public static var URL_BYTES(default, null) = haxe.io.Bytes.ofString(URL_CHARS);
static final NORMAL_62_63:NativeArray = Syntax.arrayDecl('+', '/');
static final URL_62_63:NativeArray = Syntax.arrayDecl('-', '_');
public static inline function encode(bytes:Bytes, complement = true):String {
var result = base64_encode(bytes.toString());
return (complement ? result : rtrim(result, "="));
}
public static inline function decode(str:String, complement = true):Bytes {
if (!complement) {
switch (strlen(str) % 3) {
case 1:
str += "==";
case 2:
str += "=";
default:
}
}
return Bytes.ofString(base64_decode(str, true));
}
public static inline function urlEncode(bytes:Bytes, complement = false):String {
var result = str_replace(NORMAL_62_63, URL_62_63, base64_encode(bytes.toString()));
return (complement ? result : rtrim(result, "="));
}
public static inline function urlDecode(str:String, complement = false):Bytes {
if (complement) {
switch (strlen(str) % 3) {
case 1:
str += "==";
case 2:
str += "=";
default:
}
}
return Bytes.ofString(base64_decode(str_replace(URL_62_63, NORMAL_62_63, str), 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 haxe.crypto;
import php.Global;
import haxe.io.Bytes;
class Md5 {
public static inline function encode(s:String):String {
return Global.md5(s);
}
public static inline function make(b:haxe.io.Bytes):haxe.io.Bytes {
return Bytes.ofData(Global.md5(b.getData(), 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 haxe.crypto;
import php.Global;
import haxe.io.Bytes;
class Sha1 {
public static inline function encode(s:String):String {
return Global.sha1(s);
}
public static inline function make(b:haxe.io.Bytes):haxe.io.Bytes {
return Bytes.ofData(Global.sha1(b.getData(), 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 haxe.crypto;
import php.Global;
import haxe.io.Bytes;
class Sha224 {
public static inline function encode(s:String):String {
return Global.hash('sha224', s);
}
public static function make(b:haxe.io.Bytes):haxe.io.Bytes {
return Bytes.ofData(Global.hash('sha224', b.getData(), 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 haxe.crypto;
import php.Global;
import haxe.io.Bytes;
class Sha256 {
public static inline function encode(s:String):String {
return Global.hash('sha256', s);
}
public static function make(b:haxe.io.Bytes):haxe.io.Bytes {
return Bytes.ofData(Global.hash('sha256', b.getData(), true));
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.ds;
import php.Syntax;
import php.Global;
import php.NativeArray;
import php.NativeIndexedArray;
@:coreApi class IntMap<T> implements haxe.Constraints.IMap<Int, T> {
var data:NativeIndexedArray<T>;
public function new():Void {
data = new NativeIndexedArray();
}
public inline function set(key:Int, value:T):Void {
data[key] = value;
}
public inline function get(key:Int):Null<T> {
return Syntax.coalesce(data[key], null);
}
public inline function exists(key:Int):Bool {
return Global.array_key_exists(key, data);
}
public function remove(key:Int):Bool {
if (Global.array_key_exists(key, data)) {
Global.unset(data[key]);
return true;
}
return false;
}
public inline function keys():Iterator<Int> {
return Global.array_keys(data).iterator();
}
@:ifFeature("dynamic_read.iterator", "anon_optional_read.iterator", "anon_read.iterator")
public inline function iterator():Iterator<T> {
return Global.array_values(data).iterator();
}
@:ifFeature("dynamic_read.keyValueIterator", "anon_optional_read.keyValueIterator", "anon_read.keyValueIterator")
public inline function keyValueIterator():KeyValueIterator<Int, T> {
return new haxe.iterators.MapKeyValueIterator(this);
}
public inline function copy():IntMap<T> {
return Syntax.clone(this);
}
public function toString():String {
var parts = new NativeArray();
Syntax.foreach(data, function(key:Int, value:T) {
Global.array_push(parts, '$key => ' + Std.string(value));
});
return '{' + Global.implode(', ', parts) + '}';
}
public inline function clear():Void {
data = new NativeIndexedArray();
}
}

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 haxe.ds;
import php.*;
@:coreApi
class ObjectMap<K:{}, V> implements haxe.Constraints.IMap<K, V> {
var _keys:NativeAssocArray<K>;
var _values:NativeAssocArray<V>;
public function new():Void {
_keys = new NativeAssocArray();
_values = new NativeAssocArray();
}
public function set(key:K, value:V):Void {
var id = Global.spl_object_hash(key);
_keys[id] = key;
_values[id] = value;
}
public function get(key:K):Null<V> {
var id = Global.spl_object_hash(key);
return Global.isset(_values[id]) ? _values[id] : null;
}
public function exists(key:K):Bool {
return Global.array_key_exists(Global.spl_object_hash(key), _values);
}
public function remove(key:K):Bool {
var id = Global.spl_object_hash(key);
if (Global.array_key_exists(id, _values)) {
Global.unset(_keys[id], _values[id]);
return true;
} else {
return false;
}
}
public inline function keys():Iterator<K> {
return _keys.iterator();
}
@:ifFeature("dynamic_read.iterator", "anon_optional_read.iterator", "anon_read.iterator")
public inline function iterator():Iterator<V> {
return _values.iterator();
}
@:ifFeature("dynamic_read.keyValueIterator", "anon_optional_read.keyValueIterator", "anon_read.keyValueIterator")
public inline function keyValueIterator():KeyValueIterator<K, V> {
return new haxe.iterators.MapKeyValueIterator(this);
}
public inline function copy():ObjectMap<K, V> {
return Syntax.clone(this);
}
public function toString():String {
var s = "{";
var it = keys();
for (i in it) {
s += Std.string(i);
s += " => ";
s += Std.string(get(i));
if (it.hasNext())
s += ", ";
}
return s + "}";
}
public inline function clear():Void {
_keys = new NativeAssocArray();
_values = new NativeAssocArray();
}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.ds;
import php.Syntax;
import php.Global;
import php.NativeArray;
import php.NativeAssocArray;
import haxe.Constraints;
@:coreApi class StringMap<T> implements IMap<String, T> {
private var data:NativeAssocArray<T>;
public inline function new():Void {
data = new NativeAssocArray();
}
public inline function set(key:String, value:T):Void {
data[key] = value;
}
public inline function get(key:String):Null<T> {
return Syntax.coalesce(data[key], null);
}
public inline function exists(key:String):Bool {
return Global.array_key_exists(key, data);
}
public function remove(key:String):Bool {
if (Global.array_key_exists(key, data)) {
Global.unset(data[key]);
return true;
} else {
return false;
}
}
public inline function keys():Iterator<String> {
return Global.array_map('strval', Global.array_keys(data)).iterator();
}
@:ifFeature("dynamic_read.iterator", "anon_optional_read.iterator", "anon_read.iterator")
public inline function iterator():Iterator<T> {
return data.iterator();
}
@:ifFeature("dynamic_read.keyValueIterator", "anon_optional_read.keyValueIterator", "anon_read.keyValueIterator")
public inline function keyValueIterator():KeyValueIterator<String, T> {
return new haxe.iterators.MapKeyValueIterator(this);
}
public inline function copy():StringMap<T> {
return Syntax.clone(this);
}
public function toString():String {
var parts = new NativeArray();
Syntax.foreach(data, function(key:String, value:T) {
Global.array_push(parts, '$key => ' + Std.string(value));
});
return '{' + Global.implode(', ', parts) + '}';
}
public inline function clear():Void {
data = new NativeAssocArray();
}
}

View File

@ -0,0 +1,133 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.ds;
import php.*;
private class PhpVectorData<T> {
public var length:Int;
public var data:NativeIndexedArray<T>;
public inline function new(length:Int) {
this.length = length;
data = new NativeIndexedArray();
}
}
private typedef VectorData<T> = PhpVectorData<T>;
abstract Vector<T>(VectorData<T>) {
public var length(get, never):Int;
public inline function new(length:Int) {
this = new VectorData(length);
}
@:op([]) public inline function get(index:Int):T {
return Syntax.coalesce(this.data[index], null);
}
@:op([]) public inline function set(index:Int, val:T):T {
return this.data[index] = val;
}
inline function get_length():Int {
return this.length;
}
public static function blit<T>(src:Vector<T>, srcPos:Int, dest:Vector<T>, destPos:Int, len:Int):Void {
if (src == dest) {
if (srcPos < destPos) {
var i = srcPos + len;
var j = destPos + len;
for (k in 0...len) {
i--;
j--;
src[j] = src[i];
}
} else if (srcPos > destPos) {
var i = srcPos;
var j = destPos;
for (k in 0...len) {
src[j] = src[i];
i++;
j++;
}
}
} else {
for (i in 0...len) {
dest[destPos + i] = src[srcPos + i];
}
}
}
public function toArray():Array<T> {
var result = [];
@:privateAccess result.length = length;
for (i in 0...length) {
@:privateAccess result.arr.push(get(i));
}
return result;
}
public inline function toData():VectorData<T> {
return this;
}
static public inline function fromData<T>(data:VectorData<T>):Vector<T> {
return cast data;
}
static public inline function fromArrayCopy<T>(array:Array<T>):Vector<T> {
var vectorData = new VectorData(array.length);
vectorData.data = @:privateAccess array.arr;
return cast vectorData;
}
public inline function copy<T>():Vector<T> {
return cast Syntax.clone(this);
}
public function join<T>(sep:String):String {
if (this.length == 0) {
return '';
}
var result = Std.string(get(0));
for (i in 1...this.length) {
result = Syntax.concat(result, Syntax.concat(sep, Std.string(get(i))));
}
return result;
}
public inline function map<S>(f:T->S):Vector<S> {
var result = new Vector(this.length);
Syntax.foreach(this.data, function(key:Int, value:T) {
result[key] = f(value);
});
return result;
}
public inline function sort<T>(f:T->T->Int):Void {
Global.usort(this.data, f);
}
}

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 haxe.format;
import php.Syntax;
import php.Global;
import php.NativeString;
using haxe.format.JsonParser;
class JsonParser {
static public inline function parse(str:String):Dynamic {
return new JsonParser(str).doParse();
}
var str:NativeString;
var pos:Int;
function new(str:String) {
this.str = str;
this.pos = 0;
}
function doParse():Dynamic {
var result = parseRec();
var c;
while (!StringTools.isEof(c = nextChar())) {
switch (c) {
case ' '.code, '\r'.code, '\n'.code, '\t'.code:
// allow trailing whitespace
default:
invalidChar();
}
}
return result;
}
function parseRec():Dynamic {
while (true) {
var c = nextChar();
switch (c) {
case ' '.code, '\r'.code, '\n'.code, '\t'.code:
// loop
case '{'.code:
var obj = {}, field = null, comma:Null<Bool> = null;
while (true) {
var c = nextChar();
switch (c) {
case ' '.code, '\r'.code, '\n'.code, '\t'.code:
// loop
case '}'.code:
if (field != null || comma == false)
invalidChar();
return obj;
case ':'.code:
if (field == null)
invalidChar();
Reflect.setField(obj, field, parseRec());
field = null;
comma = true;
case ','.code:
if (comma) comma = false else invalidChar();
case '"'.code:
if (field != null || comma) invalidChar();
field = parseString();
default:
invalidChar();
}
}
case '['.code:
var arr = [], comma:Null<Bool> = null;
while (true) {
var c = nextChar();
switch (c) {
case ' '.code, '\r'.code, '\n'.code, '\t'.code:
// loop
case ']'.code:
if (comma == false) invalidChar();
return arr;
case ','.code:
if (comma) comma = false else invalidChar();
default:
if (comma) invalidChar();
pos--;
arr.push(parseRec());
comma = true;
}
}
case 't'.code:
var save = pos;
if (nextChar() != 'r'.code || nextChar() != 'u'.code || nextChar() != 'e'.code) {
pos = save;
invalidChar();
}
return true;
case 'f'.code:
var save = pos;
if (nextChar() != 'a'.code || nextChar() != 'l'.code || nextChar() != 's'.code || nextChar() != 'e'.code) {
pos = save;
invalidChar();
}
return false;
case 'n'.code:
var save = pos;
if (nextChar() != 'u'.code || nextChar() != 'l'.code || nextChar() != 'l'.code) {
pos = save;
invalidChar();
}
return null;
case '"'.code:
return parseString();
case '0'.code, '1'.code, '2'.code, '3'.code, '4'.code, '5'.code, '6'.code, '7'.code, '8'.code, '9'.code, '-'.code:
return parseNumber(c);
default:
invalidChar();
}
}
}
function parseString() {
var start = pos;
var buf:NativeString = null;
while (true) {
var c = nextChar();
if (c == '"'.code)
break;
if (c == '\\'.code) {
if (buf == null) {
buf = '';
}
buf = buf.addSub(str, start, pos - start - 1);
c = nextChar();
switch (c) {
case "r".code:
buf = Syntax.concat(buf, "\r");
case "n".code:
buf = Syntax.concat(buf, "\n");
case "t".code:
buf = Syntax.concat(buf, "\t");
case "b".code:
buf = Syntax.concat(buf, Global.chr(8));
case "f".code:
buf = Syntax.concat(buf, Global.chr(12));
case "/".code, '\\'.code, '"'.code:
buf = Syntax.concat(buf, Global.mb_chr(c));
case 'u'.code:
var uc = Std.parseInt("0x" + str.substr(pos, 4));
pos += 4;
buf = Syntax.concat(buf, Global.mb_chr(uc));
default:
throw "Invalid escape sequence \\" + String.fromCharCode(c) + " at position " + (pos - 1);
}
start = pos;
}
// ensure utf8 chars are not cut
else if (c >= 0x80) {
pos++;
if (c >= 0xFC)
pos += 4;
else if (c >= 0xF8)
pos += 3;
else if (c >= 0xF0)
pos += 2;
else if (c >= 0xE0)
pos++;
} else if (StringTools.isEof(c))
throw "Unclosed string";
}
if (buf == null) {
return str.substr(start, pos - start - 1);
} else {
return buf.addSub(str, start, pos - start - 1);
}
}
inline function parseNumber(c:Int):Dynamic {
var start = pos - 1;
var minus = c == '-'.code, digit = !minus, zero = c == '0'.code;
var point = false, e = false, pm = false, end = false;
while (true) {
c = nextChar();
switch (c) {
case '0'.code:
if (zero && !point)
invalidNumber(start);
if (minus) {
minus = false;
zero = true;
}
digit = true;
case '1'.code, '2'.code, '3'.code, '4'.code, '5'.code, '6'.code, '7'.code, '8'.code, '9'.code:
if (zero && !point)
invalidNumber(start);
if (minus)
minus = false;
digit = true;
zero = false;
case '.'.code:
if (minus || point || e)
invalidNumber(start);
digit = false;
point = true;
case 'e'.code, 'E'.code:
if (minus || zero || e)
invalidNumber(start);
digit = false;
e = true;
case '+'.code, '-'.code:
if (!e || pm)
invalidNumber(start);
digit = false;
pm = true;
default:
if (!digit)
invalidNumber(start);
pos--;
end = true;
}
if (end)
break;
}
var f = Std.parseFloat(str.substr(start, pos - start));
var i = Std.int(f);
return if (i == f) i else f;
}
inline function nextChar() {
return fastCodeAt(str, pos++);
}
function invalidChar() {
pos--; // rewind
throw "Invalid char " + fastCodeAt(str, pos) + " at position " + pos;
}
function invalidNumber(start:Int) {
throw "Invalid number at position " + start + ": " + str.substr(start, pos - start);
}
// TODO: rewrite the parser using a buffer instead of a string as the data source
static inline function fastCodeAt(s:NativeString, pos:Int):Int {
return pos >= Global.strlen(s) ? 0 : Global.ord(s[pos]);
}
static inline function substr(s:NativeString, pos:Int, ?length:Int):NativeString {
return Global.substr(s, pos, length);
}
static inline function addSub(buf:NativeString, s:NativeString, pos:Int, length:Int):NativeString {
return Syntax.concat(buf, Global.substr(s, pos, length));
}
}

View File

@ -0,0 +1,169 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.io;
import php.Global;
import php.Syntax;
class Bytes {
public var length(default, null):Int;
var b:BytesData;
function new(length:Int, b:BytesData):Void {
this.length = length;
this.b = b;
}
public inline function get(pos:Int):Int {
return b.get(pos);
}
public inline function set(pos:Int, v:Int):Void {
b.set(pos, v);
}
public inline function blit(pos:Int, src:Bytes, srcpos:Int, len:Int):Void {
if (pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length) {
throw Error.OutsideBounds;
} else {
b.blit(pos, src.b, srcpos, len);
}
}
public inline function fill(pos:Int, len:Int, value:Int):Void {
b.fill(pos, len, value);
}
public inline function sub(pos:Int, len:Int):Bytes {
if (pos < 0 || len < 0 || pos + len > length) {
throw Error.OutsideBounds;
} else {
return new Bytes(len, b.sub(pos, len));
}
}
public inline function compare(other:Bytes):Int {
return b.compare(other.b);
}
public function getDouble(pos:Int):Float {
return FPHelper.i64ToDouble(getInt32(pos), getInt32(pos + 4));
}
public function getFloat(pos:Int):Float {
var b = new haxe.io.BytesInput(this, pos, 4);
return b.readFloat();
}
public function setDouble(pos:Int, v:Float):Void {
var i = FPHelper.doubleToI64(v);
setInt32(pos, i.low);
setInt32(pos + 4, i.high);
}
public function setFloat(pos:Int, v:Float):Void {
setInt32(pos, FPHelper.floatToI32(v));
}
public inline function getUInt16(pos:Int):Int {
return get(pos) | (get(pos + 1) << 8);
}
public inline function setUInt16(pos:Int, v:Int):Void {
set(pos, v);
set(pos + 1, v >> 8);
}
public inline function getInt32(pos:Int):Int {
var v = get(pos) | (get(pos + 1) << 8) | (get(pos + 2) << 16) | (get(pos + 3) << 24);
return if (v & 0x80000000 != 0) v | 0x80000000 else v;
}
public inline function getInt64(pos:Int):haxe.Int64 {
return haxe.Int64.make(getInt32(pos + 4), getInt32(pos));
}
public inline function setInt32(pos:Int, v:Int):Void {
set(pos, v);
set(pos + 1, v >> 8);
set(pos + 2, v >> 16);
set(pos + 3, v >>> 24);
}
public inline function setInt64(pos:Int, v:haxe.Int64):Void {
setInt32(pos, v.low);
setInt32(pos + 4, v.high);
}
public inline function getString(pos:Int, len:Int, ?encoding:Encoding):String {
if (pos < 0 || len < 0 || pos + len > length) {
throw Error.OutsideBounds;
} else {
// no need to handle encoding, because PHP strings are binary safe.
return b.getString(pos, len);
}
}
@:deprecated("readString is deprecated, use getString instead")
@:noCompletion
public inline function readString(pos:Int, len:Int):String {
return getString(pos, len);
}
public function toString():String {
return b;
}
public inline function toHex():String {
return php.Global.bin2hex(b.toString());
}
public inline function getData():BytesData {
return b;
}
public static function alloc(length:Int):Bytes {
return new Bytes(length, BytesData.alloc(length));
}
public static inline function ofString(s:String, ?encoding:Encoding):Bytes {
return new Bytes(php.Global.strlen(s), s);
}
public static inline function ofData(b:BytesData):Bytes {
return new Bytes(b.length, b);
}
public static function ofHex(s:String):Bytes {
var len = Global.strlen(s);
if ((len & 1) != 0)
throw "Not a hex string (odd number of digits)";
var b:String = php.Global.hex2bin(s);
return new Bytes(Global.strlen(b), b);
}
public inline static function fastGet(b:BytesData, pos:Int):Int {
return b.get(pos);
}
}

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 haxe.io;
import php.*;
import haxe.io.Error;
class BytesBuffer {
var b:NativeString;
public var length(get, never):Int;
public function new() {
b = "";
}
public inline function addByte(byte:Int) {
b = Syntax.concat(b, Global.chr(byte));
}
public inline function add(src:Bytes) {
b = Syntax.concat(b, src.getData().toNativeString());
}
public inline function addString(v:String, ?encoding:Encoding) {
b = Syntax.concat(b, v);
}
public function addInt32(v:Int) {
addByte(v & 0xFF);
addByte((v >> 8) & 0xFF);
addByte((v >> 16) & 0xFF);
addByte(v >>> 24);
}
public function addInt64(v:haxe.Int64) {
addInt32(v.low);
addInt32(v.high);
}
public inline function addFloat(v:Float) {
addInt32(FPHelper.floatToI32(v));
}
public inline function addDouble(v:Float) {
addInt64(FPHelper.doubleToI64(v));
}
public inline function addBytes(src:Bytes, pos:Int, len:Int) {
if (pos < 0 || len < 0 || pos + len > src.length) {
throw Error.OutsideBounds;
} else {
b = Syntax.concat(b, src.getData().sub(pos, len).toString());
}
}
public function getBytes():Bytes {
var bytes = @:privateAccess new Bytes(length, b);
b = null;
return bytes;
}
inline function get_length():Int {
return Global.strlen(b);
}
}

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 haxe.io;
import php.*;
using php.Syntax;
typedef BytesData = BytesDataAbstract;
private class Container {
public var s:NativeString;
public inline function new(s:NativeString)
this.s = s;
}
private abstract BytesDataAbstract(Container) from Container to Container {
public var length(get, never):Int;
public static inline function alloc(length:Int):BytesDataAbstract {
return Global.str_repeat(Global.chr(0), length);
}
@:arrayAccess
public inline function get(pos:Int):Int {
return Global.ord(this.s[pos]);
}
@:arrayAccess
public inline function set(index:Int, val:Int):Void {
this.s[index] = Global.chr(val);
}
public inline function compare(other:BytesDataAbstract):Int {
return Syntax.spaceship(this.s, (other : Container).s);
}
public inline function getString(pos:Int, len:Int):String {
return Global.substr(this.s, pos, len);
}
public inline function sub(pos:Int, len:Int):BytesDataAbstract {
return (Global.substr(this.s, pos, len) : String);
}
public inline function blit(pos:Int, src:BytesDataAbstract, srcpos:Int, len:Int):Void {
this.s = Global.substr(this.s, 0, pos).concat(Global.substr(src, srcpos, len)).concat(Global.substr(this.s, pos + len));
}
public inline function fill(pos:Int, len:Int, value:Int):Void {
this.s = Global.substr(this.s, 0, pos).concat(Global.str_repeat(Global.chr(value), len)).concat(Global.substr(this.s, pos + len));
}
inline function get_length():Int {
return Global.strlen(this.s);
}
@:from
static inline function fromNativeString(s:NativeString):BytesDataAbstract {
return new Container(s);
}
@:to
public inline function toNativeString():NativeString {
return this.s;
}
@:from
static inline function fromString(s:String):BytesDataAbstract {
return new Container(s);
}
@:to
public inline function toString():String {
return this.s;
}
}

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 haxe.io;
class BytesInput extends Input {
var b:BytesData;
var pos:Int;
var len:Int;
var totlen:Int;
public var position(get, set):Int;
public var length(get, never):Int;
public function new(b:Bytes, ?pos:Int, ?len:Int) {
if (pos == null)
pos = 0;
if (len == null)
len = b.length - pos;
if (pos < 0 || len < 0 || pos + len > b.length)
throw Error.OutsideBounds;
this.b = b.getData();
this.pos = pos;
this.len = len;
this.totlen = len;
}
inline function get_position():Int {
return pos;
}
inline function get_length():Int {
return totlen;
}
function set_position(p:Int):Int {
if (p < 0)
p = 0;
else if (p > length)
p = length;
len = totlen - p;
return pos = p;
}
public override function readByte():Int {
if (len == 0)
throw new Eof();
--len;
return b[pos++];
}
public override function readBytes(buf:Bytes, pos, len):Int {
if (pos < 0 || len < 0 || pos + len > buf.length)
throw Error.OutsideBounds;
if (this.len == 0 && len > 0)
throw new Eof();
if (this.len < len)
len = this.len;
buf.getData().blit(pos, b, this.pos, len);
this.pos += len;
this.len -= len;
return len;
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.io;
class BytesOutput extends Output {
var b:BytesBuffer;
public var length(get, never):Int;
public function new() {
b = new BytesBuffer();
}
override function writeByte(c) {
b.addByte(c);
}
override function writeBytes(buf:Bytes, pos, len):Int {
b.addBytes(buf, pos, len);
return len;
}
public function getBytes():Bytes {
return b.getBytes();
}
inline function get_length():Int {
return b.length;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.io;
import php.*;
class FPHelper {
static var isLittleEndian:Bool = Global.unpack('S', '\x01\x00')[1] == 1;
static var i64tmp = Int64.ofInt(0);
public static inline function i32ToFloat(i:Int):Float {
return Global.unpack('f', Global.pack('l', i))[1];
}
public static inline function floatToI32(f:Float):Int {
return Global.unpack('l', Global.pack('f', f))[1];
}
public static inline function i64ToDouble(low:Int, high:Int):Float {
return Global.unpack('d', Global.pack('ii', isLittleEndian ? low : high, isLittleEndian ? high : low))[1];
}
public static function doubleToI64(v:Float):Int64 {
var a = Global.unpack(isLittleEndian ? 'V2' : 'N2', Global.pack('d', v));
var i64 = i64tmp;
@:privateAccess i64.set_low(a[isLittleEndian ? 1 : 2]);
@:privateAccess i64.set_high(a[isLittleEndian ? 2 : 1]);
return i64;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.iterators;
import php.Global.*;
import php.NativeString;
class StringIteratorUnicode {
var byteOffset:Int = 0;
var totalBytes:Int;
var s:NativeString;
public inline function new(s:String) {
this.s = s;
totalBytes = strlen(s);
}
public inline function hasNext() {
return byteOffset < totalBytes;
}
public inline function next() {
var code = ord(s[byteOffset]);
if (code < 0xC0) {
byteOffset++;
} else if (code < 0xE0) {
code = ((code - 0xC0) << 6) + ord(s[byteOffset + 1]) - 0x80;
byteOffset += 2;
} else if (code < 0xF0) {
code = ((code - 0xE0) << 12) + ((ord(s[byteOffset + 1]) - 0x80) << 6) + ord(s[byteOffset + 2]) - 0x80;
byteOffset += 3;
} else {
code = ((code - 0xF0) << 18)
+ ((ord(s[byteOffset + 1]) - 0x80) << 12)
+ ((ord(s[byteOffset + 2]) - 0x80) << 6)
+ ord(s[byteOffset + 3])
- 0x80;
byteOffset += 4;
}
return code;
}
static public inline function unicodeIterator(s:String) {
return new StringIteratorUnicode(s);
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.iterators;
import php.Global.*;
import php.NativeString;
class StringKeyValueIteratorUnicode {
var charOffset:Int = 0;
var byteOffset:Int = 0;
var totalBytes:Int;
var s:NativeString;
public inline function new(s:String) {
this.s = s;
totalBytes = strlen(s);
}
public inline function hasNext() {
return byteOffset < totalBytes;
}
public inline function next() {
var code = ord(s[byteOffset]);
if (code < 0xC0) {
byteOffset++;
} else if (code < 0xE0) {
code = ((code - 0xC0) << 6) + ord(s[byteOffset + 1]) - 0x80;
byteOffset += 2;
} else if (code < 0xF0) {
code = ((code - 0xE0) << 12) + ((ord(s[byteOffset + 1]) - 0x80) << 6) + ord(s[byteOffset + 2]) - 0x80;
byteOffset += 3;
} else {
code = ((code - 0xF0) << 18)
+ ((ord(s[byteOffset + 1]) - 0x80) << 12)
+ ((ord(s[byteOffset + 2]) - 0x80) << 6)
+ ord(s[byteOffset + 3])
- 0x80;
byteOffset += 4;
}
return {key: charOffset++, value: code};
}
static public inline function unicodeKeyValueIterator(s:String) {
return new StringKeyValueIteratorUnicode(s);
}
}

View File

@ -0,0 +1,401 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.xml;
import php.Global;
import php.Syntax;
import php.NativeString;
using haxe.xml.Parser;
private enum abstract S(Int) {
var IGNORE_SPACES;
var BEGIN;
var BEGIN_NODE;
var TAG_NAME;
var BODY;
var ATTRIB_NAME;
var EQUALS;
var ATTVAL_BEGIN;
var ATTRIB_VAL;
var CHILDS;
var CLOSE;
var WAIT_END;
var WAIT_END_RET;
var PCDATA;
var HEADER;
var COMMENT;
var DOCTYPE;
var CDATA;
var ESCAPE;
}
class XmlParserException {
public var message:String;
public var lineNumber:Int;
public var positionAtLine:Int;
public var position:Int;
public var xml:String;
public function new(message:String, xml:String, position:Int) {
this.xml = xml;
this.message = message;
this.position = position;
lineNumber = 1;
positionAtLine = 0;
for (i in 0...position) {
var c = (xml : NativeString).fastCodeAt(i);
if (c == '\n'.code) {
lineNumber++;
positionAtLine = 0;
} else {
if (c != '\r'.code)
positionAtLine++;
}
}
}
public function toString():String {
return Type.getClassName(Type.getClass(this)) + ": " + message + " at line " + lineNumber + " char " + positionAtLine;
}
}
class Parser {
static var escapes = {
var h = new haxe.ds.StringMap();
h.set("lt", "<");
h.set("gt", ">");
h.set("amp", "&");
h.set("quot", '"');
h.set("apos", "'");
h;
}
static public function parse(str:String, strict = false) {
var doc = Xml.createDocument();
doParse(str, strict, 0, doc);
return doc;
}
static function doParse(str:NativeString, strict:Bool, p:Int = 0, ?parent:Xml):Int {
var xml:Xml = null;
var state = S.BEGIN;
var next = S.BEGIN;
var aname = null;
var start = 0;
var nsubs = 0;
var nbrackets = 0;
var c = str.fastCodeAt(p);
var buf:NativeString = '';
// need extra state because next is in use
var escapeNext = S.BEGIN;
var attrValQuote = -1;
inline function addChild(xml:Xml) {
parent.addChild(xml);
nsubs++;
}
while (!StringTools.isEof(c)) {
switch (state) {
case S.IGNORE_SPACES:
switch (c) {
case '\n'.code, '\r'.code, '\t'.code, ' '.code:
default:
state = next;
continue;
}
case S.BEGIN:
switch (c) {
case '<'.code:
state = S.IGNORE_SPACES;
next = S.BEGIN_NODE;
default:
start = p;
state = S.PCDATA;
continue;
}
case S.PCDATA:
if (c == '<'.code) {
buf = buf.addSub(str, start, p - start);
var child = Xml.createPCData(buf);
buf = '';
addChild(child);
state = S.IGNORE_SPACES;
next = S.BEGIN_NODE;
} else if (c == '&'.code) {
buf = buf.addSub(str, start, p - start);
state = S.ESCAPE;
escapeNext = S.PCDATA;
start = p + 1;
}
case S.CDATA:
if (c == ']'.code && str.fastCodeAt(p + 1) == ']'.code && str.fastCodeAt(p + 2) == '>'.code) {
var child = Xml.createCData(str.substr(start, p - start));
addChild(child);
p += 2;
state = S.BEGIN;
}
case S.BEGIN_NODE:
switch (c) {
case '!'.code:
if (str.fastCodeAt(p + 1) == '['.code) {
p += 2;
if (Global.strtoupper(str.substr(p, 6)) != "CDATA[")
throw new XmlParserException("Expected <![CDATA[", str, p);
p += 5;
state = S.CDATA;
start = p + 1;
} else if (str.fastCodeAt(p + 1) == 'D'.code || str.fastCodeAt(p + 1) == 'd'.code) {
if (Global.strtoupper(str.substr(p + 2, 6)) != "OCTYPE")
throw new XmlParserException("Expected <!DOCTYPE", str, p);
p += 8;
state = S.DOCTYPE;
start = p + 1;
} else if (str.fastCodeAt(p + 1) != '-'.code || str.fastCodeAt(p + 2) != '-'.code)
throw new XmlParserException("Expected <!--", str, p);
else {
p += 2;
state = S.COMMENT;
start = p + 1;
}
case '?'.code:
state = S.HEADER;
start = p;
case '/'.code:
if (parent == null)
throw new XmlParserException("Expected node name", str, p);
start = p + 1;
state = S.IGNORE_SPACES;
next = S.CLOSE;
default:
state = S.TAG_NAME;
start = p;
continue;
}
case S.TAG_NAME:
if (!isValidChar(c)) {
if (p == start)
throw new XmlParserException("Expected node name", str, p);
xml = Xml.createElement(str.substr(start, p - start));
addChild(xml);
state = S.IGNORE_SPACES;
next = S.BODY;
continue;
}
case S.BODY:
switch (c) {
case '/'.code:
state = S.WAIT_END;
case '>'.code:
state = S.CHILDS;
default:
state = S.ATTRIB_NAME;
start = p;
continue;
}
case S.ATTRIB_NAME:
if (!isValidChar(c)) {
var tmp;
if (start == p)
throw new XmlParserException("Expected attribute name", str, p);
tmp = str.substr(start, p - start);
aname = tmp;
if (xml.exists(aname))
throw new XmlParserException("Duplicate attribute [" + aname + "]", str, p);
state = S.IGNORE_SPACES;
next = S.EQUALS;
continue;
}
case S.EQUALS:
switch (c) {
case '='.code:
state = S.IGNORE_SPACES;
next = S.ATTVAL_BEGIN;
default:
throw new XmlParserException("Expected =", str, p);
}
case S.ATTVAL_BEGIN:
switch (c) {
case '"'.code | '\''.code:
buf = '';
state = S.ATTRIB_VAL;
start = p + 1;
attrValQuote = c;
default:
throw new XmlParserException("Expected \"", str, p);
}
case S.ATTRIB_VAL:
switch (c) {
case '&'.code:
buf = buf.addSub(str, start, p - start);
state = S.ESCAPE;
escapeNext = S.ATTRIB_VAL;
start = p + 1;
case '>'.code | '<'.code if (strict):
// HTML allows these in attributes values
throw new XmlParserException("Invalid unescaped " + String.fromCharCode(c) + " in attribute value", str, p);
case _ if (c == attrValQuote):
buf = buf.addSub(str, start, p - start);
var val = buf;
buf = '';
xml.set(aname, val);
state = S.IGNORE_SPACES;
next = S.BODY;
}
case S.CHILDS:
p = doParse(str, strict, p, xml);
start = p;
state = S.BEGIN;
case S.WAIT_END:
switch (c) {
case '>'.code:
state = S.BEGIN;
default:
throw new XmlParserException("Expected >", str, p);
}
case S.WAIT_END_RET:
switch (c) {
case '>'.code:
if (nsubs == 0)
parent.addChild(Xml.createPCData(""));
return p;
default:
throw new XmlParserException("Expected >", str, p);
}
case S.CLOSE:
if (!isValidChar(c)) {
if (start == p)
throw new XmlParserException("Expected node name", str, p);
var v = str.substr(start, p - start);
if (parent == null || parent.nodeType != Element) {
throw new XmlParserException('Unexpected </$v>, tag is not open', str, p);
}
if (v != parent.nodeName)
throw new XmlParserException("Expected </" + parent.nodeName + ">", str, p);
state = S.IGNORE_SPACES;
next = S.WAIT_END_RET;
continue;
}
case S.COMMENT:
if (c == '-'.code && str.fastCodeAt(p + 1) == '-'.code && str.fastCodeAt(p + 2) == '>'.code) {
addChild(Xml.createComment(str.substr(start, p - start)));
p += 2;
state = S.BEGIN;
}
case S.DOCTYPE:
if (c == '['.code)
nbrackets++;
else if (c == ']'.code)
nbrackets--;
else if (c == '>'.code && nbrackets == 0) {
addChild(Xml.createDocType(str.substr(start, p - start)));
state = S.BEGIN;
}
case S.HEADER:
if (c == '?'.code && str.fastCodeAt(p + 1) == '>'.code) {
p++;
var str = str.substr(start + 1, p - start - 2);
addChild(Xml.createProcessingInstruction(str));
state = S.BEGIN;
}
case S.ESCAPE:
if (c == ';'.code) {
var s = str.substr(start, p - start);
if (s.fastCodeAt(0) == '#'.code) {
var c = s.fastCodeAt(1) == 'x'.code ? Std.parseInt("0" + s.substr(1,
Global.strlen(s) - 1)) : Std.parseInt(s.substr(1, Global.strlen(s) - 1));
buf = Syntax.concat(buf, Global.mb_chr(c));
} else if (!escapes.exists(s)) {
if (strict)
throw new XmlParserException("Undefined entity: " + s, str, p);
buf = Syntax.concat(buf, '&$s;');
} else {
buf = Syntax.concat(buf, escapes.get(s));
}
start = p + 1;
state = escapeNext;
} else if (!isValidChar(c) && c != "#".code) {
if (strict)
throw new XmlParserException("Invalid character in entity: " + String.fromCharCode(c), str, p);
buf = Syntax.concat(buf, "&");
buf = buf.addSub(str, start, p - start);
p--;
start = p + 1;
state = escapeNext;
}
}
c = str.fastCodeAt(++p);
}
if (state == S.BEGIN) {
start = p;
state = S.PCDATA;
}
if (state == S.PCDATA) {
if (parent.nodeType == Element) {
throw new XmlParserException("Unclosed node <" + parent.nodeName + ">", str, p);
}
if (p != start || nsubs == 0) {
buf = buf.addSub(str, start, p - start);
addChild(Xml.createPCData(buf));
}
return p;
}
if (!strict && state == S.ESCAPE && escapeNext == S.PCDATA) {
buf = Syntax.concat(buf, "&");
buf = buf.addSub(str, start, p - start);
addChild(Xml.createPCData(buf));
return p;
}
throw new XmlParserException("Unexpected end", str, p);
}
static inline function isValidChar(c) {
return (c >= 'a'.code && c <= 'z'.code) || (c >= 'A'.code && c <= 'Z'.code) || (c >= '0'.code && c <= '9'.code) || c == ':'.code || c == '.'.code
|| c == '_'.code || c == '-'.code;
}
// TODO: rewrite the parser using a buffer instead of a string as the data source
@:allow(haxe.xml.XmlParserException)
static inline function fastCodeAt(s:NativeString, pos:Int):Int {
return pos >= Global.strlen(s) ? 0 : Global.ord(s[pos]);
}
static inline function substr(s:NativeString, pos:Int, ?length:Int):NativeString {
return Global.substr(s, pos, length);
}
static inline function addSub(buf:NativeString, s:NativeString, pos:Int, length:Int):NativeString {
return Syntax.concat(buf, Global.substr(s, pos, length));
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C)2005-2019 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.zip;
@:coreApi
class Compress {
private var level:Int;
public function new(level:Int):Void {
this.level = level;
}
public function execute(src:haxe.io.Bytes, srcPos:Int, dst:haxe.io.Bytes, dstPos:Int):{done:Bool, read:Int, write:Int} {
var input = src.sub(srcPos, src.length - srcPos);
var data = run(input, level);
dst.blit(dstPos, data, 0, data.length);
return {
done: true,
read: input.length,
write: data.length
};
}
public function setFlushMode(f:FlushMode):Void {}
public function close():Void {}
public static function run(s:haxe.io.Bytes, level:Int):haxe.io.Bytes {
var c = php.Global.gzcompress(s.toString(), level);
return haxe.io.Bytes.ofString(c);
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (C)2005-2012 Haxe Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package haxe.zip;
class Uncompress {
public function new(?windowBits:Int) {}
public function execute(src:haxe.io.Bytes, srcPos:Int, dst:haxe.io.Bytes, dstPos:Int):{done:Bool, read:Int, write:Int} {
var input = src.sub(srcPos, src.length - srcPos);
var data = run(input);
dst.blit(dstPos, data, 0, data.length);
return {
done: true,
read: input.length,
write: data.length
};
}
public function setFlushMode(f:FlushMode) {}
public function close() {}
public static function run(src:haxe.io.Bytes, ?bufsize:Int):haxe.io.Bytes {
var c = php.Global.gzuncompress(src.toString());
return haxe.io.Bytes.ofString(c);
}
}