Make each IXMLDOMNode interface represent one libxml2 xmlNodePtr.
[wine/wine-kai.git] / dlls / msxml3 / node.c
blob657b16c513d2079c3284cf80edef51b03db648a6
1 /*
2 * Node implementation
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
21 #include "config.h"
23 #define COBJMACROS
25 #include <stdarg.h>
26 #include <assert.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winnls.h"
31 #include "ole2.h"
32 #include "ocidl.h"
33 #include "msxml.h"
34 #include "xmldom.h"
35 #include "msxml.h"
37 #include "msxml_private.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
43 #ifdef HAVE_LIBXML2
45 typedef struct _xmlnode
47 const struct IXMLDOMNodeVtbl *lpVtbl;
48 LONG ref;
49 xmlNodePtr node;
50 } xmlnode;
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 )
59 xmlnode *This;
61 if ( !iface )
62 return NULL;
63 This = impl_from_IXMLDOMNode( iface );
64 if ( !This->node )
65 return NULL;
66 if ( type && This->node->type != type )
67 return NULL;
68 return This->node;
71 static HRESULT WINAPI xmlnode_QueryInterface(
72 IXMLDOMNode *iface,
73 REFIID riid,
74 void** ppvObject )
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 ) )
82 *ppvObject = iface;
84 else
85 return E_NOINTERFACE;
87 IXMLDOMElement_AddRef( iface );
89 return S_OK;
92 static ULONG WINAPI xmlnode_AddRef(
93 IXMLDOMNode *iface )
95 xmlnode *This = impl_from_IXMLDOMNode( iface );
96 return InterlockedIncrement( &This->ref );
99 static ULONG WINAPI xmlnode_Release(
100 IXMLDOMNode *iface )
102 xmlnode *This = impl_from_IXMLDOMNode( iface );
103 ULONG ref;
105 ref = InterlockedDecrement( &This->ref );
106 if ( ref == 0 )
108 if( This->node->type == XML_DOCUMENT_NODE )
110 xmlFreeDoc( (xmlDocPtr) This->node );
112 else
114 IXMLDOMNode *root;
115 assert( This->node->doc );
116 root = This->node->doc->_private;
117 assert( root );
118 IXMLDOMNode_Release( root );
119 This->node->_private = NULL;
121 HeapFree( GetProcessHeap(), 0, This );
124 return ref;
127 static HRESULT WINAPI xmlnode_GetTypeInfoCount(
128 IXMLDOMNode *iface,
129 UINT* pctinfo )
131 FIXME("\n");
132 return E_NOTIMPL;
135 static HRESULT WINAPI xmlnode_GetTypeInfo(
136 IXMLDOMNode *iface,
137 UINT iTInfo,
138 LCID lcid,
139 ITypeInfo** ppTInfo )
141 FIXME("\n");
142 return E_NOTIMPL;
145 static HRESULT WINAPI xmlnode_GetIDsOfNames(
146 IXMLDOMNode *iface,
147 REFIID riid,
148 LPOLESTR* rgszNames,
149 UINT cNames,
150 LCID lcid,
151 DISPID* rgDispId )
153 FIXME("\n");
154 return E_NOTIMPL;
157 static HRESULT WINAPI xmlnode_Invoke(
158 IXMLDOMNode *iface,
159 DISPID dispIdMember,
160 REFIID riid,
161 LCID lcid,
162 WORD wFlags,
163 DISPPARAMS* pDispParams,
164 VARIANT* pVarResult,
165 EXCEPINFO* pExcepInfo,
166 UINT* puArgErr )
168 FIXME("\n");
169 return E_NOTIMPL;
172 static HRESULT WINAPI xmlnode_get_nodeName(
173 IXMLDOMNode *iface,
174 BSTR* name)
176 FIXME("\n");
177 return E_NOTIMPL;
180 BSTR bstr_from_xmlChar( const xmlChar *buf )
182 DWORD len;
183 LPWSTR str;
184 BSTR bstr;
186 if ( !buf )
187 return NULL;
189 len = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) buf, -1, NULL, 0 );
190 str = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
191 if ( !str )
192 return NULL;
193 MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) buf, -1, str, len );
194 bstr = SysAllocString( str );
195 HeapFree( GetProcessHeap(), 0, str );
196 return bstr;
199 static HRESULT WINAPI xmlnode_get_nodeValue(
200 IXMLDOMNode *iface,
201 VARIANT* value)
203 xmlnode *This = impl_from_IXMLDOMNode( iface );
204 HRESULT r = S_FALSE;
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 );
216 r = S_OK;
217 break;
218 case XML_TEXT_NODE:
219 V_VT(value) = VT_BSTR;
220 V_BSTR(value) = bstr_from_xmlChar( This->node->content );
221 r = S_OK;
222 break;
223 case XML_ELEMENT_NODE:
224 case XML_DOCUMENT_NODE:
225 /* these seem to return NULL */
226 break;
227 case XML_PI_NODE:
228 default:
229 FIXME("node %p type %d\n", This, This->node->type);
232 TRACE("%p returned %s\n", This, debugstr_w( V_BSTR(value) ) );
234 return r;
237 static HRESULT WINAPI xmlnode_put_nodeValue(
238 IXMLDOMNode *iface,
239 VARIANT value)
241 FIXME("\n");
242 return E_NOTIMPL;
245 static HRESULT WINAPI xmlnode_get_nodeType(
246 IXMLDOMNode *iface,
247 DOMNodeType* type)
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;
258 return S_OK;
261 static HRESULT WINAPI xmlnode_get_parentNode(
262 IXMLDOMNode *iface,
263 IXMLDOMNode** parent)
265 FIXME("\n");
266 return E_NOTIMPL;
269 static HRESULT WINAPI xmlnode_get_childNodes(
270 IXMLDOMNode *iface,
271 IXMLDOMNodeList** childList)
273 xmlnode *This = impl_from_IXMLDOMNode( iface );
275 TRACE("%p %p\n", This, childList );
277 if ( !childList )
278 return E_INVALIDARG;
279 #if 0
280 *childList = create_nodelist( This->node->children );
281 return S_OK;
282 #else
283 return E_NOTIMPL;
284 #endif
287 static HRESULT WINAPI xmlnode_get_firstChild(
288 IXMLDOMNode *iface,
289 IXMLDOMNode** firstChild)
291 FIXME("\n");
292 return E_NOTIMPL;
295 static HRESULT WINAPI xmlnode_get_lastChild(
296 IXMLDOMNode *iface,
297 IXMLDOMNode** lastChild)
299 FIXME("\n");
300 return E_NOTIMPL;
303 static HRESULT WINAPI xmlnode_get_previousSibling(
304 IXMLDOMNode *iface,
305 IXMLDOMNode** previousSibling)
307 FIXME("\n");
308 return E_NOTIMPL;
311 static HRESULT WINAPI xmlnode_get_nextSibling(
312 IXMLDOMNode *iface,
313 IXMLDOMNode** nextSibling)
315 FIXME("\n");
316 return E_NOTIMPL;
319 static HRESULT WINAPI xmlnode_get_attributes(
320 IXMLDOMNode *iface,
321 IXMLDOMNamedNodeMap** attributeMap)
323 xmlnode *This = impl_from_IXMLDOMNode( iface );
324 TRACE("%p\n", This);
325 *attributeMap = create_nodemap( iface );
326 return S_OK;
329 static HRESULT WINAPI xmlnode_insertBefore(
330 IXMLDOMNode *iface,
331 IXMLDOMNode* newChild,
332 VARIANT refChild,
333 IXMLDOMNode** outNewChild)
335 FIXME("\n");
336 return E_NOTIMPL;
339 static HRESULT WINAPI xmlnode_replaceChild(
340 IXMLDOMNode *iface,
341 IXMLDOMNode* newChild,
342 IXMLDOMNode* oldChild,
343 IXMLDOMNode** outOldChild)
345 FIXME("\n");
346 return E_NOTIMPL;
349 static HRESULT WINAPI xmlnode_removeChild(
350 IXMLDOMNode *iface,
351 IXMLDOMNode* childNode,
352 IXMLDOMNode** oldChild)
354 FIXME("\n");
355 return E_NOTIMPL;
358 static HRESULT WINAPI xmlnode_appendChild(
359 IXMLDOMNode *iface,
360 IXMLDOMNode* newChild,
361 IXMLDOMNode** outNewChild)
363 FIXME("\n");
364 return E_NOTIMPL;
367 static HRESULT WINAPI xmlnode_hasChildNodes(
368 IXMLDOMNode *iface,
369 VARIANT_BOOL* hasChild)
371 FIXME("\n");
372 return E_NOTIMPL;
375 static HRESULT WINAPI xmlnode_get_ownerDocument(
376 IXMLDOMNode *iface,
377 IXMLDOMDocument** DOMDocument)
379 FIXME("\n");
380 return E_NOTIMPL;
383 static HRESULT WINAPI xmlnode_cloneNode(
384 IXMLDOMNode *iface,
385 VARIANT_BOOL deep,
386 IXMLDOMNode** cloneRoot)
388 FIXME("\n");
389 return E_NOTIMPL;
392 static HRESULT WINAPI xmlnode_get_nodeTypeString(
393 IXMLDOMNode *iface,
394 BSTR* xmlnodeType)
396 FIXME("\n");
397 return E_NOTIMPL;
400 static HRESULT WINAPI xmlnode_get_text(
401 IXMLDOMNode *iface,
402 BSTR* text)
404 xmlnode *This = impl_from_IXMLDOMNode( iface );
405 xmlNodePtr child;
406 BSTR str = NULL;
408 TRACE("%p\n", This);
410 if ( !text )
411 return E_INVALIDARG;
413 child = This->node->children;
414 if ( child && child->type == XML_TEXT_NODE )
415 str = bstr_from_xmlChar( child->content );
417 TRACE("%p %s\n", This, debugstr_w(str) );
418 *text = str;
420 return S_OK;
423 static HRESULT WINAPI xmlnode_put_text(
424 IXMLDOMNode *iface,
425 BSTR text)
427 FIXME("\n");
428 return E_NOTIMPL;
431 static HRESULT WINAPI xmlnode_get_specified(
432 IXMLDOMNode *iface,
433 VARIANT_BOOL* isSpecified)
435 FIXME("\n");
436 return E_NOTIMPL;
439 static HRESULT WINAPI xmlnode_get_definition(
440 IXMLDOMNode *iface,
441 IXMLDOMNode** definitionNode)
443 FIXME("\n");
444 return E_NOTIMPL;
447 static HRESULT WINAPI xmlnode_get_nodeTypedValue(
448 IXMLDOMNode *iface,
449 VARIANT* typedValue)
451 FIXME("\n");
452 return E_NOTIMPL;
455 static HRESULT WINAPI xmlnode_put_nodeTypedValue(
456 IXMLDOMNode *iface,
457 VARIANT typedValue)
459 FIXME("\n");
460 return E_NOTIMPL;
463 static HRESULT WINAPI xmlnode_get_dataType(
464 IXMLDOMNode *iface,
465 VARIANT* dataTypeName)
467 FIXME("\n");
468 return E_NOTIMPL;
471 static HRESULT WINAPI xmlnode_put_dataType(
472 IXMLDOMNode *iface,
473 BSTR dataTypeName)
475 FIXME("\n");
476 return E_NOTIMPL;
479 static HRESULT WINAPI xmlnode_get_xml(
480 IXMLDOMNode *iface,
481 BSTR* xmlString)
483 FIXME("\n");
484 return E_NOTIMPL;
487 static HRESULT WINAPI xmlnode_transformNode(
488 IXMLDOMNode *iface,
489 IXMLDOMNode* styleSheet,
490 BSTR* xmlString)
492 FIXME("\n");
493 return E_NOTIMPL;
496 static HRESULT WINAPI xmlnode_selectNodes(
497 IXMLDOMNode *iface,
498 BSTR queryString,
499 IXMLDOMNodeList** resultList)
501 FIXME("\n");
502 return E_NOTIMPL;
505 static HRESULT WINAPI xmlnode_selectSingleNode(
506 IXMLDOMNode *iface,
507 BSTR queryString,
508 IXMLDOMNode** resultNode)
510 FIXME("\n");
511 return E_NOTIMPL;
514 static HRESULT WINAPI xmlnode_get_parsed(
515 IXMLDOMNode *iface,
516 VARIANT_BOOL* isParsed)
518 FIXME("\n");
519 return E_NOTIMPL;
522 static HRESULT WINAPI xmlnode_get_namespaceURI(
523 IXMLDOMNode *iface,
524 BSTR* namespaceURI)
526 FIXME("\n");
527 return E_NOTIMPL;
530 static HRESULT WINAPI xmlnode_get_prefix(
531 IXMLDOMNode *iface,
532 BSTR* prefixString)
534 FIXME("\n");
535 return E_NOTIMPL;
538 static HRESULT WINAPI xmlnode_get_baseName(
539 IXMLDOMNode *iface,
540 BSTR* nameString)
542 xmlnode *This = impl_from_IXMLDOMNode( iface );
543 BSTR str = NULL;
544 HRESULT r = S_FALSE;
546 TRACE("%p %p\n", This, nameString );
548 if ( !nameString )
549 return E_INVALIDARG;
551 switch ( This->node->type )
553 case XML_ELEMENT_NODE:
554 case XML_ATTRIBUTE_NODE:
555 str = bstr_from_xmlChar( This->node->name );
556 r = S_OK;
557 break;
558 case XML_TEXT_NODE:
559 break;
560 default:
561 ERR("Unhandled type %d\n", This->node->type );
562 break;
565 TRACE("returning %08lx str = %s\n", r, debugstr_w( str ) );
567 *nameString = str;
568 return r;
571 static HRESULT WINAPI xmlnode_transformNodeToObject(
572 IXMLDOMNode *iface,
573 IXMLDOMNode* stylesheet,
574 VARIANT outputObject)
576 FIXME("\n");
577 return E_NOTIMPL;
580 static const struct IXMLDOMNodeVtbl xmlnode_vtbl =
582 xmlnode_QueryInterface,
583 xmlnode_AddRef,
584 xmlnode_Release,
585 xmlnode_GetTypeInfoCount,
586 xmlnode_GetTypeInfo,
587 xmlnode_GetIDsOfNames,
588 xmlnode_Invoke,
589 xmlnode_get_nodeName,
590 xmlnode_get_nodeValue,
591 xmlnode_put_nodeValue,
592 xmlnode_get_nodeType,
593 xmlnode_get_parentNode,
594 xmlnode_get_childNodes,
595 xmlnode_get_firstChild,
596 xmlnode_get_lastChild,
597 xmlnode_get_previousSibling,
598 xmlnode_get_nextSibling,
599 xmlnode_get_attributes,
600 xmlnode_insertBefore,
601 xmlnode_replaceChild,
602 xmlnode_removeChild,
603 xmlnode_appendChild,
604 xmlnode_hasChildNodes,
605 xmlnode_get_ownerDocument,
606 xmlnode_cloneNode,
607 xmlnode_get_nodeTypeString,
608 xmlnode_get_text,
609 xmlnode_put_text,
610 xmlnode_get_specified,
611 xmlnode_get_definition,
612 xmlnode_get_nodeTypedValue,
613 xmlnode_put_nodeTypedValue,
614 xmlnode_get_dataType,
615 xmlnode_put_dataType,
616 xmlnode_get_xml,
617 xmlnode_transformNode,
618 xmlnode_selectNodes,
619 xmlnode_selectSingleNode,
620 xmlnode_get_parsed,
621 xmlnode_get_namespaceURI,
622 xmlnode_get_prefix,
623 xmlnode_get_baseName,
624 xmlnode_transformNodeToObject,
627 static IXMLDOMNode *create_node( xmlNodePtr node )
629 xmlnode *This;
631 if ( !node )
632 return NULL;
634 assert( node->doc );
636 /* if an interface already exists for this node, return it */
637 if ( node->_private )
639 IXMLDOMNode *n = node->_private;
640 IXMLDOMNode_AddRef( n );
641 return n;
645 * Try adding a reference to the IXMLDOMNode implementation
646 * containing the document's root element.
648 if ( node->type != XML_DOCUMENT_NODE )
650 IXMLDOMNode *root = NULL;
652 root = node->doc->_private;
653 assert( root );
654 IXMLDOMNode_AddRef( root );
656 else
657 assert( node->doc == (xmlDocPtr) node );
659 This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
660 if ( !This )
661 return NULL;
663 This->lpVtbl = &xmlnode_vtbl;
664 This->ref = 1;
665 This->node = node;
667 /* remember which interface we associated with this node */
668 node->_private = This;
670 return (IXMLDOMNode*) &This->lpVtbl;
673 IXMLDOMNode *create_domdoc_node( xmlDocPtr node )
675 return create_node( (xmlNodePtr) node );
678 IXMLDOMNode *create_attribute_node( xmlAttrPtr node )
680 return create_node( (xmlNodePtr) node );
683 IXMLDOMNode *create_element_node( xmlNodePtr element )
685 return create_node( element );
688 IXMLDOMNode *create_generic_node( xmlNodePtr node )
690 return create_node( node );
693 #endif