From 3609e3f47f04ec01dc874f1188f9f94a7c051d74 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 23 Feb 2016 13:11:55 +0100 Subject: [PATCH] webservices: Implement WsGetNamespaceFromPrefix. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/reader.c | 61 ++++++++++ dlls/webservices/tests/reader.c | 179 ++++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 2 +- include/webservices.h | 2 + 4 files changed, 243 insertions(+), 1 deletion(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 92a8184a15f..f224720389b 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -606,6 +606,67 @@ HRESULT WINAPI WsGetHeapProperty( WS_HEAP *handle, WS_HEAP_PROPERTY_ID id, void return get_heap_prop( heap, id, buf, size ); } +/************************************************************************** + * WsGetNamespaceFromPrefix [webservices.@] + */ +HRESULT WINAPI WsGetNamespaceFromPrefix( WS_XML_READER *handle, const WS_XML_STRING *prefix, + BOOL required, const WS_XML_STRING **ns, WS_ERROR *error ) +{ + static const WS_XML_STRING xml = {3, (BYTE *)"xml"}; + static const WS_XML_STRING xmlns = {5, (BYTE *)"xmlns"}; + static const WS_XML_STRING empty_ns = {0, NULL}; + static const WS_XML_STRING xml_ns = {36, (BYTE *)"http://www.w3.org/XML/1998/namespace"}; + static const WS_XML_STRING xmlns_ns = {29, (BYTE *)"http://www.w3.org/2000/xmlns/"}; + struct reader *reader = (struct reader *)handle; + BOOL found = FALSE; + + TRACE( "%p %s %d %p %p\n", handle, debugstr_xmlstr(prefix), required, ns, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!reader || !prefix || !ns) return E_INVALIDARG; + if (reader->state != READER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION; + + if (!prefix->length) + { + *ns = &empty_ns; + found = TRUE; + } + else if (WsXmlStringEquals( prefix, &xml, NULL ) == S_OK) + { + *ns = &xml_ns; + found = TRUE; + } + else if (WsXmlStringEquals( prefix, &xmlns, NULL ) == S_OK) + { + *ns = &xmlns_ns; + found = TRUE; + } + else + { + WS_XML_ELEMENT_NODE *elem = &reader->current->hdr; + ULONG i; + + for (i = 0; i < elem->attributeCount; i++) + { + if (!elem->attributes[i]->isXmlNs) continue; + if (WsXmlStringEquals( prefix, elem->attributes[i]->prefix, NULL ) == S_OK) + { + *ns = elem->attributes[i]->ns; + found = TRUE; + break; + } + } + } + + if (!found) + { + if (required) return WS_E_INVALID_FORMAT; + *ns = NULL; + return S_FALSE; + } + return S_OK; +} + /************************************************************************** * WsGetReaderNode [webservices.@] */ diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c index 8fba4eb4b23..720379e076a 100644 --- a/dlls/webservices/tests/reader.c +++ b/dlls/webservices/tests/reader.c @@ -2005,6 +2005,184 @@ static void test_WsFindAttribute(void) WsFreeReader( reader ); } +static void prepare_namespace_test( WS_XML_READER *reader, const char *data ) +{ + HRESULT hr; + ULONG size = strlen( data ); + + hr = set_input( reader, data, size ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); +} + +static void test_WsGetNamespaceFromPrefix(void) +{ + WS_XML_STRING prefix = {0, NULL}; + const WS_XML_STRING *ns; + const WS_XML_NODE *node; + WS_XML_READER *reader; + HRESULT hr; + + hr = WsCreateReader( NULL, 0, &reader, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsGetNamespaceFromPrefix( NULL, NULL, FALSE, &ns, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsGetNamespaceFromPrefix( NULL, &prefix, FALSE, &ns, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + ns = (const WS_XML_STRING *)0xdeadbeef; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + ok( ns == (const WS_XML_STRING *)0xdeadbeef, "ns set\n" ); + + hr = set_input( reader, "", sizeof("") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsReadStartElement( reader, NULL ); + todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + prepare_namespace_test( reader, "" ); + ns = NULL; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( ns != NULL, "ns not set\n" ); + if (ns) ok( !ns->length, "got %u\n", ns->length ); + + prepare_namespace_test( reader, "" ); + ns = NULL; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( ns != NULL, "ns not set\n" ); + if (ns) ok( !ns->length, "got %u\n", ns->length ); + + prepare_namespace_test( reader, "" ); + ns = NULL; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( ns != NULL, "ns not set\n" ); + if (ns) ok( !ns->length, "got %u\n", ns->length ); + + prepare_namespace_test( reader, "" ); + prefix.bytes = (BYTE *)"prefix"; + prefix.length = 6; + ns = NULL; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( ns != NULL, "ns not set\n" ); + if (ns) + { + ok( ns->length == 2, "got %u\n", ns->length ); + ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" ); + } + + prepare_namespace_test( reader, ">/t>" ); + ns = NULL; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( ns != NULL, "ns not set\n" ); + if (ns) + { + ok( ns->length == 2, "got %u\n", ns->length ); + ok( !memcmp( ns->bytes, "ns", 2 ), "wrong data\n" ); + } + + hr = set_input( reader, "", sizeof("") - 1 ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsReadToStartElement( reader, NULL, NULL, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsGetReaderNode( reader, &node, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + if (node) + { + WS_XML_ELEMENT_NODE *elem = (WS_XML_ELEMENT_NODE *)node; + WS_XML_ATTRIBUTE *attr; + WS_XML_UTF8_TEXT *text; + + ok( elem->node.nodeType == WS_XML_NODE_TYPE_ELEMENT, "got %u\n", elem->node.nodeType ); + ok( elem->attributeCount == 1, "got %u\n", elem->attributeCount ); + ok( elem->attributes != NULL, "attributes not set\n" ); + + attr = elem->attributes[0]; + ok( attr->singleQuote, "singleQuote not set\n" ); + ok( attr->isXmlNs, "isXmlNs not set\n" ); + ok( attr->prefix != NULL, "prefix not set\n" ); + ok( attr->prefix->length == 6, "got %u\n", attr->prefix->length ); + ok( attr->prefix->bytes != NULL, "bytes not set\n" ); + ok( !memcmp( attr->prefix->bytes, "prefix", 6 ), "wrong data\n" ); + ok( attr->localName != NULL, "localName not set\n" ); + ok( attr->localName->length == 6, "got %u\n", attr->localName->length ); + ok( !memcmp( attr->localName->bytes, "prefix", 6 ), "wrong data\n" ); + ok( attr->ns != NULL, "ns not set\n" ); + ok( attr->ns->length == 2, "got %u\n", attr->ns->length ); + ok( attr->ns->bytes != NULL, "bytes set\n" ); + ok( !memcmp( attr->ns->bytes, "ns", 2 ), "wrong data\n" ); + ok( attr->value != NULL, "value not set\n" ); + + text = (WS_XML_UTF8_TEXT *)attr->value; + ok( attr->value->textType == WS_XML_TEXT_TYPE_UTF8, "got %u\n", attr->value->textType ); + ok( !text->value.length, "got %u\n", text->value.length ); + ok( text->value.bytes == NULL, "bytes set\n" ); + } + + prepare_namespace_test( reader, "" ); + hr = WsReadStartElement( reader, NULL ); + todo_wine ok( hr == S_OK, "got %08x\n", hr ); + hr = WsReadEndElement( reader, NULL ); + todo_wine ok( hr == S_OK, "got %08x\n", hr ); + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + todo_wine ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + prepare_namespace_test( reader, "" ); + ns = NULL; + prefix.bytes = (BYTE *)"xml"; + prefix.length = 3; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( ns != NULL, "ns not set\n" ); + if (ns) + { + ok( ns->length == 36, "got %u\n", ns->length ); + ok( !memcmp( ns->bytes, "http://www.w3.org/XML/1998/namespace", 36 ), "wrong data\n" ); + } + + prepare_namespace_test( reader, "" ); + ns = NULL; + prefix.bytes = (BYTE *)"xmlns"; + prefix.length = 5; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( ns != NULL, "ns not set\n" ); + if (ns) + { + ok( ns->length == 29, "got %u\n", ns->length ); + ok( !memcmp( ns->bytes, "http://www.w3.org/2000/xmlns/", 29 ), "wrong data\n" ); + } + + prepare_namespace_test( reader, "" ); + ns = (WS_XML_STRING *)0xdeadbeef; + prefix.bytes = (BYTE *)"prefix2"; + prefix.length = 7; + hr = WsGetNamespaceFromPrefix( reader, &prefix, TRUE, &ns, NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( ns == (WS_XML_STRING *)0xdeadbeef, "ns set\n" ); + + prepare_namespace_test( reader, "" ); + ns = (WS_XML_STRING *)0xdeadbeef; + prefix.bytes = (BYTE *)"prefix2"; + prefix.length = 7; + hr = WsGetNamespaceFromPrefix( reader, &prefix, FALSE, &ns, NULL ); + ok( hr == S_FALSE, "got %08x\n", hr ); + ok( ns == NULL, "ns not set\n" ); + + WsFreeReader( reader ); +} + START_TEST(reader) { test_WsCreateError(); @@ -2025,4 +2203,5 @@ START_TEST(reader) test_simple_struct_type(); test_cdata(); test_WsFindAttribute(); + test_WsGetNamespaceFromPrefix(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index f0a843ae3a5..9c0b3c76704 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -75,7 +75,7 @@ @ stub WsGetMetadataEndpoints @ stub WsGetMetadataProperty @ stub WsGetMissingMetadataDocumentAddress -@ stub WsGetNamespaceFromPrefix +@ stdcall WsGetNamespaceFromPrefix(ptr ptr long ptr ptr) @ stub WsGetOperationContextProperty @ stub WsGetPolicyAlternativeCount @ stub WsGetPolicyProperty diff --git a/include/webservices.h b/include/webservices.h index cd82cb750e4..1b13fce306b 100644 --- a/include/webservices.h +++ b/include/webservices.h @@ -556,6 +556,8 @@ void WINAPI WsFreeWriter(WS_XML_WRITER*); HRESULT WINAPI WsGetErrorProperty(WS_ERROR*, WS_ERROR_PROPERTY_ID, void*, ULONG); HRESULT WINAPI WsGetErrorString(WS_ERROR*, ULONG, WS_STRING*); HRESULT WINAPI WsGetHeapProperty(WS_HEAP*, WS_HEAP_PROPERTY_ID, void*, ULONG, WS_ERROR*); +HRESULT WINAPI WsGetNamespaceFromPrefix(WS_XML_READER*, const WS_XML_STRING*, BOOL, + const WS_XML_STRING**, WS_ERROR*); HRESULT WINAPI WsGetPrefixFromNamespace(WS_XML_WRITER*, const WS_XML_STRING*, BOOL, const WS_XML_STRING**, WS_ERROR*); HRESULT WINAPI WsGetReaderNode(WS_XML_READER*, const WS_XML_NODE**, WS_ERROR*);