| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 | /* * 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 cpp;enum abstract XmlType(Int) {	/**		Represents an XML element type.	**/	var Element = 0;	/**		Represents XML parsed character data type.	**/	var PCData = 1;	/**		Represents XML character data type.	**/	var CData = 2;	/**		Represents an XML comment type.	**/	var Comment = 3;	/**		Represents an XML doctype element type.	**/	var DocType = 4;	/**		Represents an XML processing instruction type.	**/	var ProcessingInstruction = 5;	/**		Represents an XML document type.	**/	var Document = 6;}class NativeXmlState {	var cur:Xml;	public function new(x:Xml) {		x._children = new Array<Xml>();		cur = x;	}	@:keep	public function xml(name:String, att:Dynamic<String>) {		var x = new Xml();		x._parent = cur;		x.nodeType = Xml.Element;		x._nodeName = name;		x._attributes = att;		x._children = new Array<Xml>();		cur.addChild(x);		cur = x;	}	@:keep	public function cdata(text:String) {		var x = new Xml();		x._parent = cur;		x.nodeType = Xml.CData;		x._nodeValue = text;		cur.addChild(x);	}	@:keep	public function pcdata(text:String) {		var x = new Xml();		x._parent = cur;		x.nodeType = Xml.PCData;		x._nodeValue = text;		cur.addChild(x);	}	@:keep	public function comment(text:String) {		var x = new Xml();		x._parent = cur;		if (text.length > 1 && StringTools.fastCodeAt(text, 0) == 63) {			x.nodeType = Xml.ProcessingInstruction;			text = text.substr(1, text.length - 2);		} else {			x.nodeType = Xml.Comment;		}		x._nodeValue = text;		cur.addChild(x);	}	@:keep	public function doctype(text:String) {		var x = new Xml();		x._parent = cur;		x.nodeType = Xml.DocType;		x._nodeValue = text.substr(1);		cur.addChild(x);	}	@:keep	public function done() {		cur = cur._parent;	}}private class NativeXmlIterator {	var cur = 0;	var children:Array<Xml>;	public function new(inChildren:Array<Xml>) {		children = inChildren;		cur = 0;	}	public function hasNext():Bool {		var k = cur;		var l = children.length;		while (k < l) {			if (children[k].nodeType == Xml.Element)				break;			k += 1;		}		cur = k;		return k < l;	}	public function next():Xml {		var k = cur;		var l = children.length;		while (k < l) {			var n = children[k];			k += 1;			if (n.nodeType == Xml.Element) {				cur = k;				return n;			}		}		return null;	}}private class NativeXmlNamedIterator {	var cur = 0;	var children:Array<Xml>;	var name:String;	public function new(inChildren:Array<Xml>, inName:String) {		children = inChildren;		name = inName;		cur = 0;	}	public function hasNext():Bool {		var k = cur;		var l = children.length;		while (k < l) {			var n = children[k];			if (n.nodeType == Xml.Element && n._nodeName == name)				break;			k++;		}		cur = k;		return k < l;	}	public function next():Xml {		var k = cur;		var l = children.length;		while (k < l) {			var n = children[k];			k++;			if (n.nodeType == Xml.Element && n._nodeName == name) {				cur = k;				return n;			}		}		return null;	}}@:cppInclude("./NativeXmlImport.cpp")@:allow(cpp.NativeXmlState) @:allow(cpp.NativeXmlIterator) @:allow(cpp.NativeXmlNamedIterator)class Xml {	static inline var Element = XmlType.Element;	static inline var PCData = XmlType.PCData;	static inline var CData = XmlType.CData;	static inline var Comment = XmlType.Comment;	static inline var DocType = XmlType.DocType;	static inline var ProcessingInstruction = XmlType.ProcessingInstruction;	static inline var Document = XmlType.Document;	private var _nodeName:String;	private var _nodeValue:String;	private var _attributes:Dynamic<String>;	private var _children:Array<Xml>;	private var _parent:Xml;	function new():Void {}	@:native("parse_xml")	extern static function parse_xml(str:String, state:NativeXmlState);	public static function parse(str:String):Xml {		var x = new Xml();		var state = new NativeXmlState(x);		parse_xml(str, state);		x.nodeType = Xml.Document;		return x;	}	public static function createElement(name:String):Xml {		var r = new Xml();		r.nodeType = Xml.Element;		r._nodeName = name;		r._attributes = null;		r._children = new Array();		return r;	}	public static function createPCData(data:String):Xml {		var r = new Xml();		r.nodeType = Xml.PCData;		r._nodeValue = data;		return r;	}	public static function createCData(data:String):Xml {		var r = new Xml();		r.nodeType = Xml.CData;		r._nodeValue = data;		return r;	}	public static function createComment(data:String):Xml {		var r = new Xml();		r.nodeType = Xml.Comment;		r._nodeValue = data;		return r;	}	public static function createDocType(data:String):Xml {		var r = new Xml();		r.nodeType = Xml.DocType;		r._nodeValue = data;		return r;	}	public static function createProcessingInstruction(data:String):Xml {		var r = new Xml();		r.nodeType = Xml.ProcessingInstruction;		r._nodeValue = data;		return r;	}	public static function createDocument():Xml {		var r = new Xml();		r.nodeType = Xml.Document;		r._children = new Array();		return r;	}	public var nodeType(default, null):XmlType;	public var nodeName(get, set):String;	public var nodeValue(get, set):String;	private function get_nodeName():String {		if (nodeType != Xml.Element)			throw "bad nodeType";		return _nodeName;	}	private function set_nodeName(n:String):String {		if (nodeType != Xml.Element)			throw "bad nodeType";		return _nodeName = n;	}	private function get_nodeValue():String {		if (nodeType == Xml.Element || nodeType == Xml.Document)			throw "bad nodeType";		return _nodeValue;	}	private function set_nodeValue(v:String):String {		if (nodeType == Xml.Element || nodeType == Xml.Document)			throw "bad nodeType";		return _nodeValue = v;	}	public var parent(get, null):Xml;	private function get_parent():Xml {		return _parent;	}	public function get(att:String):String {		if (nodeType != Xml.Element)			throw "bad nodeType";		return Reflect.field(_attributes, att);	}	public function set(att:String, value:String):Void {		if (nodeType != Xml.Element)			throw "bad nodeType";		if (_attributes == null)			_attributes = {};		Reflect.setField(_attributes, att, value);		return;	}	public function remove(att:String):Void {		if (nodeType != Xml.Element)			throw "bad nodeType";		Reflect.deleteField(_attributes, att);		return;	}	public function exists(att:String):Bool {		if (nodeType != Xml.Element)			throw "bad nodeType";		return Reflect.hasField(_attributes, att);	}	public function attributes():Iterator<String> {		if (nodeType != Xml.Element)			throw "bad nodeType";		return Reflect.fields(_attributes).iterator();	}	public function iterator():Iterator<Xml> {		if (_children == null)			throw "bad nodetype";		return untyped _children.iterator();	}	public function elements():Iterator<Xml> {		if (_children == null)			throw "bad nodetype";		return new NativeXmlIterator(_children);	}	public function elementsNamed(name:String):Iterator<Xml> {		if (_children == null)			throw "bad nodetype";		return new NativeXmlNamedIterator(_children, name);	}	public function firstChild():Xml {		if (_children == null)			throw "bad nodetype";		return _children[0];	}	public function firstElement():Xml {		if (_children == null)			throw "bad nodetype";		for (cur in 0..._children.length) {			var n:Xml = _children[cur];			if (n.nodeType == Xml.Element)				return n;		}		return null;	}	public function addChild(x:Xml):Void {		if (_children == null)			throw "bad nodetype";		if (x._parent != null)			x._parent._children.remove(x);		x._parent = this;		_children.push(x);		return;	}	public function removeChild(x:Xml):Bool {		if (_children == null)			throw "bad nodetype";		var b = _children.remove(x);		if (b)			x._parent = null;		return b;	}	public function insertChild(x:Xml, pos:Int):Void {		if (_children == null)			throw "bad nodetype";		if (x._parent != null)			x._parent._children.remove(x);		x._parent = this;		_children.insert(pos, x);		return;	}	public function toString():String {		var s = new StringBuf();		toStringRec(s);		return s.toString();	}	private function toStringRec(s:StringBuf):Void {		switch (nodeType) {			case Xml.Document:				for (x in _children)					x.toStringRec(s);			case Xml.Element:				s.addChar("<".code);				s.add(_nodeName);				for (k in Reflect.fields(_attributes)) {					s.addChar(" ".code);					s.add(k);					s.addChar("=".code);					s.addChar("\"".code);					s.add(Reflect.field(_attributes, k));					s.addChar("\"".code);				}				if (_children.length == 0) {					s.addChar("/".code);					s.addChar(">".code);					return;				}				s.addChar(">".code);				for (x in _children)					x.toStringRec(s);				s.addChar("<".code);				s.addChar("/".code);				s.add(_nodeName);				s.addChar(">".code);			case Xml.PCData:				s.add(StringTools.htmlEscape(_nodeValue));			case Xml.CData:				s.add("<![CDATA[");				s.add(_nodeValue);				s.add("]]>");			case Xml.Comment:				s.add("<!--");				s.add(_nodeValue);				s.add("-->");			case Xml.DocType:				s.add("<!DOCTYPE ");				s.add(_nodeValue);				s.add(">");			case Xml.ProcessingInstruction:				s.add("<?");				s.add(_nodeValue);				s.add("?>");		}	}}
 |