forked from LeenkxTeam/LNXSDK
		
	Update Files
This commit is contained in:
		
							
								
								
									
										243
									
								
								Kha/Tools/macos/std/haxe/xml/Access.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								Kha/Tools/macos/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/macos/std/haxe/xml/Check.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								Kha/Tools/macos/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/macos/std/haxe/xml/Fast.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Kha/Tools/macos/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/macos/std/haxe/xml/Parser.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										419
									
								
								Kha/Tools/macos/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/macos/std/haxe/xml/Printer.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								Kha/Tools/macos/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