xmllite: Add a name stack for elements.
This commit is contained in:
parent
c525cf381d
commit
77735419eb
|
@ -124,6 +124,12 @@ struct attribute
|
||||||
strval value;
|
strval value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct element
|
||||||
|
{
|
||||||
|
struct list entry;
|
||||||
|
strval qname;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IXmlReader IXmlReader_iface;
|
IXmlReader IXmlReader_iface;
|
||||||
|
@ -138,6 +144,7 @@ typedef struct
|
||||||
struct list attrs; /* attributes list for current node */
|
struct list attrs; /* attributes list for current node */
|
||||||
struct attribute *attr; /* current attribute */
|
struct attribute *attr; /* current attribute */
|
||||||
UINT attr_count;
|
UINT attr_count;
|
||||||
|
struct list elements;
|
||||||
strval strvalues[StringValue_Last];
|
strval strvalues[StringValue_Last];
|
||||||
} xmlreader;
|
} xmlreader;
|
||||||
|
|
||||||
|
@ -194,6 +201,21 @@ static inline void reader_free(xmlreader *reader, void *mem)
|
||||||
m_free(reader->imalloc, 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 */
|
/* reader input memory allocation functions */
|
||||||
static inline void *readerinput_alloc(xmlreaderinput *input, size_t len)
|
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;
|
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)
|
if (v->str != strval_empty.str)
|
||||||
{
|
{
|
||||||
reader_free(reader, v->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)
|
static void reader_free_strvalues(xmlreader *reader)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
@ -271,6 +297,32 @@ static void reader_free_strvalues(xmlreader *reader)
|
||||||
reader_free_strvalue(reader, type);
|
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 */
|
/* always make a copy, cause strings are supposed to be null terminated */
|
||||||
static void reader_set_strvalue(xmlreader *reader, XmlReaderStringValue type, const strval *value)
|
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 HRESULT reader_parse_stag(xmlreader *reader, strval *prefix, strval *local, strval *qname)
|
||||||
{
|
{
|
||||||
static const WCHAR endW[] = {'/','>',0};
|
static const WCHAR endW[] = {'/','>',0};
|
||||||
|
static const WCHAR gtW[] = {'>',0};
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
/* skip '<' */
|
/* skip '<' */
|
||||||
|
@ -1410,7 +1463,11 @@ static HRESULT reader_parse_stag(xmlreader *reader, strval *prefix, strval *loca
|
||||||
|
|
||||||
if (!reader_cmp(reader, endW)) return S_OK;
|
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;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1561,6 +1618,7 @@ static ULONG WINAPI xmlreader_Release(IXmlReader *iface)
|
||||||
IMalloc *imalloc = This->imalloc;
|
IMalloc *imalloc = This->imalloc;
|
||||||
if (This->input) IUnknown_Release(&This->input->IXmlReaderInput_iface);
|
if (This->input) IUnknown_Release(&This->input->IXmlReaderInput_iface);
|
||||||
reader_clear_attrs(This);
|
reader_clear_attrs(This);
|
||||||
|
reader_clear_elements(This);
|
||||||
reader_free_strvalues(This);
|
reader_free_strvalues(This);
|
||||||
reader_free(This, This);
|
reader_free(This, This);
|
||||||
if (imalloc) IMalloc_Release(imalloc);
|
if (imalloc) IMalloc_Release(imalloc);
|
||||||
|
@ -1985,6 +2043,7 @@ HRESULT WINAPI CreateXmlReader(REFIID riid, void **obj, IMalloc *imalloc)
|
||||||
list_init(&reader->attrs);
|
list_init(&reader->attrs);
|
||||||
reader->attr_count = 0;
|
reader->attr_count = 0;
|
||||||
reader->attr = NULL;
|
reader->attr = NULL;
|
||||||
|
list_init(&reader->elements);
|
||||||
|
|
||||||
for (i = 0; i < StringValue_Last; i++)
|
for (i = 0; i < StringValue_Last; i++)
|
||||||
reader->strvalues[i] = strval_empty;
|
reader->strvalues[i] = strval_empty;
|
||||||
|
|
|
@ -888,6 +888,7 @@ static const char misc_test_xml[] =
|
||||||
"<!-- comment3 -->"
|
"<!-- comment3 -->"
|
||||||
" \t \r \n"
|
" \t \r \n"
|
||||||
"<!-- comment4 -->"
|
"<!-- comment4 -->"
|
||||||
|
"<a>"
|
||||||
;
|
;
|
||||||
|
|
||||||
static struct nodes_test misc_test = {
|
static struct nodes_test misc_test = {
|
||||||
|
@ -899,6 +900,7 @@ static struct nodes_test misc_test = {
|
||||||
XmlNodeType_Comment,
|
XmlNodeType_Comment,
|
||||||
XmlNodeType_Whitespace,
|
XmlNodeType_Whitespace,
|
||||||
XmlNodeType_Comment,
|
XmlNodeType_Comment,
|
||||||
|
XmlNodeType_Element,
|
||||||
XmlNodeType_None
|
XmlNodeType_None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1028,6 +1030,9 @@ static struct test_entry element_tests[] = {
|
||||||
{ "<a:b/>", "a:b", "", NC_E_UNDECLAREDPREFIX },
|
{ "<a:b/>", "a:b", "", NC_E_UNDECLAREDPREFIX },
|
||||||
{ "<:a/>", NULL, NULL, NC_E_QNAMECHARACTER },
|
{ "<:a/>", NULL, NULL, NC_E_QNAMECHARACTER },
|
||||||
{ "< 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 }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue