ntdll: Store the namespace separately from the XML element name.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-03-26 21:02:07 +02:00
parent 7a349d8d87
commit 1aaaecba46
1 changed files with 48 additions and 18 deletions

View File

@ -102,6 +102,7 @@ typedef struct
struct xml_elem struct xml_elem
{ {
xmlstr_t name; xmlstr_t name;
xmlstr_t ns;
}; };
struct xml_attr struct xml_attr
@ -561,6 +562,8 @@ struct actctx_loader
unsigned int allocated_dependencies; unsigned int allocated_dependencies;
}; };
static const xmlstr_t empty_xmlstr;
static const WCHAR asmv1W[] = {'a','s','m','v','1',':',0}; static const WCHAR asmv1W[] = {'a','s','m','v','1',':',0};
static const WCHAR asmv2W[] = {'a','s','m','v','2',':',0}; static const WCHAR asmv2W[] = {'a','s','m','v','2',':',0};
static const WCHAR asmv3W[] = {'a','s','m','v','3',':',0}; static const WCHAR asmv3W[] = {'a','s','m','v','3',':',0};
@ -746,13 +749,19 @@ static BOOL xml_attr_cmp( const struct xml_attr *attr, const WCHAR *str )
return xmlstr_cmp( &attr->name, str ); return xmlstr_cmp( &attr->name, str );
} }
static BOOL xml_name_cmp( const struct xml_elem *elem1, const struct xml_elem *elem2 )
{
return (elem1->name.len == elem2->name.len &&
elem1->ns.len == elem2->ns.len &&
!strncmpW( elem1->name.ptr, elem2->name.ptr, elem1->name.len ) &&
!strncmpW( elem1->ns.ptr, elem2->ns.ptr, elem1->ns.len ));
}
static inline BOOL xml_elem_cmp(const struct xml_elem *elem, const WCHAR *str, const WCHAR *namespace) static inline BOOL xml_elem_cmp(const struct xml_elem *elem, const WCHAR *str, const WCHAR *namespace)
{ {
UINT len = strlenW( namespace ); return (!strncmpW(elem->name.ptr, str, elem->name.len) && !str[elem->name.len] &&
(!elem->ns.len ||
if (!strncmpW(elem->name.ptr, str, elem->name.len) && !str[elem->name.len]) return TRUE; (!strncmpW(elem->ns.ptr, namespace, elem->ns.len) && namespace[elem->ns.len] == ':')));
return (elem->name.len > len && !strncmpW(elem->name.ptr, namespace, len) &&
!strncmpW(elem->name.ptr + len, str, elem->name.len - len) && !str[elem->name.len - len]);
} }
static inline BOOL isxmlspace( WCHAR ch ) static inline BOOL isxmlspace( WCHAR ch )
@ -767,7 +776,8 @@ static inline const char* debugstr_xmlstr(const xmlstr_t* str)
static inline const char *debugstr_xml_elem( const struct xml_elem *elem ) static inline const char *debugstr_xml_elem( const struct xml_elem *elem )
{ {
return wine_dbg_sprintf( "%s", debugstr_wn( elem->name.ptr, elem->name.len )); return wine_dbg_sprintf( "%s ns %s", debugstr_wn( elem->name.ptr, elem->name.len ),
debugstr_wn( elem->ns.ptr, elem->ns.len ));
} }
static inline const char *debugstr_xml_attr( const struct xml_attr *attr ) static inline const char *debugstr_xml_attr( const struct xml_attr *attr )
@ -1232,6 +1242,26 @@ static BOOL next_xml_attr(xmlbuf_t *xmlbuf, struct xml_attr *attr, BOOL *end)
return set_error( xmlbuf ); return set_error( xmlbuf );
} }
static void read_xml_elem( xmlbuf_t *xmlbuf, struct xml_elem *elem )
{
const WCHAR* ptr = xmlbuf->ptr;
elem->ns = empty_xmlstr;
elem->name.ptr = ptr;
while (ptr < xmlbuf->end && !isxmlspace(*ptr) && *ptr != '>' && *ptr != '/')
{
if (*ptr == ':')
{
elem->ns.ptr = elem->name.ptr;
elem->ns.len = ptr - elem->ns.ptr;
elem->name.ptr = ptr + 1;
}
ptr++;
}
elem->name.len = ptr - elem->name.ptr;
xmlbuf->ptr = ptr;
}
static BOOL next_xml_elem( xmlbuf_t *xmlbuf, struct xml_elem *elem, const struct xml_elem *parent ) static BOOL next_xml_elem( xmlbuf_t *xmlbuf, struct xml_elem *elem, const struct xml_elem *parent )
{ {
const WCHAR* ptr; const WCHAR* ptr;
@ -1263,23 +1293,23 @@ static BOOL next_xml_elem( xmlbuf_t *xmlbuf, struct xml_elem *elem, const struct
} }
xmlbuf->ptr = ptr; xmlbuf->ptr = ptr;
while (ptr < xmlbuf->end && !isxmlspace(*ptr) && *ptr != '>' && (*ptr != '/' || ptr == xmlbuf->ptr))
ptr++;
/* check for element terminating the parent element */ /* check for element terminating the parent element */
if (*xmlbuf->ptr == '/' && if (ptr < xmlbuf->end && *ptr == '/')
ptr - xmlbuf->ptr == parent->name.len + 1 &&
!strncmpW( xmlbuf->ptr + 1, parent->name.ptr, parent->name.len ))
{ {
while (ptr < xmlbuf->end && isxmlspace(*ptr)) ptr++; xmlbuf->ptr++;
if (ptr == xmlbuf->end || *ptr != '>') return set_error( xmlbuf ); read_xml_elem( xmlbuf, elem );
xmlbuf->ptr = ptr + 1; if (!xml_name_cmp( elem, parent ))
{
ERR( "wrong closing element %s for %s\n",
debugstr_xmlstr(&elem->name), debugstr_xmlstr(&parent->name ));
return set_error( xmlbuf );
}
while (xmlbuf->ptr < xmlbuf->end && isxmlspace(*xmlbuf->ptr)) xmlbuf->ptr++;
if (xmlbuf->ptr == xmlbuf->end || *xmlbuf->ptr++ != '>') return set_error( xmlbuf );
return FALSE; return FALSE;
} }
elem->name.ptr = xmlbuf->ptr; read_xml_elem( xmlbuf, elem );
elem->name.len = ptr - xmlbuf->ptr;
xmlbuf->ptr = ptr;
if (xmlbuf->ptr != xmlbuf->end) return TRUE; if (xmlbuf->ptr != xmlbuf->end) return TRUE;
return set_error( xmlbuf ); return set_error( xmlbuf );