2 * DOM text node implementation
4 * Copyright 2006 Huw Davies
5 * Copyright 2007-2008 Alistair Leslie-Hughes
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.
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.
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
33 #include "msxml_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
41 typedef struct _domtext
43 const struct IXMLDOMTextVtbl *lpVtbl;
49 static inline domtext *impl_from_IXMLDOMText( IXMLDOMText *iface )
51 return (domtext *)((char*)iface - FIELD_OFFSET(domtext, lpVtbl));
54 static HRESULT WINAPI domtext_QueryInterface(
59 domtext *This = impl_from_IXMLDOMText( iface );
60 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
62 if ( IsEqualGUID( riid, &IID_IXMLDOMText ) ||
63 IsEqualGUID( riid, &IID_IXMLDOMCharacterData) ||
64 IsEqualGUID( riid, &IID_IDispatch ) ||
65 IsEqualGUID( riid, &IID_IUnknown ) )
69 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
71 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
75 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
79 IXMLDOMText_AddRef( iface );
84 static ULONG WINAPI domtext_AddRef(
87 domtext *This = impl_from_IXMLDOMText( iface );
88 return InterlockedIncrement( &This->ref );
91 static ULONG WINAPI domtext_Release(
94 domtext *This = impl_from_IXMLDOMText( iface );
97 ref = InterlockedDecrement( &This->ref );
100 IUnknown_Release( This->node_unk );
101 HeapFree( GetProcessHeap(), 0, This );
107 static HRESULT WINAPI domtext_GetTypeInfoCount(
111 domtext *This = impl_from_IXMLDOMText( iface );
113 TRACE("(%p)->(%p)\n", This, pctinfo);
120 static HRESULT WINAPI domtext_GetTypeInfo(
122 UINT iTInfo, LCID lcid,
123 ITypeInfo** ppTInfo )
125 domtext *This = impl_from_IXMLDOMText( iface );
128 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
130 hr = get_typeinfo(IXMLDOMText_tid, ppTInfo);
135 static HRESULT WINAPI domtext_GetIDsOfNames(
137 REFIID riid, LPOLESTR* rgszNames,
138 UINT cNames, LCID lcid, DISPID* rgDispId )
140 domtext *This = impl_from_IXMLDOMText( iface );
144 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
147 if(!rgszNames || cNames == 0 || !rgDispId)
150 hr = get_typeinfo(IXMLDOMText_tid, &typeinfo);
153 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
154 ITypeInfo_Release(typeinfo);
160 static HRESULT WINAPI domtext_Invoke(
162 DISPID dispIdMember, REFIID riid, LCID lcid,
163 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
164 EXCEPINFO* pExcepInfo, UINT* puArgErr )
166 domtext *This = impl_from_IXMLDOMText( iface );
170 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
171 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
173 hr = get_typeinfo(IXMLDOMText_tid, &typeinfo);
176 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
177 pVarResult, pExcepInfo, puArgErr);
178 ITypeInfo_Release(typeinfo);
184 static HRESULT WINAPI domtext_get_nodeName(
188 domtext *This = impl_from_IXMLDOMText( iface );
189 return IXMLDOMNode_get_nodeName( This->node, p );
192 static HRESULT WINAPI domtext_get_nodeValue(
196 domtext *This = impl_from_IXMLDOMText( iface );
197 return IXMLDOMNode_get_nodeValue( This->node, var1 );
200 static HRESULT WINAPI domtext_put_nodeValue(
204 domtext *This = impl_from_IXMLDOMText( iface );
205 return IXMLDOMNode_put_nodeValue( This->node, var1 );
208 static HRESULT WINAPI domtext_get_nodeType(
210 DOMNodeType* domNodeType )
212 domtext *This = impl_from_IXMLDOMText( iface );
213 return IXMLDOMNode_get_nodeType( This->node, domNodeType );
216 static HRESULT WINAPI domtext_get_parentNode(
218 IXMLDOMNode** parent )
220 domtext *This = impl_from_IXMLDOMText( iface );
221 return IXMLDOMNode_get_parentNode( This->node, parent );
224 static HRESULT WINAPI domtext_get_childNodes(
226 IXMLDOMNodeList** outList)
228 domtext *This = impl_from_IXMLDOMText( iface );
229 return IXMLDOMNode_get_childNodes( This->node, outList );
232 static HRESULT WINAPI domtext_get_firstChild(
234 IXMLDOMNode** domNode)
236 domtext *This = impl_from_IXMLDOMText( iface );
237 return IXMLDOMNode_get_firstChild( This->node, domNode );
240 static HRESULT WINAPI domtext_get_lastChild(
242 IXMLDOMNode** domNode)
244 domtext *This = impl_from_IXMLDOMText( iface );
245 return IXMLDOMNode_get_lastChild( This->node, domNode );
248 static HRESULT WINAPI domtext_get_previousSibling(
250 IXMLDOMNode** domNode)
252 domtext *This = impl_from_IXMLDOMText( iface );
253 return IXMLDOMNode_get_previousSibling( This->node, domNode );
256 static HRESULT WINAPI domtext_get_nextSibling(
258 IXMLDOMNode** domNode)
260 domtext *This = impl_from_IXMLDOMText( iface );
261 return IXMLDOMNode_get_nextSibling( This->node, domNode );
264 static HRESULT WINAPI domtext_get_attributes(
266 IXMLDOMNamedNodeMap** attributeMap)
268 domtext *This = impl_from_IXMLDOMText( iface );
269 return IXMLDOMNode_get_attributes( This->node, attributeMap );
272 static HRESULT WINAPI domtext_insertBefore(
274 IXMLDOMNode* newNode, VARIANT var1,
275 IXMLDOMNode** outOldNode)
277 domtext *This = impl_from_IXMLDOMText( iface );
278 return IXMLDOMNode_insertBefore( This->node, newNode, var1, outOldNode );
281 static HRESULT WINAPI domtext_replaceChild(
283 IXMLDOMNode* newNode,
284 IXMLDOMNode* oldNode,
285 IXMLDOMNode** outOldNode)
287 domtext *This = impl_from_IXMLDOMText( iface );
288 return IXMLDOMNode_replaceChild( This->node, newNode, oldNode, outOldNode );
291 static HRESULT WINAPI domtext_removeChild(
293 IXMLDOMNode* domNode, IXMLDOMNode** oldNode)
295 domtext *This = impl_from_IXMLDOMText( iface );
296 return IXMLDOMNode_removeChild( This->node, domNode, oldNode );
299 static HRESULT WINAPI domtext_appendChild(
301 IXMLDOMNode* newNode, IXMLDOMNode** outNewNode)
303 domtext *This = impl_from_IXMLDOMText( iface );
304 return IXMLDOMNode_appendChild( This->node, newNode, outNewNode );
307 static HRESULT WINAPI domtext_hasChildNodes(
311 domtext *This = impl_from_IXMLDOMText( iface );
312 return IXMLDOMNode_hasChildNodes( This->node, pbool );
315 static HRESULT WINAPI domtext_get_ownerDocument(
317 IXMLDOMDocument** domDocument)
319 domtext *This = impl_from_IXMLDOMText( iface );
320 return IXMLDOMNode_get_ownerDocument( This->node, domDocument );
323 static HRESULT WINAPI domtext_cloneNode(
325 VARIANT_BOOL pbool, IXMLDOMNode** outNode)
327 domtext *This = impl_from_IXMLDOMText( iface );
328 return IXMLDOMNode_cloneNode( This->node, pbool, outNode );
331 static HRESULT WINAPI domtext_get_nodeTypeString(
335 domtext *This = impl_from_IXMLDOMText( iface );
336 return IXMLDOMNode_get_nodeTypeString( This->node, p );
339 static HRESULT WINAPI domtext_get_text(
343 domtext *This = impl_from_IXMLDOMText( iface );
344 return IXMLDOMNode_get_text( This->node, p );
347 static HRESULT WINAPI domtext_put_text(
351 domtext *This = impl_from_IXMLDOMText( iface );
352 return IXMLDOMNode_put_text( This->node, p );
355 static HRESULT WINAPI domtext_get_specified(
359 domtext *This = impl_from_IXMLDOMText( iface );
360 return IXMLDOMNode_get_specified( This->node, pbool );
363 static HRESULT WINAPI domtext_get_definition(
365 IXMLDOMNode** domNode)
367 domtext *This = impl_from_IXMLDOMText( iface );
368 return IXMLDOMNode_get_definition( This->node, domNode );
371 static HRESULT WINAPI domtext_get_nodeTypedValue(
375 domtext *This = impl_from_IXMLDOMText( iface );
376 return IXMLDOMNode_get_nodeTypedValue( This->node, var1 );
379 static HRESULT WINAPI domtext_put_nodeTypedValue(
383 domtext *This = impl_from_IXMLDOMText( iface );
384 return IXMLDOMNode_put_nodeTypedValue( This->node, var1 );
387 static HRESULT WINAPI domtext_get_dataType(
391 domtext *This = impl_from_IXMLDOMText( iface );
392 return IXMLDOMNode_get_dataType( This->node, var1 );
395 static HRESULT WINAPI domtext_put_dataType(
399 domtext *This = impl_from_IXMLDOMText( iface );
400 return IXMLDOMNode_put_dataType( This->node, p );
403 static HRESULT WINAPI domtext_get_xml(
407 domtext *This = impl_from_IXMLDOMText( iface );
408 return IXMLDOMNode_get_xml( This->node, p );
411 static HRESULT WINAPI domtext_transformNode(
413 IXMLDOMNode* domNode, BSTR* p)
415 domtext *This = impl_from_IXMLDOMText( iface );
416 return IXMLDOMNode_transformNode( This->node, domNode, p );
419 static HRESULT WINAPI domtext_selectNodes(
421 BSTR p, IXMLDOMNodeList** outList)
423 domtext *This = impl_from_IXMLDOMText( iface );
424 return IXMLDOMNode_selectNodes( This->node, p, outList );
427 static HRESULT WINAPI domtext_selectSingleNode(
429 BSTR p, IXMLDOMNode** outNode)
431 domtext *This = impl_from_IXMLDOMText( iface );
432 return IXMLDOMNode_selectSingleNode( This->node, p, outNode );
435 static HRESULT WINAPI domtext_get_parsed(
439 domtext *This = impl_from_IXMLDOMText( iface );
440 return IXMLDOMNode_get_parsed( This->node, pbool );
443 static HRESULT WINAPI domtext_get_namespaceURI(
447 domtext *This = impl_from_IXMLDOMText( iface );
448 return IXMLDOMNode_get_namespaceURI( This->node, p );
451 static HRESULT WINAPI domtext_get_prefix(
455 domtext *This = impl_from_IXMLDOMText( iface );
456 return IXMLDOMNode_get_prefix( This->node, p );
459 static HRESULT WINAPI domtext_get_baseName(
463 domtext *This = impl_from_IXMLDOMText( iface );
464 return IXMLDOMNode_get_baseName( This->node, p );
467 static HRESULT WINAPI domtext_transformNodeToObject(
469 IXMLDOMNode* domNode, VARIANT var1)
471 domtext *This = impl_from_IXMLDOMText( iface );
472 return IXMLDOMNode_transformNodeToObject( This->node, domNode, var1 );
475 static HRESULT WINAPI domtext_get_data(
479 domtext *This = impl_from_IXMLDOMText( iface );
486 hr = IXMLDOMNode_get_nodeValue( This->node, &vRet );
495 static HRESULT WINAPI domtext_put_data(
499 domtext *This = impl_from_IXMLDOMText( iface );
503 TRACE("%p %s\n", This, debugstr_w(data) );
505 V_VT(&val) = VT_BSTR;
508 hr = IXMLDOMNode_put_nodeValue( This->node, val );
513 static HRESULT WINAPI domtext_get_length(
517 domtext *This = impl_from_IXMLDOMText( iface );
518 xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node );
522 TRACE("%p\n", iface);
527 pContent = xmlNodeGetContent(pDOMNode->node);
530 nLength = xmlStrlen(pContent);
539 static HRESULT WINAPI domtext_substringData(
541 long offset, long count, BSTR *p)
543 domtext *This = impl_from_IXMLDOMText( iface );
544 xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node );
547 HRESULT hr = S_FALSE;
549 TRACE("%p\n", iface);
555 if(offset < 0 || count < 0)
561 pContent = xmlNodeGetContent(pDOMNode->node);
564 nLength = xmlStrlen(pContent);
566 if( offset < nLength)
568 BSTR sContent = bstr_from_xmlChar(pContent);
569 if(offset + count > nLength)
570 *p = SysAllocString(&sContent[offset]);
572 *p = SysAllocStringLen(&sContent[offset], count);
574 SysFreeString(sContent);
584 static HRESULT WINAPI domtext_appendData(
588 domtext *This = impl_from_IXMLDOMText( iface );
589 xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node );
591 HRESULT hr = S_FALSE;
593 TRACE("%p\n", iface);
595 /* Nothing to do if NULL or an Empty string passed in. */
596 if(p == NULL || SysStringLen(p) == 0)
599 pContent = xmlChar_from_wchar( (WCHAR*)p );
602 if(xmlTextConcat(pDOMNode->node, pContent, SysStringLen(p) ) == 0)
613 static HRESULT WINAPI domtext_insertData(
617 domtext *This = impl_from_IXMLDOMText( iface );
618 xmlnode *pDOMNode = impl_from_IXMLDOMNode( This->node );
619 xmlChar *pXmlContent;
621 HRESULT hr = S_FALSE;
622 long nLength = 0, nLengthP = 0;
627 /* If have a NULL or empty string, don't do anything. */
628 if(SysStringLen(p) == 0)
636 pXmlContent = xmlNodeGetContent(pDOMNode->node);
639 BSTR sContent = bstr_from_xmlChar( pXmlContent );
640 nLength = SysStringLen(sContent);
641 nLengthP = SysStringLen(p);
645 SysFreeString(sContent);
646 xmlFree(pXmlContent);
651 sNewString = SysAllocStringLen(NULL, nLength + nLengthP + 1);
655 memcpy(sNewString, sContent, offset * sizeof(WCHAR));
657 memcpy(&sNewString[offset], p, nLengthP * sizeof(WCHAR));
659 if(offset+nLengthP < nLength)
660 memcpy(&sNewString[offset+nLengthP], &sContent[offset], (nLength-offset) * sizeof(WCHAR));
662 sNewString[nLengthP + nLength] = 0;
664 str = xmlChar_from_wchar((WCHAR*)sNewString);
667 xmlNodeSetContent(pDOMNode->node, str);
671 SysFreeString(sNewString);
674 SysFreeString(sContent);
676 xmlFree(pXmlContent);
682 static HRESULT WINAPI domtext_deleteData(
684 long offset, long count)
690 static HRESULT WINAPI domtext_replaceData(
692 long offset, long count, BSTR p)
698 static HRESULT WINAPI domtext_splitText(
700 long offset, IXMLDOMText **txtNode)
707 static const struct IXMLDOMTextVtbl domtext_vtbl =
709 domtext_QueryInterface,
712 domtext_GetTypeInfoCount,
714 domtext_GetIDsOfNames,
716 domtext_get_nodeName,
717 domtext_get_nodeValue,
718 domtext_put_nodeValue,
719 domtext_get_nodeType,
720 domtext_get_parentNode,
721 domtext_get_childNodes,
722 domtext_get_firstChild,
723 domtext_get_lastChild,
724 domtext_get_previousSibling,
725 domtext_get_nextSibling,
726 domtext_get_attributes,
727 domtext_insertBefore,
728 domtext_replaceChild,
731 domtext_hasChildNodes,
732 domtext_get_ownerDocument,
734 domtext_get_nodeTypeString,
737 domtext_get_specified,
738 domtext_get_definition,
739 domtext_get_nodeTypedValue,
740 domtext_put_nodeTypedValue,
741 domtext_get_dataType,
742 domtext_put_dataType,
744 domtext_transformNode,
746 domtext_selectSingleNode,
748 domtext_get_namespaceURI,
750 domtext_get_baseName,
751 domtext_transformNodeToObject,
755 domtext_substringData,
763 IUnknown* create_text( xmlNodePtr text )
768 This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
772 This->lpVtbl = &domtext_vtbl;
775 This->node_unk = create_basic_node( text, (IUnknown*)&This->lpVtbl );
778 HeapFree(GetProcessHeap(), 0, This);
782 hr = IUnknown_QueryInterface(This->node_unk, &IID_IXMLDOMNode, (LPVOID*)&This->node);
785 IUnknown_Release(This->node_unk);
786 HeapFree( GetProcessHeap(), 0, This );
789 /* The ref on This->node is actually looped back into this object, so release it */
790 IXMLDOMNode_Release(This->node);
792 return (IUnknown*) &This->lpVtbl;