Make each IXMLDOMNode interface represent one libxml2 xmlNodePtr.

This commit is contained in:
Mike McCormack 2005-08-18 10:48:13 +00:00 committed by Alexandre Julliard
parent 5b5e5086d7
commit 23f192d299
5 changed files with 188 additions and 133 deletions

View File

@ -53,6 +53,11 @@ static inline domdoc *impl_from_IXMLDOMDocument( IXMLDOMDocument *iface )
return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
}
static inline xmlDocPtr get_doc( domdoc *This )
{
return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
}
static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument *iface, REFIID riid, void** ppvObject )
{
domdoc *This = impl_from_IXMLDOMDocument( iface );
@ -503,7 +508,6 @@ static HRESULT WINAPI domdoc_get_documentElement(
domdoc *This = impl_from_IXMLDOMDocument( iface );
xmlDocPtr xmldoc = NULL;
xmlNodePtr root = NULL;
IXMLDOMElement* element;
TRACE("%p\n", This);
@ -512,7 +516,7 @@ static HRESULT WINAPI domdoc_get_documentElement(
if ( !This->node )
return S_FALSE;
xmldoc = xmldoc_from_xmlnode( This->node );
xmldoc = get_doc( This );
if ( !xmldoc )
return S_FALSE;
@ -520,12 +524,7 @@ static HRESULT WINAPI domdoc_get_documentElement(
if ( !root )
return S_FALSE;
element = create_element( root );
if ( element )
{
IXMLDOMNode_AddRef( This->node );
*DOMElement = element;
}
*DOMElement = create_element( root );
return S_OK;
}

View File

@ -52,6 +52,11 @@ static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
return (domelem *)((char*)iface - FIELD_OFFSET(domelem, lpVtbl));
}
static inline xmlNodePtr get_element( domelem *This )
{
return xmlNodePtr_from_domnode( This->node, XML_ELEMENT_NODE );
}
static HRESULT WINAPI domelem_QueryInterface(
IXMLDOMElement *iface,
REFIID riid,
@ -137,16 +142,16 @@ static HRESULT WINAPI domelem_get_nodeName(
IXMLDOMElement *iface,
BSTR* p )
{
FIXME("\n");
return E_NOTIMPL;
domelem *This = impl_from_IXMLDOMElement( iface );
return IXMLDOMNode_get_nodeName( This->node, p );
}
static HRESULT WINAPI domelem_get_nodeValue(
IXMLDOMElement *iface,
VARIANT* var1 )
{
FIXME("\n");
return E_NOTIMPL;
domelem *This = impl_from_IXMLDOMElement( iface );
return IXMLDOMNode_get_nodeValue( This->node, var1 );
}
static HRESULT WINAPI domelem_put_nodeValue(
@ -161,8 +166,8 @@ static HRESULT WINAPI domelem_get_nodeType(
IXMLDOMElement *iface,
DOMNodeType* domNodeType )
{
FIXME("\n");
return E_NOTIMPL;
domelem *This = impl_from_IXMLDOMElement( iface );
return IXMLDOMNode_get_nodeType( This->node, domNodeType );
}
static HRESULT WINAPI domelem_get_parentNode(
@ -177,8 +182,8 @@ static HRESULT WINAPI domelem_get_childNodes(
IXMLDOMElement *iface,
IXMLDOMNodeList** outList)
{
FIXME("\n");
return E_NOTIMPL;
domelem *This = impl_from_IXMLDOMElement( iface );
return IXMLDOMNode_get_childNodes( This->node, outList );
}
static HRESULT WINAPI domelem_get_firstChild(
@ -217,8 +222,8 @@ static HRESULT WINAPI domelem_get_attributes(
IXMLDOMElement *iface,
IXMLDOMNamedNodeMap** attributeMap)
{
FIXME("\n");
return E_NOTIMPL;
domelem *This = impl_from_IXMLDOMElement( iface );
return IXMLDOMNode_get_attributes( This->node, attributeMap );
}
static HRESULT WINAPI domelem_insertBefore(
@ -412,8 +417,8 @@ static HRESULT WINAPI domelem_get_baseName(
IXMLDOMElement *iface,
BSTR* p)
{
FIXME("\n");
return E_NOTIMPL;
domelem *This = impl_from_IXMLDOMElement( iface );
return IXMLDOMNode_get_baseName( This->node, p );
}
static HRESULT WINAPI domelem_transformNodeToObject(
@ -436,7 +441,7 @@ static HRESULT WINAPI domelem_get_tagName(
if ( !This->node )
return E_FAIL;
element = xmlelement_from_xmlnode( This->node );
element = get_element( This );
if ( !element )
return E_FAIL;

View File

@ -36,10 +36,12 @@ extern IXMLDOMNode *create_attribute_node( xmlAttrPtr attr );
extern IUnknown *create_xmldoc( void );
extern IXMLDOMElement *create_element( xmlNodePtr element );
extern IXMLDOMNode *create_element_node( xmlNodePtr element );
extern IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node );
extern IXMLDOMNode *create_generic_node( xmlNodePtr node );
extern IXMLDOMNodeList *create_nodelist( xmlNodePtr node );
/* data accessors */
extern xmlDocPtr xmldoc_from_xmlnode( IXMLDOMNode *iface );
extern xmlNodePtr xmlelement_from_xmlnode( IXMLDOMNode *iface );
xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type );
/* helpers */
extern xmlChar *xmlChar_from_wchar( LPWSTR str );

View File

@ -23,6 +23,7 @@
#define COBJMACROS
#include <stdarg.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
@ -41,20 +42,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
#ifdef HAVE_LIBXML2
typedef union {
xmlDocPtr doc;
xmlNodePtr node;
xmlAttrPtr attr;
xmlElementPtr element;
} libxml_node;
typedef struct _xmlnode
{
const struct IXMLDOMNodeVtbl *lpVtbl;
LONG ref;
BOOL free_me;
xmlElementType type;
libxml_node u;
xmlNodePtr node;
} xmlnode;
static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
@ -62,25 +54,18 @@ static inline xmlnode *impl_from_IXMLDOMNode( IXMLDOMNode *iface )
return (xmlnode *)((char*)iface - FIELD_OFFSET(xmlnode, lpVtbl));
}
xmlDocPtr xmldoc_from_xmlnode( IXMLDOMNode *iface )
xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type )
{
xmlnode *This;
if ( !iface )
return NULL;
This = impl_from_IXMLDOMNode( iface );
if (This->type != XML_DOCUMENT_NODE )
if ( !This->node )
return NULL;
return This->u.doc;
}
xmlNodePtr xmlelement_from_xmlnode( IXMLDOMNode *iface )
{
xmlnode *This = impl_from_IXMLDOMNode( iface );
if (This->type != XML_ELEMENT_NODE )
if ( type && This->node->type != type )
return NULL;
return This->u.node;
return This->node;
}
static HRESULT WINAPI xmlnode_QueryInterface(
@ -120,20 +105,18 @@ static ULONG WINAPI xmlnode_Release(
ref = InterlockedDecrement( &This->ref );
if ( ref == 0 )
{
if ( This->free_me )
if( This->node->type == XML_DOCUMENT_NODE )
{
switch( This->type )
{
case XML_DOCUMENT_NODE:
xmlFreeDoc( This->u.doc );
break;
case XML_ATTRIBUTE_NODE:
case XML_ELEMENT_NODE:
/* don't free these */
break;
default:
ERR("don't know how to free this element\n");
}
xmlFreeDoc( (xmlDocPtr) This->node );
}
else
{
IXMLDOMNode *root;
assert( This->node->doc );
root = This->node->doc->_private;
assert( root );
IXMLDOMNode_Release( root );
This->node->_private = NULL;
}
HeapFree( GetProcessHeap(), 0, This );
}
@ -218,33 +201,37 @@ static HRESULT WINAPI xmlnode_get_nodeValue(
VARIANT* value)
{
xmlnode *This = impl_from_IXMLDOMNode( iface );
HRESULT r = S_FALSE;
TRACE("%p %p\n", This, value);
switch ( This->type )
V_BSTR(value) = NULL;
V_VT(value) = VT_NULL;
switch ( This->node->type )
{
case XML_COMMENT_NODE:
FIXME("comment\n");
return E_FAIL;
break;
case XML_ATTRIBUTE_NODE:
V_VT(value) = VT_BSTR;
V_BSTR(value) = bstr_from_xmlChar( This->u.attr->name );
V_BSTR(value) = bstr_from_xmlChar( This->node->name );
r = S_OK;
break;
case XML_PI_NODE:
FIXME("processing instruction\n");
return E_FAIL;
case XML_TEXT_NODE:
V_VT(value) = VT_BSTR;
V_BSTR(value) = bstr_from_xmlChar( This->node->content );
r = S_OK;
break;
case XML_ELEMENT_NODE:
case XML_DOCUMENT_NODE:
default:
return E_FAIL;
/* these seem to return NULL */
break;
case XML_PI_NODE:
default:
FIXME("node %p type %d\n", This, This->node->type);
}
TRACE("%p returned %s\n", This, debugstr_w( V_BSTR(value) ) );
return S_OK;
return r;
}
static HRESULT WINAPI xmlnode_put_nodeValue(
@ -259,8 +246,16 @@ static HRESULT WINAPI xmlnode_get_nodeType(
IXMLDOMNode *iface,
DOMNodeType* type)
{
FIXME("\n");
return E_NOTIMPL;
xmlnode *This = impl_from_IXMLDOMNode( iface );
TRACE("%p %p\n", This, type);
assert( NODE_ELEMENT == XML_ELEMENT_NODE );
assert( NODE_NOTATION == XML_NOTATION_NODE );
*type = This->node->type;
return S_OK;
}
static HRESULT WINAPI xmlnode_get_parentNode(
@ -276,9 +271,17 @@ static HRESULT WINAPI xmlnode_get_childNodes(
IXMLDOMNodeList** childList)
{
xmlnode *This = impl_from_IXMLDOMNode( iface );
FIXME("%p\n", This);
TRACE("%p %p\n", This, childList );
if ( !childList )
return E_INVALIDARG;
#if 0
*childList = create_nodelist( This->node->children );
return S_OK;
#else
return E_NOTIMPL;
/*return NodeList_create( childList, This );*/
#endif
}
static HRESULT WINAPI xmlnode_get_firstChild(
@ -318,9 +321,9 @@ static HRESULT WINAPI xmlnode_get_attributes(
IXMLDOMNamedNodeMap** attributeMap)
{
xmlnode *This = impl_from_IXMLDOMNode( iface );
FIXME("%p\n", This);
return E_NOTIMPL;
/*return NodeMap_create( attributeMap, This, node ); */
TRACE("%p\n", This);
*attributeMap = create_nodemap( iface );
return S_OK;
}
static HRESULT WINAPI xmlnode_insertBefore(
@ -398,8 +401,23 @@ static HRESULT WINAPI xmlnode_get_text(
IXMLDOMNode *iface,
BSTR* text)
{
FIXME("\n");
return E_NOTIMPL;
xmlnode *This = impl_from_IXMLDOMNode( iface );
xmlNodePtr child;
BSTR str = NULL;
TRACE("%p\n", This);
if ( !text )
return E_INVALIDARG;
child = This->node->children;
if ( child && child->type == XML_TEXT_NODE )
str = bstr_from_xmlChar( child->content );
TRACE("%p %s\n", This, debugstr_w(str) );
*text = str;
return S_OK;
}
static HRESULT WINAPI xmlnode_put_text(
@ -521,8 +539,33 @@ static HRESULT WINAPI xmlnode_get_baseName(
IXMLDOMNode *iface,
BSTR* nameString)
{
FIXME("\n");
return E_NOTIMPL;
xmlnode *This = impl_from_IXMLDOMNode( iface );
BSTR str = NULL;
HRESULT r = S_FALSE;
TRACE("%p %p\n", This, nameString );
if ( !nameString )
return E_INVALIDARG;
switch ( This->node->type )
{
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
str = bstr_from_xmlChar( This->node->name );
r = S_OK;
break;
case XML_TEXT_NODE:
break;
default:
ERR("Unhandled type %d\n", This->node->type );
break;
}
TRACE("returning %08lx str = %s\n", r, debugstr_w( str ) );
*nameString = str;
return r;
}
static HRESULT WINAPI xmlnode_transformNodeToObject(
@ -581,71 +624,70 @@ static const struct IXMLDOMNodeVtbl xmlnode_vtbl =
xmlnode_transformNodeToObject,
};
static xmlnode *create_node( void )
static IXMLDOMNode *create_node( xmlNodePtr node )
{
xmlnode *This;
if ( !node )
return NULL;
assert( node->doc );
/* if an interface already exists for this node, return it */
if ( node->_private )
{
IXMLDOMNode *n = node->_private;
IXMLDOMNode_AddRef( n );
return n;
}
/*
* Try adding a reference to the IXMLDOMNode implementation
* containing the document's root element.
*/
if ( node->type != XML_DOCUMENT_NODE )
{
IXMLDOMNode *root = NULL;
root = node->doc->_private;
assert( root );
IXMLDOMNode_AddRef( root );
}
else
assert( node->doc == (xmlDocPtr) node );
This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
if ( !This )
return NULL;
This->lpVtbl = &xmlnode_vtbl;
This->ref = 1;
This->free_me = TRUE;
This->u.doc = NULL;
This->node = node;
return This;
/* remember which interface we associated with this node */
node->_private = This;
return (IXMLDOMNode*) &This->lpVtbl;
}
IXMLDOMNode *create_domdoc_node( xmlDocPtr node )
{
xmlnode *This;
if ( !node )
return NULL;
This = create_node();
if ( !This )
return NULL;
This->type = XML_DOCUMENT_NODE;
This->u.doc = node;
return (IXMLDOMNode*) &This->lpVtbl;
return create_node( (xmlNodePtr) node );
}
IXMLDOMNode *create_attribute_node( xmlAttrPtr node )
{
xmlnode *This;
if ( !node )
return NULL;
This = create_node();
if ( !This )
return NULL;
This->type = XML_ATTRIBUTE_NODE;
This->u.attr = node;
return (IXMLDOMNode*) &This->lpVtbl;
return create_node( (xmlNodePtr) node );
}
IXMLDOMNode *create_element_node( xmlNodePtr element )
{
xmlnode *This;
return create_node( element );
}
if ( !element )
return NULL;
This = create_node();
if ( !This )
return NULL;
This->type = XML_ELEMENT_NODE;
This->u.node = element;
return (IXMLDOMNode*) &This->lpVtbl;
IXMLDOMNode *create_generic_node( xmlNodePtr node )
{
return create_node( node );
}
#endif

View File

@ -45,8 +45,7 @@ typedef struct _xmlnodemap
{
const struct IXMLDOMNamedNodeMapVtbl *lpVtbl;
LONG ref;
xmlDocPtr xmldoc;
xmlNodePtr node;
IXMLDOMNode *node;
} xmlnodemap;
static inline xmlnodemap *impl_from_IXMLDOMNamedNodeMap( IXMLDOMNamedNodeMap *iface )
@ -91,6 +90,7 @@ static ULONG WINAPI xmlnodemap_Release(
ref = InterlockedDecrement( &This->ref );
if ( ref == 0 )
{
IXMLDOMNode_Release( This->node );
HeapFree( GetProcessHeap(), 0, This );
}
@ -153,16 +153,24 @@ static HRESULT WINAPI xmlnodemap_getNamedItem(
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
xmlChar *element_name;
xmlAttrPtr attr;
xmlNodePtr node;
TRACE("%p %s\n", This, debugstr_w(name) );
node = xmlNodePtr_from_domnode( This->node, 0 );
if ( !node )
return E_FAIL;
element_name = xmlChar_from_wchar( name );
attr = xmlHasNsProp( This->node, element_name, NULL );
TRACE("xmlHasNsProp returned %p for %s\n", attr, element_name );
attr = xmlHasNsProp( node, element_name, NULL );
HeapFree( GetProcessHeap(), 0, element_name );
if ( !attr )
return E_FAIL;
/* return Node_create( namedItem, This->xmldoc, attr ); */
return E_NOTIMPL;
*namedItem = create_attribute_node( attr );
return S_OK;
}
static HRESULT WINAPI xmlnodemap_setNamedItem(
@ -264,22 +272,21 @@ static const struct IXMLDOMNamedNodeMapVtbl xmlnodemap_vtbl =
xmlnodemap__newEnum,
};
HRESULT NodeMap_create( IXMLDOMNamedNodeMap** DomNamedNodeMap, xmlDocPtr xmldoc, xmlNodePtr node )
IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node )
{
xmlnodemap *nodemap;
nodemap = HeapAlloc( GetProcessHeap(), 0, sizeof *nodemap );
if ( !nodemap )
return E_OUTOFMEMORY;
return NULL;
nodemap->lpVtbl = &xmlnodemap_vtbl;
nodemap->xmldoc = xmldoc;
nodemap->node = node;
nodemap->ref = 1;
*DomNamedNodeMap = (IXMLDOMNamedNodeMap*) &nodemap->lpVtbl;
IXMLDOMNode_AddRef( node );
return S_OK;
return (IXMLDOMNamedNodeMap*) &nodemap->lpVtbl;
}
#endif