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
;