Module: wine Branch: master Commit: 77735419eb58624eef936c536cd168d52197fa98 URL: http://source.winehq.org/git/wine.git/?a=commit;h=77735419eb58624eef936c536c...
Author: Nikolay Sivov nsivov@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 } };