[PATCH 5/5] xmllite/reader: Improve the way nesting level returned by GetDepth() is updated
Nikolay Sivov
nsivov at codeweavers.com
Mon Mar 6 03:35:59 CST 2017
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/xmllite/reader.c | 69 +++++++++++++++++-------------
dlls/xmllite/tests/reader.c | 100 +++++++++++++++++++++++++-------------------
2 files changed, 98 insertions(+), 71 deletions(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index 8e975b329c..5f53d3f1f2 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -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);
- 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;
}
@@ -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)
- reader_pop_ns_nodes(reader, &reader->empty_element);
- else if (nodetype == XmlNodeType_EndElement)
+ switch (nodetype)
+ {
+ 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);
+ /* 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 */
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index 6389019702..07e149f631 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -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;
- hr = IXmlReader_GetDepth(reader, &depth);
- ok(hr == S_OK, "got %08x\n", hr);
- ok(depth == 0, "got %d\n", depth);
+ 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);
- type = XmlNodeType_None;
- hr = IXmlReader_Read(reader, &type);
- ok(hr == S_OK, "got %08x\n", hr);
- ok(type == XmlNodeType_Element, "got %d\n", type);
+ depth = 123;
+ hr = IXmlReader_GetDepth(reader, &depth);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(depth == depths[i], "%u: got depth %u, expected %u\n", i, depth, depths[i]);
- depth = 1;
- hr = IXmlReader_GetDepth(reader, &depth);
- ok(hr == S_OK, "got %08x\n", hr);
- ok(depth == 0, "got %d\n", depth);
+ if (type == XmlNodeType_Element)
+ {
+ UINT count = 0;
- type = XmlNodeType_None;
- hr = IXmlReader_Read(reader, &type);
- ok(hr == S_OK, "got %08x\n", hr);
- ok(type == XmlNodeType_Element, "got %d\n", type);
+ hr = IXmlReader_GetAttributeCount(reader, &count);
+ ok(hr == S_OK, "got %08x\n", hr);
- depth = 0;
- hr = IXmlReader_GetDepth(reader, &depth);
- ok(hr == S_OK, "got %08x\n", hr);
- ok(depth == 1, "got %d\n", depth);
+ /* moving to attributes increases depth */
+ if (count)
+ {
+ hr = IXmlReader_MoveToFirstAttribute(reader);
+ ok(hr == S_OK, "got %08x\n", hr);
- /* 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 = 123;
+ hr = IXmlReader_GetDepth(reader, &depth);
+ 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);
- depth = 0;
- hr = IXmlReader_GetDepth(reader, &depth);
- ok(hr == S_OK, "got %08x\n", hr);
-todo_wine
- ok(depth == 2, "got %d\n", depth);
+ hr = IXmlReader_MoveToElement(reader);
+ ok(hr == S_OK, "got %08x\n", hr);
- /* 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 = 123;
+ hr = IXmlReader_GetDepth(reader, &depth);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(depth == depths[i], "%u: got depth %u, expected %u\n", i, depth, depths[i]);
+ }
+ }
- 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);
--
2.11.0
More information about the wine-patches
mailing list