--- parser3/src/classes/xnode.C 2011/05/25 04:00:40 1.85 +++ parser3/src/classes/xnode.C 2020/12/15 17:10:29 1.97 @@ -1,14 +1,12 @@ /** @file Parser: @b dom parser class. - Copyright (c) 2001-2009 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001-2020 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,7 @@ static const char * const IDENT_XNODE_C= #include "libxml/xpath.h" #include "libxml/xpathInternals.h" -// global variable - -DECLARE_CLASS_VAR(xnode, new MXnode, 0); +volatile const char * IDENT_XNODE_C="$Id: xnode.C,v 1.97 2020/12/15 17:10:29 moko Exp $" IDENT_XNODE_H; // classes @@ -148,10 +144,10 @@ 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)); + r.write(xdoc.wrap(*node)); } static xmlNode* pa_getAttributeNodeNS(xmlNode& selfNode, @@ -162,7 +158,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 +180,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 +268,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 +283,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 +319,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 +338,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 @@ -355,18 +355,18 @@ static void _hasChildNodes(Request& r, M xmlNode& node=vnode.get_xmlnode(); // write out result - r.write_no_lang(VBool::get(node.children!=0)); + r.write(VBool::get(node.children!=0)); } // 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,35 +385,38 @@ 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); // write out result - r.write_pass_lang(r.transcode(attribute_value)); + r.write(r.transcode(attribute_value)); } // 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 +424,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 +443,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 +467,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 +485,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, @@ -495,35 +504,36 @@ static void _getElementsByTagName(Reques &info); // write out result - r.write_no_lang(result); + r.write(result); } // DOM 2 // 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 - r.write_pass_lang(r.transcode(attribute_value)); + r.write(r.transcode(attribute_value)); } // 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 +553,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 +573,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,26 +588,26 @@ 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)); + r.write(VBool::get(xmlHasProp(&element, name)!=0)); } // 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)); + r.write(VBool::get(xmlHasNsProp(&element, localName, namespaceURI)!=0)); } // boolean hasAttributes @@ -604,18 +616,23 @@ static void _hasAttributes(Request& r, M xmlNode& element=get_self_element(vnode); // write out result - r.write_no_lang(VBool::get(element.properties!=0)); + r.write(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, @@ -625,7 +642,7 @@ static void _getElementsByTagNameNS(Requ &info); // write out result - r.write_no_lang(result); + r.write(result); } @@ -685,13 +702,13 @@ 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()) handler(r, expression, res, vdoc, result); if(result) - r.write_no_lang(*result); + r.write(*result); } static void selectNodesHandler(Request&, @@ -848,9 +865,7 @@ static void _selectString(Request& r, Me // constructor /// @bug one can change const and ruin other's work, we need unchangable VIntConst class -MXnode::MXnode(const char* aname, VStateless_class *abase): - Methoded(aname?aname:"xnode", abase) -{ +MXnode::MXnode(const char* aname): Methoded(aname?aname:"xnode") { /// DOM1 node // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException); @@ -922,10 +937,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); @@ -941,10 +954,4 @@ MXnode::MXnode(const char* aname, VState CONST(NOTATION_NODE); } -#else - -// global variable - -DECLARE_CLASS_VAR(xnode, 0, 0); // fictive - #endif