mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
[MSXML3] Sync with Wine Staging 1.9.4. CORE-10912
svn path=/trunk/; revision=70885
This commit is contained in:
parent
565ee09080
commit
ce187684eb
5 changed files with 169 additions and 65 deletions
|
@ -428,7 +428,14 @@ static void sax_characters(void *ctx, const xmlChar *ch, int len)
|
|||
(!ctxt->node->last ||
|
||||
((ctxt->node->last && (cur == '<' || ctxt->node->last->type != XML_TEXT_NODE))
|
||||
)))
|
||||
{
|
||||
/* Keep information about ignorable whitespace text node in previous or parent node */
|
||||
if (ctxt->node->last)
|
||||
*(DWORD*)&ctxt->node->last->_private |= NODE_PRIV_TRAILING_IGNORABLE_WS;
|
||||
else if (ctxt->node->type != XML_DOCUMENT_NODE)
|
||||
*(DWORD*)&ctxt->node->_private |= NODE_PRIV_CHILD_IGNORABLE_WS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xmlSAX2Characters(ctxt, ch, len);
|
||||
|
@ -1217,8 +1224,31 @@ static HRESULT WINAPI domdoc_cloneNode(
|
|||
IXMLDOMNode** outNode)
|
||||
{
|
||||
domdoc *This = impl_from_IXMLDOMDocument3( iface );
|
||||
xmlNodePtr clone;
|
||||
|
||||
TRACE("(%p)->(%d %p)\n", This, deep, outNode);
|
||||
return node_clone( &This->node, deep, outNode );
|
||||
|
||||
if (!outNode)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*outNode = NULL;
|
||||
|
||||
clone = xmlCopyNode((xmlNodePtr)get_doc(This), deep ? 1 : 2);
|
||||
if (!clone)
|
||||
return E_FAIL;
|
||||
|
||||
clone->doc->_private = create_priv();
|
||||
xmldoc_add_orphan(clone->doc, clone);
|
||||
xmldoc_add_ref(clone->doc);
|
||||
|
||||
priv_from_xmlDocPtr(clone->doc)->properties = copy_properties(This->properties);
|
||||
if (!(*outNode = (IXMLDOMNode*)create_domdoc(clone)))
|
||||
{
|
||||
xmldoc_release(clone->doc);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3613,16 +3643,16 @@ HRESULT DOMDocument_create(MSXML_VERSION version, void **ppObj)
|
|||
|
||||
IUnknown* create_domdoc( xmlNodePtr document )
|
||||
{
|
||||
void* pObj = NULL;
|
||||
IUnknown *obj = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)\n", document);
|
||||
|
||||
hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
|
||||
hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&obj);
|
||||
if (FAILED(hr))
|
||||
return NULL;
|
||||
|
||||
return pObj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
@ -152,6 +152,19 @@ static void free_response_headers(httprequest *This)
|
|||
This->raw_respheaders = NULL;
|
||||
}
|
||||
|
||||
static void free_request_headers(httprequest *This)
|
||||
{
|
||||
struct httpheader *header, *header2;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(header, header2, &This->reqheaders, struct httpheader, entry)
|
||||
{
|
||||
list_remove(&header->entry);
|
||||
SysFreeString(header->header);
|
||||
SysFreeString(header->value);
|
||||
heap_free(header);
|
||||
}
|
||||
}
|
||||
|
||||
struct BindStatusCallback
|
||||
{
|
||||
IBindStatusCallback IBindStatusCallback_iface;
|
||||
|
@ -864,6 +877,7 @@ static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url,
|
|||
SysFreeString(This->user);
|
||||
SysFreeString(This->password);
|
||||
This->user = This->password = NULL;
|
||||
free_request_headers(This);
|
||||
|
||||
if (!strcmpiW(method, MethodGetW))
|
||||
{
|
||||
|
@ -1249,8 +1263,6 @@ static HRESULT httprequest_put_onreadystatechange(httprequest *This, IDispatch *
|
|||
|
||||
static void httprequest_release(httprequest *This)
|
||||
{
|
||||
struct httpheader *header, *header2;
|
||||
|
||||
if (This->site)
|
||||
IUnknown_Release( This->site );
|
||||
if (This->uri)
|
||||
|
@ -1262,15 +1274,8 @@ static void httprequest_release(httprequest *This)
|
|||
SysFreeString(This->user);
|
||||
SysFreeString(This->password);
|
||||
|
||||
/* request headers */
|
||||
LIST_FOR_EACH_ENTRY_SAFE(header, header2, &This->reqheaders, struct httpheader, entry)
|
||||
{
|
||||
list_remove(&header->entry);
|
||||
SysFreeString(header->header);
|
||||
SysFreeString(header->value);
|
||||
heap_free(header);
|
||||
}
|
||||
/* response headers */
|
||||
/* cleanup headers lists */
|
||||
free_request_headers(This);
|
||||
free_response_headers(This);
|
||||
SysFreeString(This->status_text);
|
||||
|
||||
|
|
|
@ -559,4 +559,7 @@ HRESULT detach_bsc(bsc_t*) DECLSPEC_HIDDEN;
|
|||
/* ... */
|
||||
#define E_XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020
|
||||
|
||||
#define NODE_PRIV_TRAILING_IGNORABLE_WS 0x40000000
|
||||
#define NODE_PRIV_CHILD_IGNORABLE_WS 0x80000000
|
||||
#define NODE_PRIV_REFCOUNT_MASK ~(NODE_PRIV_TRAILING_IGNORABLE_WS|NODE_PRIV_CHILD_IGNORABLE_WS)
|
||||
#endif /* __MSXML_PRIVATE__ */
|
||||
|
|
|
@ -379,7 +379,7 @@ HRESULT node_get_next_sibling(xmlnode *This, IXMLDOMNode **ret)
|
|||
|
||||
static int node_get_inst_cnt(xmlNodePtr node)
|
||||
{
|
||||
int ret = *(LONG *)&node->_private;
|
||||
int ret = *(LONG *)&node->_private & NODE_PRIV_REFCOUNT_MASK;
|
||||
xmlNodePtr child;
|
||||
|
||||
/* add attribute counts */
|
||||
|
@ -410,6 +410,20 @@ int xmlnode_get_inst_cnt(xmlnode *node)
|
|||
return node_get_inst_cnt(node->node);
|
||||
}
|
||||
|
||||
/* _private field holds a number of COM instances spawned from this libxml2 node
|
||||
* most significant bits are used to store information about ignorrable whitespace nodes */
|
||||
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);
|
||||
}
|
||||
|
||||
HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT *ref_child,
|
||||
IXMLDOMNode **ret)
|
||||
{
|
||||
|
@ -470,6 +484,7 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
|
|||
|
||||
if(before)
|
||||
{
|
||||
xmlNodePtr new_node;
|
||||
xmlnode *before_node_obj = get_node_obj(before);
|
||||
|
||||
/* refs count including subtree */
|
||||
|
@ -477,19 +492,35 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
|
|||
refcount = xmlnode_get_inst_cnt(node_obj);
|
||||
|
||||
if (refcount) xmldoc_add_refs(before_node_obj->node->doc, refcount);
|
||||
node_obj->node = xmlAddPrevSibling(before_node_obj->node, node_obj->node);
|
||||
new_node = xmlAddPrevSibling(before_node_obj->node, node_obj->node);
|
||||
if (new_node != node_obj->node)
|
||||
{
|
||||
if (refcount != 1)
|
||||
FIXME("referenced xmlNode was freed, expect crashes\n");
|
||||
xmlnode_add_ref(new_node);
|
||||
node_obj->node = new_node;
|
||||
}
|
||||
if (refcount) xmldoc_release_refs(doc, refcount);
|
||||
node_obj->parent = This->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlNodePtr new_node;
|
||||
|
||||
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);
|
||||
node_obj->node = xmlAddChild(This->node, node_obj->node);
|
||||
new_node = xmlAddChild(This->node, node_obj->node);
|
||||
if (new_node != node_obj->node)
|
||||
{
|
||||
if (refcount != 1)
|
||||
FIXME("referenced xmlNode was freed, expect crashes\n");
|
||||
xmlnode_add_ref(new_node);
|
||||
node_obj->node = new_node;
|
||||
}
|
||||
if (refcount) xmldoc_release_refs(doc, refcount);
|
||||
node_obj->parent = This->iface;
|
||||
}
|
||||
|
@ -673,48 +704,63 @@ HRESULT node_clone(xmlnode *This, VARIANT_BOOL deep, IXMLDOMNode **cloneNode)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static inline xmlChar* trim_whitespace(xmlChar* str)
|
||||
{
|
||||
xmlChar* ret = str;
|
||||
int len;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
while (*ret && isspace(*ret))
|
||||
++ret;
|
||||
len = xmlStrlen(ret);
|
||||
if (len)
|
||||
while (isspace(ret[len-1])) --len;
|
||||
|
||||
ret = xmlStrndup(ret, len);
|
||||
xmlFree(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static xmlChar* do_get_text(xmlNodePtr node)
|
||||
static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, DWORD *first, DWORD *last, BOOL *trail_ig_ws)
|
||||
{
|
||||
xmlNodePtr child;
|
||||
xmlChar* str;
|
||||
BOOL preserving = is_preserving_whitespace(node);
|
||||
|
||||
*first = -1;
|
||||
*last = 0;
|
||||
|
||||
if (!node->children)
|
||||
{
|
||||
str = xmlNodeGetContent(node);
|
||||
*trail_ig_ws = *(DWORD*)&node->_private & NODE_PRIV_CHILD_IGNORABLE_WS;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlElementType prev_type = XML_TEXT_NODE;
|
||||
BOOL ig_ws = FALSE;
|
||||
xmlChar* tmp;
|
||||
DWORD pos = 0;
|
||||
str = xmlStrdup(BAD_CAST "");
|
||||
|
||||
if (node->type != XML_DOCUMENT_NODE)
|
||||
ig_ws = *(DWORD*)&node->_private & NODE_PRIV_CHILD_IGNORABLE_WS;
|
||||
*trail_ig_ws = FALSE;
|
||||
|
||||
for (child = node->children; child != NULL; child = child->next)
|
||||
{
|
||||
switch (child->type)
|
||||
{
|
||||
case XML_ELEMENT_NODE:
|
||||
tmp = do_get_text(child);
|
||||
case XML_ELEMENT_NODE: {
|
||||
DWORD node_first, node_last;
|
||||
|
||||
tmp = do_get_text(child, FALSE, &node_first, &node_last, trail_ig_ws);
|
||||
|
||||
if (node_first!=-1 && pos+node_first<*first)
|
||||
*first = pos+node_first;
|
||||
if (node_last && pos+node_last>*last)
|
||||
*last = pos+node_last;
|
||||
break;
|
||||
}
|
||||
case XML_TEXT_NODE:
|
||||
tmp = xmlNodeGetContent(child);
|
||||
if (!preserving && tmp[0])
|
||||
{
|
||||
xmlChar *beg;
|
||||
|
||||
for (beg = tmp; *beg; beg++)
|
||||
if (!isspace(*beg)) break;
|
||||
|
||||
if (!*beg)
|
||||
{
|
||||
ig_ws = TRUE;
|
||||
xmlFree(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
case XML_ENTITY_REF_NODE:
|
||||
case XML_ENTITY_NODE:
|
||||
|
@ -725,18 +771,33 @@ static xmlChar* do_get_text(xmlNodePtr node)
|
|||
break;
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
if ((tmp && *tmp) || child->type==XML_CDATA_SECTION_NODE)
|
||||
{
|
||||
if (*tmp)
|
||||
if (ig_ws && str[0])
|
||||
{
|
||||
if (prev_type == XML_ELEMENT_NODE && child->type == XML_ELEMENT_NODE)
|
||||
str = xmlStrcat(str, BAD_CAST " ");
|
||||
str = xmlStrcat(str, tmp);
|
||||
prev_type = child->type;
|
||||
str = xmlStrcat(str, BAD_CAST " ");
|
||||
pos++;
|
||||
}
|
||||
xmlFree(tmp);
|
||||
if (tmp && *tmp) str = xmlStrcat(str, tmp);
|
||||
if (child->type==XML_CDATA_SECTION_NODE && pos<*first)
|
||||
*first = pos;
|
||||
if (tmp && *tmp) pos += xmlStrlen(tmp);
|
||||
if (child->type==XML_CDATA_SECTION_NODE && pos>*last)
|
||||
*last = pos;
|
||||
ig_ws = FALSE;
|
||||
}
|
||||
if (tmp) xmlFree(tmp);
|
||||
|
||||
if (!ig_ws)
|
||||
{
|
||||
ig_ws = *(DWORD*)&child->_private & NODE_PRIV_TRAILING_IGNORABLE_WS;
|
||||
}
|
||||
if (!ig_ws)
|
||||
ig_ws = *trail_ig_ws;
|
||||
*trail_ig_ws = FALSE;
|
||||
}
|
||||
|
||||
*trail_ig_ws = ig_ws;
|
||||
}
|
||||
|
||||
switch (node->type)
|
||||
|
@ -747,8 +808,24 @@ static xmlChar* do_get_text(xmlNodePtr node)
|
|||
case XML_ENTITY_NODE:
|
||||
case XML_DOCUMENT_NODE:
|
||||
case XML_DOCUMENT_FRAG_NODE:
|
||||
if (!preserving)
|
||||
str = trim_whitespace(str);
|
||||
if (trim && !preserving)
|
||||
{
|
||||
xmlChar* ret = str;
|
||||
int len;
|
||||
|
||||
if (!str)
|
||||
break;
|
||||
|
||||
for (ret = str; *ret && isspace(*ret) && (*first)--; ret++)
|
||||
if (*last) (*last)--;
|
||||
for (len = xmlStrlen(ret)-1; len >= 0 && len >= *last; len--)
|
||||
if(!isspace(ret[len])) break;
|
||||
|
||||
ret = xmlStrndup(ret, len+1);
|
||||
xmlFree(str);
|
||||
str = ret;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -761,10 +838,12 @@ HRESULT node_get_text(const xmlnode *This, BSTR *text)
|
|||
{
|
||||
BSTR str = NULL;
|
||||
xmlChar *content;
|
||||
DWORD first, last;
|
||||
BOOL tmp;
|
||||
|
||||
if (!text) return E_INVALIDARG;
|
||||
|
||||
content = do_get_text(This->node);
|
||||
content = do_get_text(This->node, TRUE, &first, &last, &tmp);
|
||||
if (content)
|
||||
{
|
||||
str = bstr_from_xmlChar(content);
|
||||
|
@ -1373,19 +1452,6 @@ 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)
|
||||
|
|
|
@ -131,7 +131,7 @@ reactos/dll/win32/msvfw32 # Synced to WineStaging-1.7.55
|
|||
reactos/dll/win32/msvidc32 # Synced to WineStaging-1.7.55
|
||||
reactos/dll/win32/msxml # Synced to WineStaging-1.7.55
|
||||
reactos/dll/win32/msxml2 # Synced to WineStaging-1.7.55
|
||||
reactos/dll/win32/msxml3 # Synced to WineStaging-1.7.55
|
||||
reactos/dll/win32/msxml3 # Synced to WineStaging-1.9.4
|
||||
reactos/dll/win32/msxml4 # Synced to WineStaging-1.7.55
|
||||
reactos/dll/win32/msxml6 # Synced to WineStaging-1.7.55
|
||||
reactos/dll/win32/nddeapi # Synced to WineStaging-1.7.55
|
||||
|
|
Loading…
Reference in a new issue