2 * DOM Document 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
35 #include "wine/debug.h"
37 #include "msxml_private.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
43 typedef struct _domdoc
45 const struct IXMLDOMDocumentVtbl *lpVtbl;
51 static inline domdoc *impl_from_IXMLDOMDocument( IXMLDOMDocument *iface )
53 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
56 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument *iface, REFIID riid, void** ppvObject )
58 domdoc *This = impl_from_IXMLDOMDocument( iface );
60 TRACE("%p %p %p\n", This, debugstr_guid( riid ), ppvObject );
62 if ( IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
63 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
64 IsEqualGUID( riid, &IID_IDispatch ) ||
65 IsEqualGUID( riid, &IID_IUnknown ) )
72 IXMLDOMDocument_AddRef( iface );
78 static ULONG WINAPI domdoc_AddRef(
79 IXMLDOMDocument *iface )
81 domdoc *This = impl_from_IXMLDOMDocument( iface );
83 return InterlockedIncrement( &This->ref );
87 static ULONG WINAPI domdoc_Release(
88 IXMLDOMDocument *iface )
90 domdoc *This = impl_from_IXMLDOMDocument( iface );
95 ref = InterlockedDecrement( &This->ref );
98 IXMLDOMElement_Release( This->node );
99 HeapFree( GetProcessHeap(), 0, This );
105 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument *iface, UINT* pctinfo )
111 static HRESULT WINAPI domdoc_GetTypeInfo(
112 IXMLDOMDocument *iface,
113 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
119 static HRESULT WINAPI domdoc_GetIDsOfNames(
120 IXMLDOMDocument *iface,
132 static HRESULT WINAPI domdoc_Invoke(
133 IXMLDOMDocument *iface,
138 DISPPARAMS* pDispParams,
140 EXCEPINFO* pExcepInfo,
148 static HRESULT WINAPI domdoc_get_nodeName(
149 IXMLDOMDocument *iface,
157 static HRESULT WINAPI domdoc_get_nodeValue(
158 IXMLDOMDocument *iface,
166 static HRESULT WINAPI domdoc_put_nodeValue(
167 IXMLDOMDocument *iface,
175 static HRESULT WINAPI domdoc_get_nodeType(
176 IXMLDOMDocument *iface,
184 static HRESULT WINAPI domdoc_get_parentNode(
185 IXMLDOMDocument *iface,
186 IXMLDOMNode** parent )
193 static HRESULT WINAPI domdoc_get_childNodes(
194 IXMLDOMDocument *iface,
195 IXMLDOMNodeList** childList )
202 static HRESULT WINAPI domdoc_get_firstChild(
203 IXMLDOMDocument *iface,
204 IXMLDOMNode** firstChild )
211 static HRESULT WINAPI domdoc_get_lastChild(
212 IXMLDOMDocument *iface,
213 IXMLDOMNode** lastChild )
220 static HRESULT WINAPI domdoc_get_previousSibling(
221 IXMLDOMDocument *iface,
222 IXMLDOMNode** previousSibling )
229 static HRESULT WINAPI domdoc_get_nextSibling(
230 IXMLDOMDocument *iface,
231 IXMLDOMNode** nextSibling )
238 static HRESULT WINAPI domdoc_get_attributes(
239 IXMLDOMDocument *iface,
240 IXMLDOMNamedNodeMap** attributeMap )
247 static HRESULT WINAPI domdoc_insertBefore(
248 IXMLDOMDocument *iface,
249 IXMLDOMNode* newChild,
251 IXMLDOMNode** outNewChild )
258 static HRESULT WINAPI domdoc_replaceChild(
259 IXMLDOMDocument *iface,
260 IXMLDOMNode* newChild,
261 IXMLDOMNode* oldChild,
262 IXMLDOMNode** outOldChild)
269 static HRESULT WINAPI domdoc_removeChild(
270 IXMLDOMDocument *iface,
271 IXMLDOMNode* childNode,
272 IXMLDOMNode** oldChild)
279 static HRESULT WINAPI domdoc_appendChild(
280 IXMLDOMDocument *iface,
281 IXMLDOMNode* newChild,
282 IXMLDOMNode** outNewChild)
289 static HRESULT WINAPI domdoc_hasChildNodes(
290 IXMLDOMDocument *iface,
291 VARIANT_BOOL* hasChild)
298 static HRESULT WINAPI domdoc_get_ownerDocument(
299 IXMLDOMDocument *iface,
300 IXMLDOMDocument** DOMDocument)
307 static HRESULT WINAPI domdoc_cloneNode(
308 IXMLDOMDocument *iface,
310 IXMLDOMNode** cloneRoot)
317 static HRESULT WINAPI domdoc_get_nodeTypeString(
318 IXMLDOMDocument *iface,
326 static HRESULT WINAPI domdoc_get_text(
327 IXMLDOMDocument *iface,
335 static HRESULT WINAPI domdoc_put_text(
336 IXMLDOMDocument *iface,
344 static HRESULT WINAPI domdoc_get_specified(
345 IXMLDOMDocument *iface,
346 VARIANT_BOOL* isSpecified )
353 static HRESULT WINAPI domdoc_get_definition(
354 IXMLDOMDocument *iface,
355 IXMLDOMNode** definitionNode )
362 static HRESULT WINAPI domdoc_get_nodeTypedValue(
363 IXMLDOMDocument *iface,
364 VARIANT* typedValue )
370 static HRESULT WINAPI domdoc_put_nodeTypedValue(
371 IXMLDOMDocument *iface,
379 static HRESULT WINAPI domdoc_get_dataType(
380 IXMLDOMDocument *iface,
381 VARIANT* dataTypeName )
388 static HRESULT WINAPI domdoc_put_dataType(
389 IXMLDOMDocument *iface,
397 static HRESULT WINAPI domdoc_get_xml(
398 IXMLDOMDocument *iface,
406 static HRESULT WINAPI domdoc_transformNode(
407 IXMLDOMDocument *iface,
408 IXMLDOMNode* styleSheet,
416 static HRESULT WINAPI domdoc_selectNodes(
417 IXMLDOMDocument *iface,
419 IXMLDOMNodeList** resultList )
426 static HRESULT WINAPI domdoc_selectSingleNode(
427 IXMLDOMDocument *iface,
429 IXMLDOMNode** resultNode )
436 static HRESULT WINAPI domdoc_get_parsed(
437 IXMLDOMDocument *iface,
438 VARIANT_BOOL* isParsed )
445 static HRESULT WINAPI domdoc_get_namespaceURI(
446 IXMLDOMDocument *iface,
454 static HRESULT WINAPI domdoc_get_prefix(
455 IXMLDOMDocument *iface,
463 static HRESULT WINAPI domdoc_get_baseName(
464 IXMLDOMDocument *iface,
472 static HRESULT WINAPI domdoc_transformNodeToObject(
473 IXMLDOMDocument *iface,
474 IXMLDOMNode* stylesheet,
475 VARIANT outputObject)
482 static HRESULT WINAPI domdoc_get_doctype(
483 IXMLDOMDocument *iface,
484 IXMLDOMDocument** documentType )
491 static HRESULT WINAPI domdoc_get_implementation(
492 IXMLDOMDocument *iface,
493 IXMLDOMImplementation** impl )
499 static HRESULT WINAPI domdoc_get_documentElement(
500 IXMLDOMDocument *iface,
501 IXMLDOMElement** DOMElement )
503 domdoc *This = impl_from_IXMLDOMDocument( iface );
504 xmlDocPtr xmldoc = NULL;
505 xmlNodePtr root = NULL;
506 IXMLDOMElement* element;
515 xmldoc = xmldoc_from_xmlnode( This->node );
519 root = xmlDocGetRootElement( xmldoc );
523 element = create_element( root );
526 IXMLDOMNode_AddRef( This->node );
527 *DOMElement = element;
534 static HRESULT WINAPI domdoc_documentElement(
535 IXMLDOMDocument *iface,
536 IXMLDOMElement* DOMElement )
543 static HRESULT WINAPI domdoc_createElement(
544 IXMLDOMDocument *iface,
546 IXMLDOMElement** element )
553 static HRESULT WINAPI domdoc_createDocumentFragment(
554 IXMLDOMDocument *iface,
555 IXMLDOMDocumentFragment** docFrag )
562 static HRESULT WINAPI domdoc_createTextNode(
563 IXMLDOMDocument *iface,
572 static HRESULT WINAPI domdoc_createComment(
573 IXMLDOMDocument *iface,
575 IXMLDOMComment** comment )
582 static HRESULT WINAPI domdoc_createCDATASection(
583 IXMLDOMDocument *iface,
585 IXMLDOMCDATASection** cdata )
592 static HRESULT WINAPI domdoc_createProcessingInstruction(
593 IXMLDOMDocument *iface,
596 IXMLDOMProcessingInstruction** pi )
603 static HRESULT WINAPI domdoc_createAttribute(
604 IXMLDOMDocument *iface,
606 IXMLDOMAttribute** attribute )
613 static HRESULT WINAPI domdoc_createEntityReference(
614 IXMLDOMDocument *iface,
616 IXMLDOMEntityReference** entityRef )
623 static HRESULT WINAPI domdoc_getElementsByTagName(
624 IXMLDOMDocument *iface,
626 IXMLDOMNodeList** resultList )
633 static HRESULT WINAPI domdoc_createNode(
634 IXMLDOMDocument *iface,
645 static HRESULT WINAPI domdoc_nodeFromID(
646 IXMLDOMDocument *iface,
654 static xmlDocPtr doparse( char *ptr, int len )
656 #ifdef HAVE_XMLREADMEMORY
658 * use xmlReadMemory if possible so we can supress
659 * writing errors to stderr
661 return xmlReadMemory( ptr, len, NULL, NULL,
662 XML_PARSE_NOERROR | XML_PARSE_NOWARNING );
664 return xmlParseMemory( ptr, len );
668 static xmlDocPtr doread( LPWSTR filename )
670 HANDLE handle, mapping;
672 xmlDocPtr xmldoc = NULL;
675 TRACE("%s\n", debugstr_w( filename ));
677 handle = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ,
678 NULL, OPEN_EXISTING, 0, NULL );
679 if( handle == INVALID_HANDLE_VALUE )
682 len = GetFileSize( handle, NULL );
683 if( len != INVALID_FILE_SIZE || GetLastError() == NO_ERROR )
685 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
688 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, len );
691 xmldoc = doparse( ptr, len );
692 UnmapViewOfFile( ptr );
694 CloseHandle( mapping );
697 CloseHandle( handle );
703 static HRESULT WINAPI domdoc_load(
704 IXMLDOMDocument *iface,
706 VARIANT_BOOL* isSuccessful )
708 domdoc *This = impl_from_IXMLDOMDocument( iface );
709 LPWSTR filename = NULL;
712 TRACE("type %d\n", V_VT(&xmlSource) );
716 IXMLDOMNode_Release( This->node );
720 switch( V_VT(&xmlSource) )
723 filename = V_BSTR(&xmlSource);
729 xmldoc = doread( filename );
733 This->node = create_domdoc_node( xmldoc );
736 *isSuccessful = VARIANT_FALSE;
740 *isSuccessful = VARIANT_TRUE;
745 static HRESULT WINAPI domdoc_get_readyState(
746 IXMLDOMDocument *iface,
754 static HRESULT WINAPI domdoc_get_parseError(
755 IXMLDOMDocument *iface,
756 IXMLDOMParseError** errorObj )
763 static HRESULT WINAPI domdoc_get_url(
764 IXMLDOMDocument *iface,
772 static HRESULT WINAPI domdoc_get_async(
773 IXMLDOMDocument *iface,
774 VARIANT_BOOL* isAsync )
776 domdoc *This = impl_from_IXMLDOMDocument( iface );
778 TRACE("%p <- %d\n", isAsync, This->async);
779 *isAsync = This->async;
784 static HRESULT WINAPI domdoc_put_async(
785 IXMLDOMDocument *iface,
786 VARIANT_BOOL isAsync )
788 domdoc *This = impl_from_IXMLDOMDocument( iface );
790 TRACE("%d\n", isAsync);
791 This->async = isAsync;
796 static HRESULT WINAPI domdoc_abort(
797 IXMLDOMDocument *iface )
804 BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
806 UINT len, blen = SysStringLen( bstr );
809 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
810 str = HeapAlloc( GetProcessHeap(), 0, len );
813 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
819 static HRESULT WINAPI domdoc_loadXML(
820 IXMLDOMDocument *iface,
822 VARIANT_BOOL* isSuccessful )
824 domdoc *This = impl_from_IXMLDOMDocument( iface );
829 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
833 IXMLDOMNode_Release( This->node );
840 *isSuccessful = VARIANT_FALSE;
845 if ( !bstr_to_utf8( bstrXML, &str, &len ) )
848 xmldoc = doparse( str, len );
849 HeapFree( GetProcessHeap(), 0, str );
851 This->node = create_domdoc_node( xmldoc );
855 *isSuccessful = VARIANT_TRUE;
860 static HRESULT WINAPI domdoc_save(
861 IXMLDOMDocument *iface,
862 VARIANT destination )
868 static HRESULT WINAPI domdoc_get_validateOnParse(
869 IXMLDOMDocument *iface,
870 VARIANT_BOOL* isValidating )
877 static HRESULT WINAPI domdoc_put_validateOnParse(
878 IXMLDOMDocument *iface,
879 VARIANT_BOOL isValidating )
886 static HRESULT WINAPI domdoc_get_resolveExternals(
887 IXMLDOMDocument *iface,
888 VARIANT_BOOL* isResolving )
895 static HRESULT WINAPI domdoc_put_resolveExternals(
896 IXMLDOMDocument *iface,
897 VARIANT_BOOL isValidating )
904 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
905 IXMLDOMDocument *iface,
906 VARIANT_BOOL* isPreserving )
913 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
914 IXMLDOMDocument *iface,
915 VARIANT_BOOL isPreserving )
922 static HRESULT WINAPI domdoc_put_onReadyStateChange(
923 IXMLDOMDocument *iface,
924 VARIANT readyStateChangeSink )
931 static HRESULT WINAPI domdoc_put_onDataAvailable(
932 IXMLDOMDocument *iface,
933 VARIANT onDataAvailableSink )
939 static HRESULT WINAPI domdoc_put_onTransformNode(
940 IXMLDOMDocument *iface,
941 VARIANT onTransformNodeSink )
947 const struct IXMLDOMDocumentVtbl domdoc_vtbl =
949 domdoc_QueryInterface,
952 domdoc_GetTypeInfoCount,
954 domdoc_GetIDsOfNames,
957 domdoc_get_nodeValue,
958 domdoc_put_nodeValue,
960 domdoc_get_parentNode,
961 domdoc_get_childNodes,
962 domdoc_get_firstChild,
963 domdoc_get_lastChild,
964 domdoc_get_previousSibling,
965 domdoc_get_nextSibling,
966 domdoc_get_attributes,
971 domdoc_hasChildNodes,
972 domdoc_get_ownerDocument,
974 domdoc_get_nodeTypeString,
977 domdoc_get_specified,
978 domdoc_get_definition,
979 domdoc_get_nodeTypedValue,
980 domdoc_put_nodeTypedValue,
984 domdoc_transformNode,
986 domdoc_selectSingleNode,
988 domdoc_get_namespaceURI,
991 domdoc_transformNodeToObject,
993 domdoc_get_implementation,
994 domdoc_get_documentElement,
995 domdoc_documentElement,
996 domdoc_createElement,
997 domdoc_createDocumentFragment,
998 domdoc_createTextNode,
999 domdoc_createComment,
1000 domdoc_createCDATASection,
1001 domdoc_createProcessingInstruction,
1002 domdoc_createAttribute,
1003 domdoc_createEntityReference,
1004 domdoc_getElementsByTagName,
1008 domdoc_get_readyState,
1009 domdoc_get_parseError,
1016 domdoc_get_validateOnParse,
1017 domdoc_put_validateOnParse,
1018 domdoc_get_resolveExternals,
1019 domdoc_put_resolveExternals,
1020 domdoc_get_preserveWhiteSpace,
1021 domdoc_put_preserveWhiteSpace,
1022 domdoc_put_onReadyStateChange,
1023 domdoc_put_onDataAvailable,
1024 domdoc_put_onTransformNode,
1027 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1031 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1033 return E_OUTOFMEMORY;
1035 doc->lpVtbl = &domdoc_vtbl;
1040 *ppObj = &doc->lpVtbl;
1047 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1049 MESSAGE("This program tried to use a DOMDocument object, but\n"
1050 "libxml2 support was not present at compile time.\n");