forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
324
Kha/Tools/linux_arm64/std/haxe/format/JsonParser.hx
Normal file
324
Kha/Tools/linux_arm64/std/haxe/format/JsonParser.hx
Normal file
@ -0,0 +1,324 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
An implementation of JSON parser in Haxe.
|
||||
|
||||
This class is used by `haxe.Json` when native JSON implementation
|
||||
is not available.
|
||||
|
||||
@see https://haxe.org/manual/std-Json-parsing.html
|
||||
**/
|
||||
class JsonParser {
|
||||
/**
|
||||
Parses given JSON-encoded `str` and returns the resulting object.
|
||||
|
||||
JSON objects are parsed into anonymous structures and JSON arrays
|
||||
are parsed into `Array<Dynamic>`.
|
||||
|
||||
If given `str` is not valid JSON, an exception will be thrown.
|
||||
|
||||
If `str` is null, the result is unspecified.
|
||||
**/
|
||||
static public inline function parse(str:String):Dynamic {
|
||||
return new JsonParser(str).doParse();
|
||||
}
|
||||
|
||||
var str:String;
|
||||
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:StringBuf = null;
|
||||
#if target.unicode
|
||||
var prev = -1;
|
||||
inline function cancelSurrogate() {
|
||||
// invalid high surrogate (not followed by low surrogate)
|
||||
buf.addChar(0xFFFD);
|
||||
prev = -1;
|
||||
}
|
||||
#end
|
||||
while (true) {
|
||||
var c = nextChar();
|
||||
if (c == '"'.code)
|
||||
break;
|
||||
if (c == '\\'.code) {
|
||||
if (buf == null) {
|
||||
buf = new StringBuf();
|
||||
}
|
||||
buf.addSub(str, start, pos - start - 1);
|
||||
c = nextChar();
|
||||
#if target.unicode
|
||||
if (c != "u".code && prev != -1)
|
||||
cancelSurrogate();
|
||||
#end
|
||||
switch (c) {
|
||||
case "r".code:
|
||||
buf.addChar("\r".code);
|
||||
case "n".code:
|
||||
buf.addChar("\n".code);
|
||||
case "t".code:
|
||||
buf.addChar("\t".code);
|
||||
case "b".code:
|
||||
buf.addChar(8);
|
||||
case "f".code:
|
||||
buf.addChar(12);
|
||||
case "/".code, '\\'.code, '"'.code:
|
||||
buf.addChar(c);
|
||||
case 'u'.code:
|
||||
var uc:Int = Std.parseInt("0x" + str.substr(pos, 4));
|
||||
pos += 4;
|
||||
#if !target.unicode
|
||||
if (uc <= 0x7F)
|
||||
buf.addChar(uc);
|
||||
else if (uc <= 0x7FF) {
|
||||
buf.addChar(0xC0 | (uc >> 6));
|
||||
buf.addChar(0x80 | (uc & 63));
|
||||
} else if (uc <= 0xFFFF) {
|
||||
buf.addChar(0xE0 | (uc >> 12));
|
||||
buf.addChar(0x80 | ((uc >> 6) & 63));
|
||||
buf.addChar(0x80 | (uc & 63));
|
||||
} else {
|
||||
buf.addChar(0xF0 | (uc >> 18));
|
||||
buf.addChar(0x80 | ((uc >> 12) & 63));
|
||||
buf.addChar(0x80 | ((uc >> 6) & 63));
|
||||
buf.addChar(0x80 | (uc & 63));
|
||||
}
|
||||
#else
|
||||
if (prev != -1) {
|
||||
if (uc < 0xDC00 || uc > 0xDFFF)
|
||||
cancelSurrogate();
|
||||
else {
|
||||
buf.addChar(((prev - 0xD800) << 10) + (uc - 0xDC00) + 0x10000);
|
||||
prev = -1;
|
||||
}
|
||||
} else if (uc >= 0xD800 && uc <= 0xDBFF)
|
||||
prev = uc;
|
||||
else
|
||||
buf.addChar(uc);
|
||||
#end
|
||||
default:
|
||||
throw "Invalid escape sequence \\" + String.fromCharCode(c) + " at position " + (pos - 1);
|
||||
}
|
||||
start = pos;
|
||||
}
|
||||
#if !(target.unicode)
|
||||
// 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++;
|
||||
}
|
||||
#end
|
||||
else if (StringTools.isEof(c))
|
||||
throw "Unclosed string";
|
||||
}
|
||||
#if target.unicode
|
||||
if (prev != -1)
|
||||
cancelSurrogate();
|
||||
#end
|
||||
if (buf == null) {
|
||||
return str.substr(start, pos - start - 1);
|
||||
} else {
|
||||
buf.addSub(str, start, pos - start - 1);
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
if(point) {
|
||||
return f;
|
||||
} else {
|
||||
var i = Std.int(f);
|
||||
return if (i == f) i else f;
|
||||
}
|
||||
}
|
||||
|
||||
inline function nextChar() {
|
||||
return StringTools.fastCodeAt(str, pos++);
|
||||
}
|
||||
|
||||
function invalidChar() {
|
||||
pos--; // rewind
|
||||
throw "Invalid char " + StringTools.fastCodeAt(str, pos) + " at position " + pos;
|
||||
}
|
||||
|
||||
function invalidNumber(start:Int) {
|
||||
throw "Invalid number at position " + start + ": " + str.substr(start, pos - start);
|
||||
}
|
||||
}
|
291
Kha/Tools/linux_arm64/std/haxe/format/JsonPrinter.hx
Normal file
291
Kha/Tools/linux_arm64/std/haxe/format/JsonPrinter.hx
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
An implementation of JSON printer in Haxe.
|
||||
|
||||
This class is used by `haxe.Json` when native JSON implementation
|
||||
is not available.
|
||||
|
||||
@see https://haxe.org/manual/std-Json-encoding.html
|
||||
**/
|
||||
class JsonPrinter {
|
||||
/**
|
||||
Encodes `o`'s value and returns the resulting JSON string.
|
||||
|
||||
If `replacer` is given and is not null, it is used to retrieve
|
||||
actual object to be encoded. The `replacer` function takes two parameters,
|
||||
the key and the value being encoded. Initial key value is an empty string.
|
||||
|
||||
If `space` is given and is not null, the result will be pretty-printed.
|
||||
Successive levels will be indented by this string.
|
||||
**/
|
||||
static public function print(o:Dynamic, ?replacer:(key:Dynamic, value:Dynamic) -> Dynamic, ?space:String):String {
|
||||
var printer = new JsonPrinter(replacer, space);
|
||||
printer.write("", o);
|
||||
return printer.buf.toString();
|
||||
}
|
||||
|
||||
var buf:#if flash flash.utils.ByteArray #else StringBuf #end;
|
||||
var replacer:(key:Dynamic, value:Dynamic) -> Dynamic;
|
||||
var indent:String;
|
||||
var pretty:Bool;
|
||||
var nind:Int;
|
||||
|
||||
function new(replacer:(key:Dynamic, value:Dynamic) -> Dynamic, space:String) {
|
||||
this.replacer = replacer;
|
||||
this.indent = space;
|
||||
this.pretty = space != null;
|
||||
this.nind = 0;
|
||||
|
||||
#if flash
|
||||
buf = new flash.utils.ByteArray();
|
||||
buf.endian = flash.utils.Endian.BIG_ENDIAN;
|
||||
buf.position = 0;
|
||||
#else
|
||||
buf = new StringBuf();
|
||||
#end
|
||||
}
|
||||
|
||||
inline function ipad():Void {
|
||||
if (pretty)
|
||||
add(StringTools.lpad('', indent, nind * indent.length));
|
||||
}
|
||||
|
||||
inline function newl():Void {
|
||||
if (pretty)
|
||||
addChar('\n'.code);
|
||||
}
|
||||
|
||||
function write(k:Dynamic, v:Dynamic) {
|
||||
if (replacer != null)
|
||||
v = replacer(k, v);
|
||||
switch (Type.typeof(v)) {
|
||||
case TUnknown:
|
||||
add('"???"');
|
||||
case TObject:
|
||||
objString(v);
|
||||
case TInt:
|
||||
add(#if (jvm || hl) Std.string(v) #else v #end);
|
||||
case TFloat:
|
||||
add(Math.isFinite(v) ? Std.string(v) : 'null');
|
||||
case TFunction:
|
||||
add('"<fun>"');
|
||||
case TClass(c):
|
||||
if (c == String)
|
||||
quote(v);
|
||||
else if (c == Array) {
|
||||
var v:Array<Dynamic> = v;
|
||||
addChar('['.code);
|
||||
|
||||
var len = v.length;
|
||||
var last = len - 1;
|
||||
for (i in 0...len) {
|
||||
if (i > 0)
|
||||
addChar(','.code)
|
||||
else
|
||||
nind++;
|
||||
newl();
|
||||
ipad();
|
||||
write(i, v[i]);
|
||||
if (i == last) {
|
||||
nind--;
|
||||
newl();
|
||||
ipad();
|
||||
}
|
||||
}
|
||||
addChar(']'.code);
|
||||
} else if (c == haxe.ds.StringMap) {
|
||||
var v:haxe.ds.StringMap<Dynamic> = v;
|
||||
var o = {};
|
||||
for (k in v.keys())
|
||||
Reflect.setField(o, k, v.get(k));
|
||||
objString(o);
|
||||
} else if (c == Date) {
|
||||
var v:Date = v;
|
||||
quote(v.toString());
|
||||
} else
|
||||
classString(v);
|
||||
case TEnum(_):
|
||||
var i:Dynamic = Type.enumIndex(v);
|
||||
add(i);
|
||||
case TBool:
|
||||
add(#if (php || jvm || hl) (v ? 'true' : 'false') #else v #end);
|
||||
case TNull:
|
||||
add('null');
|
||||
}
|
||||
}
|
||||
|
||||
extern inline function addChar(c:Int) {
|
||||
#if flash
|
||||
buf.writeByte(c);
|
||||
#else
|
||||
buf.addChar(c);
|
||||
#end
|
||||
}
|
||||
|
||||
extern inline function add(v:String) {
|
||||
#if flash
|
||||
// argument is not always a string but will be automatically casted
|
||||
buf.writeUTFBytes(v);
|
||||
#else
|
||||
buf.add(v);
|
||||
#end
|
||||
}
|
||||
|
||||
function classString(v:Dynamic) {
|
||||
fieldsString(v, Type.getInstanceFields(Type.getClass(v)));
|
||||
}
|
||||
|
||||
inline function objString(v:Dynamic) {
|
||||
fieldsString(v, Reflect.fields(v));
|
||||
}
|
||||
|
||||
function fieldsString(v:Dynamic, fields:Array<String>) {
|
||||
addChar('{'.code);
|
||||
var len = fields.length;
|
||||
var last = len - 1;
|
||||
var first = true;
|
||||
for (i in 0...len) {
|
||||
var f = fields[i];
|
||||
var value = Reflect.field(v, f);
|
||||
if (Reflect.isFunction(value))
|
||||
continue;
|
||||
if (first) {
|
||||
nind++;
|
||||
first = false;
|
||||
} else
|
||||
addChar(','.code);
|
||||
newl();
|
||||
ipad();
|
||||
quote(f);
|
||||
addChar(':'.code);
|
||||
if (pretty)
|
||||
addChar(' '.code);
|
||||
write(f, value);
|
||||
if (i == last) {
|
||||
nind--;
|
||||
newl();
|
||||
ipad();
|
||||
}
|
||||
}
|
||||
addChar('}'.code);
|
||||
}
|
||||
|
||||
function quote(s:String) {
|
||||
#if neko
|
||||
if (s.length != neko.Utf8.length(s)) {
|
||||
quoteUtf8(s);
|
||||
return;
|
||||
}
|
||||
#end
|
||||
addChar('"'.code);
|
||||
var i = 0;
|
||||
var length = s.length;
|
||||
#if hl
|
||||
var prev = -1;
|
||||
#end
|
||||
while (i < length) {
|
||||
var c = StringTools.unsafeCodeAt(s, i++);
|
||||
switch (c) {
|
||||
case '"'.code:
|
||||
add('\\"');
|
||||
case '\\'.code:
|
||||
add('\\\\');
|
||||
case '\n'.code:
|
||||
add('\\n');
|
||||
case '\r'.code:
|
||||
add('\\r');
|
||||
case '\t'.code:
|
||||
add('\\t');
|
||||
case 8:
|
||||
add('\\b');
|
||||
case 12:
|
||||
add('\\f');
|
||||
default:
|
||||
#if flash
|
||||
if (c >= 128)
|
||||
add(String.fromCharCode(c))
|
||||
else
|
||||
addChar(c);
|
||||
#elseif hl
|
||||
if (prev >= 0) {
|
||||
if (c >= 0xD800 && c <= 0xDFFF) {
|
||||
addChar((((prev - 0xD800) << 10) | (c - 0xDC00)) + 0x10000);
|
||||
prev = -1;
|
||||
} else {
|
||||
addChar("□".code);
|
||||
prev = c;
|
||||
}
|
||||
} else {
|
||||
if (c >= 0xD800 && c <= 0xDFFF)
|
||||
prev = c;
|
||||
else
|
||||
addChar(c);
|
||||
}
|
||||
#else
|
||||
addChar(c);
|
||||
#end
|
||||
}
|
||||
}
|
||||
#if hl
|
||||
if (prev >= 0)
|
||||
addChar("□".code);
|
||||
#end
|
||||
addChar('"'.code);
|
||||
}
|
||||
|
||||
#if neko
|
||||
function quoteUtf8(s:String) {
|
||||
var u = new neko.Utf8();
|
||||
neko.Utf8.iter(s, function(c) {
|
||||
switch (c) {
|
||||
case '\\'.code, '"'.code:
|
||||
u.addChar('\\'.code);
|
||||
u.addChar(c);
|
||||
case '\n'.code:
|
||||
u.addChar('\\'.code);
|
||||
u.addChar('n'.code);
|
||||
case '\r'.code:
|
||||
u.addChar('\\'.code);
|
||||
u.addChar('r'.code);
|
||||
case '\t'.code:
|
||||
u.addChar('\\'.code);
|
||||
u.addChar('t'.code);
|
||||
case 8:
|
||||
u.addChar('\\'.code);
|
||||
u.addChar('b'.code);
|
||||
case 12:
|
||||
u.addChar('\\'.code);
|
||||
u.addChar('f'.code);
|
||||
default:
|
||||
u.addChar(c);
|
||||
}
|
||||
});
|
||||
buf.add('"');
|
||||
buf.add(u.toString());
|
||||
buf.add('"');
|
||||
}
|
||||
#end
|
||||
}
|
Reference in New Issue
Block a user