Nikolay Sivov : xmllite: Implement IsEmptyElement().

Alexandre Julliard julliard at winehq.org
Mon Jul 22 14:22:45 CDT 2013


Module: wine
Branch: master
Commit: d315e438a2df28fc74203e4ac185f6fdff844a85
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d315e438a2df28fc74203e4ac185f6fdff844a85

Author: Nikolay Sivov <nsivov at 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();




More information about the wine-cvs mailing list