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 inline xmlDocPtr get_doc( domdoc *This )
58 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
61 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument *iface, REFIID riid, void** ppvObject )
63 domdoc *This = impl_from_IXMLDOMDocument( iface );
65 TRACE("%p %p %p\n", This, debugstr_guid( riid ), ppvObject );
67 if ( IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
68 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
69 IsEqualGUID( riid, &IID_IDispatch ) ||
70 IsEqualGUID( riid, &IID_IUnknown ) )
77 IXMLDOMDocument_AddRef( iface );
83 static ULONG WINAPI domdoc_AddRef(
84 IXMLDOMDocument *iface )
86 domdoc *This = impl_from_IXMLDOMDocument( iface );
88 return InterlockedIncrement( &This->ref );
92 static ULONG WINAPI domdoc_Release(
93 IXMLDOMDocument *iface )
95 domdoc *This = impl_from_IXMLDOMDocument( iface );
100 ref = InterlockedDecrement( &This->ref );
103 IXMLDOMElement_Release( This->node );
104 HeapFree( GetProcessHeap(), 0, This );
110 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument *iface, UINT* pctinfo )
116 static HRESULT WINAPI domdoc_GetTypeInfo(
117 IXMLDOMDocument *iface,
118 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
124 static HRESULT WINAPI domdoc_GetIDsOfNames(
125 IXMLDOMDocument *iface,
137 static HRESULT WINAPI domdoc_Invoke(
138 IXMLDOMDocument *iface,
143 DISPPARAMS* pDispParams,
145 EXCEPINFO* pExcepInfo,
153 static HRESULT WINAPI domdoc_get_nodeName(
154 IXMLDOMDocument *iface,
162 static HRESULT WINAPI domdoc_get_nodeValue(
163 IXMLDOMDocument *iface,
171 static HRESULT WINAPI domdoc_put_nodeValue(
172 IXMLDOMDocument *iface,
180 static HRESULT WINAPI domdoc_get_nodeType(
181 IXMLDOMDocument *iface,
189 static HRESULT WINAPI domdoc_get_parentNode(
190 IXMLDOMDocument *iface,
191 IXMLDOMNode** parent )
198 static HRESULT WINAPI domdoc_get_childNodes(
199 IXMLDOMDocument *iface,
200 IXMLDOMNodeList** childList )
207 static HRESULT WINAPI domdoc_get_firstChild(
208 IXMLDOMDocument *iface,
209 IXMLDOMNode** firstChild )
216 static HRESULT WINAPI domdoc_get_lastChild(
217 IXMLDOMDocument *iface,
218 IXMLDOMNode** lastChild )
225 static HRESULT WINAPI domdoc_get_previousSibling(
226 IXMLDOMDocument *iface,
227 IXMLDOMNode** previousSibling )
234 static HRESULT WINAPI domdoc_get_nextSibling(
235 IXMLDOMDocument *iface,
236 IXMLDOMNode** nextSibling )
243 static HRESULT WINAPI domdoc_get_attributes(
244 IXMLDOMDocument *iface,
245 IXMLDOMNamedNodeMap** attributeMap )
252 static HRESULT WINAPI domdoc_insertBefore(
253 IXMLDOMDocument *iface,
254 IXMLDOMNode* newChild,
256 IXMLDOMNode** outNewChild )
263 static HRESULT WINAPI domdoc_replaceChild(
264 IXMLDOMDocument *iface,
265 IXMLDOMNode* newChild,
266 IXMLDOMNode* oldChild,
267 IXMLDOMNode** outOldChild)
274 static HRESULT WINAPI domdoc_removeChild(
275 IXMLDOMDocument *iface,
276 IXMLDOMNode* childNode,
277 IXMLDOMNode** oldChild)
284 static HRESULT WINAPI domdoc_appendChild(
285 IXMLDOMDocument *iface,
286 IXMLDOMNode* newChild,
287 IXMLDOMNode** outNewChild)
294 static HRESULT WINAPI domdoc_hasChildNodes(
295 IXMLDOMDocument *iface,
296 VARIANT_BOOL* hasChild)
303 static HRESULT WINAPI domdoc_get_ownerDocument(
304 IXMLDOMDocument *iface,
305 IXMLDOMDocument** DOMDocument)
312 static HRESULT WINAPI domdoc_cloneNode(
313 IXMLDOMDocument *iface,
315 IXMLDOMNode** cloneRoot)
322 static HRESULT WINAPI domdoc_get_nodeTypeString(
323 IXMLDOMDocument *iface,
331 static HRESULT WINAPI domdoc_get_text(
332 IXMLDOMDocument *iface,
340 static HRESULT WINAPI domdoc_put_text(
341 IXMLDOMDocument *iface,
349 static HRESULT WINAPI domdoc_get_specified(
350 IXMLDOMDocument *iface,
351 VARIANT_BOOL* isSpecified )
358 static HRESULT WINAPI domdoc_get_definition(
359 IXMLDOMDocument *iface,
360 IXMLDOMNode** definitionNode )
367 static HRESULT WINAPI domdoc_get_nodeTypedValue(
368 IXMLDOMDocument *iface,
369 VARIANT* typedValue )
375 static HRESULT WINAPI domdoc_put_nodeTypedValue(
376 IXMLDOMDocument *iface,
384 static HRESULT WINAPI domdoc_get_dataType(
385 IXMLDOMDocument *iface,
386 VARIANT* dataTypeName )
393 static HRESULT WINAPI domdoc_put_dataType(
394 IXMLDOMDocument *iface,
402 static HRESULT WINAPI domdoc_get_xml(
403 IXMLDOMDocument *iface,
411 static HRESULT WINAPI domdoc_transformNode(
412 IXMLDOMDocument *iface,
413 IXMLDOMNode* styleSheet,
421 static HRESULT WINAPI domdoc_selectNodes(
422 IXMLDOMDocument *iface,
424 IXMLDOMNodeList** resultList )
431 static HRESULT WINAPI domdoc_selectSingleNode(
432 IXMLDOMDocument *iface,
434 IXMLDOMNode** resultNode )
441 static HRESULT WINAPI domdoc_get_parsed(
442 IXMLDOMDocument *iface,
443 VARIANT_BOOL* isParsed )
450 static HRESULT WINAPI domdoc_get_namespaceURI(
451 IXMLDOMDocument *iface,
459 static HRESULT WINAPI domdoc_get_prefix(
460 IXMLDOMDocument *iface,
468 static HRESULT WINAPI domdoc_get_baseName(
469 IXMLDOMDocument *iface,
477 static HRESULT WINAPI domdoc_transformNodeToObject(
478 IXMLDOMDocument *iface,
479 IXMLDOMNode* stylesheet,
480 VARIANT outputObject)
487 static HRESULT WINAPI domdoc_get_doctype(
488 IXMLDOMDocument *iface,
489 IXMLDOMDocument** documentType )
496 static HRESULT WINAPI domdoc_get_implementation(
497 IXMLDOMDocument *iface,
498 IXMLDOMImplementation** impl )
504 static HRESULT WINAPI domdoc_get_documentElement(
505 IXMLDOMDocument *iface,
506 IXMLDOMElement** DOMElement )
508 domdoc *This = impl_from_IXMLDOMDocument( iface );
509 xmlDocPtr xmldoc = NULL;
510 xmlNodePtr root = NULL;
519 xmldoc = get_doc( This );
523 root = xmlDocGetRootElement( xmldoc );
527 *DOMElement = create_element( root );
533 static HRESULT WINAPI domdoc_documentElement(
534 IXMLDOMDocument *iface,
535 IXMLDOMElement* DOMElement )
542 static HRESULT WINAPI domdoc_createElement(
543 IXMLDOMDocument *iface,
545 IXMLDOMElement** element )
552 static HRESULT WINAPI domdoc_createDocumentFragment(
553 IXMLDOMDocument *iface,
554 IXMLDOMDocumentFragment** docFrag )
561 static HRESULT WINAPI domdoc_createTextNode(
562 IXMLDOMDocument *iface,
571 static HRESULT WINAPI domdoc_createComment(
572 IXMLDOMDocument *iface,
574 IXMLDOMComment** comment )
581 static HRESULT WINAPI domdoc_createCDATASection(
582 IXMLDOMDocument *iface,
584 IXMLDOMCDATASection** cdata )
591 static HRESULT WINAPI domdoc_createProcessingInstruction(
592 IXMLDOMDocument *iface,
595 IXMLDOMProcessingInstruction** pi )
602 static HRESULT WINAPI domdoc_createAttribute(
603 IXMLDOMDocument *iface,
605 IXMLDOMAttribute** attribute )
612 static HRESULT WINAPI domdoc_createEntityReference(
613 IXMLDOMDocument *iface,
615 IXMLDOMEntityReference** entityRef )
622 static HRESULT WINAPI domdoc_getElementsByTagName(
623 IXMLDOMDocument *iface,
625 IXMLDOMNodeList** resultList )
632 static HRESULT WINAPI domdoc_createNode(
633 IXMLDOMDocument *iface,
644 static HRESULT WINAPI domdoc_nodeFromID(
645 IXMLDOMDocument *iface,
653 static xmlDocPtr doparse( char *ptr, int len )
655 #ifdef HAVE_XMLREADMEMORY
657 * use xmlReadMemory if possible so we can suppress
658 * writing errors to stderr
660 return xmlReadMemory( ptr, len, NULL, NULL,
661 XML_PARSE_NOERROR | XML_PARSE_NOWARNING );
663 return xmlParseMemory( ptr, len );
667 static xmlDocPtr doread( LPWSTR filename )
669 HANDLE handle, mapping;
671 xmlDocPtr xmldoc = NULL;
674 TRACE("%s\n", debugstr_w( filename ));
676 handle = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ,
677 NULL, OPEN_EXISTING, 0, NULL );
678 if( handle == INVALID_HANDLE_VALUE )
681 len = GetFileSize( handle, NULL );
682 if( len != INVALID_FILE_SIZE || GetLastError() == NO_ERROR )
684 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
687 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, len );
690 xmldoc = doparse( ptr, len );
691 UnmapViewOfFile( ptr );
693 CloseHandle( mapping );
696 CloseHandle( handle );
702 static HRESULT WINAPI domdoc_load(
703 IXMLDOMDocument *iface,
705 VARIANT_BOOL* isSuccessful )
707 domdoc *This = impl_from_IXMLDOMDocument( iface );
708 LPWSTR filename = NULL;
711 TRACE("type %d\n", V_VT(&xmlSource) );
715 IXMLDOMNode_Release( This->node );
719 switch( V_VT(&xmlSource) )
722 filename = V_BSTR(&xmlSource);
728 xmldoc = doread( filename );
732 This->node = create_node( (xmlNodePtr) xmldoc );
735 *isSuccessful = VARIANT_FALSE;
739 *isSuccessful = VARIANT_TRUE;
744 static HRESULT WINAPI domdoc_get_readyState(
745 IXMLDOMDocument *iface,
753 static HRESULT WINAPI domdoc_get_parseError(
754 IXMLDOMDocument *iface,
755 IXMLDOMParseError** errorObj )
762 static HRESULT WINAPI domdoc_get_url(
763 IXMLDOMDocument *iface,
771 static HRESULT WINAPI domdoc_get_async(
772 IXMLDOMDocument *iface,
773 VARIANT_BOOL* isAsync )
775 domdoc *This = impl_from_IXMLDOMDocument( iface );
777 TRACE("%p <- %d\n", isAsync, This->async);
778 *isAsync = This->async;
783 static HRESULT WINAPI domdoc_put_async(
784 IXMLDOMDocument *iface,
785 VARIANT_BOOL isAsync )
787 domdoc *This = impl_from_IXMLDOMDocument( iface );
789 TRACE("%d\n", isAsync);
790 This->async = isAsync;
795 static HRESULT WINAPI domdoc_abort(
796 IXMLDOMDocument *iface )
803 BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
805 UINT len, blen = SysStringLen( bstr );
808 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
809 str = HeapAlloc( GetProcessHeap(), 0, len );
812 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
818 static HRESULT WINAPI domdoc_loadXML(
819 IXMLDOMDocument *iface,
821 VARIANT_BOOL* isSuccessful )
823 domdoc *This = impl_from_IXMLDOMDocument( iface );
828 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
832 IXMLDOMNode_Release( This->node );
839 *isSuccessful = VARIANT_FALSE;
844 if ( !bstr_to_utf8( bstrXML, &str, &len ) )
847 xmldoc = doparse( str, len );
848 HeapFree( GetProcessHeap(), 0, str );
850 This->node = create_node( (xmlNodePtr) xmldoc );
854 *isSuccessful = VARIANT_TRUE;
859 static HRESULT WINAPI domdoc_save(
860 IXMLDOMDocument *iface,
861 VARIANT destination )
867 static HRESULT WINAPI domdoc_get_validateOnParse(
868 IXMLDOMDocument *iface,
869 VARIANT_BOOL* isValidating )
876 static HRESULT WINAPI domdoc_put_validateOnParse(
877 IXMLDOMDocument *iface,
878 VARIANT_BOOL isValidating )
885 static HRESULT WINAPI domdoc_get_resolveExternals(
886 IXMLDOMDocument *iface,
887 VARIANT_BOOL* isResolving )
894 static HRESULT WINAPI domdoc_put_resolveExternals(
895 IXMLDOMDocument *iface,
896 VARIANT_BOOL isValidating )
903 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
904 IXMLDOMDocument *iface,
905 VARIANT_BOOL* isPreserving )
912 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
913 IXMLDOMDocument *iface,
914 VARIANT_BOOL isPreserving )
921 static HRESULT WINAPI domdoc_put_onReadyStateChange(
922 IXMLDOMDocument *iface,
923 VARIANT readyStateChangeSink )
930 static HRESULT WINAPI domdoc_put_onDataAvailable(
931 IXMLDOMDocument *iface,
932 VARIANT onDataAvailableSink )
938 static HRESULT WINAPI domdoc_put_onTransformNode(
939 IXMLDOMDocument *iface,
940 VARIANT onTransformNodeSink )
946 const struct IXMLDOMDocumentVtbl domdoc_vtbl =
948 domdoc_QueryInterface,
951 domdoc_GetTypeInfoCount,
953 domdoc_GetIDsOfNames,
956 domdoc_get_nodeValue,
957 domdoc_put_nodeValue,
959 domdoc_get_parentNode,
960 domdoc_get_childNodes,
961 domdoc_get_firstChild,
962 domdoc_get_lastChild,
963 domdoc_get_previousSibling,
964 domdoc_get_nextSibling,
965 domdoc_get_attributes,
970 domdoc_hasChildNodes,
971 domdoc_get_ownerDocument,
973 domdoc_get_nodeTypeString,
976 domdoc_get_specified,
977 domdoc_get_definition,
978 domdoc_get_nodeTypedValue,
979 domdoc_put_nodeTypedValue,
983 domdoc_transformNode,
985 domdoc_selectSingleNode,
987 domdoc_get_namespaceURI,
990 domdoc_transformNodeToObject,
992 domdoc_get_implementation,
993 domdoc_get_documentElement,
994 domdoc_documentElement,
995 domdoc_createElement,
996 domdoc_createDocumentFragment,
997 domdoc_createTextNode,
998 domdoc_createComment,
999 domdoc_createCDATASection,
1000 domdoc_createProcessingInstruction,
1001 domdoc_createAttribute,
1002 domdoc_createEntityReference,
1003 domdoc_getElementsByTagName,
1007 domdoc_get_readyState,
1008 domdoc_get_parseError,
1015 domdoc_get_validateOnParse,
1016 domdoc_put_validateOnParse,
1017 domdoc_get_resolveExternals,
1018 domdoc_put_resolveExternals,
1019 domdoc_get_preserveWhiteSpace,
1020 domdoc_put_preserveWhiteSpace,
1021 domdoc_put_onReadyStateChange,
1022 domdoc_put_onDataAvailable,
1023 domdoc_put_onTransformNode,
1026 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1030 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1032 return E_OUTOFMEMORY;
1034 doc->lpVtbl = &domdoc_vtbl;
1039 *ppObj = &doc->lpVtbl;
1046 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1048 MESSAGE("This program tried to use a DOMDocument object, but\n"
1049 "libxml2 support was not present at compile time.\n");