forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
243
Kha/Tools/linux_arm64/std/haxe/xml/Access.hx
Normal file
243
Kha/Tools/linux_arm64/std/haxe/xml/Access.hx
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
private abstract NodeAccess(Xml) from Xml {
|
||||
@:op(a.b)
|
||||
public function resolve(name:String):Access {
|
||||
var x = this.elementsNamed(name).next();
|
||||
if (x == null) {
|
||||
var xname = if (this.nodeType == Xml.Document) "Document" else this.nodeName;
|
||||
throw xname + " is missing element " + name;
|
||||
}
|
||||
return new Access(x);
|
||||
}
|
||||
}
|
||||
|
||||
private abstract AttribAccess(Xml) from Xml {
|
||||
@:op(a.b)
|
||||
public function resolve(name:String):String {
|
||||
if (this.nodeType == Xml.Document)
|
||||
throw "Cannot access document attribute " + name;
|
||||
var v = this.get(name);
|
||||
if (v == null)
|
||||
throw this.nodeName + " is missing attribute " + name;
|
||||
return v;
|
||||
}
|
||||
|
||||
@:op(a.b)
|
||||
function _hx_set(name:String, value:String):String {
|
||||
if (this.nodeType == Xml.Document)
|
||||
throw "Cannot access document attribute " + name;
|
||||
this.set(name, value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private abstract HasAttribAccess(Xml) from Xml {
|
||||
@:op(a.b)
|
||||
public function resolve(name:String):Bool {
|
||||
if (this.nodeType == Xml.Document)
|
||||
throw "Cannot access document attribute " + name;
|
||||
return this.exists(name);
|
||||
}
|
||||
}
|
||||
|
||||
private abstract HasNodeAccess(Xml) from Xml {
|
||||
@:op(a.b)
|
||||
public function resolve(name:String):Bool {
|
||||
return this.elementsNamed(name).hasNext();
|
||||
}
|
||||
}
|
||||
|
||||
private abstract NodeListAccess(Xml) from Xml {
|
||||
@:op(a.b)
|
||||
public function resolve(name:String):Array<Access> {
|
||||
var l = [];
|
||||
for (x in this.elementsNamed(name))
|
||||
l.push(new Access(x));
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The `haxe.xml.Access` API helps providing a fast dot-syntax access to the
|
||||
most common `Xml` methods.
|
||||
**/
|
||||
abstract Access(Xml) {
|
||||
public var x(get, never):Xml;
|
||||
|
||||
public inline function get_x()
|
||||
return this;
|
||||
|
||||
/**
|
||||
The name of the current element. This is the same as `Xml.nodeName`.
|
||||
**/
|
||||
public var name(get, never):String;
|
||||
|
||||
inline function get_name() {
|
||||
return if (this.nodeType == Xml.Document) "Document" else this.nodeName;
|
||||
}
|
||||
|
||||
/**
|
||||
The inner PCDATA or CDATA of the node.
|
||||
|
||||
An exception is thrown if there is no data or if there not only data
|
||||
but also other nodes.
|
||||
**/
|
||||
public var innerData(get, never):String;
|
||||
|
||||
/**
|
||||
The XML string built with all the sub nodes, excluding the current one.
|
||||
**/
|
||||
public var innerHTML(get, never):String;
|
||||
|
||||
/**
|
||||
Access to the first sub element with the given name.
|
||||
|
||||
An exception is thrown if the element doesn't exists.
|
||||
Use `hasNode` to check the existence of a node.
|
||||
|
||||
```haxe
|
||||
var access = new haxe.xml.Access(Xml.parse("<user><name>John</name></user>"));
|
||||
var user = access.node.user;
|
||||
var name = user.node.name;
|
||||
trace(name.innerData); // John
|
||||
|
||||
// Uncaught Error: Document is missing element password
|
||||
var password = user.node.password;
|
||||
```
|
||||
**/
|
||||
public var node(get, never):NodeAccess;
|
||||
|
||||
inline function get_node():NodeAccess
|
||||
return x;
|
||||
|
||||
/**
|
||||
Access to the List of elements with the given name.
|
||||
```haxe
|
||||
var fast = new haxe.xml.Access(Xml.parse("
|
||||
<users>
|
||||
<user name='John'/>
|
||||
<user name='Andy'/>
|
||||
<user name='Dan'/>
|
||||
</users>"
|
||||
));
|
||||
|
||||
var users = fast.node.users;
|
||||
for (user in users.nodes.user) {
|
||||
trace(user.att.name);
|
||||
}
|
||||
```
|
||||
**/
|
||||
public var nodes(get, never):NodeListAccess;
|
||||
|
||||
inline function get_nodes():NodeListAccess
|
||||
return this;
|
||||
|
||||
/**
|
||||
Access to a given attribute.
|
||||
|
||||
An exception is thrown if the attribute doesn't exists.
|
||||
Use `has` to check the existence of an attribute.
|
||||
|
||||
```haxe
|
||||
var f = new haxe.xml.Access(Xml.parse("<user name='Mark'></user>"));
|
||||
var user = f.node.user;
|
||||
if (user.has.name) {
|
||||
trace(user.att.name); // Mark
|
||||
}
|
||||
```
|
||||
**/
|
||||
public var att(get, never):AttribAccess;
|
||||
|
||||
inline function get_att():AttribAccess
|
||||
return this;
|
||||
|
||||
/**
|
||||
Check the existence of an attribute with the given name.
|
||||
**/
|
||||
public var has(get, never):HasAttribAccess;
|
||||
|
||||
inline function get_has():HasAttribAccess
|
||||
return this;
|
||||
|
||||
/**
|
||||
Check the existence of a sub node with the given name.
|
||||
|
||||
```haxe
|
||||
var f = new haxe.xml.Access(Xml.parse("<user><age>31</age></user>"));
|
||||
var user = f.node.user;
|
||||
if (user.hasNode.age) {
|
||||
trace(user.node.age.innerData); // 31
|
||||
}
|
||||
```
|
||||
**/
|
||||
public var hasNode(get, never):HasNodeAccess;
|
||||
|
||||
inline function get_hasNode():HasNodeAccess
|
||||
return x;
|
||||
|
||||
/**
|
||||
The list of all sub-elements which are the nodes with type `Xml.Element`.
|
||||
**/
|
||||
public var elements(get, never):Iterator<Access>;
|
||||
|
||||
inline function get_elements():Iterator<Access>
|
||||
return cast this.elements();
|
||||
|
||||
public inline function new(x:Xml) {
|
||||
if (x.nodeType != Xml.Document && x.nodeType != Xml.Element)
|
||||
throw "Invalid nodeType " + x.nodeType;
|
||||
this = x;
|
||||
}
|
||||
|
||||
function get_innerData() {
|
||||
var it = this.iterator();
|
||||
if (!it.hasNext())
|
||||
throw name + " does not have data";
|
||||
var v = it.next();
|
||||
if (it.hasNext()) {
|
||||
var n = it.next();
|
||||
// handle <spaces>CDATA<spaces>
|
||||
if (v.nodeType == Xml.PCData && n.nodeType == Xml.CData && StringTools.trim(v.nodeValue) == "") {
|
||||
if (!it.hasNext())
|
||||
return n.nodeValue;
|
||||
var n2 = it.next();
|
||||
if (n2.nodeType == Xml.PCData && StringTools.trim(n2.nodeValue) == "" && !it.hasNext())
|
||||
return n.nodeValue;
|
||||
}
|
||||
throw name + " does not only have data";
|
||||
}
|
||||
if (v.nodeType != Xml.PCData && v.nodeType != Xml.CData)
|
||||
throw name + " does not have data";
|
||||
return v.nodeValue;
|
||||
}
|
||||
|
||||
function get_innerHTML() {
|
||||
var s = new StringBuf();
|
||||
for (x in this)
|
||||
s.add(x.toString());
|
||||
return s.toString();
|
||||
}
|
||||
}
|
329
Kha/Tools/linux_arm64/std/haxe/xml/Check.hx
Normal file
329
Kha/Tools/linux_arm64/std/haxe/xml/Check.hx
Normal file
@ -0,0 +1,329 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
enum Filter {
|
||||
FInt;
|
||||
FBool;
|
||||
FEnum(values:Array<String>);
|
||||
FReg(matcher:EReg);
|
||||
}
|
||||
|
||||
enum Attrib {
|
||||
Att(name:String, ?filter:Filter, ?defvalue:String);
|
||||
}
|
||||
|
||||
enum Rule {
|
||||
RNode(name:String, ?attribs:Array<Attrib>, ?childs:Rule);
|
||||
RData(?filter:Filter);
|
||||
RMulti(rule:Rule, ?atLeastOne:Bool);
|
||||
RList(rules:Array<Rule>, ?ordered:Bool);
|
||||
RChoice(choices:Array<Rule>);
|
||||
ROptional(rule:Rule);
|
||||
}
|
||||
|
||||
private enum CheckResult {
|
||||
CMatch;
|
||||
CMissing(r:Rule);
|
||||
CExtra(x:Xml);
|
||||
CElementExpected(name:String, x:Xml);
|
||||
CDataExpected(x:Xml);
|
||||
CExtraAttrib(att:String, x:Xml);
|
||||
CMissingAttrib(att:String, x:Xml);
|
||||
CInvalidAttrib(att:String, x:Xml, f:Filter);
|
||||
CInvalidData(x:Xml, f:Filter);
|
||||
CInElement(x:Xml, r:CheckResult);
|
||||
}
|
||||
|
||||
class Check {
|
||||
static var blanks = ~/^[ \r\n\t]*$/;
|
||||
|
||||
static function isBlank(x:Xml) {
|
||||
return (x.nodeType == Xml.PCData && blanks.match(x.nodeValue)) || x.nodeType == Xml.Comment;
|
||||
}
|
||||
|
||||
static function filterMatch(s:String, f:Filter) {
|
||||
switch (f) {
|
||||
case FInt:
|
||||
return filterMatch(s, FReg(~/[0-9]+/));
|
||||
case FBool:
|
||||
return filterMatch(s, FEnum(["true", "false", "0", "1"]));
|
||||
case FEnum(values):
|
||||
for (v in values)
|
||||
if (s == v)
|
||||
return true;
|
||||
return false;
|
||||
case FReg(r):
|
||||
return r.match(s);
|
||||
}
|
||||
}
|
||||
|
||||
static function isNullable(r:Rule) {
|
||||
switch (r) {
|
||||
case RMulti(r, one):
|
||||
return (one != true || isNullable(r));
|
||||
case RList(rl, _):
|
||||
for (r in rl)
|
||||
if (!isNullable(r))
|
||||
return false;
|
||||
return true;
|
||||
case RChoice(rl):
|
||||
for (r in rl)
|
||||
if (isNullable(r))
|
||||
return true;
|
||||
return false;
|
||||
case RData(_):
|
||||
return false;
|
||||
case RNode(_, _, _):
|
||||
return false;
|
||||
case ROptional(_):
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static function check(x:Xml, r:Rule) {
|
||||
switch (r) {
|
||||
// check the node validity
|
||||
case RNode(name, attribs, childs):
|
||||
if (x.nodeType != Xml.Element || x.nodeName != name)
|
||||
return CElementExpected(name, x);
|
||||
var attribs = if (attribs == null) new Array() else attribs.copy();
|
||||
// check defined attributes
|
||||
for (xatt in x.attributes()) {
|
||||
var found = false;
|
||||
for (att in attribs)
|
||||
switch (att) {
|
||||
case Att(name, filter, _):
|
||||
if (xatt != name)
|
||||
continue;
|
||||
if (filter != null && !filterMatch(x.get(xatt), filter))
|
||||
return CInvalidAttrib(name, x, filter);
|
||||
attribs.remove(att);
|
||||
found = true;
|
||||
}
|
||||
if (!found)
|
||||
return CExtraAttrib(xatt, x);
|
||||
}
|
||||
// check remaining unchecked attributes
|
||||
for (att in attribs)
|
||||
switch (att) {
|
||||
case Att(name, _, defvalue):
|
||||
if (defvalue == null)
|
||||
return CMissingAttrib(name, x);
|
||||
}
|
||||
// check childs
|
||||
if (childs == null)
|
||||
childs = RList([]);
|
||||
var m = checkList(x.iterator(), childs);
|
||||
if (m != CMatch)
|
||||
return CInElement(x, m);
|
||||
// set default attribs values
|
||||
for (att in attribs)
|
||||
switch (att) {
|
||||
case Att(name, _, defvalue):
|
||||
x.set(name, defvalue);
|
||||
}
|
||||
return CMatch;
|
||||
// check the data validity
|
||||
case RData(filter):
|
||||
if (x.nodeType != Xml.PCData && x.nodeType != Xml.CData)
|
||||
return CDataExpected(x);
|
||||
if (filter != null && !filterMatch(x.nodeValue, filter))
|
||||
return CInvalidData(x, filter);
|
||||
return CMatch;
|
||||
// several choices
|
||||
case RChoice(choices):
|
||||
if (choices.length == 0)
|
||||
throw "No choice possible";
|
||||
for (c in choices)
|
||||
if (check(x, c) == CMatch)
|
||||
return CMatch;
|
||||
return check(x, choices[0]);
|
||||
case ROptional(r):
|
||||
return check(x, r);
|
||||
default:
|
||||
throw "Unexpected " + Std.string(r);
|
||||
}
|
||||
}
|
||||
|
||||
static function checkList(it:Iterator<Xml>, r:Rule) {
|
||||
switch (r) {
|
||||
case RList(rules, ordered):
|
||||
var rules = rules.copy();
|
||||
for (x in it) {
|
||||
if (isBlank(x))
|
||||
continue;
|
||||
var found = false;
|
||||
for (r in rules) {
|
||||
var m = checkList([x].iterator(), r);
|
||||
if (m == CMatch) {
|
||||
found = true;
|
||||
switch (r) {
|
||||
case RMulti(rsub, one):
|
||||
if (one) {
|
||||
var i;
|
||||
for (i in 0...rules.length)
|
||||
if (rules[i] == r)
|
||||
rules[i] = RMulti(rsub);
|
||||
}
|
||||
default:
|
||||
rules.remove(r);
|
||||
}
|
||||
break;
|
||||
} else if (ordered && !isNullable(r))
|
||||
return m;
|
||||
}
|
||||
if (!found)
|
||||
return CExtra(x);
|
||||
}
|
||||
for (r in rules)
|
||||
if (!isNullable(r))
|
||||
return CMissing(r);
|
||||
return CMatch;
|
||||
case RMulti(r, one):
|
||||
var found = false;
|
||||
for (x in it) {
|
||||
if (isBlank(x))
|
||||
continue;
|
||||
var m = checkList([x].iterator(), r);
|
||||
if (m != CMatch)
|
||||
return m;
|
||||
found = true;
|
||||
}
|
||||
if (one && !found)
|
||||
return CMissing(r);
|
||||
return CMatch;
|
||||
default:
|
||||
var found = false;
|
||||
for (x in it) {
|
||||
if (isBlank(x))
|
||||
continue;
|
||||
var m = check(x, r);
|
||||
if (m != CMatch)
|
||||
return m;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found) {
|
||||
switch (r) {
|
||||
case ROptional(_):
|
||||
default: return CMissing(r);
|
||||
}
|
||||
}
|
||||
for (x in it) {
|
||||
if (isBlank(x))
|
||||
continue;
|
||||
return CExtra(x);
|
||||
}
|
||||
return CMatch;
|
||||
}
|
||||
}
|
||||
|
||||
static function makeWhere(path:Array<Xml>) {
|
||||
if (path.length == 0)
|
||||
return "";
|
||||
var s = "In ";
|
||||
var first = true;
|
||||
for (x in path) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
s += ".";
|
||||
s += x.nodeName;
|
||||
}
|
||||
return s + ": ";
|
||||
}
|
||||
|
||||
static function makeString(x:Xml) {
|
||||
if (x.nodeType == Xml.Element)
|
||||
return "element " + x.nodeName;
|
||||
var s = x.nodeValue.split("\r").join("\\r").split("\n").join("\\n").split("\t").join("\\t");
|
||||
if (s.length > 20)
|
||||
return s.substr(0, 17) + "...";
|
||||
return s;
|
||||
}
|
||||
|
||||
static function makeRule(r:Rule) {
|
||||
switch (r) {
|
||||
case RNode(name, _, _):
|
||||
return "element " + name;
|
||||
case RData(_):
|
||||
return "data";
|
||||
case RMulti(r, _):
|
||||
return makeRule(r);
|
||||
case RList(rules, _):
|
||||
return makeRule(rules[0]);
|
||||
case RChoice(choices):
|
||||
return makeRule(choices[0]);
|
||||
case ROptional(r):
|
||||
return makeRule(r);
|
||||
}
|
||||
}
|
||||
|
||||
static function makeError(m, ?path) {
|
||||
if (path == null)
|
||||
path = new Array();
|
||||
switch (m) {
|
||||
case CMatch:
|
||||
throw "assert";
|
||||
case CMissing(r):
|
||||
return makeWhere(path) + "Missing " + makeRule(r);
|
||||
case CExtra(x):
|
||||
return makeWhere(path) + "Unexpected " + makeString(x);
|
||||
case CElementExpected(name, x):
|
||||
return makeWhere(path) + makeString(x) + " while expected element " + name;
|
||||
case CDataExpected(x):
|
||||
return makeWhere(path) + makeString(x) + " while data expected";
|
||||
case CExtraAttrib(att, x):
|
||||
path.push(x);
|
||||
return makeWhere(path) + "unexpected attribute " + att;
|
||||
case CMissingAttrib(att, x):
|
||||
path.push(x);
|
||||
return makeWhere(path) + "missing required attribute " + att;
|
||||
case CInvalidAttrib(att, x, _):
|
||||
path.push(x);
|
||||
return makeWhere(path) + "invalid attribute value for " + att;
|
||||
case CInvalidData(x, _):
|
||||
return makeWhere(path) + "invalid data format for " + makeString(x);
|
||||
case CInElement(x, m):
|
||||
path.push(x);
|
||||
return makeError(m, path);
|
||||
}
|
||||
}
|
||||
|
||||
public static function checkNode(x:Xml, r:Rule) {
|
||||
var m = checkList([x].iterator(), r);
|
||||
if (m == CMatch)
|
||||
return;
|
||||
throw makeError(m);
|
||||
}
|
||||
|
||||
public static function checkDocument(x:Xml, r:Rule) {
|
||||
if (x.nodeType != Xml.Document)
|
||||
throw "Document expected";
|
||||
var m = checkList(x.iterator(), r);
|
||||
if (m == CMatch)
|
||||
return;
|
||||
throw makeError(m);
|
||||
}
|
||||
}
|
25
Kha/Tools/linux_arm64/std/haxe/xml/Fast.hx
Normal file
25
Kha/Tools/linux_arm64/std/haxe/xml/Fast.hx
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@:deprecated typedef Fast = haxe.xml.Access;
|
419
Kha/Tools/linux_arm64/std/haxe/xml/Parser.hx
Normal file
419
Kha/Tools/linux_arm64/std/haxe/xml/Parser.hx
Normal file
@ -0,0 +1,419 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
using StringTools;
|
||||
|
||||
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 {
|
||||
/**
|
||||
the XML parsing error message
|
||||
**/
|
||||
public var message:String;
|
||||
|
||||
/**
|
||||
the line number at which the XML parsing error occurred
|
||||
**/
|
||||
public var lineNumber:Int;
|
||||
|
||||
/**
|
||||
the character position in the reported line at which the parsing error occurred
|
||||
**/
|
||||
public var positionAtLine:Int;
|
||||
|
||||
/**
|
||||
the character position in the XML string at which the parsing error occurred
|
||||
**/
|
||||
public var position:Int;
|
||||
|
||||
/**
|
||||
the invalid XML string
|
||||
**/
|
||||
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.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;
|
||||
}
|
||||
|
||||
/**
|
||||
Parses the String into an XML Document. Set strict parsing to true in order to enable a strict check of XML attributes and entities.
|
||||
|
||||
@throws haxe.xml.XmlParserException
|
||||
**/
|
||||
static public function parse(str:String, strict = false) {
|
||||
var doc = Xml.createDocument();
|
||||
doParse(str, strict, 0, doc);
|
||||
return doc;
|
||||
}
|
||||
|
||||
static function doParse(str:String, 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 buf = new StringBuf();
|
||||
// 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 (p < str.length) {
|
||||
var c = str.unsafeCodeAt(p);
|
||||
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.addSub(str, start, p - start);
|
||||
var child = Xml.createPCData(buf.toString());
|
||||
buf = new StringBuf();
|
||||
addChild(child);
|
||||
state = S.IGNORE_SPACES;
|
||||
next = S.BEGIN_NODE;
|
||||
} else if (c == '&'.code) {
|
||||
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 (str.substr(p, 6).toUpperCase() != "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 (str.substr(p + 2, 6).toUpperCase() != "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 = new StringBuf();
|
||||
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.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.addSub(str, start, p - start);
|
||||
var val = buf.toString();
|
||||
buf = new StringBuf();
|
||||
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, s.length - 1)) : Std.parseInt(s.substr(1, s.length - 1));
|
||||
#if !(target.unicode)
|
||||
if (c >= 128) {
|
||||
// UTF8-encode it
|
||||
if (c <= 0x7FF) {
|
||||
buf.addChar(0xC0 | (c >> 6));
|
||||
buf.addChar(0x80 | (c & 63));
|
||||
} else if (c <= 0xFFFF) {
|
||||
buf.addChar(0xE0 | (c >> 12));
|
||||
buf.addChar(0x80 | ((c >> 6) & 63));
|
||||
buf.addChar(0x80 | (c & 63));
|
||||
} else if (c <= 0x10FFFF) {
|
||||
buf.addChar(0xF0 | (c >> 18));
|
||||
buf.addChar(0x80 | ((c >> 12) & 63));
|
||||
buf.addChar(0x80 | ((c >> 6) & 63));
|
||||
buf.addChar(0x80 | (c & 63));
|
||||
} else
|
||||
throw new XmlParserException("Cannot encode UTF8-char " + c, str, p);
|
||||
} else
|
||||
#end
|
||||
buf.addChar(c);
|
||||
} else if (!escapes.exists(s)) {
|
||||
if (strict)
|
||||
throw new XmlParserException("Undefined entity: " + s, str, p);
|
||||
buf.add('&$s;');
|
||||
} else {
|
||||
buf.add(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.addChar("&".code);
|
||||
buf.addSub(str, start, p - start);
|
||||
p--;
|
||||
start = p + 1;
|
||||
state = escapeNext;
|
||||
}
|
||||
}
|
||||
++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.addSub(str, start, p - start);
|
||||
addChild(Xml.createPCData(buf.toString()));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
if (!strict && state == S.ESCAPE && escapeNext == S.PCDATA) {
|
||||
buf.addChar("&".code);
|
||||
buf.addSub(str, start, p - start);
|
||||
addChild(Xml.createPCData(buf.toString()));
|
||||
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;
|
||||
}
|
||||
}
|
128
Kha/Tools/linux_arm64/std/haxe/xml/Printer.hx
Normal file
128
Kha/Tools/linux_arm64/std/haxe/xml/Printer.hx
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
This class provides utility methods to convert Xml instances to
|
||||
String representation.
|
||||
**/
|
||||
class Printer {
|
||||
/**
|
||||
Convert `Xml` to string representation.
|
||||
|
||||
Set `pretty` to `true` to prettify the result.
|
||||
**/
|
||||
static public function print(xml:Xml, ?pretty = false) {
|
||||
var printer = new Printer(pretty);
|
||||
printer.writeNode(xml, "");
|
||||
return printer.output.toString();
|
||||
}
|
||||
|
||||
var output:StringBuf;
|
||||
var pretty:Bool;
|
||||
|
||||
function new(pretty) {
|
||||
output = new StringBuf();
|
||||
this.pretty = pretty;
|
||||
}
|
||||
|
||||
function writeNode(value:Xml, tabs:String) {
|
||||
switch (value.nodeType) {
|
||||
case CData:
|
||||
write(tabs + "<![CDATA[");
|
||||
write(value.nodeValue);
|
||||
write("]]>");
|
||||
newline();
|
||||
case Comment:
|
||||
var commentContent:String = value.nodeValue;
|
||||
commentContent = ~/[\n\r\t]+/g.replace(commentContent, "");
|
||||
commentContent = "<!--" + commentContent + "-->";
|
||||
write(tabs);
|
||||
write(StringTools.trim(commentContent));
|
||||
newline();
|
||||
case Document:
|
||||
for (child in value) {
|
||||
writeNode(child, tabs);
|
||||
}
|
||||
case Element:
|
||||
write(tabs + "<");
|
||||
write(value.nodeName);
|
||||
for (attribute in value.attributes()) {
|
||||
write(" " + attribute + "=\"");
|
||||
write(StringTools.htmlEscape(value.get(attribute), true));
|
||||
write("\"");
|
||||
}
|
||||
if (hasChildren(value)) {
|
||||
write(">");
|
||||
newline();
|
||||
for (child in value) {
|
||||
writeNode(child, pretty ? tabs + "\t" : tabs);
|
||||
}
|
||||
write(tabs + "</");
|
||||
write(value.nodeName);
|
||||
write(">");
|
||||
newline();
|
||||
} else {
|
||||
write("/>");
|
||||
newline();
|
||||
}
|
||||
case PCData:
|
||||
var nodeValue:String = value.nodeValue;
|
||||
if (nodeValue.length != 0) {
|
||||
write(tabs + StringTools.htmlEscape(nodeValue));
|
||||
newline();
|
||||
}
|
||||
case ProcessingInstruction:
|
||||
write("<?" + value.nodeValue + "?>");
|
||||
newline();
|
||||
case DocType:
|
||||
write("<!DOCTYPE " + value.nodeValue + ">");
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
inline function write(input:String) {
|
||||
output.add(input);
|
||||
}
|
||||
|
||||
inline function newline() {
|
||||
if (pretty) {
|
||||
output.add("\n");
|
||||
}
|
||||
}
|
||||
|
||||
function hasChildren(value:Xml):Bool {
|
||||
for (child in value) {
|
||||
switch (child.nodeType) {
|
||||
case Element, PCData:
|
||||
return true;
|
||||
case CData, Comment:
|
||||
if (StringTools.ltrim(child.nodeValue).length != 0) {
|
||||
return true;
|
||||
}
|
||||
case _:
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user