|
|
| version 1.35, 2002/01/28 10:50:03 | version 1.45, 2002/04/18 15:54:39 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: @b dom parser class. | Parser: @b dom parser class. |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| $Id$ | $Id$ |
| */ | */ |
| Line 24 extern "C" { | Line 24 extern "C" { |
| #include "gdome.h" | #include "gdome.h" |
| #include "libxml/xpath.h" | #include "libxml/xpath.h" |
| // defines | |
| #define XNODE_CLASS_NAME "xnode" | |
| // classes | // classes |
| class xmlXPathObject_auto_ptr { | class xmlXPathObject_auto_ptr { |
| Line 98 private: | Line 94 private: |
| // helpers | // helpers |
| GdomeNode *as_node(Pool& pool, const String& method_name, MethodParams *params, | GdomeNode *as_node(const String& method_name, MethodParams *params, |
| int index, const char *msg) { | int index, const char *msg) { |
| Value& value=params->as_no_junction(index, msg); | Value& value=params->as_no_junction(index, msg); |
| if(strcmp(value.type(), VXNODE_TYPE)!=0 | if(!(strcmp(value.type(), VXNODE_TYPE)==0 |
| || strcmp(value.type(), VXDOC_TYPE)!=0) | || strcmp(value.type(), VXDOC_TYPE)==0)) |
| throw Exception(0, 0, | throw Exception("parser.runtime", |
| &method_name, | &method_name, |
| msg); | msg); |
| Line 115 GdomeNode *as_node(Pool& pool, const Str | Line 111 GdomeNode *as_node(Pool& pool, const Str |
| GdomeAttr * as_attr(Pool& pool, const String& method_name, MethodParams *params, | GdomeAttr * as_attr(Pool& pool, const String& method_name, MethodParams *params, |
| int index, const char *msg) { | int index, const char *msg) { |
| GdomeNode *node=as_node(pool, method_name, params, index, msg); | GdomeNode *node=as_node(method_name, params, index, msg); |
| GdomeException exc; | GdomeException exc; |
| if(gdome_n_nodeType(node, &exc)!=GDOME_ATTRIBUTE_NODE) | if(gdome_n_nodeType(node, &exc)!=GDOME_ATTRIBUTE_NODE) |
| throw Exception(0, 0, | throw Exception("parser.runtime", |
| &method_name, | &method_name, |
| msg); | msg); |
| Line 134 static void _insertBefore(Request& r, co | Line 130 static void _insertBefore(Request& r, co |
| Pool& pool=r.pool(); | Pool& pool=r.pool(); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXnode& vnode=*static_cast<VXnode *>(r.self); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | GdomeNode *selfNode=vnode.get_node(&method_name); |
| GdomeNode *newChild=as_node(pool, method_name, params, 0, "newChild must be node"); | GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node"); |
| GdomeNode *refChild=as_node(pool, method_name, params, 1, "refChild must be node"); | GdomeNode *refChild=as_node(method_name, params, 1, "refChild must be node"); |
| GdomeException exc; | GdomeException exc; |
| if(GdomeNode *retNode=gdome_n_insertBefore(selfNode, newChild, refChild, &exc)) { | if(GdomeNode *retNode=gdome_n_insertBefore(selfNode, newChild, refChild, &exc)) { |
| Line 143 static void _insertBefore(Request& r, co | Line 139 static void _insertBefore(Request& r, co |
| VXnode& result=*new(pool) VXnode(pool, retNode); | VXnode& result=*new(pool) VXnode(pool, retNode); |
| r.write_no_lang(result); | r.write_no_lang(result); |
| } else | } else |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 153 static void _replaceChild(Request& r, co | Line 149 static void _replaceChild(Request& r, co |
| Pool& pool=r.pool(); | Pool& pool=r.pool(); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXnode& vnode=*static_cast<VXnode *>(r.self); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | GdomeNode *selfNode=vnode.get_node(&method_name); |
| GdomeNode *newChild=as_node(pool, method_name, params, 0, "newChild must be node"); | GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node"); |
| GdomeNode *refChild=as_node(pool, method_name, params, 1, "refChild must be node"); | GdomeNode *refChild=as_node(method_name, params, 1, "refChild must be node"); |
| GdomeException exc; | GdomeException exc; |
| if(GdomeNode *retNode=gdome_n_replaceChild(selfNode, newChild, refChild, &exc)) { | if(GdomeNode *retNode=gdome_n_replaceChild(selfNode, newChild, refChild, &exc)) { |
| // write out result | // write out result |
| r.write_no_lang(*new(pool) VXnode(pool, retNode)); | r.write_no_lang(*new(pool) VXnode(pool, retNode)); |
| } else | } else |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 171 static void _removeChild(Request& r, con | Line 167 static void _removeChild(Request& r, con |
| Pool& pool=r.pool(); | Pool& pool=r.pool(); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXnode& vnode=*static_cast<VXnode *>(r.self); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | GdomeNode *selfNode=vnode.get_node(&method_name); |
| GdomeNode *oldChild=as_node(pool, method_name, params, 0, "oldChild must be node"); | GdomeNode *oldChild=as_node(method_name, params, 0, "oldChild must be node"); |
| GdomeException exc; | GdomeException exc; |
| if(GdomeNode *retNode=gdome_n_removeChild(selfNode, oldChild, &exc)) { | if(GdomeNode *retNode=gdome_n_removeChild(selfNode, oldChild, &exc)) { |
| // write out result | // write out result |
| r.write_no_lang(*new(pool) VXnode(pool, retNode)); | r.write_no_lang(*new(pool) VXnode(pool, retNode)); |
| } else | } else |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 188 static void _appendChild(Request& r, con | Line 184 static void _appendChild(Request& r, con |
| Pool& pool=r.pool(); | Pool& pool=r.pool(); |
| VXnode& vnode=*static_cast<VXnode *>(r.self); | VXnode& vnode=*static_cast<VXnode *>(r.self); |
| GdomeNode *selfNode=vnode.get_node(&method_name); | GdomeNode *selfNode=vnode.get_node(&method_name); |
| GdomeNode *newChild=as_node(pool, method_name, params, 0, "newChild must be node"); | GdomeNode *newChild=as_node(method_name, params, 0, "newChild must be node"); |
| GdomeException exc; | GdomeException exc; |
| if(GdomeNode *retNode=gdome_n_appendChild(selfNode, newChild, &exc)) { | if(GdomeNode *retNode=gdome_n_appendChild(selfNode, newChild, &exc)) { |
| // write out result | // write out result |
| r.write_no_lang(*new(pool) VXnode(pool, retNode)); | r.write_no_lang(*new(pool) VXnode(pool, retNode)); |
| } else | } else |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 208 static void _hasChildNodes(Request& r, c | Line 204 static void _hasChildNodes(Request& r, c |
| GdomeException exc; | GdomeException exc; |
| // write out result | // write out result |
| VBool& result=*new(pool) VBool(pool, gdome_n_hasChildNodes(node, &exc)!=0); | bool result=gdome_n_hasChildNodes(node, &exc)!=0; |
| result.set_name(method_name); | r.write_no_lang(*new(pool) VBool(pool, result)); |
| r.write_no_lang(result); | |
| } | } |
| // Node cloneNode(in boolean deep); | // Node cloneNode(in boolean deep); |
| Line 223 static void _cloneNode(Request& r, const | Line 218 static void _cloneNode(Request& r, const |
| GdomeException exc; | GdomeException exc; |
| // write out result | // write out result |
| VXnode& result=*new(pool) VXnode(pool, gdome_n_cloneNode(node, deep, &exc)); | r.write_no_lang(*new(pool) VXnode(pool, gdome_n_cloneNode(node, deep, &exc))); |
| result.set_name(method_name); | |
| r.write_no_lang(result); | |
| } | } |
| // DOM1 element | // DOM1 element |
| Line 237 GdomeElement *get_self_element(Request& | Line 230 GdomeElement *get_self_element(Request& |
| GdomeException exc; | GdomeException exc; |
| if(gdome_n_nodeType(node, &exc)!=GDOME_ELEMENT_NODE) | if(gdome_n_nodeType(node, &exc)!=GDOME_ELEMENT_NODE) |
| throw Exception(0, 0, | throw Exception("parser.runtime", |
| &method_name, | &method_name, |
| "method can be called on node of ELEMENT type"); | "method can be called on node of ELEMENT type"); |
| Line 254 static void _getAttribute(Request& r, co | Line 247 static void _getAttribute(Request& r, co |
| GdomeDOMString *attribute_value= | GdomeDOMString *attribute_value= |
| gdome_el_getAttribute(element, pool.transcode(name).get(), &exc); | gdome_el_getAttribute(element, pool.transcode(name).get(), &exc); |
| // write out result | // write out result |
| r.write_no_lang(*new(pool) VString(pool.transcode(attribute_value))); | r.write_no_lang(pool.transcode(attribute_value)); |
| } | } |
| // void setAttribute(in DOMString name, in DOMString value) raises(DOMException); | // void setAttribute(in DOMString name, in DOMString value) raises(DOMException); |
| Line 270 static void _setAttribute(Request& r, co | Line 263 static void _setAttribute(Request& r, co |
| pool.transcode(attribute_value).get(), | pool.transcode(attribute_value).get(), |
| &exc); | &exc); |
| if(exc) | if(exc) |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 284 static void _removeAttribute(Request& r, | Line 277 static void _removeAttribute(Request& r, |
| GdomeException exc; | GdomeException exc; |
| gdome_el_removeAttribute(element, pool.transcode(name).get(), &exc); | gdome_el_removeAttribute(element, pool.transcode(name).get(), &exc); |
| if(exc) | if(exc) |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 301 static void _getAttributeNode(Request& r | Line 294 static void _getAttributeNode(Request& r |
| VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)attr); | VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)attr); |
| r.write_no_lang(result); | r.write_no_lang(result); |
| } else if(exc) | } else if(exc) |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 318 static void _setAttributeNode(Request& r | Line 311 static void _setAttributeNode(Request& r |
| VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)returnAttr); | VXnode& result=*new(pool) VXnode(pool, (GdomeNode *)returnAttr); |
| r.write_no_lang(result); | r.write_no_lang(result); |
| } else | } else |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 332 static void _removeAttributeNode(Request | Line 325 static void _removeAttributeNode(Request |
| GdomeException exc; | GdomeException exc; |
| gdome_el_removeAttributeNode(element, oldAttr, &exc); | gdome_el_removeAttributeNode(element, oldAttr, &exc); |
| if(exc) | if(exc) |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 360 static void _getElementsByTagName(Reques | Line 353 static void _getElementsByTagName(Reques |
| result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc))); | result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc))); |
| } | } |
| } else if(exc) | } else if(exc) |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| Line 368 static void _getElementsByTagName(Reques | Line 361 static void _getElementsByTagName(Reques |
| r.write_no_lang(result); | r.write_no_lang(result); |
| } | } |
| static void _getElementsByTagNameNS(Request& r, const String& method_name, MethodParams *params) { | |
| Pool& pool=r.pool(); | |
| GdomeElement *element=get_self_element(r, method_name); | |
| // namespaceURI;localName | |
| const String& namespaceURI=params->as_string(0, "namespaceURI must be string"); | |
| const String& localName=params->as_string(1, "localName must be string"); | |
| GdomeException exc; | |
| VHash& result=*new(pool) VHash(pool); | |
| if(GdomeNodeList *nodes= | |
| gdome_el_getElementsByTagNameNS( | |
| element, | |
| pool.transcode(namespaceURI).get(), | |
| pool.transcode(localName).get(), | |
| &exc)) { | |
| gulong length=gdome_nl_length(nodes, &exc); | |
| for(gulong i=0; i<length; i++) { | |
| String& skey=*new(pool) String(pool); | |
| { | |
| char *buf=(char *)pool.malloc(MAX_NUMBER); | |
| snprintf(buf, MAX_NUMBER, "%d", i); | |
| skey << buf; | |
| } | |
| result.hash(0).put(skey, new(pool) VXnode(pool, gdome_nl_item(nodes, i, &exc))); | |
| } | |
| } | |
| // write out result | |
| r.write_no_lang(result); | |
| } | |
| // void normalize(); | // void normalize(); |
| static void _normalize(Request& r, const String& method_name, MethodParams *) { | static void _normalize(Request& r, const String& method_name, MethodParams *) { |
| Pool& pool=r.pool(); | Pool& pool=r.pool(); |
| Line 377 static void _normalize(Request& r, const | Line 403 static void _normalize(Request& r, const |
| GdomeException exc; | GdomeException exc; |
| gdome_n_normalize(selfNode, &exc); | gdome_n_normalize(selfNode, &exc); |
| if(exc) | if(exc) |
| throw Exception(0, 0, | throw Exception( |
| &method_name, | &method_name, |
| exc); | exc); |
| } | } |
| Line 408 static void _selectX(Request& r, const S | Line 434 static void _selectX(Request& r, const S |
| if(xmlHaveGenericErrors()) { | if(xmlHaveGenericErrors()) { |
| GdomeException exc=0; | GdomeException exc=0; |
| throw Exception(0, 0, | throw Exception(&expression, exc); |
| &expression, | |
| exc); | |
| } | } |
| Value *result=0; | Value *result=0; |
| if(res.get()) | if(res.get()) |
| handler(pool, expression, res, result); | handler(pool, expression, res, result); |
| if(result) { | if(result) |
| result->set_name(method_name); | |
| r.write_no_lang(*result); | r.write_no_lang(*result); |
| } | |
| } | } |
| static void selectNodesHandler(Pool& pool, | static void selectNodesHandler(Pool& pool, |
| Line 431 static void selectNodesHandler(Pool& poo | Line 453 static void selectNodesHandler(Pool& poo |
| case XPATH_UNDEFINED: | case XPATH_UNDEFINED: |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(int size=res->nodesetval->nodeNr) { | if(res->nodesetval) |
| Hash& hash=vhash->hash(0); | if(int size=res->nodesetval->nodeNr) { |
| for(int i=0; i<size; i++) { | Hash& hash=vhash->hash(0); |
| String& skey=*new(pool) String(pool); | for(int i=0; i<size; i++) { |
| { | String& skey=*new(pool) String(pool); |
| char *buf=(char *)pool.malloc(MAX_NUMBER); | { |
| snprintf(buf, MAX_NUMBER, "%d", i); | char *buf=(char *)pool.malloc(MAX_NUMBER); |
| skey << buf; | snprintf(buf, MAX_NUMBER, "%d", i); |
| } | skey << buf; |
| } | |
| hash.put(skey, new(pool) VXnode(pool, | hash.put(skey, new(pool) VXnode(pool, |
| gdome_xml_n_mkref(res->nodesetval->nodeTab[i]))); | gdome_xml_n_mkref(res->nodesetval->nodeTab[i]))); |
| } | |
| } | } |
| } | |
| break; | break; |
| default: | default: |
| throw Exception(0, 0, | throw Exception(0, |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| Line 462 static void selectNodeHandler(Pool& pool | Line 485 static void selectNodeHandler(Pool& pool |
| case XPATH_UNDEFINED: | case XPATH_UNDEFINED: |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(res->nodesetval->nodeNr) { // empty result strangly has NODESET res->type | if(res->nodesetval && res->nodesetval->nodeNr) { // empty result strangly has NODESET res->type |
| if(res->nodesetval->nodeNr>1) | if(res->nodesetval->nodeNr>1) |
| throw Exception(0, 0, | throw Exception("parser.runtime", |
| &expression, | &expression, |
| "resulted not in a single node (%d)", res->nodesetval->nodeNr); | "resulted not in a single node (%d)", res->nodesetval->nodeNr); |
| Line 484 static void selectNodeHandler(Pool& pool | Line 507 static void selectNodeHandler(Pool& pool |
| gdome_str_mkref_dup((const gchar *)res->stringval)).get())); | gdome_str_mkref_dup((const gchar *)res->stringval)).get())); |
| break; | break; |
| default: | default: |
| throw Exception(0, 0, | throw Exception("parser.runtime", |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| Line 500 static void selectBoolHandler(Pool& pool | Line 523 static void selectBoolHandler(Pool& pool |
| result=new(pool) VBool(pool, res->boolval!=0); | result=new(pool) VBool(pool, res->boolval!=0); |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(!res->nodesetval->nodeNr) | if(!(res->nodesetval && res->nodesetval->nodeNr)) |
| break; | break; |
| // else[nodeset] fall down to default | // else[nodeset] fall down to default |
| default: | default: |
| throw Exception(0, 0, | throw Exception("parser.runtime", |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| Line 520 static void selectNumberHandler(Pool& po | Line 543 static void selectNumberHandler(Pool& po |
| result=new(pool) VDouble(pool, res->floatval); | result=new(pool) VDouble(pool, res->floatval); |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(!res->nodesetval->nodeNr) | if(!(res->nodesetval && res->nodesetval->nodeNr)) |
| break; | break; |
| // else[nodeset] fall down to default | // else[nodeset] fall down to default |
| default: | default: |
| throw Exception(0, 0, | throw Exception("parser.runtime", |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| Line 545 static void selectStringHandler(Pool& po | Line 568 static void selectStringHandler(Pool& po |
| gdome_str_mkref_dup((const gchar *)res->stringval)).get())); | gdome_str_mkref_dup((const gchar *)res->stringval)).get())); |
| break; | break; |
| case XPATH_NODESET: | case XPATH_NODESET: |
| if(!res->nodesetval->nodeNr) | if(!(res->nodesetval && res->nodesetval->nodeNr)) |
| break; | break; |
| // else[nodeset] fall down to default | // else[nodeset] fall down to default |
| default: | default: |
| throw Exception(0, 0, | throw Exception("parser.runtime", |
| &expression, | &expression, |
| "wrong xmlXPathEvalExpression result type (%d)", res->type); | "wrong xmlXPathEvalExpression result type (%d)", res->type); |
| break; // never | break; // never |
| Line 583 static void _selectString(Request& r, co | Line 606 static void _selectString(Request& r, co |
| // constructor | // constructor |
| MXnode::MXnode(Pool& apool) : Methoded(apool), | MXnode::MXnode(Pool& apool, const char *aname, VStateless_class *abase) : |
| consts(apool) { | Methoded(apool, aname?aname:"xnode", abase), |
| set_name(*NEW String(pool(), XNODE_CLASS_NAME)); | |
| consts(apool) | |
| { | |
| /// DOM1 node | /// DOM1 node |
| // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException); | // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException); |
| Line 618 MXnode::MXnode(Pool& apool) : Methoded(a | Line 642 MXnode::MXnode(Pool& apool) : Methoded(a |
| add_native_method("removeAttributeNode", Method::CT_DYNAMIC, _removeAttributeNode, 1, 1); | add_native_method("removeAttributeNode", Method::CT_DYNAMIC, _removeAttributeNode, 1, 1); |
| // NodeList getElementsByTagName(in DOMString name); | // NodeList getElementsByTagName(in DOMString name); |
| add_native_method("getElementsByTagName", Method::CT_DYNAMIC, _getElementsByTagName, 1, 1); | add_native_method("getElementsByTagName", Method::CT_DYNAMIC, _getElementsByTagName, 1, 1); |
| // NodeList getElementsByTagNameNS(in DOMString namespaceURI, in DOMString localName); | |
| add_native_method("getElementsByTagNameNS", Method::CT_DYNAMIC, _getElementsByTagNameNS, 2, 2); | |
| // void normalize(); | // void normalize(); |
| add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0); | add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0); |