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)
|
||||
{
|
||||
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)
|
||||
|
@ -541,33 +542,21 @@ static HRESULT reader_push_element(xmlreader *reader, strval *prefix, strval *lo
|
|||
struct element *element;
|
||||
HRESULT hr;
|
||||
|
||||
if (!list_empty(&reader->elements))
|
||||
{
|
||||
hr = reader_inc_depth(reader);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
element = reader_alloc_zero(reader, sizeof(*element));
|
||||
if (!element) {
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto failed;
|
||||
}
|
||||
if (!element)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if ((hr = reader_strvaldup(reader, prefix, &element->prefix)) != S_OK ||
|
||||
(hr = reader_strvaldup(reader, localname, &element->localname)) != S_OK ||
|
||||
(hr = reader_strvaldup(reader, qname, &element->qname)) != 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, qname, &element->qname)) == S_OK)
|
||||
{
|
||||
reader_free_element(reader, element);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
list_add_head(&reader->elements, &element->entry);
|
||||
reader_mark_ns_nodes(reader, element);
|
||||
reader->is_empty_element = FALSE;
|
||||
}
|
||||
else
|
||||
reader_free_element(reader, element);
|
||||
|
||||
failed:
|
||||
reader_dec_depth(reader);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -608,7 +597,6 @@ static void reader_pop_element(xmlreader *reader)
|
|||
|
||||
reader_pop_ns_nodes(reader, element);
|
||||
reader_free_element(reader, element);
|
||||
reader_dec_depth(reader);
|
||||
|
||||
/* It was a root element, the rest is expected as Misc */
|
||||
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;
|
||||
reader_skipn(reader, 2);
|
||||
|
||||
reader_inc_depth(reader);
|
||||
reader->nodetype = XmlNodeType_XmlDeclaration;
|
||||
reader_set_strvalue(reader, StringValue_LocalName, &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);
|
||||
|
||||
/* When moving from EndElement or empty element, pop its own namespace definitions */
|
||||
if (nodetype == XmlNodeType_Element && reader->is_empty_element)
|
||||
switch (nodetype)
|
||||
{
|
||||
case XmlNodeType_Element:
|
||||
if (reader->is_empty_element)
|
||||
reader_pop_ns_nodes(reader, &reader->empty_element);
|
||||
else if (nodetype == XmlNodeType_EndElement)
|
||||
else
|
||||
reader_inc_depth(reader);
|
||||
break;
|
||||
case XmlNodeType_EndElement:
|
||||
reader_pop_element(reader);
|
||||
/* fallthrough */
|
||||
case XmlNodeType_Attribute:
|
||||
reader_dec_depth(reader);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -2658,6 +2658,7 @@ static HRESULT WINAPI xmlreader_SetInput(IXmlReader* iface, IUnknown *input)
|
|||
This->line = This->pos = 0;
|
||||
reader_clear_elements(This);
|
||||
This->depth = 0;
|
||||
This->nodetype = XmlNodeType_None;
|
||||
This->resumestate = XmlReadResumeState_Initial;
|
||||
memset(This->resume, 0, sizeof(This->resume));
|
||||
|
||||
|
@ -2816,6 +2817,14 @@ static HRESULT reader_move_to_first_attribute(xmlreader *reader)
|
|||
if (!reader->attr_count)
|
||||
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_set_strvalue(reader, StringValue_Prefix, &reader->attr->prefix);
|
||||
reader_set_strvalue(reader, StringValue_LocalName, &reader->attr->localname);
|
||||
|
@ -2872,6 +2881,10 @@ static HRESULT WINAPI xmlreader_MoveToElement(IXmlReader* iface)
|
|||
TRACE("(%p)\n", This);
|
||||
|
||||
if (!This->attr_count) return S_FALSE;
|
||||
|
||||
if (This->attr)
|
||||
reader_dec_depth(This);
|
||||
|
||||
This->attr = NULL;
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(*val == 0, "got %s\n", wine_dbgstr_w(val));
|
||||
|
@ -763,6 +768,11 @@ static void test_read_xmldeclaration(void)
|
|||
hr = IXmlReader_MoveToNextAttribute(reader);
|
||||
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;
|
||||
hr = IXmlReader_GetNodeType(reader, &type);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -845,7 +856,7 @@ todo_wine {
|
|||
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_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);
|
||||
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(type == XmlNodeType_Element, "expected Element, got %s\n", type_to_str(type));
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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>";
|
||||
IXmlReader *reader;
|
||||
XmlNodeType type;
|
||||
IStream *stream;
|
||||
unsigned int i;
|
||||
UINT depth;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -1424,56 +1444,50 @@ static void test_read_element(void)
|
|||
|
||||
/* test reader depth increment */
|
||||
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);
|
||||
|
||||
depth = 1;
|
||||
i = 0;
|
||||
while (IXmlReader_Read(reader, &type) == S_OK)
|
||||
{
|
||||
ok(type == XmlNodeType_Element || type == XmlNodeType_EndElement ||
|
||||
type == XmlNodeType_Text, "Unexpected node type %d\n", type);
|
||||
|
||||
depth = 123;
|
||||
hr = IXmlReader_GetDepth(reader, &depth);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(depth == 0, "got %d\n", depth);
|
||||
ok(depth == depths[i], "%u: got depth %u, expected %u\n", i, depth, depths[i]);
|
||||
|
||||
type = XmlNodeType_None;
|
||||
hr = IXmlReader_Read(reader, &type);
|
||||
if (type == XmlNodeType_Element)
|
||||
{
|
||||
UINT count = 0;
|
||||
|
||||
hr = IXmlReader_GetAttributeCount(reader, &count);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(type == XmlNodeType_Element, "got %d\n", type);
|
||||
|
||||
depth = 1;
|
||||
/* moving to attributes increases depth */
|
||||
if (count)
|
||||
{
|
||||
hr = IXmlReader_MoveToFirstAttribute(reader);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
|
||||
depth = 123;
|
||||
hr = IXmlReader_GetDepth(reader, &depth);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(depth == 0, "got %d\n", depth);
|
||||
ok(depth == depths[i] + 1, "%u: got depth %u, expected %u\n", i, depth, depths[i] + 1);
|
||||
|
||||
type = XmlNodeType_None;
|
||||
hr = IXmlReader_Read(reader, &type);
|
||||
hr = IXmlReader_MoveToElement(reader);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(type == XmlNodeType_Element, "got %d\n", type);
|
||||
|
||||
depth = 0;
|
||||
depth = 123;
|
||||
hr = IXmlReader_GetDepth(reader, &depth);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(depth == 1, "got %d\n", depth);
|
||||
ok(depth == depths[i], "%u: got depth %u, expected %u\n", i, depth, depths[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* read end tag for inner element */
|
||||
type = XmlNodeType_None;
|
||||
hr = IXmlReader_Read(reader, &type);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(type == XmlNodeType_EndElement, "got %d\n", type);
|
||||
|
||||
depth = 0;
|
||||
hr = IXmlReader_GetDepth(reader, &depth);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
todo_wine
|
||||
ok(depth == 2, "got %d\n", depth);
|
||||
|
||||
/* read end tag for container element */
|
||||
type = XmlNodeType_None;
|
||||
hr = IXmlReader_Read(reader, &type);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(type == XmlNodeType_EndElement, "got %d\n", type);
|
||||
|
||||
depth = 0;
|
||||
hr = IXmlReader_GetDepth(reader, &depth);
|
||||
ok(hr == S_OK, "got %08x\n", hr);
|
||||
ok(depth == 1, "got %d\n", depth);
|
||||
i++;
|
||||
}
|
||||
|
||||
IStream_Release(stream);
|
||||
|
||||
|
|
Loading…
Reference in New Issue