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 %s %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(
176 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
179 TRACE("%p\n", This
);
187 switch( This
->node
->type
)
190 str
= (const xmlChar
*) "#text";
192 case XML_DOCUMENT_NODE
:
193 str
= (const xmlChar
*) "#document";
196 str
= This
->node
->name
;
200 *name
= bstr_from_xmlChar( str
);
207 BSTR
bstr_from_xmlChar( const xmlChar
*buf
)
216 len
= MultiByteToWideChar( CP_UTF8
, 0, (LPCSTR
) buf
, -1, NULL
, 0 );
217 str
= (LPWSTR
) HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
220 MultiByteToWideChar( CP_UTF8
, 0, (LPCSTR
) buf
, -1, str
, len
);
221 bstr
= SysAllocString( str
);
222 HeapFree( GetProcessHeap(), 0, str
);
226 static HRESULT WINAPI
xmlnode_get_nodeValue(
230 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
233 TRACE("%p %p\n", This
, value
);
235 V_BSTR(value
) = NULL
;
236 V_VT(value
) = VT_NULL
;
238 switch ( This
->node
->type
)
240 case XML_ATTRIBUTE_NODE
:
241 V_VT(value
) = VT_BSTR
;
242 V_BSTR(value
) = bstr_from_xmlChar( This
->node
->name
);
246 V_VT(value
) = VT_BSTR
;
247 V_BSTR(value
) = bstr_from_xmlChar( This
->node
->content
);
250 case XML_ELEMENT_NODE
:
251 case XML_DOCUMENT_NODE
:
252 /* these seem to return NULL */
256 FIXME("node %p type %d\n", This
, This
->node
->type
);
259 TRACE("%p returned %s\n", This
, debugstr_w( V_BSTR(value
) ) );
264 static HRESULT WINAPI
xmlnode_put_nodeValue(
272 static HRESULT WINAPI
xmlnode_get_nodeType(
276 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
278 TRACE("%p %p\n", This
, type
);
280 assert( NODE_ELEMENT
== XML_ELEMENT_NODE
);
281 assert( NODE_NOTATION
== XML_NOTATION_NODE
);
283 *type
= This
->node
->type
;
288 static HRESULT
get_node(
294 TRACE("%p->%s %p\n", This
, name
, node
);
298 *out
= create_node( node
);
304 static HRESULT WINAPI
xmlnode_get_parentNode(
306 IXMLDOMNode
** parent
)
308 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
309 return get_node( This
, "parent", This
->node
->parent
, parent
);
312 static HRESULT WINAPI
xmlnode_get_childNodes(
314 IXMLDOMNodeList
** childList
)
316 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
318 TRACE("%p %p\n", This
, childList
);
322 *childList
= create_nodelist( This
->node
->children
);
328 static HRESULT WINAPI
xmlnode_get_firstChild(
330 IXMLDOMNode
** firstChild
)
332 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
333 return get_node( This
, "firstChild", This
->node
->children
, firstChild
);
336 static HRESULT WINAPI
xmlnode_get_lastChild(
338 IXMLDOMNode
** lastChild
)
340 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
341 return get_node( This
, "lastChild", This
->node
->last
, lastChild
);
344 static HRESULT WINAPI
xmlnode_get_previousSibling(
346 IXMLDOMNode
** previousSibling
)
348 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
349 return get_node( This
, "previous", This
->node
->prev
, previousSibling
);
352 static HRESULT WINAPI
xmlnode_get_nextSibling(
354 IXMLDOMNode
** nextSibling
)
356 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
357 return get_node( This
, "next", This
->node
->next
, nextSibling
);
360 static HRESULT WINAPI
xmlnode_get_attributes(
362 IXMLDOMNamedNodeMap
** attributeMap
)
364 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
366 *attributeMap
= create_nodemap( iface
);
370 static HRESULT WINAPI
xmlnode_insertBefore(
372 IXMLDOMNode
* newChild
,
374 IXMLDOMNode
** outNewChild
)
380 static HRESULT WINAPI
xmlnode_replaceChild(
382 IXMLDOMNode
* newChild
,
383 IXMLDOMNode
* oldChild
,
384 IXMLDOMNode
** outOldChild
)
390 static HRESULT WINAPI
xmlnode_removeChild(
392 IXMLDOMNode
* childNode
,
393 IXMLDOMNode
** oldChild
)
399 static HRESULT WINAPI
xmlnode_appendChild(
401 IXMLDOMNode
* newChild
,
402 IXMLDOMNode
** outNewChild
)
408 static HRESULT WINAPI
xmlnode_hasChildNodes(
410 VARIANT_BOOL
* hasChild
)
412 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
418 if (!This
->node
->children
)
420 *hasChild
= VARIANT_FALSE
;
424 *hasChild
= VARIANT_TRUE
;
428 static HRESULT WINAPI
xmlnode_get_ownerDocument(
430 IXMLDOMDocument
** DOMDocument
)
436 static HRESULT WINAPI
xmlnode_cloneNode(
439 IXMLDOMNode
** cloneRoot
)
445 static HRESULT WINAPI
xmlnode_get_nodeTypeString(
453 static HRESULT WINAPI
xmlnode_get_text(
457 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
466 child
= This
->node
->children
;
467 if ( child
&& child
->type
== XML_TEXT_NODE
)
468 str
= bstr_from_xmlChar( child
->content
);
470 TRACE("%p %s\n", This
, debugstr_w(str
) );
476 static HRESULT WINAPI
xmlnode_put_text(
484 static HRESULT WINAPI
xmlnode_get_specified(
486 VARIANT_BOOL
* isSpecified
)
492 static HRESULT WINAPI
xmlnode_get_definition(
494 IXMLDOMNode
** definitionNode
)
500 static HRESULT WINAPI
xmlnode_get_nodeTypedValue(
508 static HRESULT WINAPI
xmlnode_put_nodeTypedValue(
516 static HRESULT WINAPI
xmlnode_get_dataType(
518 VARIANT
* dataTypeName
)
524 static HRESULT WINAPI
xmlnode_put_dataType(
532 static HRESULT WINAPI
xmlnode_get_xml(
540 static HRESULT WINAPI
xmlnode_transformNode(
542 IXMLDOMNode
* styleSheet
,
549 static HRESULT WINAPI
xmlnode_selectNodes(
552 IXMLDOMNodeList
** resultList
)
554 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
558 TRACE("%p %s %p\n", This
, debugstr_w(queryString
), resultList
);
560 str
= xmlChar_from_wchar( queryString
);
564 *resultList
= create_filtered_nodelist( This
->node
->children
, str
);
565 HeapFree( GetProcessHeap(), 0, str
);
569 static HRESULT WINAPI
xmlnode_selectSingleNode(
572 IXMLDOMNode
** resultNode
)
578 static HRESULT WINAPI
xmlnode_get_parsed(
580 VARIANT_BOOL
* isParsed
)
586 static HRESULT WINAPI
xmlnode_get_namespaceURI(
594 static HRESULT WINAPI
xmlnode_get_prefix(
602 static HRESULT WINAPI
xmlnode_get_baseName(
606 xmlnode
*This
= impl_from_IXMLDOMNode( iface
);
610 TRACE("%p %p\n", This
, nameString
);
615 switch ( This
->node
->type
)
617 case XML_ELEMENT_NODE
:
618 case XML_ATTRIBUTE_NODE
:
619 str
= bstr_from_xmlChar( This
->node
->name
);
625 ERR("Unhandled type %d\n", This
->node
->type
);
629 TRACE("returning %08lx str = %s\n", r
, debugstr_w( str
) );
635 static HRESULT WINAPI
xmlnode_transformNodeToObject(
637 IXMLDOMNode
* stylesheet
,
638 VARIANT outputObject
)
644 static const struct IXMLDOMNodeVtbl xmlnode_vtbl
=
646 xmlnode_QueryInterface
,
649 xmlnode_GetTypeInfoCount
,
651 xmlnode_GetIDsOfNames
,
653 xmlnode_get_nodeName
,
654 xmlnode_get_nodeValue
,
655 xmlnode_put_nodeValue
,
656 xmlnode_get_nodeType
,
657 xmlnode_get_parentNode
,
658 xmlnode_get_childNodes
,
659 xmlnode_get_firstChild
,
660 xmlnode_get_lastChild
,
661 xmlnode_get_previousSibling
,
662 xmlnode_get_nextSibling
,
663 xmlnode_get_attributes
,
664 xmlnode_insertBefore
,
665 xmlnode_replaceChild
,
668 xmlnode_hasChildNodes
,
669 xmlnode_get_ownerDocument
,
671 xmlnode_get_nodeTypeString
,
674 xmlnode_get_specified
,
675 xmlnode_get_definition
,
676 xmlnode_get_nodeTypedValue
,
677 xmlnode_put_nodeTypedValue
,
678 xmlnode_get_dataType
,
679 xmlnode_put_dataType
,
681 xmlnode_transformNode
,
683 xmlnode_selectSingleNode
,
685 xmlnode_get_namespaceURI
,
687 xmlnode_get_baseName
,
688 xmlnode_transformNodeToObject
,
691 IXMLDOMNode
*create_node( xmlNodePtr node
)
700 /* if an interface already exists for this node, return it */
701 if ( node
->_private
)
703 IXMLDOMNode
*n
= node
->_private
;
704 IXMLDOMNode_AddRef( n
);
709 * Try adding a reference to the IXMLDOMNode implementation
710 * containing the document's root element.
712 if ( node
->type
!= XML_DOCUMENT_NODE
)
714 IXMLDOMNode
*root
= NULL
;
716 root
= node
->doc
->_private
;
718 IXMLDOMNode_AddRef( root
);
721 assert( node
->doc
== (xmlDocPtr
) node
);
723 This
= HeapAlloc( GetProcessHeap(), 0, sizeof *This
);
727 This
->lpVtbl
= &xmlnode_vtbl
;
731 /* remember which interface we associated with this node */
732 node
->_private
= This
;
734 return (IXMLDOMNode
*) &This
->lpVtbl
;