4 * Copyright 2005 Mike McCormack
6 * iface library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * iface library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 #include "msxml_private.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
45 typedef struct _xmlnode
47 const struct IXMLDOMNodeVtbl *lpVtbl;
52 static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
54 return (xmlnode *)((char*)iface - FIELD_OFFSET(xmlnode, lpVtbl));
57 xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type )
63 This = impl_from_IXMLDOMNode( iface );
66 if ( type && This->node->type != type )
71 static HRESULT WINAPI xmlnode_QueryInterface(
76 TRACE("%p %p %p\n", iface, debugstr_guid(riid), ppvObject);
78 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
79 IsEqualGUID( riid, &IID_IDispatch ) ||
80 IsEqualGUID( riid, &IID_IXMLDOMNode ) )
87 IXMLDOMElement_AddRef( iface );
92 static ULONG WINAPI xmlnode_AddRef(
95 xmlnode *This = impl_from_IXMLDOMNode( iface );
96 return InterlockedIncrement( &This->ref );
99 static ULONG WINAPI xmlnode_Release(
102 xmlnode *This = impl_from_IXMLDOMNode( iface );
105 ref = InterlockedDecrement( &This->ref );
108 if( This->node->type == XML_DOCUMENT_NODE )
110 xmlFreeDoc( (xmlDocPtr) This->node );
115 assert( This->node->doc );
116 root = This->node->doc->_private;
118 IXMLDOMNode_Release( root );
119 This->node->_private = NULL;
121 HeapFree( GetProcessHeap(), 0, This );
127 static HRESULT WINAPI xmlnode_GetTypeInfoCount(
135 static HRESULT WINAPI xmlnode_GetTypeInfo(
139 ITypeInfo** ppTInfo )
145 static HRESULT WINAPI xmlnode_GetIDsOfNames(
157 static HRESULT WINAPI xmlnode_Invoke(
163 DISPPARAMS* pDispParams,
165 EXCEPINFO* pExcepInfo,
172 static HRESULT WINAPI xmlnode_get_nodeName(
180 BSTR bstr_from_xmlChar( const xmlChar *buf )
189 len = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) buf, -1, NULL, 0 );
190 str = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
193 MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) buf, -1, str, len );
194 bstr = SysAllocString( str );
195 HeapFree( GetProcessHeap(), 0, str );
199 static HRESULT WINAPI xmlnode_get_nodeValue(
203 xmlnode *This = impl_from_IXMLDOMNode( iface );
206 TRACE("%p %p\n", This, value);
208 V_BSTR(value) = NULL;
209 V_VT(value) = VT_NULL;
211 switch ( This->node->type )
213 case XML_ATTRIBUTE_NODE:
214 V_VT(value) = VT_BSTR;
215 V_BSTR(value) = bstr_from_xmlChar( This->node->name );
219 V_VT(value) = VT_BSTR;
220 V_BSTR(value) = bstr_from_xmlChar( This->node->content );
223 case XML_ELEMENT_NODE:
224 case XML_DOCUMENT_NODE:
225 /* these seem to return NULL */
229 FIXME("node %p type %d\n", This, This->node->type);
232 TRACE("%p returned %s\n", This, debugstr_w( V_BSTR(value) ) );
237 static HRESULT WINAPI xmlnode_put_nodeValue(
245 static HRESULT WINAPI xmlnode_get_nodeType(
249 xmlnode *This = impl_from_IXMLDOMNode( iface );
251 TRACE("%p %p\n", This, type);
253 assert( NODE_ELEMENT == XML_ELEMENT_NODE );
254 assert( NODE_NOTATION == XML_NOTATION_NODE );
256 *type = This->node->type;
261 static HRESULT get_node(
267 TRACE("%p->%s %p\n", This, name, node );
271 *out = create_node( node );
277 static HRESULT WINAPI xmlnode_get_parentNode(
279 IXMLDOMNode** parent)
281 xmlnode *This = impl_from_IXMLDOMNode( iface );
282 return get_node( This, "parent", This->node->parent, parent );
285 static HRESULT WINAPI xmlnode_get_childNodes(
287 IXMLDOMNodeList** childList)
289 xmlnode *This = impl_from_IXMLDOMNode( iface );
291 TRACE("%p %p\n", This, childList );
295 *childList = create_nodelist( This->node->children );
301 static HRESULT WINAPI xmlnode_get_firstChild(
303 IXMLDOMNode** firstChild)
305 xmlnode *This = impl_from_IXMLDOMNode( iface );
306 return get_node( This, "firstChild", This->node->children, firstChild );
309 static HRESULT WINAPI xmlnode_get_lastChild(
311 IXMLDOMNode** lastChild)
313 xmlnode *This = impl_from_IXMLDOMNode( iface );
314 return get_node( This, "lastChild", This->node->last, lastChild );
317 static HRESULT WINAPI xmlnode_get_previousSibling(
319 IXMLDOMNode** previousSibling)
321 xmlnode *This = impl_from_IXMLDOMNode( iface );
322 return get_node( This, "previous", This->node->prev, previousSibling );
325 static HRESULT WINAPI xmlnode_get_nextSibling(
327 IXMLDOMNode** nextSibling)
329 xmlnode *This = impl_from_IXMLDOMNode( iface );
330 return get_node( This, "next", This->node->next, nextSibling );
333 static HRESULT WINAPI xmlnode_get_attributes(
335 IXMLDOMNamedNodeMap** attributeMap)
337 xmlnode *This = impl_from_IXMLDOMNode( iface );
339 *attributeMap = create_nodemap( iface );
343 static HRESULT WINAPI xmlnode_insertBefore(
345 IXMLDOMNode* newChild,
347 IXMLDOMNode** outNewChild)
353 static HRESULT WINAPI xmlnode_replaceChild(
355 IXMLDOMNode* newChild,
356 IXMLDOMNode* oldChild,
357 IXMLDOMNode** outOldChild)
363 static HRESULT WINAPI xmlnode_removeChild(
365 IXMLDOMNode* childNode,
366 IXMLDOMNode** oldChild)
372 static HRESULT WINAPI xmlnode_appendChild(
374 IXMLDOMNode* newChild,
375 IXMLDOMNode** outNewChild)
381 static HRESULT WINAPI xmlnode_hasChildNodes(
383 VARIANT_BOOL* hasChild)
385 xmlnode *This = impl_from_IXMLDOMNode( iface );
391 if (!This->node->children)
393 *hasChild = VARIANT_FALSE;
397 *hasChild = VARIANT_TRUE;
401 static HRESULT WINAPI xmlnode_get_ownerDocument(
403 IXMLDOMDocument** DOMDocument)
409 static HRESULT WINAPI xmlnode_cloneNode(
412 IXMLDOMNode** cloneRoot)
418 static HRESULT WINAPI xmlnode_get_nodeTypeString(
426 static HRESULT WINAPI xmlnode_get_text(
430 xmlnode *This = impl_from_IXMLDOMNode( iface );
439 child = This->node->children;
440 if ( child && child->type == XML_TEXT_NODE )
441 str = bstr_from_xmlChar( child->content );
443 TRACE("%p %s\n", This, debugstr_w(str) );
449 static HRESULT WINAPI xmlnode_put_text(
457 static HRESULT WINAPI xmlnode_get_specified(
459 VARIANT_BOOL* isSpecified)
465 static HRESULT WINAPI xmlnode_get_definition(
467 IXMLDOMNode** definitionNode)
473 static HRESULT WINAPI xmlnode_get_nodeTypedValue(
481 static HRESULT WINAPI xmlnode_put_nodeTypedValue(
489 static HRESULT WINAPI xmlnode_get_dataType(
491 VARIANT* dataTypeName)
497 static HRESULT WINAPI xmlnode_put_dataType(
505 static HRESULT WINAPI xmlnode_get_xml(
513 static HRESULT WINAPI xmlnode_transformNode(
515 IXMLDOMNode* styleSheet,
522 static HRESULT WINAPI xmlnode_selectNodes(
525 IXMLDOMNodeList** resultList)
527 xmlnode *This = impl_from_IXMLDOMNode( iface );
531 TRACE("%p %s %p\n", This, debugstr_w(queryString), resultList );
533 str = xmlChar_from_wchar( queryString );
537 *resultList = create_filtered_nodelist( This->node->children, str );
538 HeapFree( GetProcessHeap(), 0, str );
542 static HRESULT WINAPI xmlnode_selectSingleNode(
545 IXMLDOMNode** resultNode)
551 static HRESULT WINAPI xmlnode_get_parsed(
553 VARIANT_BOOL* isParsed)
559 static HRESULT WINAPI xmlnode_get_namespaceURI(
567 static HRESULT WINAPI xmlnode_get_prefix(
575 static HRESULT WINAPI xmlnode_get_baseName(
579 xmlnode *This = impl_from_IXMLDOMNode( iface );
583 TRACE("%p %p\n", This, nameString );
588 switch ( This->node->type )
590 case XML_ELEMENT_NODE:
591 case XML_ATTRIBUTE_NODE:
592 str = bstr_from_xmlChar( This->node->name );
598 ERR("Unhandled type %d\n", This->node->type );
602 TRACE("returning %08lx str = %s\n", r, debugstr_w( str ) );
608 static HRESULT WINAPI xmlnode_transformNodeToObject(
610 IXMLDOMNode* stylesheet,
611 VARIANT outputObject)
617 static const struct IXMLDOMNodeVtbl xmlnode_vtbl =
619 xmlnode_QueryInterface,
622 xmlnode_GetTypeInfoCount,
624 xmlnode_GetIDsOfNames,
626 xmlnode_get_nodeName,
627 xmlnode_get_nodeValue,
628 xmlnode_put_nodeValue,
629 xmlnode_get_nodeType,
630 xmlnode_get_parentNode,
631 xmlnode_get_childNodes,
632 xmlnode_get_firstChild,
633 xmlnode_get_lastChild,
634 xmlnode_get_previousSibling,
635 xmlnode_get_nextSibling,
636 xmlnode_get_attributes,
637 xmlnode_insertBefore,
638 xmlnode_replaceChild,
641 xmlnode_hasChildNodes,
642 xmlnode_get_ownerDocument,
644 xmlnode_get_nodeTypeString,
647 xmlnode_get_specified,
648 xmlnode_get_definition,
649 xmlnode_get_nodeTypedValue,
650 xmlnode_put_nodeTypedValue,
651 xmlnode_get_dataType,
652 xmlnode_put_dataType,
654 xmlnode_transformNode,
656 xmlnode_selectSingleNode,
658 xmlnode_get_namespaceURI,
660 xmlnode_get_baseName,
661 xmlnode_transformNodeToObject,
664 IXMLDOMNode *create_node( xmlNodePtr node )
673 /* if an interface already exists for this node, return it */
674 if ( node->_private )
676 IXMLDOMNode *n = node->_private;
677 IXMLDOMNode_AddRef( n );
682 * Try adding a reference to the IXMLDOMNode implementation
683 * containing the document's root element.
685 if ( node->type != XML_DOCUMENT_NODE )
687 IXMLDOMNode *root = NULL;
689 root = node->doc->_private;
691 IXMLDOMNode_AddRef( root );
694 assert( node->doc == (xmlDocPtr) node );
696 This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
700 This->lpVtbl = &xmlnode_vtbl;
704 /* remember which interface we associated with this node */
705 node->_private = This;
707 return (IXMLDOMNode*) &This->lpVtbl;