xmllite: Add a name stack for elements.

This commit is contained in:
Nikolay Sivov 2013-01-20 23:46:25 +04:00 committed by Alexandre Julliard
parent c525cf381d
commit 77735419eb
2 changed files with 68 additions and 4 deletions

View File

@ -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;

View File

@ -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 }
};