[SHELL32] Implement support for IID_IDropTarget in CDesktopFolder::GetUIObjectOf...
[reactos.git] / reactos / dll / win32 / 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 #include "precomp.h"
23
24 #ifdef HAVE_LIBXML2
25 # include <libxml/parserInternals.h>
26 #endif
27
28 #ifdef HAVE_LIBXML2
29
30 typedef struct _domtext
31 {
32 xmlnode node;
33 IXMLDOMText IXMLDOMText_iface;
34 LONG ref;
35 } domtext;
36
37 static inline domtext *impl_from_IXMLDOMText( IXMLDOMText *iface )
38 {
39 return CONTAINING_RECORD(iface, domtext, IXMLDOMText_iface);
40 }
41
42 static void domtext_reset_noenc(domtext *This)
43 {
44 This->node.node->name = NULL;
45 }
46
47 static HRESULT WINAPI domtext_QueryInterface(
48 IXMLDOMText *iface,
49 REFIID riid,
50 void** ppvObject )
51 {
52 domtext *This = impl_from_IXMLDOMText( iface );
53 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
54
55 if ( IsEqualGUID( riid, &IID_IXMLDOMText ) ||
56 IsEqualGUID( riid, &IID_IXMLDOMCharacterData) ||
57 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
58 IsEqualGUID( riid, &IID_IDispatch ) ||
59 IsEqualGUID( riid, &IID_IUnknown ) )
60 {
61 *ppvObject = iface;
62 }
63 else if(node_query_interface(&This->node, riid, ppvObject))
64 {
65 return *ppvObject ? S_OK : E_NOINTERFACE;
66 }
67 else
68 {
69 TRACE("Unsupported interface %s\n", debugstr_guid(riid));
70 *ppvObject = NULL;
71 return E_NOINTERFACE;
72 }
73
74 IXMLDOMText_AddRef(iface);
75 return S_OK;
76 }
77
78 static ULONG WINAPI domtext_AddRef(
79 IXMLDOMText *iface )
80 {
81 domtext *This = impl_from_IXMLDOMText( iface );
82 ULONG ref = InterlockedIncrement( &This->ref );
83 TRACE("(%p)->(%d)\n", This, ref);
84 return ref;
85 }
86
87 static ULONG WINAPI domtext_Release(
88 IXMLDOMText *iface )
89 {
90 domtext *This = impl_from_IXMLDOMText( iface );
91 ULONG ref = InterlockedDecrement( &This->ref );
92
93 TRACE("(%p)->(%d)\n", This, ref);
94 if ( ref == 0 )
95 {
96 destroy_xmlnode(&This->node);
97 heap_free( This );
98 }
99
100 return ref;
101 }
102
103 static HRESULT WINAPI domtext_GetTypeInfoCount(
104 IXMLDOMText *iface,
105 UINT* pctinfo )
106 {
107 domtext *This = impl_from_IXMLDOMText( iface );
108 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo);
109 }
110
111 static HRESULT WINAPI domtext_GetTypeInfo(
112 IXMLDOMText *iface,
113 UINT iTInfo, LCID lcid,
114 ITypeInfo** ppTInfo )
115 {
116 domtext *This = impl_from_IXMLDOMText( iface );
117 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface,
118 iTInfo, lcid, ppTInfo);
119 }
120
121 static HRESULT WINAPI domtext_GetIDsOfNames(
122 IXMLDOMText *iface,
123 REFIID riid, LPOLESTR* rgszNames,
124 UINT cNames, LCID lcid, DISPID* rgDispId )
125 {
126 domtext *This = impl_from_IXMLDOMText( iface );
127 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface,
128 riid, rgszNames, cNames, lcid, rgDispId);
129 }
130
131 static HRESULT WINAPI domtext_Invoke(
132 IXMLDOMText *iface,
133 DISPID dispIdMember, REFIID riid, LCID lcid,
134 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
135 EXCEPINFO* pExcepInfo, UINT* puArgErr )
136 {
137 domtext *This = impl_from_IXMLDOMText( iface );
138 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface,
139 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
140 }
141
142 static HRESULT WINAPI domtext_get_nodeName(
143 IXMLDOMText *iface,
144 BSTR* p )
145 {
146 domtext *This = impl_from_IXMLDOMText( iface );
147
148 static const WCHAR textW[] = {'#','t','e','x','t',0};
149
150 TRACE("(%p)->(%p)\n", This, p);
151
152 return return_bstr(textW, p);
153 }
154
155 static HRESULT WINAPI domtext_get_nodeValue(
156 IXMLDOMText *iface,
157 VARIANT* value )
158 {
159 domtext *This = impl_from_IXMLDOMText( iface );
160
161 TRACE("(%p)->(%p)\n", This, value);
162
163 return node_get_content(&This->node, value);
164 }
165
166 static HRESULT WINAPI domtext_put_nodeValue(
167 IXMLDOMText *iface,
168 VARIANT value)
169 {
170 domtext *This = impl_from_IXMLDOMText( iface );
171
172 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
173
174 domtext_reset_noenc(This);
175 return node_put_value(&This->node, &value);
176 }
177
178 static HRESULT WINAPI domtext_get_nodeType(
179 IXMLDOMText *iface,
180 DOMNodeType* domNodeType )
181 {
182 domtext *This = impl_from_IXMLDOMText( iface );
183
184 TRACE("(%p)->(%p)\n", This, domNodeType);
185
186 *domNodeType = NODE_TEXT;
187 return S_OK;
188 }
189
190 static HRESULT WINAPI domtext_get_parentNode(
191 IXMLDOMText *iface,
192 IXMLDOMNode** parent )
193 {
194 domtext *This = impl_from_IXMLDOMText( iface );
195
196 TRACE("(%p)->(%p)\n", This, parent);
197
198 return node_get_parent(&This->node, parent);
199 }
200
201 static HRESULT WINAPI domtext_get_childNodes(
202 IXMLDOMText *iface,
203 IXMLDOMNodeList** outList)
204 {
205 domtext *This = impl_from_IXMLDOMText( iface );
206
207 TRACE("(%p)->(%p)\n", This, outList);
208
209 return node_get_child_nodes(&This->node, outList);
210 }
211
212 static HRESULT WINAPI domtext_get_firstChild(
213 IXMLDOMText *iface,
214 IXMLDOMNode** domNode)
215 {
216 domtext *This = impl_from_IXMLDOMText( iface );
217
218 TRACE("(%p)->(%p)\n", This, domNode);
219
220 return return_null_node(domNode);
221 }
222
223 static HRESULT WINAPI domtext_get_lastChild(
224 IXMLDOMText *iface,
225 IXMLDOMNode** domNode)
226 {
227 domtext *This = impl_from_IXMLDOMText( iface );
228
229 TRACE("(%p)->(%p)\n", This, domNode);
230
231 return return_null_node(domNode);
232 }
233
234 static HRESULT WINAPI domtext_get_previousSibling(
235 IXMLDOMText *iface,
236 IXMLDOMNode** domNode)
237 {
238 domtext *This = impl_from_IXMLDOMText( iface );
239
240 TRACE("(%p)->(%p)\n", This, domNode);
241
242 return node_get_previous_sibling(&This->node, domNode);
243 }
244
245 static HRESULT WINAPI domtext_get_nextSibling(
246 IXMLDOMText *iface,
247 IXMLDOMNode** domNode)
248 {
249 domtext *This = impl_from_IXMLDOMText( iface );
250
251 TRACE("(%p)->(%p)\n", This, domNode);
252
253 return node_get_next_sibling(&This->node, domNode);
254 }
255
256 static HRESULT WINAPI domtext_get_attributes(
257 IXMLDOMText *iface,
258 IXMLDOMNamedNodeMap** attributeMap)
259 {
260 domtext *This = impl_from_IXMLDOMText( iface );
261
262 TRACE("(%p)->(%p)\n", This, attributeMap);
263
264 return return_null_ptr((void**)attributeMap);
265 }
266
267 static HRESULT WINAPI domtext_insertBefore(
268 IXMLDOMText *iface,
269 IXMLDOMNode* newNode, VARIANT refChild,
270 IXMLDOMNode** outOldNode)
271 {
272 domtext *This = impl_from_IXMLDOMText( iface );
273
274 FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode);
275
276 return node_insert_before(&This->node, newNode, &refChild, outOldNode);
277 }
278
279 static HRESULT WINAPI domtext_replaceChild(
280 IXMLDOMText *iface,
281 IXMLDOMNode* newNode,
282 IXMLDOMNode* oldNode,
283 IXMLDOMNode** outOldNode)
284 {
285 domtext *This = impl_from_IXMLDOMText( iface );
286
287 FIXME("(%p)->(%p %p %p) needs test\n", This, newNode, oldNode, outOldNode);
288
289 return node_replace_child(&This->node, newNode, oldNode, outOldNode);
290 }
291
292 static HRESULT WINAPI domtext_removeChild(
293 IXMLDOMText *iface,
294 IXMLDOMNode *child, IXMLDOMNode **oldChild)
295 {
296 domtext *This = impl_from_IXMLDOMText( iface );
297 TRACE("(%p)->(%p %p)\n", This, child, oldChild);
298 return node_remove_child(&This->node, child, oldChild);
299 }
300
301 static HRESULT WINAPI domtext_appendChild(
302 IXMLDOMText *iface,
303 IXMLDOMNode *child, IXMLDOMNode **outChild)
304 {
305 domtext *This = impl_from_IXMLDOMText( iface );
306 TRACE("(%p)->(%p %p)\n", This, child, outChild);
307 return node_append_child(&This->node, child, outChild);
308 }
309
310 static HRESULT WINAPI domtext_hasChildNodes(
311 IXMLDOMText *iface,
312 VARIANT_BOOL *ret)
313 {
314 domtext *This = impl_from_IXMLDOMText( iface );
315 TRACE("(%p)->(%p)\n", This, ret);
316 return return_var_false(ret);
317 }
318
319 static HRESULT WINAPI domtext_get_ownerDocument(
320 IXMLDOMText *iface,
321 IXMLDOMDocument **doc)
322 {
323 domtext *This = impl_from_IXMLDOMText( iface );
324 TRACE("(%p)->(%p)\n", This, doc);
325 return node_get_owner_doc(&This->node, doc);
326 }
327
328 static HRESULT WINAPI domtext_cloneNode(
329 IXMLDOMText *iface,
330 VARIANT_BOOL deep, IXMLDOMNode** outNode)
331 {
332 domtext *This = impl_from_IXMLDOMText( iface );
333 TRACE("(%p)->(%d %p)\n", This, deep, outNode);
334 return node_clone( &This->node, deep, outNode );
335 }
336
337 static HRESULT WINAPI domtext_get_nodeTypeString(
338 IXMLDOMText *iface,
339 BSTR* p)
340 {
341 domtext *This = impl_from_IXMLDOMText( iface );
342 static const WCHAR textW[] = {'t','e','x','t',0};
343
344 TRACE("(%p)->(%p)\n", This, p);
345
346 return return_bstr(textW, p);
347 }
348
349 static HRESULT WINAPI domtext_get_text(
350 IXMLDOMText *iface,
351 BSTR* p)
352 {
353 domtext *This = impl_from_IXMLDOMText( iface );
354 TRACE("(%p)->(%p)\n", This, p);
355 return node_get_text(&This->node, p);
356 }
357
358 static HRESULT WINAPI domtext_put_text(
359 IXMLDOMText *iface,
360 BSTR p)
361 {
362 domtext *This = impl_from_IXMLDOMText( iface );
363 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
364 domtext_reset_noenc(This);
365 return node_put_text( &This->node, p );
366 }
367
368 static HRESULT WINAPI domtext_get_specified(
369 IXMLDOMText *iface,
370 VARIANT_BOOL* isSpecified)
371 {
372 domtext *This = impl_from_IXMLDOMText( iface );
373 FIXME("(%p)->(%p) stub!\n", This, isSpecified);
374 *isSpecified = VARIANT_TRUE;
375 return S_OK;
376 }
377
378 static HRESULT WINAPI domtext_get_definition(
379 IXMLDOMText *iface,
380 IXMLDOMNode** definitionNode)
381 {
382 domtext *This = impl_from_IXMLDOMText( iface );
383 FIXME("(%p)->(%p)\n", This, definitionNode);
384 return E_NOTIMPL;
385 }
386
387 static HRESULT WINAPI domtext_get_nodeTypedValue(
388 IXMLDOMText *iface,
389 VARIANT* var1)
390 {
391 domtext *This = impl_from_IXMLDOMText( iface );
392 IXMLDOMNode* parent = NULL;
393 HRESULT hr;
394
395 TRACE("(%p)->(%p)\n", This, var1);
396
397 if (!var1)
398 return E_INVALIDARG;
399
400 hr = IXMLDOMText_get_parentNode(iface, &parent);
401
402 if (hr == S_OK)
403 {
404 hr = IXMLDOMNode_get_nodeTypedValue(parent, var1);
405 IXMLDOMNode_Release(parent);
406 }
407 else
408 {
409 V_VT(var1) = VT_NULL;
410 V_BSTR(var1) = NULL;
411 hr = S_FALSE;
412 }
413
414 return hr;
415 }
416
417 static HRESULT WINAPI domtext_put_nodeTypedValue(
418 IXMLDOMText *iface,
419 VARIANT value)
420 {
421 domtext *This = impl_from_IXMLDOMText( iface );
422 IXMLDOMNode* parent = NULL;
423 HRESULT hr;
424
425 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
426
427 hr = IXMLDOMText_get_parentNode(iface, &parent);
428
429 if (hr == S_OK)
430 {
431 hr = IXMLDOMNode_put_nodeTypedValue(parent, value);
432 IXMLDOMNode_Release(parent);
433 }
434 else
435 {
436 hr = S_FALSE;
437 }
438
439 return hr;
440 }
441
442 static HRESULT WINAPI domtext_get_dataType(
443 IXMLDOMText *iface,
444 VARIANT* dtName)
445 {
446 domtext *This = impl_from_IXMLDOMText( iface );
447 IXMLDOMNode* parent = NULL;
448 HRESULT hr;
449
450 TRACE("(%p)->(%p)\n", This, dtName);
451
452 if (!dtName)
453 return E_INVALIDARG;
454
455 hr = IXMLDOMText_get_parentNode(iface, &parent);
456
457 if (hr == S_OK)
458 {
459 hr = IXMLDOMNode_get_dataType(parent, dtName);
460 IXMLDOMNode_Release(parent);
461 }
462 else
463 {
464 V_VT(dtName) = VT_NULL;
465 V_BSTR(dtName) = NULL;
466 hr = S_FALSE;
467 }
468
469 return hr;
470 }
471
472 static HRESULT WINAPI domtext_put_dataType(
473 IXMLDOMText *iface,
474 BSTR dtName)
475 {
476 domtext *This = impl_from_IXMLDOMText( iface );
477 IXMLDOMNode* parent = NULL;
478 HRESULT hr;
479
480 TRACE("(%p)->(%p)\n", This, dtName);
481
482 if (!dtName)
483 return E_INVALIDARG;
484
485 hr = IXMLDOMText_get_parentNode(iface, &parent);
486
487 if (hr == S_OK)
488 {
489 hr = IXMLDOMNode_put_dataType(parent, dtName);
490 IXMLDOMNode_Release(parent);
491 }
492 else
493 {
494 hr = S_FALSE;
495 }
496
497 return hr;
498 }
499
500 static HRESULT WINAPI domtext_get_xml(
501 IXMLDOMText *iface,
502 BSTR* p)
503 {
504 domtext *This = impl_from_IXMLDOMText( iface );
505
506 TRACE("(%p)->(%p)\n", This, p);
507
508 return node_get_xml(&This->node, FALSE, p);
509 }
510
511 static HRESULT WINAPI domtext_transformNode(
512 IXMLDOMText *iface,
513 IXMLDOMNode *node, BSTR *p)
514 {
515 domtext *This = impl_from_IXMLDOMText( iface );
516 TRACE("(%p)->(%p %p)\n", This, node, p);
517 return node_transform_node(&This->node, node, p);
518 }
519
520 static HRESULT WINAPI domtext_selectNodes(
521 IXMLDOMText *iface,
522 BSTR p, IXMLDOMNodeList** outList)
523 {
524 domtext *This = impl_from_IXMLDOMText( iface );
525 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList);
526 return node_select_nodes(&This->node, p, outList);
527 }
528
529 static HRESULT WINAPI domtext_selectSingleNode(
530 IXMLDOMText *iface,
531 BSTR p, IXMLDOMNode** outNode)
532 {
533 domtext *This = impl_from_IXMLDOMText( iface );
534 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode);
535 return node_select_singlenode(&This->node, p, outNode);
536 }
537
538 static HRESULT WINAPI domtext_get_parsed(
539 IXMLDOMText *iface,
540 VARIANT_BOOL* isParsed)
541 {
542 domtext *This = impl_from_IXMLDOMText( iface );
543 FIXME("(%p)->(%p) stub!\n", This, isParsed);
544 *isParsed = VARIANT_TRUE;
545 return S_OK;
546 }
547
548 static HRESULT WINAPI domtext_get_namespaceURI(
549 IXMLDOMText *iface,
550 BSTR* p)
551 {
552 domtext *This = impl_from_IXMLDOMText( iface );
553 TRACE("(%p)->(%p)\n", This, p);
554 return node_get_namespaceURI(&This->node, p);
555 }
556
557 static HRESULT WINAPI domtext_get_prefix(
558 IXMLDOMText *iface,
559 BSTR* prefix)
560 {
561 domtext *This = impl_from_IXMLDOMText( iface );
562 TRACE("(%p)->(%p)\n", This, prefix);
563 return return_null_bstr( prefix );
564 }
565
566 static HRESULT WINAPI domtext_get_baseName(
567 IXMLDOMText *iface,
568 BSTR* name)
569 {
570 domtext *This = impl_from_IXMLDOMText( iface );
571 TRACE("(%p)->(%p)\n", This, name);
572 return return_null_bstr( name );
573 }
574
575 static HRESULT WINAPI domtext_transformNodeToObject(
576 IXMLDOMText *iface,
577 IXMLDOMNode* domNode, VARIANT var1)
578 {
579 domtext *This = impl_from_IXMLDOMText( iface );
580 FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
581 return E_NOTIMPL;
582 }
583
584 static HRESULT WINAPI domtext_get_data(
585 IXMLDOMText *iface,
586 BSTR *p)
587 {
588 domtext *This = impl_from_IXMLDOMText( iface );
589
590 if(!p)
591 return E_INVALIDARG;
592
593 *p = bstr_from_xmlChar(This->node.node->content);
594 return S_OK;
595 }
596
597 static HRESULT WINAPI domtext_put_data(
598 IXMLDOMText *iface,
599 BSTR data)
600 {
601 domtext *This = impl_from_IXMLDOMText( iface );
602 static const WCHAR rnW[] = {'\r','\n',0};
603
604 TRACE("(%p)->(%s)\n", This, debugstr_w(data));
605
606 if (data && !strcmpW(rnW, data))
607 This->node.node->name = xmlStringTextNoenc;
608 else
609 domtext_reset_noenc(This);
610 return node_set_content(&This->node, data);
611 }
612
613 static HRESULT WINAPI domtext_get_length(
614 IXMLDOMText *iface,
615 LONG *len)
616 {
617 domtext *This = impl_from_IXMLDOMText( iface );
618 HRESULT hr;
619 BSTR data;
620
621 TRACE("(%p)->(%p)\n", This, len);
622
623 if(!len)
624 return E_INVALIDARG;
625
626 hr = IXMLDOMText_get_data(iface, &data);
627 if(hr == S_OK)
628 {
629 *len = SysStringLen(data);
630 SysFreeString(data);
631 }
632
633 return hr;
634 }
635
636 static HRESULT WINAPI domtext_substringData(
637 IXMLDOMText *iface,
638 LONG offset, LONG count, BSTR *p)
639 {
640 domtext *This = impl_from_IXMLDOMText( iface );
641 HRESULT hr;
642 BSTR data;
643
644 TRACE("(%p)->(%d %d %p)\n", This, offset, count, p);
645
646 if(!p)
647 return E_INVALIDARG;
648
649 *p = NULL;
650 if(offset < 0 || count < 0)
651 return E_INVALIDARG;
652
653 if(count == 0)
654 return S_FALSE;
655
656 hr = IXMLDOMText_get_data(iface, &data);
657 if(hr == S_OK)
658 {
659 LONG len = SysStringLen(data);
660
661 if(offset < len)
662 {
663 if(offset + count > len)
664 *p = SysAllocString(&data[offset]);
665 else
666 *p = SysAllocStringLen(&data[offset], count);
667 }
668 else
669 hr = S_FALSE;
670
671 SysFreeString(data);
672 }
673
674 return hr;
675 }
676
677 static HRESULT WINAPI domtext_appendData(
678 IXMLDOMText *iface,
679 BSTR p)
680 {
681 domtext *This = impl_from_IXMLDOMText( iface );
682 HRESULT hr;
683 BSTR data;
684 LONG p_len;
685
686 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
687
688 /* Nothing to do if NULL or an Empty string passed in. */
689 if((p_len = SysStringLen(p)) == 0) return S_OK;
690
691 hr = IXMLDOMText_get_data(iface, &data);
692 if(hr == S_OK)
693 {
694 LONG len = SysStringLen(data);
695 BSTR str = SysAllocStringLen(NULL, p_len + len);
696
697 memcpy(str, data, len*sizeof(WCHAR));
698 memcpy(&str[len], p, p_len*sizeof(WCHAR));
699 str[len+p_len] = 0;
700
701 hr = IXMLDOMText_put_data(iface, str);
702
703 SysFreeString(str);
704 SysFreeString(data);
705 }
706
707 return hr;
708 }
709
710 static HRESULT WINAPI domtext_insertData(
711 IXMLDOMText *iface,
712 LONG offset, BSTR p)
713 {
714 domtext *This = impl_from_IXMLDOMText( iface );
715 HRESULT hr;
716 BSTR data;
717 LONG p_len;
718
719 TRACE("(%p)->(%d %s)\n", This, offset, debugstr_w(p));
720
721 /* If have a NULL or empty string, don't do anything. */
722 if((p_len = SysStringLen(p)) == 0)
723 return S_OK;
724
725 if(offset < 0)
726 {
727 return E_INVALIDARG;
728 }
729
730 hr = IXMLDOMText_get_data(iface, &data);
731 if(hr == S_OK)
732 {
733 LONG len = SysStringLen(data);
734 BSTR str;
735
736 if(len < offset)
737 {
738 SysFreeString(data);
739 return E_INVALIDARG;
740 }
741
742 str = SysAllocStringLen(NULL, len + p_len);
743 /* start part, supplied string and end part */
744 memcpy(str, data, offset*sizeof(WCHAR));
745 memcpy(&str[offset], p, p_len*sizeof(WCHAR));
746 memcpy(&str[offset+p_len], &data[offset], (len-offset)*sizeof(WCHAR));
747 str[len+p_len] = 0;
748
749 hr = IXMLDOMText_put_data(iface, str);
750
751 SysFreeString(str);
752 SysFreeString(data);
753 }
754
755 return hr;
756 }
757
758 static HRESULT WINAPI domtext_deleteData(
759 IXMLDOMText *iface,
760 LONG offset, LONG count)
761 {
762 HRESULT hr;
763 LONG len = -1;
764 BSTR str;
765
766 TRACE("(%p)->(%d %d)\n", iface, offset, count);
767
768 hr = IXMLDOMText_get_length(iface, &len);
769 if(hr != S_OK) return hr;
770
771 if((offset < 0) || (offset > len) || (count < 0))
772 return E_INVALIDARG;
773
774 if(len == 0) return S_OK;
775
776 /* cutting start or end */
777 if((offset == 0) || ((count + offset) >= len))
778 {
779 if(offset == 0)
780 IXMLDOMText_substringData(iface, count, len - count, &str);
781 else
782 IXMLDOMText_substringData(iface, 0, offset, &str);
783 hr = IXMLDOMText_put_data(iface, str);
784 }
785 else
786 /* cutting from the inside */
787 {
788 BSTR str_end;
789
790 IXMLDOMText_substringData(iface, 0, offset, &str);
791 IXMLDOMText_substringData(iface, offset + count, len - count, &str_end);
792
793 hr = IXMLDOMText_put_data(iface, str);
794 if(hr == S_OK)
795 hr = IXMLDOMText_appendData(iface, str_end);
796
797 SysFreeString(str_end);
798 }
799
800 SysFreeString(str);
801
802 return hr;
803 }
804
805 static HRESULT WINAPI domtext_replaceData(
806 IXMLDOMText *iface,
807 LONG offset, LONG count, BSTR p)
808 {
809 domtext *This = impl_from_IXMLDOMText( iface );
810 HRESULT hr;
811
812 TRACE("(%p)->(%d %d %s)\n", This, offset, count, debugstr_w(p));
813
814 hr = IXMLDOMText_deleteData(iface, offset, count);
815
816 if (hr == S_OK)
817 hr = IXMLDOMText_insertData(iface, offset, p);
818
819 return hr;
820 }
821
822 static HRESULT WINAPI domtext_splitText(
823 IXMLDOMText *iface,
824 LONG offset, IXMLDOMText **txtNode)
825 {
826 domtext *This = impl_from_IXMLDOMText( iface );
827 LONG length = 0;
828
829 TRACE("(%p)->(%d %p)\n", This, offset, txtNode);
830
831 if (!txtNode || offset < 0) return E_INVALIDARG;
832
833 *txtNode = NULL;
834
835 IXMLDOMText_get_length(iface, &length);
836
837 if (offset > length) return E_INVALIDARG;
838 if (offset == length) return S_FALSE;
839
840 FIXME("adjacent text nodes are not supported\n");
841
842 return E_NOTIMPL;
843 }
844
845 static const struct IXMLDOMTextVtbl domtext_vtbl =
846 {
847 domtext_QueryInterface,
848 domtext_AddRef,
849 domtext_Release,
850 domtext_GetTypeInfoCount,
851 domtext_GetTypeInfo,
852 domtext_GetIDsOfNames,
853 domtext_Invoke,
854 domtext_get_nodeName,
855 domtext_get_nodeValue,
856 domtext_put_nodeValue,
857 domtext_get_nodeType,
858 domtext_get_parentNode,
859 domtext_get_childNodes,
860 domtext_get_firstChild,
861 domtext_get_lastChild,
862 domtext_get_previousSibling,
863 domtext_get_nextSibling,
864 domtext_get_attributes,
865 domtext_insertBefore,
866 domtext_replaceChild,
867 domtext_removeChild,
868 domtext_appendChild,
869 domtext_hasChildNodes,
870 domtext_get_ownerDocument,
871 domtext_cloneNode,
872 domtext_get_nodeTypeString,
873 domtext_get_text,
874 domtext_put_text,
875 domtext_get_specified,
876 domtext_get_definition,
877 domtext_get_nodeTypedValue,
878 domtext_put_nodeTypedValue,
879 domtext_get_dataType,
880 domtext_put_dataType,
881 domtext_get_xml,
882 domtext_transformNode,
883 domtext_selectNodes,
884 domtext_selectSingleNode,
885 domtext_get_parsed,
886 domtext_get_namespaceURI,
887 domtext_get_prefix,
888 domtext_get_baseName,
889 domtext_transformNodeToObject,
890 domtext_get_data,
891 domtext_put_data,
892 domtext_get_length,
893 domtext_substringData,
894 domtext_appendData,
895 domtext_insertData,
896 domtext_deleteData,
897 domtext_replaceData,
898 domtext_splitText
899 };
900
901 static const tid_t domtext_iface_tids[] = {
902 IXMLDOMText_tid,
903 0
904 };
905
906 static dispex_static_data_t domtext_dispex = {
907 NULL,
908 IXMLDOMText_tid,
909 NULL,
910 domtext_iface_tids
911 };
912
913 IUnknown* create_text( xmlNodePtr text )
914 {
915 domtext *This;
916
917 This = heap_alloc( sizeof *This );
918 if ( !This )
919 return NULL;
920
921 This->IXMLDOMText_iface.lpVtbl = &domtext_vtbl;
922 This->ref = 1;
923
924 init_xmlnode(&This->node, text, (IXMLDOMNode*)&This->IXMLDOMText_iface, &domtext_dispex);
925
926 return (IUnknown*)&This->IXMLDOMText_iface;
927 }
928
929 #endif