mshtml: Allow task queue to be used for different targets.
[wine] / dlls / msxml3 / text.c
1 /*
2  *    DOM text node implementation
3  *
4  * Copyright 2006 Huw Davies
5  * Copyright 2007-2008 Alistair Leslie-Hughes
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #define COBJMACROS
23
24 #include "config.h"
25
26 #include <stdarg.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "ole2.h"
31 #include "msxml2.h"
32
33 #include "msxml_private.h"
34
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
38
39 #ifdef HAVE_LIBXML2
40
41 typedef struct _domtext
42 {
43     xmlnode node;
44     const struct IXMLDOMTextVtbl *lpVtbl;
45     LONG ref;
46 } domtext;
47
48 static inline domtext *impl_from_IXMLDOMText( IXMLDOMText *iface )
49 {
50     return (domtext *)((char*)iface - FIELD_OFFSET(domtext, lpVtbl));
51 }
52
53 static HRESULT WINAPI domtext_QueryInterface(
54     IXMLDOMText *iface,
55     REFIID riid,
56     void** ppvObject )
57 {
58     domtext *This = impl_from_IXMLDOMText( iface );
59     TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
60
61     if ( IsEqualGUID( riid, &IID_IXMLDOMText ) ||
62          IsEqualGUID( riid, &IID_IXMLDOMCharacterData) ||
63          IsEqualGUID( riid, &IID_IDispatch ) ||
64          IsEqualGUID( riid, &IID_IUnknown ) )
65     {
66         *ppvObject = iface;
67     }
68     else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
69     {
70         *ppvObject = IXMLDOMNode_from_impl(&This->node);
71     }
72     else if ( IsEqualGUID( riid, &IID_IXMLDOMElement ) ||
73               IsEqualGUID( riid, &IID_IXMLDOMCDATASection ) )
74     {
75         /* IXMLDOMText is known to be correct in not implementing these */
76         TRACE("Unsupported interface\n");
77         return E_NOINTERFACE;
78     }
79     else
80     {
81         FIXME("Unsupported interface %s\n", debugstr_guid(riid));
82         return E_NOINTERFACE;
83     }
84
85     IXMLDOMText_AddRef((IUnknown*)*ppvObject);
86     return S_OK;
87 }
88
89 static ULONG WINAPI domtext_AddRef(
90     IXMLDOMText *iface )
91 {
92     domtext *This = impl_from_IXMLDOMText( iface );
93     return InterlockedIncrement( &This->ref );
94 }
95
96 static ULONG WINAPI domtext_Release(
97     IXMLDOMText *iface )
98 {
99     domtext *This = impl_from_IXMLDOMText( iface );
100     ULONG ref;
101
102     ref = InterlockedDecrement( &This->ref );
103     if ( ref == 0 )
104     {
105         destroy_xmlnode(&This->node);
106         HeapFree( GetProcessHeap(), 0, This );
107     }
108
109     return ref;
110 }
111
112 static HRESULT WINAPI domtext_GetTypeInfoCount(
113     IXMLDOMText *iface,
114     UINT* pctinfo )
115 {
116     domtext *This = impl_from_IXMLDOMText( iface );
117
118     TRACE("(%p)->(%p)\n", This, pctinfo);
119
120     *pctinfo = 1;
121
122     return S_OK;
123 }
124
125 static HRESULT WINAPI domtext_GetTypeInfo(
126     IXMLDOMText *iface,
127     UINT iTInfo, LCID lcid,
128     ITypeInfo** ppTInfo )
129 {
130     domtext *This = impl_from_IXMLDOMText( iface );
131     HRESULT hr;
132
133     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
134
135     hr = get_typeinfo(IXMLDOMText_tid, ppTInfo);
136
137     return hr;
138 }
139
140 static HRESULT WINAPI domtext_GetIDsOfNames(
141     IXMLDOMText *iface,
142     REFIID riid, LPOLESTR* rgszNames,
143     UINT cNames, LCID lcid, DISPID* rgDispId )
144 {
145     domtext *This = impl_from_IXMLDOMText( iface );
146     ITypeInfo *typeinfo;
147     HRESULT hr;
148
149     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
150           lcid, rgDispId);
151
152     if(!rgszNames || cNames == 0 || !rgDispId)
153         return E_INVALIDARG;
154
155     hr = get_typeinfo(IXMLDOMText_tid, &typeinfo);
156     if(SUCCEEDED(hr))
157     {
158         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
159         ITypeInfo_Release(typeinfo);
160     }
161
162     return hr;
163 }
164
165 static HRESULT WINAPI domtext_Invoke(
166     IXMLDOMText *iface,
167     DISPID dispIdMember, REFIID riid, LCID lcid,
168     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
169     EXCEPINFO* pExcepInfo, UINT* puArgErr )
170 {
171     domtext *This = impl_from_IXMLDOMText( iface );
172     ITypeInfo *typeinfo;
173     HRESULT hr;
174
175     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
176           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
177
178     hr = get_typeinfo(IXMLDOMText_tid, &typeinfo);
179     if(SUCCEEDED(hr))
180     {
181         hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
182                 pVarResult, pExcepInfo, puArgErr);
183         ITypeInfo_Release(typeinfo);
184     }
185
186     return hr;
187 }
188
189 static HRESULT WINAPI domtext_get_nodeName(
190     IXMLDOMText *iface,
191     BSTR* p )
192 {
193     domtext *This = impl_from_IXMLDOMText( iface );
194     return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), p );
195 }
196
197 static HRESULT WINAPI domtext_get_nodeValue(
198     IXMLDOMText *iface,
199     VARIANT* var1 )
200 {
201     domtext *This = impl_from_IXMLDOMText( iface );
202     return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
203 }
204
205 static HRESULT WINAPI domtext_put_nodeValue(
206     IXMLDOMText *iface,
207     VARIANT var1 )
208 {
209     domtext *This = impl_from_IXMLDOMText( iface );
210     return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
211 }
212
213 static HRESULT WINAPI domtext_get_nodeType(
214     IXMLDOMText *iface,
215     DOMNodeType* domNodeType )
216 {
217     domtext *This = impl_from_IXMLDOMText( iface );
218     return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), domNodeType );
219 }
220
221 static HRESULT WINAPI domtext_get_parentNode(
222     IXMLDOMText *iface,
223     IXMLDOMNode** parent )
224 {
225     domtext *This = impl_from_IXMLDOMText( iface );
226     return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
227 }
228
229 static HRESULT WINAPI domtext_get_childNodes(
230     IXMLDOMText *iface,
231     IXMLDOMNodeList** outList)
232 {
233     domtext *This = impl_from_IXMLDOMText( iface );
234     return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), outList );
235 }
236
237 static HRESULT WINAPI domtext_get_firstChild(
238     IXMLDOMText *iface,
239     IXMLDOMNode** domNode)
240 {
241     domtext *This = impl_from_IXMLDOMText( iface );
242     return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), domNode );
243 }
244
245 static HRESULT WINAPI domtext_get_lastChild(
246     IXMLDOMText *iface,
247     IXMLDOMNode** domNode)
248 {
249     domtext *This = impl_from_IXMLDOMText( iface );
250     return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), domNode );
251 }
252
253 static HRESULT WINAPI domtext_get_previousSibling(
254     IXMLDOMText *iface,
255     IXMLDOMNode** domNode)
256 {
257     domtext *This = impl_from_IXMLDOMText( iface );
258     return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), domNode );
259 }
260
261 static HRESULT WINAPI domtext_get_nextSibling(
262     IXMLDOMText *iface,
263     IXMLDOMNode** domNode)
264 {
265     domtext *This = impl_from_IXMLDOMText( iface );
266     return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), domNode );
267 }
268
269 static HRESULT WINAPI domtext_get_attributes(
270     IXMLDOMText *iface,
271     IXMLDOMNamedNodeMap** attributeMap)
272 {
273     domtext *This = impl_from_IXMLDOMText( iface );
274     return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
275 }
276
277 static HRESULT WINAPI domtext_insertBefore(
278     IXMLDOMText *iface,
279     IXMLDOMNode* newNode, VARIANT var1,
280     IXMLDOMNode** outOldNode)
281 {
282     domtext *This = impl_from_IXMLDOMText( iface );
283     return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newNode, var1, outOldNode );
284 }
285
286 static HRESULT WINAPI domtext_replaceChild(
287     IXMLDOMText *iface,
288     IXMLDOMNode* newNode,
289     IXMLDOMNode* oldNode,
290     IXMLDOMNode** outOldNode)
291 {
292     domtext *This = impl_from_IXMLDOMText( iface );
293     return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newNode, oldNode, outOldNode );
294 }
295
296 static HRESULT WINAPI domtext_removeChild(
297     IXMLDOMText *iface,
298     IXMLDOMNode* domNode, IXMLDOMNode** oldNode)
299 {
300     domtext *This = impl_from_IXMLDOMText( iface );
301     return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), domNode, oldNode );
302 }
303
304 static HRESULT WINAPI domtext_appendChild(
305     IXMLDOMText *iface,
306     IXMLDOMNode* newNode, IXMLDOMNode** outNewNode)
307 {
308     domtext *This = impl_from_IXMLDOMText( iface );
309     return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newNode, outNewNode );
310 }
311
312 static HRESULT WINAPI domtext_hasChildNodes(
313     IXMLDOMText *iface,
314     VARIANT_BOOL* pbool)
315 {
316     domtext *This = impl_from_IXMLDOMText( iface );
317     return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), pbool );
318 }
319
320 static HRESULT WINAPI domtext_get_ownerDocument(
321     IXMLDOMText *iface,
322     IXMLDOMDocument** domDocument)
323 {
324     domtext *This = impl_from_IXMLDOMText( iface );
325     return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), domDocument );
326 }
327
328 static HRESULT WINAPI domtext_cloneNode(
329     IXMLDOMText *iface,
330     VARIANT_BOOL pbool, IXMLDOMNode** outNode)
331 {
332     domtext *This = impl_from_IXMLDOMText( iface );
333     return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), pbool, outNode );
334 }
335
336 static HRESULT WINAPI domtext_get_nodeTypeString(
337     IXMLDOMText *iface,
338     BSTR* p)
339 {
340     domtext *This = impl_from_IXMLDOMText( iface );
341     return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), p );
342 }
343
344 static HRESULT WINAPI domtext_get_text(
345     IXMLDOMText *iface,
346     BSTR* p)
347 {
348     domtext *This = impl_from_IXMLDOMText( iface );
349     return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), p );
350 }
351
352 static HRESULT WINAPI domtext_put_text(
353     IXMLDOMText *iface,
354     BSTR p)
355 {
356     domtext *This = impl_from_IXMLDOMText( iface );
357     return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), p );
358 }
359
360 static HRESULT WINAPI domtext_get_specified(
361     IXMLDOMText *iface,
362     VARIANT_BOOL* pbool)
363 {
364     domtext *This = impl_from_IXMLDOMText( iface );
365     return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), pbool );
366 }
367
368 static HRESULT WINAPI domtext_get_definition(
369     IXMLDOMText *iface,
370     IXMLDOMNode** domNode)
371 {
372     domtext *This = impl_from_IXMLDOMText( iface );
373     return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), domNode );
374 }
375
376 static HRESULT WINAPI domtext_get_nodeTypedValue(
377     IXMLDOMText *iface,
378     VARIANT* var1)
379 {
380     domtext *This = impl_from_IXMLDOMText( iface );
381     return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
382 }
383
384 static HRESULT WINAPI domtext_put_nodeTypedValue(
385     IXMLDOMText *iface,
386     VARIANT var1)
387 {
388     domtext *This = impl_from_IXMLDOMText( iface );
389     return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
390 }
391
392 static HRESULT WINAPI domtext_get_dataType(
393     IXMLDOMText *iface,
394     VARIANT* var1)
395 {
396     domtext *This = impl_from_IXMLDOMText( iface );
397     return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), var1 );
398 }
399
400 static HRESULT WINAPI domtext_put_dataType(
401     IXMLDOMText *iface,
402     BSTR p)
403 {
404     domtext *This = impl_from_IXMLDOMText( iface );
405     return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), p );
406 }
407
408 static HRESULT WINAPI domtext_get_xml(
409     IXMLDOMText *iface,
410     BSTR* p)
411 {
412     domtext *This = impl_from_IXMLDOMText( iface );
413     return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), p );
414 }
415
416 static HRESULT WINAPI domtext_transformNode(
417     IXMLDOMText *iface,
418     IXMLDOMNode* domNode, BSTR* p)
419 {
420     domtext *This = impl_from_IXMLDOMText( iface );
421     return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), domNode, p );
422 }
423
424 static HRESULT WINAPI domtext_selectNodes(
425     IXMLDOMText *iface,
426     BSTR p, IXMLDOMNodeList** outList)
427 {
428     domtext *This = impl_from_IXMLDOMText( iface );
429     return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), p, outList );
430 }
431
432 static HRESULT WINAPI domtext_selectSingleNode(
433     IXMLDOMText *iface,
434     BSTR p, IXMLDOMNode** outNode)
435 {
436     domtext *This = impl_from_IXMLDOMText( iface );
437     return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), p, outNode );
438 }
439
440 static HRESULT WINAPI domtext_get_parsed(
441     IXMLDOMText *iface,
442     VARIANT_BOOL* pbool)
443 {
444     domtext *This = impl_from_IXMLDOMText( iface );
445     return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), pbool );
446 }
447
448 static HRESULT WINAPI domtext_get_namespaceURI(
449     IXMLDOMText *iface,
450     BSTR* p)
451 {
452     domtext *This = impl_from_IXMLDOMText( iface );
453     return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), p );
454 }
455
456 static HRESULT WINAPI domtext_get_prefix(
457     IXMLDOMText *iface,
458     BSTR* p)
459 {
460     domtext *This = impl_from_IXMLDOMText( iface );
461     return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), p );
462 }
463
464 static HRESULT WINAPI domtext_get_baseName(
465     IXMLDOMText *iface,
466     BSTR* p)
467 {
468     domtext *This = impl_from_IXMLDOMText( iface );
469     return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), p );
470 }
471
472 static HRESULT WINAPI domtext_transformNodeToObject(
473     IXMLDOMText *iface,
474     IXMLDOMNode* domNode, VARIANT var1)
475 {
476     domtext *This = impl_from_IXMLDOMText( iface );
477     return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), domNode, var1 );
478 }
479
480 static HRESULT WINAPI domtext_get_data(
481     IXMLDOMText *iface,
482     BSTR *p)
483 {
484     domtext *This = impl_from_IXMLDOMText( iface );
485     HRESULT hr = E_FAIL;
486     VARIANT vRet;
487
488     if(!p)
489         return E_INVALIDARG;
490
491     hr = IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), &vRet );
492     if(hr == S_OK)
493     {
494         *p = V_BSTR(&vRet);
495     }
496
497     return hr;
498 }
499
500 static HRESULT WINAPI domtext_put_data(
501     IXMLDOMText *iface,
502     BSTR data)
503 {
504     domtext *This = impl_from_IXMLDOMText( iface );
505     HRESULT hr = E_FAIL;
506     VARIANT val;
507
508     TRACE("%p %s\n", This, debugstr_w(data) );
509
510     V_VT(&val) = VT_BSTR;
511     V_BSTR(&val) = data;
512
513     hr = IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), val );
514
515     return hr;
516 }
517
518 static HRESULT WINAPI domtext_get_length(
519     IXMLDOMText *iface,
520     LONG *len)
521 {
522     domtext *This = impl_from_IXMLDOMText( iface );
523     xmlChar *pContent;
524     LONG nLength = 0;
525
526     TRACE("%p\n", iface);
527
528     if(!len)
529         return E_INVALIDARG;
530
531     pContent = xmlNodeGetContent(This->node.node);
532     if(pContent)
533     {
534         nLength = xmlStrlen(pContent);
535         xmlFree(pContent);
536     }
537
538     *len = nLength;
539
540     return S_OK;
541 }
542
543 static HRESULT WINAPI domtext_substringData(
544     IXMLDOMText *iface,
545     LONG offset, LONG count, BSTR *p)
546 {
547     domtext *This = impl_from_IXMLDOMText( iface );
548     xmlChar *pContent;
549     LONG nLength = 0;
550     HRESULT hr = S_FALSE;
551
552     TRACE("%p\n", iface);
553
554     if(!p)
555         return E_INVALIDARG;
556
557     *p = NULL;
558     if(offset < 0 || count < 0)
559         return E_INVALIDARG;
560
561     if(count == 0)
562         return hr;
563
564     pContent = xmlNodeGetContent(This->node.node);
565     if(pContent)
566     {
567         nLength = xmlStrlen(pContent);
568
569         if( offset < nLength)
570         {
571             BSTR sContent = bstr_from_xmlChar(pContent);
572             if(offset + count > nLength)
573                 *p = SysAllocString(&sContent[offset]);
574             else
575                 *p = SysAllocStringLen(&sContent[offset], count);
576
577             SysFreeString(sContent);
578             hr = S_OK;
579         }
580
581         xmlFree(pContent);
582     }
583
584     return hr;
585 }
586
587 static HRESULT WINAPI domtext_appendData(
588     IXMLDOMText *iface,
589     BSTR p)
590 {
591     domtext *This = impl_from_IXMLDOMText( iface );
592     xmlChar *pContent;
593     HRESULT hr = S_FALSE;
594
595     TRACE("%p\n", iface);
596
597     /* Nothing to do if NULL or an Empty string passed in. */
598     if(p == NULL || SysStringLen(p) == 0)
599         return S_OK;
600
601     pContent = xmlChar_from_wchar( p );
602     if(pContent)
603     {
604         if(xmlTextConcat(This->node.node, pContent, SysStringLen(p)) == 0)
605             hr = S_OK;
606         else
607             hr = E_FAIL;
608         HeapFree( GetProcessHeap(), 0, pContent );
609     }
610     else
611         hr = E_FAIL;
612
613     return hr;
614 }
615
616 static HRESULT WINAPI domtext_insertData(
617     IXMLDOMText *iface,
618     LONG offset, BSTR p)
619 {
620     domtext *This = impl_from_IXMLDOMText( iface );
621     xmlChar *pXmlContent;
622     BSTR sNewString;
623     HRESULT hr = S_FALSE;
624     LONG nLength = 0, nLengthP = 0;
625     xmlChar *str = NULL;
626
627     TRACE("%p\n", This);
628
629     /* If have a NULL or empty string, don't do anything. */
630     if(SysStringLen(p) == 0)
631         return S_OK;
632
633     if(offset < 0)
634     {
635         return E_INVALIDARG;
636     }
637
638     pXmlContent = xmlNodeGetContent(This->node.node);
639     if(pXmlContent)
640     {
641         BSTR sContent = bstr_from_xmlChar( pXmlContent );
642         nLength = SysStringLen(sContent);
643         nLengthP = SysStringLen(p);
644
645         if(nLength < offset)
646         {
647             SysFreeString(sContent);
648             xmlFree(pXmlContent);
649
650             return E_INVALIDARG;
651         }
652
653         sNewString = SysAllocStringLen(NULL, nLength + nLengthP + 1);
654         if(sNewString)
655         {
656             if(offset > 0)
657                 memcpy(sNewString, sContent, offset * sizeof(WCHAR));
658
659             memcpy(&sNewString[offset], p, nLengthP * sizeof(WCHAR));
660
661             if(offset+nLengthP < nLength)
662                 memcpy(&sNewString[offset+nLengthP], &sContent[offset], (nLength-offset) * sizeof(WCHAR));
663
664             sNewString[nLengthP + nLength] = 0;
665
666             str = xmlChar_from_wchar(sNewString);
667             if(str)
668             {
669                 xmlNodeSetContent(This->node.node, str);
670                 hr = S_OK;
671             }
672             HeapFree(GetProcessHeap(), 0, str);
673
674             SysFreeString(sNewString);
675         }
676
677         SysFreeString(sContent);
678
679         xmlFree(pXmlContent);
680     }
681
682     return hr;
683 }
684
685 static HRESULT WINAPI domtext_deleteData(
686     IXMLDOMText *iface,
687     LONG offset, LONG count)
688 {
689     FIXME("\n");
690     return E_NOTIMPL;
691 }
692
693 static HRESULT WINAPI domtext_replaceData(
694     IXMLDOMText *iface,
695     LONG offset, LONG count, BSTR p)
696 {
697     FIXME("\n");
698     return E_NOTIMPL;
699 }
700
701 static HRESULT WINAPI domtext_splitText(
702     IXMLDOMText *iface,
703     LONG offset, IXMLDOMText **txtNode)
704 {
705     FIXME("\n");
706     return E_NOTIMPL;
707 }
708
709
710 static const struct IXMLDOMTextVtbl domtext_vtbl =
711 {
712     domtext_QueryInterface,
713     domtext_AddRef,
714     domtext_Release,
715     domtext_GetTypeInfoCount,
716     domtext_GetTypeInfo,
717     domtext_GetIDsOfNames,
718     domtext_Invoke,
719     domtext_get_nodeName,
720     domtext_get_nodeValue,
721     domtext_put_nodeValue,
722     domtext_get_nodeType,
723     domtext_get_parentNode,
724     domtext_get_childNodes,
725     domtext_get_firstChild,
726     domtext_get_lastChild,
727     domtext_get_previousSibling,
728     domtext_get_nextSibling,
729     domtext_get_attributes,
730     domtext_insertBefore,
731     domtext_replaceChild,
732     domtext_removeChild,
733     domtext_appendChild,
734     domtext_hasChildNodes,
735     domtext_get_ownerDocument,
736     domtext_cloneNode,
737     domtext_get_nodeTypeString,
738     domtext_get_text,
739     domtext_put_text,
740     domtext_get_specified,
741     domtext_get_definition,
742     domtext_get_nodeTypedValue,
743     domtext_put_nodeTypedValue,
744     domtext_get_dataType,
745     domtext_put_dataType,
746     domtext_get_xml,
747     domtext_transformNode,
748     domtext_selectNodes,
749     domtext_selectSingleNode,
750     domtext_get_parsed,
751     domtext_get_namespaceURI,
752     domtext_get_prefix,
753     domtext_get_baseName,
754     domtext_transformNodeToObject,
755     domtext_get_data,
756     domtext_put_data,
757     domtext_get_length,
758     domtext_substringData,
759     domtext_appendData,
760     domtext_insertData,
761     domtext_deleteData,
762     domtext_replaceData,
763     domtext_splitText
764 };
765
766 IUnknown* create_text( xmlNodePtr text )
767 {
768     domtext *This;
769
770     This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
771     if ( !This )
772         return NULL;
773
774     This->lpVtbl = &domtext_vtbl;
775     This->ref = 1;
776
777     init_xmlnode(&This->node, text, (IUnknown*)&This->lpVtbl, NULL);
778
779     return (IUnknown*) &This->lpVtbl;
780 }
781
782 #endif