Module: wine Branch: master Commit: d315e438a2df28fc74203e4ac185f6fdff844a85 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d315e438a2df28fc74203e4ac1...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sat Jun 15 21:53:33 2013 +0400
xmllite: Implement IsEmptyElement().
---
dlls/xmllite/reader.c | 25 +++++++++++++++++----- dlls/xmllite/tests/reader.c | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 6 deletions(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c index ec2a071..0a89edb 100644 --- a/dlls/xmllite/reader.c +++ b/dlls/xmllite/reader.c @@ -189,6 +189,7 @@ typedef struct struct list elements; strval strvalues[StringValue_Last]; UINT depth; + BOOL empty_element; WCHAR *resume[XmlReadResume_Last]; /* pointers used to resume reader */ } xmlreader;
@@ -364,6 +365,7 @@ static void reader_clear_elements(xmlreader *reader) reader_free(reader, elem); } list_init(&reader->elements); + reader->empty_element = FALSE; }
static HRESULT reader_inc_depth(xmlreader *reader) @@ -397,6 +399,7 @@ static HRESULT reader_push_element(xmlreader *reader, strval *qname) }
list_add_head(&reader->elements, &elem->entry); + reader->empty_element = FALSE; return hr; }
@@ -1221,6 +1224,14 @@ static inline int is_namechar(WCHAR ch) return (ch == ':') || is_ncnamechar(ch); }
+static XmlNodeType reader_get_nodetype(const xmlreader *reader) +{ + /* When we're on attribute always return attribute type, container node type is kept. + Note that container is not necessarily an element, and attribute doesn't mean it's + an attribute in XML spec terms. */ + return reader->attr ? XmlNodeType_Attribute : reader->nodetype; +} + /* [4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] @@ -1699,6 +1710,7 @@ static HRESULT reader_parse_stag(xmlreader *reader, strval *prefix, strval *loca { /* skip '/>' */ reader_skipn(reader, 2); + reader->empty_element = TRUE; return S_OK; }
@@ -2235,10 +2247,7 @@ static HRESULT WINAPI xmlreader_GetNodeType(IXmlReader* iface, XmlNodeType *node xmlreader *This = impl_from_IXmlReader(iface); TRACE("(%p)->(%p)\n", This, node_type);
- /* When we're on attribute always return attribute type, container node type is kept. - Note that container is not necessarily an element, and attribute doesn't mean it's - an attribute in XML spec terms. */ - *node_type = This->attr ? XmlNodeType_Attribute : This->nodetype; + *node_type = reader_get_nodetype(This); return This->state == XmlReadState_Closed ? S_FALSE : S_OK; }
@@ -2402,8 +2411,11 @@ static BOOL WINAPI xmlreader_IsDefault(IXmlReader* iface)
static BOOL WINAPI xmlreader_IsEmptyElement(IXmlReader* iface) { - FIXME("(%p): stub\n", iface); - return E_NOTIMPL; + xmlreader *This = impl_from_IXmlReader(iface); + TRACE("(%p)\n", This); + /* Empty elements are not placed in stack, it's stored as a global reader flag that makes sense + when current node is start tag of an element */ + return (reader_get_nodetype(This) == XmlNodeType_Element) ? This->empty_element : FALSE; }
static HRESULT WINAPI xmlreader_GetLineNumber(IXmlReader* iface, UINT *lineNumber) @@ -2583,6 +2595,7 @@ HRESULT WINAPI CreateXmlReader(REFIID riid, void **obj, IMalloc *imalloc) reader->attr = NULL; list_init(&reader->elements); reader->depth = 0; + reader->empty_element = FALSE; memset(reader->resume, 0, sizeof(reader->resume));
for (i = 0; i < StringValue_Last; i++) diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c index c666712..9be5125 100644 --- a/dlls/xmllite/tests/reader.c +++ b/dlls/xmllite/tests/reader.c @@ -1518,6 +1518,51 @@ static void test_read_text(void) IXmlReader_Release(reader); }
+struct test_entry_empty { + const char *xml; + BOOL empty; +}; + +static struct test_entry_empty empty_element_tests[] = { + { "<a></a>", FALSE }, + { "<a/>", TRUE }, + { NULL } +}; + +static void test_isemptyelement(void) +{ + struct test_entry_empty *test = empty_element_tests; + IXmlReader *reader; + HRESULT hr; + + hr = pCreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL); + ok(hr == S_OK, "S_OK, got %08x\n", hr); + + while (test->xml) + { + XmlNodeType type; + IStream *stream; + BOOL ret; + + stream = create_stream_on_data(test->xml, strlen(test->xml)+1); + hr = IXmlReader_SetInput(reader, (IUnknown*)stream); + ok(hr == S_OK, "got %08x\n", hr); + + type = XmlNodeType_None; + hr = IXmlReader_Read(reader, &type); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(type == XmlNodeType_Element, "got %d\n", type); + + ret = IXmlReader_IsEmptyElement(reader); + ok(ret == test->empty, "got %d, expected %d. xml=%s\n", ret, test->empty, test->xml); + + IStream_Release(stream); + test++; + } + + IXmlReader_Release(reader); +} + START_TEST(reader) { HRESULT r; @@ -1539,6 +1584,7 @@ START_TEST(reader) test_read_pi(); test_read_dtd(); test_read_element(); + test_isemptyelement(); test_read_text(); test_read_full(); test_read_pending();