xmllite: Keep a list of namespace definitions.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2016-12-09 16:38:24 +03:00 committed by Alexandre Julliard
parent 635c409126
commit 18d6deff6d
1 changed files with 83 additions and 19 deletions

View File

@ -216,11 +216,14 @@ typedef struct
} strval;
static WCHAR emptyW[] = {0};
static WCHAR xmlnsW[] = {'x','m','l','n','s',0};
static const strval strval_empty = { emptyW };
static const strval strval_xmlns = { xmlnsW, 5 };
struct attribute
{
struct list entry;
strval prefix;
strval localname;
strval value;
};
@ -233,6 +236,14 @@ struct element
strval qname;
};
struct ns
{
struct list entry;
strval prefix;
strval uri;
struct element *element;
};
typedef struct
{
IXmlReader IXmlReader_iface;
@ -250,6 +261,8 @@ typedef struct
struct list attrs; /* attributes list for current node */
struct attribute *attr; /* current attribute */
UINT attr_count;
struct list nsdef;
struct list ns;
struct list elements;
strval strvalues[StringValue_Last];
UINT depth;
@ -369,13 +382,17 @@ static void reader_clear_attrs(xmlreader *reader)
/* attribute data holds pointers to buffer data, so buffer shrink is not possible
while we are on a node with attributes */
static HRESULT reader_add_attr(xmlreader *reader, strval *localname, strval *value)
static HRESULT reader_add_attr(xmlreader *reader, strval *prefix, strval *localname, strval *value)
{
struct attribute *attr;
attr = reader_alloc(reader, sizeof(*attr));
if (!attr) return E_OUTOFMEMORY;
if (prefix)
attr->prefix = *prefix;
else
memset(&attr->prefix, 0, sizeof(attr->prefix));
attr->localname = *localname;
attr->value = *value;
list_add_tail(&reader->attrs, &attr->entry);
@ -457,6 +474,36 @@ static void reader_dec_depth(xmlreader *reader)
if (reader->depth > 1) reader->depth--;
}
static HRESULT reader_push_ns(xmlreader *reader, const strval *prefix, const strval *uri, BOOL def)
{
struct ns *ns;
HRESULT hr;
ns = reader_alloc(reader, sizeof(*ns));
if (!ns) return E_OUTOFMEMORY;
if (def)
memset(&ns->prefix, 0, sizeof(ns->prefix));
else {
hr = reader_strvaldup(reader, prefix, &ns->prefix);
if (FAILED(hr)) {
reader_free(reader, ns);
return hr;
}
}
hr = reader_strvaldup(reader, uri, &ns->uri);
if (FAILED(hr)) {
reader_free_strvalued(reader, &ns->prefix);
reader_free(reader, ns);
return hr;
}
ns->element = NULL;
list_add_head(def ? &reader->nsdef : &reader->ns, &ns->entry);
return hr;
}
static void reader_free_element(xmlreader *reader, struct element *element)
{
reader_free_strvalued(reader, &element->prefix);
@ -1056,7 +1103,7 @@ static HRESULT reader_parse_versioninfo(xmlreader *reader)
/* skip "'"|'"' */
reader_skipn(reader, 1);
return reader_add_attr(reader, &name, &val);
return reader_add_attr(reader, NULL, &name, &val);
}
/* ([A-Za-z0-9._] | '-') */
@ -1132,7 +1179,7 @@ static HRESULT reader_parse_encdecl(xmlreader *reader)
/* skip "'"|'"' */
reader_skipn(reader, 1);
return reader_add_attr(reader, &name, &val);
return reader_add_attr(reader, NULL, &name, &val);
}
/* [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')) */
@ -1174,7 +1221,7 @@ static HRESULT reader_parse_sddecl(xmlreader *reader)
/* skip "'"|'"' */
reader_skipn(reader, 1);
return reader_add_attr(reader, &name, &val);
return reader_add_attr(reader, NULL, &name, &val);
}
/* [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' */
@ -1644,7 +1691,7 @@ static HRESULT reader_parse_externalid(xmlreader *reader)
if (FAILED(hr)) return hr;
reader_init_cstrvalue(publicW, strlenW(publicW), &name);
hr = reader_add_attr(reader, &name, &pub);
hr = reader_add_attr(reader, NULL, &name, &pub);
if (FAILED(hr)) return hr;
cnt = reader_skipspaces(reader);
@ -1655,7 +1702,7 @@ static HRESULT reader_parse_externalid(xmlreader *reader)
if (FAILED(hr)) return S_OK;
reader_init_cstrvalue(systemW, strlenW(systemW), &name);
hr = reader_add_attr(reader, &name, &sys);
hr = reader_add_attr(reader, NULL, &name, &sys);
if (FAILED(hr)) return hr;
return S_OK;
@ -1669,7 +1716,7 @@ static HRESULT reader_parse_externalid(xmlreader *reader)
if (FAILED(hr)) return hr;
reader_init_cstrvalue(systemW, strlenW(systemW), &name);
return reader_add_attr(reader, &name, &sys);
return reader_add_attr(reader, NULL, &name, &sys);
}
return S_FALSE;
@ -2042,23 +2089,18 @@ static HRESULT reader_parse_attvalue(xmlreader *reader, strval *value)
[15 NS] Attribute ::= NSAttName Eq AttValue | QName Eq AttValue */
static HRESULT reader_parse_attribute(xmlreader *reader)
{
static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
strval prefix, local, qname, xmlns, value;
strval prefix, local, qname, value;
BOOL ns = FALSE, nsdef = FALSE;
HRESULT hr;
hr = reader_parse_qname(reader, &prefix, &local, &qname);
if (FAILED(hr)) return hr;
reader_init_cstrvalue((WCHAR*)xmlnsW, 5, &xmlns);
if (strval_eq(reader, &prefix, &strval_xmlns))
ns = TRUE;
if (strval_eq(reader, &prefix, &xmlns))
{
FIXME("namespace definitions not supported\n");
return E_NOTIMPL;
}
if (strval_eq(reader, &qname, &xmlns))
FIXME("default namespace definitions not supported\n");
if (strval_eq(reader, &qname, &strval_xmlns))
ns = nsdef = TRUE;
hr = reader_parse_eq(reader);
if (FAILED(hr)) return hr;
@ -2066,8 +2108,11 @@ static HRESULT reader_parse_attribute(xmlreader *reader)
hr = reader_parse_attvalue(reader, &value);
if (FAILED(hr)) return hr;
if (ns)
reader_push_ns(reader, nsdef ? &strval_xmlns : &local, &value, nsdef);
TRACE("%s=%s\n", debug_strval(reader, &local), debug_strval(reader, &value));
return reader_add_attr(reader, &local, &value);
return reader_add_attr(reader, &prefix, &local, &value);
}
/* [12 NS] STag ::= '<' QName (S Attribute)* S? '>'
@ -2487,6 +2532,22 @@ static ULONG WINAPI xmlreader_AddRef(IXmlReader *iface)
return ref;
}
static void reader_clear_ns(xmlreader *reader)
{
struct ns *ns, *ns2;
LIST_FOR_EACH_ENTRY_SAFE(ns, ns2, &reader->ns, struct ns, entry) {
reader_free_strvalued(reader, &ns->prefix);
reader_free_strvalued(reader, &ns->uri);
reader_free(reader, ns);
}
LIST_FOR_EACH_ENTRY_SAFE(ns, ns2, &reader->nsdef, struct ns, entry) {
reader_free_strvalued(reader, &ns->uri);
reader_free(reader, ns);
}
}
static ULONG WINAPI xmlreader_Release(IXmlReader *iface)
{
xmlreader *This = impl_from_IXmlReader(iface);
@ -2501,6 +2562,7 @@ static ULONG WINAPI xmlreader_Release(IXmlReader *iface)
if (This->resolver) IXmlResolver_Release(This->resolver);
if (This->mlang) IUnknown_Release(This->mlang);
reader_clear_attrs(This);
reader_clear_ns(This);
reader_clear_elements(This);
reader_free_strvalues(This);
reader_free(This, This);
@ -3044,6 +3106,8 @@ HRESULT WINAPI CreateXmlReader(REFIID riid, void **obj, IMalloc *imalloc)
list_init(&reader->attrs);
reader->attr_count = 0;
reader->attr = NULL;
list_init(&reader->nsdef);
list_init(&reader->ns);
list_init(&reader->elements);
reader->depth = 0;
reader->max_depth = 256;