Unicodify wineesd.
[wine] / dlls / msxml3 / node.c
1 /*
2  *    Node implementation
3  *
4  * Copyright 2005 Mike McCormack
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
23 #define COBJMACROS
24
25 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31 #include "ocidl.h"
32 #include "msxml.h"
33 #include "xmldom.h"
34 #include "msxml.h"
35
36 #include "msxml_private.h"
37
38 #include "wine/debug.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
41
42 #ifdef HAVE_LIBXML2
43
44 typedef union {
45    xmlDocPtr     doc;
46    xmlNodePtr    node;
47    xmlAttrPtr    attr;
48    xmlElementPtr element;
49 } libxml_node;
50
51 typedef struct _xmlnode
52 {
53     const struct IXMLDOMNodeVtbl *lpVtbl;
54     LONG ref;
55     BOOL free_me;
56     xmlElementType type;
57     libxml_node u;
58 } xmlnode;
59
60 static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
61 {
62     return (xmlnode *)((char*)iface - FIELD_OFFSET(xmlnode, lpVtbl));
63 }
64
65 xmlDocPtr xmldoc_from_xmlnode( IXMLDOMNode *iface )
66 {
67     xmlnode *This;
68
69     if ( !iface )
70         return NULL;
71
72     This = impl_from_IXMLDOMNode( iface );
73     if (This->type != XML_DOCUMENT_NODE )
74         return NULL;
75     return This->u.doc;
76 }
77
78 xmlNodePtr xmlelement_from_xmlnode( IXMLDOMNode *iface )
79 {
80     xmlnode *This = impl_from_IXMLDOMNode( iface );
81     if (This->type != XML_ELEMENT_NODE )
82         return NULL;
83     return This->u.node;
84 }
85
86 static HRESULT WINAPI xmlnode_QueryInterface(
87     IXMLDOMNode *iface,
88     REFIID riid,
89     void** ppvObject )
90 {
91     TRACE("%p %p %p\n", iface, debugstr_guid(riid), ppvObject);
92
93     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
94          IsEqualGUID( riid, &IID_IDispatch ) ||
95          IsEqualGUID( riid, &IID_IXMLDOMNode ) )
96     {
97         *ppvObject = iface;
98     }
99     else
100         return E_NOINTERFACE;
101
102     IXMLDOMElement_AddRef( iface );
103
104     return S_OK;
105 }
106
107 static ULONG WINAPI xmlnode_AddRef(
108     IXMLDOMNode *iface )
109 {
110     xmlnode *This = impl_from_IXMLDOMNode( iface );
111     return InterlockedIncrement( &This->ref );
112 }
113
114 static ULONG WINAPI xmlnode_Release(
115     IXMLDOMNode *iface )
116 {
117     xmlnode *This = impl_from_IXMLDOMNode( iface );
118     ULONG ref;
119
120     ref = InterlockedDecrement( &This->ref );
121     if ( ref == 0 )
122     {
123         if ( This->free_me )
124         {
125             switch( This->type )
126             {
127             case XML_DOCUMENT_NODE:
128                 xmlFreeDoc( This->u.doc );
129                 break;
130             case XML_ATTRIBUTE_NODE:
131             case XML_ELEMENT_NODE:
132                 /* don't free these */
133                 break;
134             default:
135                 ERR("don't know how to free this element\n");
136             }
137         }
138         HeapFree( GetProcessHeap(), 0, This );
139     }
140
141     return ref;
142 }
143
144 static HRESULT WINAPI xmlnode_GetTypeInfoCount(
145     IXMLDOMNode *iface,
146     UINT* pctinfo )
147 {
148     FIXME("\n");
149     return E_NOTIMPL;
150 }
151
152 static HRESULT WINAPI xmlnode_GetTypeInfo(
153     IXMLDOMNode *iface,
154     UINT iTInfo,
155     LCID lcid,
156     ITypeInfo** ppTInfo )
157 {
158     FIXME("\n");
159     return E_NOTIMPL;
160 }
161
162 static HRESULT WINAPI xmlnode_GetIDsOfNames(
163     IXMLDOMNode *iface,
164     REFIID riid,
165     LPOLESTR* rgszNames,
166     UINT cNames,
167     LCID lcid,
168     DISPID* rgDispId )
169 {
170     FIXME("\n");
171     return E_NOTIMPL;
172 }
173
174 static HRESULT WINAPI xmlnode_Invoke(
175     IXMLDOMNode *iface,
176     DISPID dispIdMember,
177     REFIID riid,
178     LCID lcid,
179     WORD wFlags,
180     DISPPARAMS* pDispParams,
181     VARIANT* pVarResult,
182     EXCEPINFO* pExcepInfo,
183     UINT* puArgErr )
184 {
185     FIXME("\n");
186     return E_NOTIMPL;
187 }
188
189 static HRESULT WINAPI xmlnode_get_xmlnodeName(
190     IXMLDOMNode *iface,
191     BSTR* name)
192 {
193     FIXME("\n");
194     return E_NOTIMPL;
195 }
196
197 BSTR bstr_from_xmlChar( const xmlChar *buf )
198 {
199     DWORD len;
200     LPWSTR str;
201     BSTR bstr;
202
203     if ( !buf )
204         return NULL;
205
206     len = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) buf, -1, NULL, 0 );
207     str = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
208     if ( !str )
209         return NULL;
210     MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) buf, -1, str, len );
211     bstr = SysAllocString( str );
212     HeapFree( GetProcessHeap(), 0, str );
213     return bstr;
214 }
215
216 static HRESULT WINAPI xmlnode_get_xmlnodeValue(
217     IXMLDOMNode *iface,
218     VARIANT* value)
219 {
220     xmlnode *This = impl_from_IXMLDOMNode( iface );
221
222     TRACE("%p %p\n", This, value);
223
224     switch ( This->type )
225     {
226     case XML_COMMENT_NODE:
227         FIXME("comment\n");
228         return E_FAIL;
229         break;
230     case XML_ATTRIBUTE_NODE:
231         V_VT(value) = VT_BSTR;
232         V_BSTR(value) = bstr_from_xmlChar( This->u.attr->name );
233         break;
234     case XML_PI_NODE:
235         FIXME("processing instruction\n");
236         return E_FAIL;
237         break;
238     case XML_ELEMENT_NODE:
239     case XML_DOCUMENT_NODE:
240     default:
241         return E_FAIL;
242         break;
243     }
244  
245     TRACE("%p returned %s\n", This, debugstr_w( V_BSTR(value) ) );
246
247     return S_OK;
248 }
249
250 static HRESULT WINAPI xmlnode_put_xmlnodeValue(
251     IXMLDOMNode *iface,
252     VARIANT value)
253 {
254     FIXME("\n");
255     return E_NOTIMPL;
256 }
257
258 static HRESULT WINAPI xmlnode_get_xmlnodeType(
259     IXMLDOMNode *iface,
260     DOMNodeType* type)
261 {
262     FIXME("\n");
263     return E_NOTIMPL;
264 }
265
266 static HRESULT WINAPI xmlnode_get_parentNode(
267     IXMLDOMNode *iface,
268     IXMLDOMNode** parent)
269 {
270     FIXME("\n");
271     return E_NOTIMPL;
272 }
273
274 static HRESULT WINAPI xmlnode_get_childNodes(
275     IXMLDOMNode *iface,
276     IXMLDOMNodeList** childList)
277 {
278     xmlnode *This = impl_from_IXMLDOMNode( iface );
279     FIXME("%p\n", This);
280     return E_NOTIMPL;
281     /*return NodeList_create( childList, This );*/
282 }
283
284 static HRESULT WINAPI xmlnode_get_firstChild(
285     IXMLDOMNode *iface,
286     IXMLDOMNode** firstChild)
287 {
288     FIXME("\n");
289     return E_NOTIMPL;
290 }
291
292 static HRESULT WINAPI xmlnode_get_lastChild(
293     IXMLDOMNode *iface,
294     IXMLDOMNode** lastChild)
295 {
296     FIXME("\n");
297     return E_NOTIMPL;
298 }
299
300 static HRESULT WINAPI xmlnode_get_previousSibling(
301     IXMLDOMNode *iface,
302     IXMLDOMNode** previousSibling)
303 {
304     FIXME("\n");
305     return E_NOTIMPL;
306 }
307
308 static HRESULT WINAPI xmlnode_get_nextSibling(
309     IXMLDOMNode *iface,
310     IXMLDOMNode** nextSibling)
311 {
312     FIXME("\n");
313     return E_NOTIMPL;
314 }
315
316 static HRESULT WINAPI xmlnode_get_attributes(
317     IXMLDOMNode *iface,
318     IXMLDOMNamedNodeMap** attributeMap)
319 {
320     xmlnode *This = impl_from_IXMLDOMNode( iface );
321     FIXME("%p\n", This);
322     return E_NOTIMPL;
323     /*return NodeMap_create( attributeMap, This, node ); */
324 }
325
326 static HRESULT WINAPI xmlnode_insertBefore(
327     IXMLDOMNode *iface,
328     IXMLDOMNode* newChild,
329     VARIANT refChild,
330     IXMLDOMNode** outNewChild)
331 {
332     FIXME("\n");
333     return E_NOTIMPL;
334 }
335
336 static HRESULT WINAPI xmlnode_replaceChild(
337     IXMLDOMNode *iface,
338     IXMLDOMNode* newChild,
339     IXMLDOMNode* oldChild,
340     IXMLDOMNode** outOldChild)
341 {
342     FIXME("\n");
343     return E_NOTIMPL;
344 }
345
346 static HRESULT WINAPI xmlnode_removeChild(
347     IXMLDOMNode *iface,
348     IXMLDOMNode* childNode,
349     IXMLDOMNode** oldChild)
350 {
351     FIXME("\n");
352     return E_NOTIMPL;
353 }
354
355 static HRESULT WINAPI xmlnode_appendChild(
356     IXMLDOMNode *iface,
357     IXMLDOMNode* newChild,
358     IXMLDOMNode** outNewChild)
359 {
360     FIXME("\n");
361     return E_NOTIMPL;
362 }
363
364 static HRESULT WINAPI xmlnode_hasChildNodes(
365     IXMLDOMNode *iface,
366     VARIANT_BOOL* hasChild)
367 {
368     FIXME("\n");
369     return E_NOTIMPL;
370 }
371
372 static HRESULT WINAPI xmlnode_get_ownerDocument(
373     IXMLDOMNode *iface,
374     IXMLDOMDocument** DOMDocument)
375 {
376     FIXME("\n");
377     return E_NOTIMPL;
378 }
379
380 static HRESULT WINAPI xmlnode_cloneNode(
381     IXMLDOMNode *iface,
382     VARIANT_BOOL deep,
383     IXMLDOMNode** cloneRoot)
384 {
385     FIXME("\n");
386     return E_NOTIMPL;
387 }
388
389 static HRESULT WINAPI xmlnode_get_xmlnodeTypeString(
390     IXMLDOMNode *iface,
391     BSTR* xmlnodeType)
392 {
393     FIXME("\n");
394     return E_NOTIMPL;
395 }
396
397 static HRESULT WINAPI xmlnode_get_text(
398     IXMLDOMNode *iface,
399     BSTR* text)
400 {
401     FIXME("\n");
402     return E_NOTIMPL;
403 }
404
405 static HRESULT WINAPI xmlnode_put_text(
406     IXMLDOMNode *iface,
407     BSTR text)
408 {
409     FIXME("\n");
410     return E_NOTIMPL;
411 }
412
413 static HRESULT WINAPI xmlnode_get_specified(
414     IXMLDOMNode *iface,
415     VARIANT_BOOL* isSpecified)
416 {
417     FIXME("\n");
418     return E_NOTIMPL;
419 }
420
421 static HRESULT WINAPI xmlnode_get_definition(
422     IXMLDOMNode *iface,
423     IXMLDOMNode** definitionNode)
424 {
425     FIXME("\n");
426     return E_NOTIMPL;
427 }
428
429 static HRESULT WINAPI xmlnode_get_xmlnodeTypedValue(
430     IXMLDOMNode *iface,
431     VARIANT* typedValue)
432 {
433     FIXME("\n");
434     return E_NOTIMPL;
435 }
436
437 static HRESULT WINAPI xmlnode_put_xmlnodeTypedValue(
438     IXMLDOMNode *iface,
439     VARIANT typedValue)
440 {
441     FIXME("\n");
442     return E_NOTIMPL;
443 }
444
445 static HRESULT WINAPI xmlnode_get_dataType(
446     IXMLDOMNode *iface,
447     VARIANT* dataTypeName)
448 {
449     FIXME("\n");
450     return E_NOTIMPL;
451 }
452
453 static HRESULT WINAPI xmlnode_put_dataType(
454     IXMLDOMNode *iface,
455     BSTR dataTypeName)
456 {
457     FIXME("\n");
458     return E_NOTIMPL;
459 }
460
461 static HRESULT WINAPI xmlnode_get_xml(
462     IXMLDOMNode *iface,
463     BSTR* xmlString)
464 {
465     FIXME("\n");
466     return E_NOTIMPL;
467 }
468
469 static HRESULT WINAPI xmlnode_transformNode(
470     IXMLDOMNode *iface,
471     IXMLDOMNode* styleSheet,
472     BSTR* xmlString)
473 {
474     FIXME("\n");
475     return E_NOTIMPL;
476 }
477
478 static HRESULT WINAPI xmlnode_selectNodes(
479     IXMLDOMNode *iface,
480     BSTR queryString,
481     IXMLDOMNodeList** resultList)
482 {
483     FIXME("\n");
484     return E_NOTIMPL;
485 }
486
487 static HRESULT WINAPI xmlnode_selectSingleNode(
488     IXMLDOMNode *iface,
489     BSTR queryString,
490     IXMLDOMNode** resultNode)
491 {
492     FIXME("\n");
493     return E_NOTIMPL;
494 }
495
496 static HRESULT WINAPI xmlnode_get_parsed(
497     IXMLDOMNode *iface,
498     VARIANT_BOOL* isParsed)
499 {
500     FIXME("\n");
501     return E_NOTIMPL;
502 }
503
504 static HRESULT WINAPI xmlnode_get_namespaceURI(
505     IXMLDOMNode *iface,
506     BSTR* namespaceURI)
507 {
508     FIXME("\n");
509     return E_NOTIMPL;
510 }
511
512 static HRESULT WINAPI xmlnode_get_prefix(
513     IXMLDOMNode *iface,
514     BSTR* prefixString)
515 {
516     FIXME("\n");
517     return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI xmlnode_get_baseName(
521     IXMLDOMNode *iface,
522     BSTR* nameString)
523 {
524     FIXME("\n");
525     return E_NOTIMPL;
526 }
527
528 static HRESULT WINAPI xmlnode_transformNodeToObject(
529     IXMLDOMNode *iface,
530     IXMLDOMNode* stylesheet,
531     VARIANT outputObject)
532 {
533     FIXME("\n");
534     return E_NOTIMPL;
535 }
536
537 static const struct IXMLDOMNodeVtbl xmlnode_vtbl =
538 {
539     xmlnode_QueryInterface,
540     xmlnode_AddRef,
541     xmlnode_Release,
542     xmlnode_GetTypeInfoCount,
543     xmlnode_GetTypeInfo,
544     xmlnode_GetIDsOfNames,
545     xmlnode_Invoke,
546     xmlnode_get_xmlnodeName,
547     xmlnode_get_xmlnodeValue,
548     xmlnode_put_xmlnodeValue,
549     xmlnode_get_xmlnodeType,
550     xmlnode_get_parentNode,
551     xmlnode_get_childNodes,
552     xmlnode_get_firstChild,
553     xmlnode_get_lastChild,
554     xmlnode_get_previousSibling,
555     xmlnode_get_nextSibling,
556     xmlnode_get_attributes,
557     xmlnode_insertBefore,
558     xmlnode_replaceChild,
559     xmlnode_removeChild,
560     xmlnode_appendChild,
561     xmlnode_hasChildNodes,
562     xmlnode_get_ownerDocument,
563     xmlnode_cloneNode,
564     xmlnode_get_xmlnodeTypeString,
565     xmlnode_get_text,
566     xmlnode_put_text,
567     xmlnode_get_specified,
568     xmlnode_get_definition,
569     xmlnode_get_xmlnodeTypedValue,
570     xmlnode_put_xmlnodeTypedValue,
571     xmlnode_get_dataType,
572     xmlnode_put_dataType,
573     xmlnode_get_xml,
574     xmlnode_transformNode,
575     xmlnode_selectNodes,
576     xmlnode_selectSingleNode,
577     xmlnode_get_parsed,
578     xmlnode_get_namespaceURI,
579     xmlnode_get_prefix,
580     xmlnode_get_baseName,
581     xmlnode_transformNodeToObject,
582 };
583
584 static xmlnode *create_node( void )
585 {
586     xmlnode *This;
587
588     This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
589     if ( !This )
590         return NULL;
591
592     This->lpVtbl = &xmlnode_vtbl;
593     This->ref = 1;
594     This->free_me = TRUE;
595     This->u.doc = NULL;
596
597     return This;
598 }
599
600 IXMLDOMNode *create_domdoc_node( xmlDocPtr node )
601 {
602     xmlnode *This;
603
604     if ( !node )
605         return NULL;
606
607     This = create_node();
608     if ( !This )
609         return NULL;
610
611     This->type = XML_DOCUMENT_NODE;
612     This->u.doc = node;
613  
614     return (IXMLDOMNode*) &This->lpVtbl;
615 }
616
617 IXMLDOMNode *create_attribute_node( xmlAttrPtr node )
618 {
619     xmlnode *This;
620
621     if ( !node )
622         return NULL;
623
624     This = create_node();
625     if ( !This )
626         return NULL;
627
628     This->type = XML_ATTRIBUTE_NODE;
629     This->u.attr = node;
630  
631     return (IXMLDOMNode*) &This->lpVtbl;
632 }
633
634 IXMLDOMNode *create_element_node( xmlNodePtr element )
635 {
636     xmlnode *This;
637
638     if ( !element )
639         return NULL;
640
641     This = create_node();
642     if ( !This )
643         return NULL;
644
645     This->type = XML_ELEMENT_NODE;
646     This->u.node = element;
647  
648     return (IXMLDOMNode*) &This->lpVtbl;
649 }
650
651 #endif