--- parser3/src/classes/xnode.C 2011/05/25 04:00:40 1.85 +++ parser3/src/classes/xnode.C 2016/03/31 21:46:20 1.92 @@ -1,14 +1,12 @@ /** @file Parser: @b dom parser class. - Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ #include "classes.h" #ifdef XML -static const char * const IDENT_XNODE_C="$Date: 2011/05/25 04:00:40 $"; - #include "pa_vmethod_frame.h" #include "pa_charset.h" @@ -23,9 +21,11 @@ static const char * const IDENT_XNODE_C= #include "libxml/xpath.h" #include "libxml/xpathInternals.h" +volatile const char * IDENT_XNODE_C="$Id: xnode.C,v 1.92 2016/03/31 21:46:20 moko Exp $" IDENT_XNODE_H; + // global variable -DECLARE_CLASS_VAR(xnode, new MXnode, 0); +DECLARE_CLASS_VAR(xnode, new MXnode); // classes @@ -148,7 +148,7 @@ xmlAttr& as_attr(MethodParams& params, i static void writeNode(Request& r, VXdoc& xdoc, xmlNode* node) { if(!node|| xmlHaveGenericErrors()) - throw XmlException(0); // OOM, bad name, things like that + throw XmlException(0, r); // OOM, bad name, things like that // write out result r.write_no_lang(xdoc.wrap(*node)); @@ -162,7 +162,7 @@ static xmlNode* pa_getAttributeNodeNS(xm currentNode; currentNode=currentNode->next) { - if(!namespaceURI || currentNode->ns && xmlStrEqual(currentNode->ns->href, namespaceURI)) + if(!namespaceURI || (currentNode->ns && xmlStrEqual(currentNode->ns->href, namespaceURI)) ) if(!localName || xmlStrEqual(currentNode->name, localName)) return currentNode; } @@ -184,7 +184,7 @@ xmlNs& pa_xmlMapNs(xmlDoc& doc, const xm if (cur == NULL) { cur = xmlNewNs (NULL, href, prefix); if(!cur || xmlHaveGenericErrors()) - throw XmlException(0); + throw XmlException(); cur->next = doc.oldNs; doc.oldNs = cur; } @@ -272,12 +272,13 @@ pa_xmlNamedPreorderTraversal ( // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException); static void _insertBefore(Request& r, MethodParams& params) { + xmlNode& newChild=as_node(params, 0, "newChild must be node"); + xmlNode& refChild=as_node(params, 1, "refChild must be node"); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); //xmlNode& selfNode=vnode.get_xmlnode(); - xmlNode& newChild=as_node(params, 0, "newChild must be node"); - xmlNode& refChild=as_node(params, 1, "refChild must be node"); xmlNode* retNode=xmlAddPrevSibling(&refChild, &newChild); // write out result @@ -286,12 +287,13 @@ static void _insertBefore(Request& r, Me // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException); static void _replaceChild(Request& r, MethodParams& params) { + xmlNode& newChild=as_node(params, 0, "newChild must be node"); + xmlNode& oldChild=as_node(params, 1, "oldChild must be node"); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlDoc& xmldoc=vxdoc.get_xmldoc(); xmlNode& selfNode=vnode.get_xmlnode(); - xmlNode& newChild=as_node(params, 0, "newChild must be node"); - xmlNode& oldChild=as_node(params, 1, "oldChild must be node"); if(newChild.doc!=&xmldoc) throw Exception("xml.dom", @@ -321,11 +323,12 @@ static void _replaceChild(Request& r, Me // Node removeChild(in Node oldChild) raises(DOMException); static void _removeChild(Request& r, MethodParams& params) { + xmlNode& oldChild=as_node(params, 0, "refChild must be node"); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlDoc& xmldoc=vxdoc.get_xmldoc(); // xmlNode& selfNode=vnode.get_xmlnode(); - xmlNode& oldChild=as_node(params, 0, "refChild must be node"); if(oldChild.doc!=&xmldoc) throw Exception("xml.dom", @@ -339,10 +342,11 @@ static void _removeChild(Request& r, Met // Node appendChild(in Node newChild) raises(DOMException); static void _appendChild(Request& r, MethodParams& params) { + xmlNode& newChild=as_node(params, 0, "newChild must be node"); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlNode& selfNode=vnode.get_xmlnode(); - xmlNode& newChild=as_node(params, 0, "newChild must be node"); xmlNode* retNode=xmlAddChild(&selfNode, &newChild); // write out result @@ -360,13 +364,13 @@ static void _hasChildNodes(Request& r, M // Node cloneNode(in boolean deep); static void _cloneNode(Request& r, MethodParams& params) { + bool deep=params.as_bool(0, "deep must be bool", r); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& selfNode=vnode.get_xmlnode(); VXdoc& vxdoc=vnode.get_vxdoc(); xmlDoc& xmldoc=vxdoc.get_xmldoc(); - bool deep=params.as_bool(0, "deep must be bool", r); - xmlNode* retNode=xmlDocCopyNode(&selfNode, &xmldoc, deep?1: 0); // write out result writeNode(r, vxdoc, retNode); @@ -385,11 +389,12 @@ xmlNode& get_self_element(VXnode& vnode) return node; } - +// DOMString getAttribute(in DOMString name); static void _getAttribute(Request& r, MethodParams& params) { + const xmlChar* name=as_xmlname(r, params, 0); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); - const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING); // @todo: when name="xmlns" xmlChar* attribute_value=xmlGetProp(&element, name); @@ -399,21 +404,23 @@ static void _getAttribute(Request& r, Me // void setAttribute(in DOMString name, in DOMString value) raises(DOMException); static void _setAttribute(Request& r, MethodParams& params) { + const xmlChar* name=as_xmlname(r, params, 0); + const xmlChar* attribute_value=as_xmlchar(r, params, 1, XML_VALUE_MUST_BE_STRING); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); - const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING); - const xmlChar* attribute_value=as_xmlchar(r, params, 1, VALUE_MUST_BE_STRING); // @todo: when name="xmlns" if(!xmlSetProp(&element, name, attribute_value)) - throw XmlException(0); + throw XmlException(0, r); } // void removeAttribute(in DOMString name) raises(DOMException); static void _removeAttribute(Request& r, MethodParams& params) { + const xmlChar* name=as_xmlname(r, params, 0); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); - const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING); // @todo: when name="xmlns" xmlUnsetProp(&element, name); @@ -421,10 +428,11 @@ static void _removeAttribute(Request& r, // Attr getAttributeNode(in DOMString name); static void _getAttributeNode(Request& r, MethodParams& params) { + const xmlChar* localName=as_xmlname(r, params, 0); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlNode& element=get_self_element(vnode); - const xmlChar* localName=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING); if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, 0)){ // write out result @@ -439,6 +447,7 @@ static void _setAttributeNode(Request& r VXdoc& vxdoc=vnode.get_vxdoc(); xmlNode& element=get_self_element(vnode); xmlDoc& xmldoc=vxdoc.get_xmldoc(); + xmlAttr& newAttr=as_attr(params, 0, "newAttr must be ATTRIBUTE node"); if(newAttr.doc!=&xmldoc) @@ -462,10 +471,11 @@ static void _setAttributeNode(Request& r // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException); static void _removeAttributeNode(Request& r, MethodParams& params) { + xmlAttr& oldAttr=as_attr(params, 0, "oldAttr must be ATTRIBUTE node"); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlNode& element=get_self_element(vnode); - xmlAttr& oldAttr=as_attr(params, 0, "oldAttr must be ATTRIBUTE node"); if(oldAttr.parent!=&element) throw Exception("xml.dom", @@ -479,13 +489,16 @@ static void _removeAttributeNode(Request } // NodeList getElementsByTagName(in DOMString name); +// '*' means all tags static void _getElementsByTagName(Request& r, MethodParams& params) { + xmlChar* tagName=as_xmlchar(r, params, 0, XML_LOCAL_NAME_MUST_BE_STRING); + if(xmlValidateName(tagName, 0) != 0 && strcmp((const char*)tagName, "*") != 0) + throw XmlException(0, XML_INVALID_LOCAL_NAME, tagName); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlNode& xmlnode=vnode.get_xmlnode(); - xmlChar* tagName=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING); - VHash& result=*new VHash; AccumulateFoundInfo info={&result.hash(), &vxdoc, 0}; pa_xmlNamedPreorderTraversal(&xmlnode, @@ -502,12 +515,12 @@ static void _getElementsByTagName(Reques // DOMString getAttributeNS(in DOMString namespaceURI, in DOMString localName); static void _getAttributeNS(Request& r, MethodParams& params) { + xmlChar* namespaceURI=as_xmlnsuri(r, params, 0); + xmlChar* localName=as_xmlname(r, params, 1); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); - xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING); - xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING); - // todo: when name="xmlns" xmlChar* attribute_value=xmlGetNsProp(&element, localName, namespaceURI); // write out result @@ -517,13 +530,14 @@ static void _getAttributeNS(Request& r, // void setAttributeNS(in DOMString namespaceURI, in DOMString qualifiedName, in DOMString value) raises(DOMException); static void _setAttributeNS(Request& r, MethodParams& params) { + const xmlChar* namespaceURI=as_xmlnsuri(r, params, 0); + const xmlChar* qualifiedName=as_xmlqname(r, params, 1); + const xmlChar* attribute_value=as_xmlchar(r, params, 2, XML_VALUE_MUST_BE_STRING); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlDoc& xmldoc=vxdoc.get_xmldoc(); - const xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING); - const xmlChar* qualifiedName=as_xmlchar(r, params, 1, "qualifiedName must be string"); - const xmlChar* attribute_value=as_xmlchar(r, params, 2, VALUE_MUST_BE_STRING); xmlChar* prefix=0; xmlChar* localName=xmlSplitQName2(qualifiedName, &prefix); @@ -543,17 +557,18 @@ static void _setAttributeNS(Request& r, } if(!attrNode) - throw XmlException(0); + throw XmlException(0, r); } // void removeAttributeNS(in DOMString namespaceURI, in DOMString localName) raises(DOMException); static void _removeAttributeNS(Request& r, MethodParams& params) { + const xmlChar* namespaceURI=as_xmlnsuri(r, params, 0); + const xmlChar* localName=as_xmlname(r, params, 1); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlDoc& xmldoc=vxdoc.get_xmldoc(); - const xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING); - const xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING); // @todo: when name="xmlns" xmlNs& ns=pa_xmlMapNs(xmldoc, namespaceURI, 0); @@ -562,11 +577,12 @@ static void _removeAttributeNS(Request& // Attr getAttributeNodeNS(in DOMString namespaceURI, in DOMString localName); static void _getAttributeNodeNS(Request& r, MethodParams& params) { + const xmlChar* namespaceURI=as_xmlnsuri(r, params, 0); + const xmlChar* localName=as_xmlname(r, params, 1); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vxdoc=vnode.get_vxdoc(); xmlNode& element=get_self_element(vnode); - const xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING); - const xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING); if(xmlNode* retNode=pa_getAttributeNodeNS(element, localName, namespaceURI)){ // write out result @@ -576,11 +592,11 @@ static void _getAttributeNodeNS(Request& // boolean hasAttribute(in DOMString name) raises(DOMException); static void _hasAttribute(Request& r, MethodParams& params) { + const xmlChar* name=as_xmlname(r, params, 0); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); - const xmlChar* name=as_xmlchar(r, params, 0, NAME_MUST_BE_STRING); - // @todo: when name="xmlns" // write out result r.write_no_lang(VBool::get(xmlHasProp(&element, name)!=0)); @@ -588,12 +604,12 @@ static void _hasAttribute(Request& r, Me // boolean hasAttributeNS(n DOMString namespaceURI, in DOMString localName) raises(DOMException); static void _hasAttributeNS(Request& r, MethodParams& params) { + const xmlChar* namespaceURI=as_xmlnsuri(r, params, 0); + const xmlChar* localName=as_xmlname(r, params, 1); + VXnode& vnode=GET_SELF(r, VXnode); xmlNode& element=get_self_element(vnode); - const xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING); - const xmlChar* localName=as_xmlchar(r, params, 1, LOCALNAME_MUST_BE_STRING); - // write out result r.write_no_lang(VBool::get(xmlHasNsProp(&element, localName, namespaceURI)!=0)); } @@ -607,15 +623,20 @@ static void _hasAttributes(Request& r, M r.write_no_lang(VBool::get(element.properties!=0)); } +// NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName); +// '*' as namespaceURI means get all namespaces +// '*' as localName means get all tags static void _getElementsByTagNameNS(Request& r, MethodParams& params) { + xmlChar* namespaceURI=as_xmlchar(r, params, 0, XML_NAMESPACEURI_MUST_BE_STRING); + + xmlChar* localName=as_xmlchar(r, params, 1, XML_LOCAL_NAME_MUST_BE_STRING); + if(xmlValidateName(localName, 0) != 0 && strcmp((const char*)localName, "*") != 0) + throw XmlException(0, XML_INVALID_LOCAL_NAME, localName); + VXnode& vnode=GET_SELF(r, VXnode); VXdoc& vdoc=vnode.get_vxdoc(); xmlDoc& xmldoc=vdoc.get_xmldoc(); - // namespaceURI;localName - xmlChar* namespaceURI=as_xmlchar(r, params, 0, NAMESPACEURI_MUST_BE_STRING); - xmlChar* localName=as_xmlchar(r, params, 1, NAME_MUST_BE_STRING); - VHash& result=*new VHash; AccumulateFoundInfo info={&result.hash(), &vdoc, 0}; pa_xmlNamedPreorderTraversal((xmlNode*)&xmldoc, @@ -685,7 +706,7 @@ static void _selectX(Request& r, MethodP xmlXPathEvalExpression(r.transcode(expression), ctxt.get())); if(xmlHaveGenericErrors()) - throw XmlException(0); + throw XmlException(0, r); Value* result=0; if(res.get()) @@ -922,10 +943,8 @@ MXnode::MXnode(const char* aname, VState // consts -#define CONST(name) \ - consts.put(String::Body(#name), new VInt(XML_##name)) -#define CONST2(name, value) \ - consts.put(String::Body(#name), new VInt(value)) +#define CONST(name) consts.put(#name, new VInt(XML_##name)) +#define CONST2(name, value) consts.put(#name, new VInt(value)) CONST(ELEMENT_NODE); CONST(ATTRIBUTE_NODE); @@ -945,6 +964,6 @@ MXnode::MXnode(const char* aname, VState // global variable -DECLARE_CLASS_VAR(xnode, 0, 0); // fictive +DECLARE_CLASS_VAR(xnode, 0); // fictive #endif