Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
cb9d787b
Commit
cb9d787b
authored
Feb 25, 2013
by
Nikolay Sivov
Committed by
Alexandre Julliard
Feb 27, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msxml3: Better handle cross-tree node moves.
parent
91cec0e8
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
91 additions
and
10 deletions
+91
-10
domdoc.c
dlls/msxml3/domdoc.c
+19
-5
msxml_private.h
dlls/msxml3/msxml_private.h
+2
-0
node.c
dlls/msxml3/node.c
+70
-5
No files found.
dlls/msxml3/domdoc.c
View file @
cb9d787b
...
...
@@ -553,19 +553,28 @@ void xmldoc_init(xmlDocPtr doc, MSXML_VERSION version)
priv_from_xmlDocPtr
(
doc
)
->
properties
=
create_properties
(
version
);
}
LONG
xmldoc_add_ref
(
xmlDocPtr
doc
)
LONG
xmldoc_add_ref
s
(
xmlDocPtr
doc
,
LONG
refs
)
{
LONG
ref
=
Interlocked
Increment
(
&
priv_from_xmlDocPtr
(
doc
)
->
refs
)
;
LONG
ref
=
Interlocked
ExchangeAdd
(
&
priv_from_xmlDocPtr
(
doc
)
->
refs
,
refs
)
+
refs
;
TRACE
(
"(%p)->(%d)
\n
"
,
doc
,
ref
);
return
ref
;
}
LONG
xmldoc_release
(
xmlDocPtr
doc
)
LONG
xmldoc_add_ref
(
xmlDocPtr
doc
)
{
return
xmldoc_add_refs
(
doc
,
1
);
}
LONG
xmldoc_release_refs
(
xmlDocPtr
doc
,
LONG
refs
)
{
xmldoc_priv
*
priv
=
priv_from_xmlDocPtr
(
doc
);
LONG
ref
=
Interlocked
Decrement
(
&
priv
->
refs
)
;
LONG
ref
=
Interlocked
ExchangeAdd
(
&
priv
->
refs
,
-
refs
)
-
refs
;
TRACE
(
"(%p)->(%d)
\n
"
,
doc
,
ref
);
if
(
ref
==
0
)
if
(
ref
<
0
)
WARN
(
"negative refcount, expect troubles
\n
"
);
if
(
ref
==
0
)
{
orphan_entry
*
orphan
,
*
orphan2
;
TRACE
(
"freeing docptr %p
\n
"
,
doc
);
...
...
@@ -584,6 +593,11 @@ LONG xmldoc_release(xmlDocPtr doc)
return
ref
;
}
LONG
xmldoc_release
(
xmlDocPtr
doc
)
{
return
xmldoc_release_refs
(
doc
,
1
);
}
HRESULT
xmldoc_add_orphan
(
xmlDocPtr
doc
,
xmlNodePtr
node
)
{
xmldoc_priv
*
priv
=
priv_from_xmlDocPtr
(
doc
);
...
...
dlls/msxml3/msxml_private.h
View file @
cb9d787b
...
...
@@ -292,6 +292,8 @@ extern xmlChar *xmlChar_from_wchar( LPCWSTR str ) DECLSPEC_HIDDEN;
extern
void
xmldoc_init
(
xmlDocPtr
doc
,
MSXML_VERSION
version
)
DECLSPEC_HIDDEN
;
extern
LONG
xmldoc_add_ref
(
xmlDocPtr
doc
)
DECLSPEC_HIDDEN
;
extern
LONG
xmldoc_release
(
xmlDocPtr
doc
)
DECLSPEC_HIDDEN
;
extern
LONG
xmldoc_add_refs
(
xmlDocPtr
doc
,
LONG
refs
)
DECLSPEC_HIDDEN
;
extern
LONG
xmldoc_release_refs
(
xmlDocPtr
doc
,
LONG
refs
)
DECLSPEC_HIDDEN
;
extern
HRESULT
xmldoc_add_orphan
(
xmlDocPtr
doc
,
xmlNodePtr
node
)
DECLSPEC_HIDDEN
;
extern
HRESULT
xmldoc_remove_orphan
(
xmlDocPtr
doc
,
xmlNodePtr
node
)
DECLSPEC_HIDDEN
;
extern
void
xmldoc_link_xmldecl
(
xmlDocPtr
doc
,
xmlNodePtr
node
)
DECLSPEC_HIDDEN
;
...
...
dlls/msxml3/node.c
View file @
cb9d787b
...
...
@@ -374,11 +374,45 @@ HRESULT node_get_next_sibling(xmlnode *This, IXMLDOMNode **ret)
return
get_node
(
This
,
"next"
,
This
->
node
->
next
,
ret
);
}
static
int
node_get_inst_cnt
(
xmlNodePtr
node
)
{
int
ret
=
*
(
LONG
*
)
&
node
->
_private
;
xmlNodePtr
child
;
/* add attribute counts */
if
(
node
->
type
==
XML_ELEMENT_NODE
)
{
xmlAttrPtr
prop
=
node
->
properties
;
while
(
prop
)
{
ret
+=
node_get_inst_cnt
((
xmlNodePtr
)
prop
);
prop
=
prop
->
next
;
}
}
/* add children counts */
child
=
node
->
children
;
while
(
child
)
{
ret
+=
node_get_inst_cnt
(
child
);
child
=
child
->
next
;
}
return
ret
;
}
static
int
xmlnode_get_inst_cnt
(
xmlnode
*
node
)
{
return
node_get_inst_cnt
(
node
->
node
);
}
HRESULT
node_insert_before
(
xmlnode
*
This
,
IXMLDOMNode
*
new_child
,
const
VARIANT
*
ref_child
,
IXMLDOMNode
**
ret
)
{
IXMLDOMNode
*
before
=
NULL
;
xmlnode
*
node_obj
;
int
refcount
=
0
;
xmlDocPtr
doc
;
HRESULT
hr
;
...
...
@@ -414,6 +448,8 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
if
(
xmldoc_remove_orphan
(
node_obj
->
node
->
doc
,
node_obj
->
node
)
!=
S_OK
)
WARN
(
"%p is not an orphan of %p
\n
"
,
node_obj
->
node
,
node_obj
->
node
->
doc
);
refcount
=
xmlnode_get_inst_cnt
(
node_obj
);
if
(
before
)
{
xmlnode
*
before_node_obj
=
get_node_obj
(
before
);
...
...
@@ -426,10 +462,16 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
hr
=
IXMLDOMNode_removeChild
(
node_obj
->
parent
,
node_obj
->
iface
,
NULL
);
if
(
hr
==
S_OK
)
xmldoc_remove_orphan
(
node_obj
->
node
->
doc
,
node_obj
->
node
);
}
doc
=
node_obj
->
node
->
doc
;
xmldoc_add_ref
(
before_node_obj
->
node
->
doc
);
/* refs count including subtree */
if
(
doc
!=
before_node_obj
->
node
->
doc
)
refcount
=
xmlnode_get_inst_cnt
(
node_obj
);
if
(
refcount
)
xmldoc_add_refs
(
before_node_obj
->
node
->
doc
,
refcount
);
xmlAddPrevSibling
(
before_node_obj
->
node
,
node_obj
->
node
);
xmldoc_release
(
doc
);
if
(
refcount
)
xmldoc_release_refs
(
doc
,
refcount
);
node_obj
->
parent
=
This
->
parent
;
}
else
...
...
@@ -441,11 +483,15 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
if
(
hr
==
S_OK
)
xmldoc_remove_orphan
(
node_obj
->
node
->
doc
,
node_obj
->
node
);
}
doc
=
node_obj
->
node
->
doc
;
xmldoc_add_ref
(
This
->
node
->
doc
);
if
(
doc
!=
This
->
node
->
doc
)
refcount
=
xmlnode_get_inst_cnt
(
node_obj
);
if
(
refcount
)
xmldoc_add_refs
(
This
->
node
->
doc
,
refcount
);
/* xmlAddChild doesn't unlink node from previous parent */
xmlUnlinkNode
(
node_obj
->
node
);
xmlAddChild
(
This
->
node
,
node_obj
->
node
);
xmldoc_release
(
doc
);
if
(
refcount
)
xmldoc_release_refs
(
doc
,
refcount
);
node_obj
->
parent
=
This
->
iface
;
}
...
...
@@ -1017,17 +1063,36 @@ HRESULT node_get_base_name(xmlnode *This, BSTR *name)
return
S_OK
;
}
/* _private field holds a number of COM instances spawned from this libxml2 node */
static
void
xmlnode_add_ref
(
xmlNodePtr
node
)
{
if
(
node
->
type
==
XML_DOCUMENT_NODE
)
return
;
InterlockedIncrement
((
LONG
*
)
&
node
->
_private
);
}
static
void
xmlnode_release
(
xmlNodePtr
node
)
{
if
(
node
->
type
==
XML_DOCUMENT_NODE
)
return
;
InterlockedDecrement
((
LONG
*
)
&
node
->
_private
);
}
void
destroy_xmlnode
(
xmlnode
*
This
)
{
if
(
This
->
node
)
{
xmlnode_release
(
This
->
node
);
xmldoc_release
(
This
->
node
->
doc
);
}
release_dispex
(
&
This
->
dispex
);
}
void
init_xmlnode
(
xmlnode
*
This
,
xmlNodePtr
node
,
IXMLDOMNode
*
node_iface
,
dispex_static_data_t
*
dispex_data
)
{
if
(
node
)
xmldoc_add_ref
(
node
->
doc
);
{
xmlnode_add_ref
(
node
);
xmldoc_add_ref
(
node
->
doc
);
}
This
->
node
=
node
;
This
->
iface
=
node_iface
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment