Nikolay Sivov : xmllite: Add a name stack for elements.

Alexandre Julliard julliard at winehq.org
Mon Jan 21 13:52:24 CST 2013


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun Jan 20 23:46:25 2013 +0400

xmllite: Add a name stack for elements.

---

 dlls/xmllite/reader.c       |   67 ++++++++++++++++++++++++++++++++++++++++--
 dlls/xmllite/tests/reader.c |    5 +++
 2 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index 058875a..c18dd41 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -124,6 +124,12 @@ struct attribute
     strval value;
 };
 
+struct element
+{
+    struct list entry;
+    strval qname;
+};
+
 typedef struct
 {
     IXmlReader IXmlReader_iface;
@@ -138,6 +144,7 @@ typedef struct
     struct list attrs; /* attributes list for current node */
     struct attribute *attr; /* current attribute */
     UINT attr_count;
+    struct list elements;
     strval strvalues[StringValue_Last];
 } xmlreader;
 
@@ -194,6 +201,21 @@ static inline void reader_free(xmlreader *reader, void *mem)
     m_free(reader->imalloc, mem);
 }
 
+static HRESULT reader_strvaldup(xmlreader *reader, const strval *src, strval *dest)
+{
+    *dest = *src;
+
+    if (src->str != strval_empty.str)
+    {
+        dest->str = reader_alloc(reader, (dest->len+1)*sizeof(WCHAR));
+        if (!dest->str) return E_OUTOFMEMORY;
+        memcpy(dest->str, src->str, dest->len*sizeof(WCHAR));
+        dest->str[dest->len] = 0;
+    }
+
+    return S_OK;
+}
+
 /* reader input memory allocation functions */
 static inline void *readerinput_alloc(xmlreaderinput *input, size_t len)
 {
@@ -253,10 +275,9 @@ static HRESULT reader_add_attr(xmlreader *reader, strval *localname, strval *val
     return S_OK;
 }
 
-static void reader_free_strvalue(xmlreader *reader, XmlReaderStringValue type)
+/* This one frees stored string value if needed */
+static void reader_free_strvalued(xmlreader *reader, strval *v)
 {
-    strval *v = &reader->strvalues[type];
-
     if (v->str != strval_empty.str)
     {
         reader_free(reader, v->str);
@@ -264,6 +285,11 @@ static void reader_free_strvalue(xmlreader *reader, XmlReaderStringValue type)
     }
 }
 
+static void reader_free_strvalue(xmlreader *reader, XmlReaderStringValue type)
+{
+    reader_free_strvalued(reader, &reader->strvalues[type]);
+}
+
 static void reader_free_strvalues(xmlreader *reader)
 {
     int type;
@@ -271,6 +297,32 @@ static void reader_free_strvalues(xmlreader *reader)
         reader_free_strvalue(reader, type);
 }
 
+static void reader_clear_elements(xmlreader *reader)
+{
+    struct element *elem, *elem2;
+    LIST_FOR_EACH_ENTRY_SAFE(elem, elem2, &reader->elements, struct element, entry)
+    {
+        reader_free_strvalued(reader, &elem->qname);
+        reader_free(reader, elem);
+    }
+    list_init(&reader->elements);
+}
+
+static HRESULT reader_push_element(xmlreader *reader, strval *qname)
+{
+    struct element *elem;
+    HRESULT hr;
+
+    elem = reader_alloc(reader, sizeof(*elem));
+    if (!elem) return E_OUTOFMEMORY;
+
+    hr = reader_strvaldup(reader, qname, &elem->qname);
+    if (FAILED(hr)) return hr;
+
+    list_add_head(&reader->elements, &elem->entry);
+    return hr;
+}
+
 /* always make a copy, cause strings are supposed to be null terminated */
 static void reader_set_strvalue(xmlreader *reader, XmlReaderStringValue type, const strval *value)
 {
@@ -1398,6 +1450,7 @@ static HRESULT reader_parse_qname(xmlreader *reader, strval *prefix, strval *loc
 static HRESULT reader_parse_stag(xmlreader *reader, strval *prefix, strval *local, strval *qname)
 {
     static const WCHAR endW[] = {'/','>',0};
+    static const WCHAR gtW[] = {'>',0};
     HRESULT hr;
 
     /* skip '<' */
@@ -1410,7 +1463,11 @@ static HRESULT reader_parse_stag(xmlreader *reader, strval *prefix, strval *loca
 
     if (!reader_cmp(reader, endW)) return S_OK;
 
-    FIXME("only empty elements without attributes supported\n");
+    /* got a start tag */
+    if (!reader_cmp(reader, gtW))
+        return reader_push_element(reader, qname);
+
+    FIXME("only empty elements/start tags without attribute list supported\n");
     return E_NOTIMPL;
 }
 
@@ -1561,6 +1618,7 @@ static ULONG WINAPI xmlreader_Release(IXmlReader *iface)
         IMalloc *imalloc = This->imalloc;
         if (This->input) IUnknown_Release(&This->input->IXmlReaderInput_iface);
         reader_clear_attrs(This);
+        reader_clear_elements(This);
         reader_free_strvalues(This);
         reader_free(This, This);
         if (imalloc) IMalloc_Release(imalloc);
@@ -1985,6 +2043,7 @@ HRESULT WINAPI CreateXmlReader(REFIID riid, void **obj, IMalloc *imalloc)
     list_init(&reader->attrs);
     reader->attr_count = 0;
     reader->attr = NULL;
+    list_init(&reader->elements);
 
     for (i = 0; i < StringValue_Last; i++)
         reader->strvalues[i] = strval_empty;
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index 7394564..2ef9b6a 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -888,6 +888,7 @@ static const char misc_test_xml[] =
     "<!-- comment3 -->"
     " \t \r \n"
     "<!-- comment4 -->"
+    "<a>"
 ;
 
 static struct nodes_test misc_test = {
@@ -899,6 +900,7 @@ static struct nodes_test misc_test = {
         XmlNodeType_Comment,
         XmlNodeType_Whitespace,
         XmlNodeType_Comment,
+        XmlNodeType_Element,
         XmlNodeType_None
     }
 };
@@ -1028,6 +1030,9 @@ static struct test_entry element_tests[] = {
     { "<a:b/>", "a:b", "", NC_E_UNDECLAREDPREFIX },
     { "<:a/>", NULL, NULL, NC_E_QNAMECHARACTER },
     { "< a/>", NULL, NULL, NC_E_QNAMECHARACTER },
+    { "<a>", "a", "", S_OK },
+    { "<a >", "a", "", S_OK },
+    { "<a \r \t\n>", "a", "", S_OK },
     { NULL }
 };
 




More information about the wine-cvs mailing list