xmllite/reader: Improve the way nesting level returned by GetDepth() is updated.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
073c43a139
commit
8f0c235f81
|
@ -477,7 +477,8 @@ static HRESULT reader_inc_depth(xmlreader *reader)
|
||||||
|
|
||||||
static void reader_dec_depth(xmlreader *reader)
|
static void reader_dec_depth(xmlreader *reader)
|
||||||
{
|
{
|
||||||
if (reader->depth > 1) reader->depth--;
|
if (reader->depth)
|
||||||
|
reader->depth--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT reader_push_ns(xmlreader *reader, const strval *prefix, const strval *uri, BOOL def)
|
static HRESULT reader_push_ns(xmlreader *reader, const strval *prefix, const strval *uri, BOOL def)
|
||||||
|
@ -541,33 +542,21 @@ static HRESULT reader_push_element(xmlreader *reader, strval *prefix, strval *lo
|
||||||
struct element *element;
|
struct element *element;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (!list_empty(&reader->elements))
|
|
||||||
{
|
|
||||||
hr = reader_inc_depth(reader);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
element = reader_alloc_zero(reader, sizeof(*element));
|
element = reader_alloc_zero(reader, sizeof(*element));
|
||||||
if (!element) {
|
if (!element)
|
||||||
hr = E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hr = reader_strvaldup(reader, prefix, &element->prefix)) != S_OK ||
|
if ((hr = reader_strvaldup(reader, prefix, &element->prefix)) == S_OK &&
|
||||||
(hr = reader_strvaldup(reader, localname, &element->localname)) != S_OK ||
|
(hr = reader_strvaldup(reader, localname, &element->localname)) == S_OK &&
|
||||||
(hr = reader_strvaldup(reader, qname, &element->qname)) != S_OK)
|
(hr = reader_strvaldup(reader, qname, &element->qname)) == S_OK)
|
||||||
{
|
{
|
||||||
reader_free_element(reader, element);
|
list_add_head(&reader->elements, &element->entry);
|
||||||
goto failed;
|
reader_mark_ns_nodes(reader, element);
|
||||||
|
reader->is_empty_element = FALSE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
reader_free_element(reader, element);
|
||||||
|
|
||||||
list_add_head(&reader->elements, &element->entry);
|
|
||||||
reader_mark_ns_nodes(reader, element);
|
|
||||||
reader->is_empty_element = FALSE;
|
|
||||||
|
|
||||||
failed:
|
|
||||||
reader_dec_depth(reader);
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +597,6 @@ static void reader_pop_element(xmlreader *reader)
|
||||||
|
|
||||||
reader_pop_ns_nodes(reader, element);
|
reader_pop_ns_nodes(reader, element);
|
||||||
reader_free_element(reader, element);
|
reader_free_element(reader, element);
|
||||||
reader_dec_depth(reader);
|
|
||||||
|
|
||||||
/* It was a root element, the rest is expected as Misc */
|
/* It was a root element, the rest is expected as Misc */
|
||||||
if (list_empty(&reader->elements))
|
if (list_empty(&reader->elements))
|
||||||
|
@ -1310,7 +1298,6 @@ static HRESULT reader_parse_xmldecl(xmlreader *reader)
|
||||||
if (reader_cmp(reader, declcloseW)) return WC_E_XMLDECL;
|
if (reader_cmp(reader, declcloseW)) return WC_E_XMLDECL;
|
||||||
reader_skipn(reader, 2);
|
reader_skipn(reader, 2);
|
||||||
|
|
||||||
reader_inc_depth(reader);
|
|
||||||
reader->nodetype = XmlNodeType_XmlDeclaration;
|
reader->nodetype = XmlNodeType_XmlDeclaration;
|
||||||
reader_set_strvalue(reader, StringValue_LocalName, &strval_empty);
|
reader_set_strvalue(reader, StringValue_LocalName, &strval_empty);
|
||||||
reader_set_strvalue(reader, StringValue_QualifiedName, &strval_empty);
|
reader_set_strvalue(reader, StringValue_QualifiedName, &strval_empty);
|
||||||
|
@ -2478,10 +2465,23 @@ static HRESULT reader_parse_nextnode(xmlreader *reader)
|
||||||
reader_clear_attrs(reader);
|
reader_clear_attrs(reader);
|
||||||
|
|
||||||
/* When moving from EndElement or empty element, pop its own namespace definitions */
|
/* When moving from EndElement or empty element, pop its own namespace definitions */
|
||||||
if (nodetype == XmlNodeType_Element && reader->is_empty_element)
|
switch (nodetype)
|
||||||
reader_pop_ns_nodes(reader, &reader->empty_element);
|
{
|
||||||
else if (nodetype == XmlNodeType_EndElement)
|
case XmlNodeType_Element:
|
||||||
|
if (reader->is_empty_element)
|
||||||
|
reader_pop_ns_nodes(reader, &reader->empty_element);
|
||||||
|
else
|
||||||
|
reader_inc_depth(reader);
|
||||||
|
break;
|
||||||
|
case XmlNodeType_EndElement:
|
||||||
reader_pop_element(reader);
|
reader_pop_element(reader);
|
||||||
|
/* fallthrough */
|
||||||
|
case XmlNodeType_Attribute:
|
||||||
|
reader_dec_depth(reader);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
@ -2658,6 +2658,7 @@ static HRESULT WINAPI xmlreader_SetInput(IXmlReader* iface, IUnknown *input)
|
||||||
This->line = This->pos = 0;
|
This->line = This->pos = 0;
|
||||||
reader_clear_elements(This);
|
reader_clear_elements(This);
|
||||||
This->depth = 0;
|
This->depth = 0;
|
||||||
|
This->nodetype = XmlNodeType_None;
|
||||||
This->resumestate = XmlReadResumeState_Initial;
|
This->resumestate = XmlReadResumeState_Initial;
|
||||||
memset(This->resume, 0, sizeof(This->resume));
|
memset(This->resume, 0, sizeof(This->resume));
|
||||||
|
|
||||||
|
@ -2816,6 +2817,14 @@ static HRESULT reader_move_to_first_attribute(xmlreader *reader)
|
||||||
if (!reader->attr_count)
|
if (!reader->attr_count)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
|
if (!reader->attr)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (FAILED(hr = reader_inc_depth(reader)))
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
reader->attr = LIST_ENTRY(list_head(&reader->attrs), struct attribute, entry);
|
reader->attr = LIST_ENTRY(list_head(&reader->attrs), struct attribute, entry);
|
||||||
reader_set_strvalue(reader, StringValue_Prefix, &reader->attr->prefix);
|
reader_set_strvalue(reader, StringValue_Prefix, &reader->attr->prefix);
|
||||||
reader_set_strvalue(reader, StringValue_LocalName, &reader->attr->localname);
|
reader_set_strvalue(reader, StringValue_LocalName, &reader->attr->localname);
|
||||||
|
@ -2872,6 +2881,10 @@ static HRESULT WINAPI xmlreader_MoveToElement(IXmlReader* iface)
|
||||||
TRACE("(%p)\n", This);
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
if (!This->attr_count) return S_FALSE;
|
if (!This->attr_count) return S_FALSE;
|
||||||
|
|
||||||
|
if (This->attr)
|
||||||
|
reader_dec_depth(This);
|
||||||
|
|
||||||
This->attr = NULL;
|
This->attr = NULL;
|
||||||
|
|
||||||
/* FIXME: support other node types with 'attributes' like DTD */
|
/* FIXME: support other node types with 'attributes' like DTD */
|
||||||
|
|
|
@ -755,6 +755,11 @@ static void test_read_xmldeclaration(void)
|
||||||
ok_pos(reader, 1, 3, -1, 55, TRUE);
|
ok_pos(reader, 1, 3, -1, 55, TRUE);
|
||||||
test_read_state(reader, XmlReadState_Interactive, -1, FALSE);
|
test_read_state(reader, XmlReadState_Interactive, -1, FALSE);
|
||||||
|
|
||||||
|
count = 1;
|
||||||
|
hr = IXmlReader_GetDepth(reader, &count);
|
||||||
|
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
|
||||||
|
ok(count == 0, "Expected 1, got %d\n", count);
|
||||||
|
|
||||||
hr = IXmlReader_GetValue(reader, &val, NULL);
|
hr = IXmlReader_GetValue(reader, &val, NULL);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
ok(*val == 0, "got %s\n", wine_dbgstr_w(val));
|
ok(*val == 0, "got %s\n", wine_dbgstr_w(val));
|
||||||
|
@ -763,6 +768,11 @@ static void test_read_xmldeclaration(void)
|
||||||
hr = IXmlReader_MoveToNextAttribute(reader);
|
hr = IXmlReader_MoveToNextAttribute(reader);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
hr = IXmlReader_GetDepth(reader, &count);
|
||||||
|
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
|
||||||
|
ok(count == 1, "Expected 1, got %d\n", count);
|
||||||
|
|
||||||
type = XmlNodeType_None;
|
type = XmlNodeType_None;
|
||||||
hr = IXmlReader_GetNodeType(reader, &type);
|
hr = IXmlReader_GetNodeType(reader, &type);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
@ -812,6 +822,7 @@ static void test_read_xmldeclaration(void)
|
||||||
ok(hr == ((i < count - 1) ? S_OK : S_FALSE), "got %08x\n", hr);
|
ok(hr == ((i < count - 1) ? S_OK : S_FALSE), "got %08x\n", hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count = 0;
|
||||||
hr = IXmlReader_GetDepth(reader, &count);
|
hr = IXmlReader_GetDepth(reader, &count);
|
||||||
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
|
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
|
||||||
ok(count == 1, "Expected 1, got %d\n", count);
|
ok(count == 1, "Expected 1, got %d\n", count);
|
||||||
|
@ -845,7 +856,7 @@ todo_wine {
|
||||||
ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
|
ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
|
||||||
ok(type == XmlNodeType_XmlDeclaration, "expected XmlDeclaration, got %s\n", type_to_str(type));
|
ok(type == XmlNodeType_XmlDeclaration, "expected XmlDeclaration, got %s\n", type_to_str(type));
|
||||||
ok_pos(reader, 1, 3, 1, 21, TRUE);
|
ok_pos(reader, 1, 3, 1, 21, TRUE);
|
||||||
test_read_state(reader, XmlReadState_Interactive, -1, TRUE);
|
test_read_state(reader, XmlReadState_Interactive, -1, FALSE);
|
||||||
|
|
||||||
hr = IXmlReader_GetAttributeCount(reader, &count);
|
hr = IXmlReader_GetAttributeCount(reader, &count);
|
||||||
ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
|
ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
|
||||||
|
@ -882,7 +893,7 @@ todo_wine
|
||||||
ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
|
ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
|
||||||
ok(type == XmlNodeType_Element, "expected Element, got %s\n", type_to_str(type));
|
ok(type == XmlNodeType_Element, "expected Element, got %s\n", type_to_str(type));
|
||||||
ok_pos(reader, 1, 23, 1, 40, TRUE);
|
ok_pos(reader, 1, 23, 1, 40, TRUE);
|
||||||
test_read_state(reader, XmlReadState_Interactive, -1, TRUE);
|
test_read_state(reader, XmlReadState_Interactive, -1, FALSE);
|
||||||
|
|
||||||
hr = IXmlReader_GetAttributeCount(reader, &count);
|
hr = IXmlReader_GetAttributeCount(reader, &count);
|
||||||
ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
|
ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
|
||||||
|
@ -1368,11 +1379,20 @@ static struct test_entry element_tests[] = {
|
||||||
static void test_read_element(void)
|
static void test_read_element(void)
|
||||||
{
|
{
|
||||||
struct test_entry *test = element_tests;
|
struct test_entry *test = element_tests;
|
||||||
static const char stag[] = "<a><b></b></a>";
|
static const char stag[] =
|
||||||
|
"<a attr1=\"_a\">"
|
||||||
|
"<b attr2=\"_b\">"
|
||||||
|
"text"
|
||||||
|
"<c attr3=\"_c\"/>"
|
||||||
|
"<d attr4=\"_d\"></d>"
|
||||||
|
"</b>"
|
||||||
|
"</a>";
|
||||||
|
static const UINT depths[] = { 0, 1, 2, 2, 2, 3, 2, 1 };
|
||||||
static const char mismatch[] = "<a></b>";
|
static const char mismatch[] = "<a></b>";
|
||||||
IXmlReader *reader;
|
IXmlReader *reader;
|
||||||
XmlNodeType type;
|
XmlNodeType type;
|
||||||
IStream *stream;
|
IStream *stream;
|
||||||
|
unsigned int i;
|
||||||
UINT depth;
|
UINT depth;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -1424,56 +1444,50 @@ static void test_read_element(void)
|
||||||
|
|
||||||
/* test reader depth increment */
|
/* test reader depth increment */
|
||||||
stream = create_stream_on_data(stag, sizeof(stag));
|
stream = create_stream_on_data(stag, sizeof(stag));
|
||||||
hr = IXmlReader_SetInput(reader, (IUnknown*)stream);
|
hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
|
||||||
depth = 1;
|
i = 0;
|
||||||
hr = IXmlReader_GetDepth(reader, &depth);
|
while (IXmlReader_Read(reader, &type) == S_OK)
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
{
|
||||||
ok(depth == 0, "got %d\n", depth);
|
ok(type == XmlNodeType_Element || type == XmlNodeType_EndElement ||
|
||||||
|
type == XmlNodeType_Text, "Unexpected node type %d\n", type);
|
||||||
|
|
||||||
type = XmlNodeType_None;
|
depth = 123;
|
||||||
hr = IXmlReader_Read(reader, &type);
|
hr = IXmlReader_GetDepth(reader, &depth);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
ok(type == XmlNodeType_Element, "got %d\n", type);
|
ok(depth == depths[i], "%u: got depth %u, expected %u\n", i, depth, depths[i]);
|
||||||
|
|
||||||
depth = 1;
|
if (type == XmlNodeType_Element)
|
||||||
hr = IXmlReader_GetDepth(reader, &depth);
|
{
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
UINT count = 0;
|
||||||
ok(depth == 0, "got %d\n", depth);
|
|
||||||
|
|
||||||
type = XmlNodeType_None;
|
hr = IXmlReader_GetAttributeCount(reader, &count);
|
||||||
hr = IXmlReader_Read(reader, &type);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
|
||||||
ok(type == XmlNodeType_Element, "got %d\n", type);
|
|
||||||
|
|
||||||
depth = 0;
|
/* moving to attributes increases depth */
|
||||||
hr = IXmlReader_GetDepth(reader, &depth);
|
if (count)
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
{
|
||||||
ok(depth == 1, "got %d\n", depth);
|
hr = IXmlReader_MoveToFirstAttribute(reader);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
|
||||||
/* read end tag for inner element */
|
depth = 123;
|
||||||
type = XmlNodeType_None;
|
hr = IXmlReader_GetDepth(reader, &depth);
|
||||||
hr = IXmlReader_Read(reader, &type);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
ok(depth == depths[i] + 1, "%u: got depth %u, expected %u\n", i, depth, depths[i] + 1);
|
||||||
ok(type == XmlNodeType_EndElement, "got %d\n", type);
|
|
||||||
|
|
||||||
depth = 0;
|
hr = IXmlReader_MoveToElement(reader);
|
||||||
hr = IXmlReader_GetDepth(reader, &depth);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
|
||||||
todo_wine
|
|
||||||
ok(depth == 2, "got %d\n", depth);
|
|
||||||
|
|
||||||
/* read end tag for container element */
|
depth = 123;
|
||||||
type = XmlNodeType_None;
|
hr = IXmlReader_GetDepth(reader, &depth);
|
||||||
hr = IXmlReader_Read(reader, &type);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
ok(depth == depths[i], "%u: got depth %u, expected %u\n", i, depth, depths[i]);
|
||||||
ok(type == XmlNodeType_EndElement, "got %d\n", type);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
depth = 0;
|
i++;
|
||||||
hr = IXmlReader_GetDepth(reader, &depth);
|
}
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
|
||||||
ok(depth == 1, "got %d\n", depth);
|
|
||||||
|
|
||||||
IStream_Release(stream);
|
IStream_Release(stream);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue