From 992da703397758445f4190f24dfa2c2ea684fb60 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Fri, 28 Apr 2017 12:12:47 +0200 Subject: [PATCH] webservices: Implement WsWriteQualifiedName. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/tests/writer.c | 79 ++++++++++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 2 +- dlls/webservices/writer.c | 84 +++++++++++++++++++++++++++++++++++++++ include/webservices.h | 2 + 4 files changed, 166 insertions(+), 1 deletion(-) diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 8cd9762fa2b..3d0124544aa 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -3036,6 +3036,84 @@ static void test_repeating_element(void) WsFreeWriter( writer ); } +static const WS_XML_STRING *init_xmlstring( const char *src, WS_XML_STRING *str ) +{ + if (!src) return NULL; + str->length = strlen( src ); + str->bytes = (BYTE *)src; + return str; +} + +static void test_WsWriteQualifiedName(void) +{ + WS_XML_STRING prefix = {1, (BYTE *)"p"}, localname = {1, (BYTE *)"t"}, ns = {2, (BYTE *)"ns"}; + WS_XML_WRITER *writer; + HRESULT hr; + ULONG i; + static const struct + { + const char *prefix; + const char *localname; + const char *ns; + HRESULT hr; + const char *result; + } tests[] = + { + { NULL, NULL, NULL, E_INVALIDARG, NULL }, + { NULL, "t2", NULL, E_INVALIDARG, NULL }, + { "p2", "t2", NULL, S_OK, "p2:t2" }, + { NULL, "t2", "ns2", WS_E_INVALID_FORMAT, NULL }, + { NULL, "t2", "ns", S_OK, "p:t2" }, + { "p2", "t2", "ns2", S_OK, "p2:t2" }, + { "p2", "t2", "ns", S_OK, "p2:t2" }, + { "p", "t", NULL, S_OK, "p:t" }, + { NULL, "t", "ns", S_OK, "p:t" }, + { "p2", "", "", S_OK, "p2:" }, + { "p2", "", "ns2", S_OK, "p2:" }, + { "p2", "t2", "", S_OK, "p2:t2" }, + { "", "t2", "", S_OK, "t2" }, + { "", "", "ns2", S_OK, "" }, + { "", "", "", S_OK, "" }, + }; + + hr = WsWriteQualifiedName( NULL, NULL, NULL, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsCreateWriter( NULL, 0, &writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteQualifiedName( writer, NULL, NULL, NULL, NULL ); + ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsWriteQualifiedName( writer, NULL, NULL, NULL, NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + WS_XML_STRING prefix2, localname2, ns2; + const WS_XML_STRING *prefix_ptr, *localname_ptr, *ns_ptr; + + hr = set_output( writer ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + hr = WsWriteStartElement( writer, &prefix, &localname, &ns, NULL ); + ok( hr == S_OK, "%u: got %08x\n", i, hr ); + + prefix_ptr = init_xmlstring( tests[i].prefix, &prefix2 ); + localname_ptr = init_xmlstring( tests[i].localname, &localname2 ); + ns_ptr = init_xmlstring( tests[i].ns, &ns2 ); + + hr = WsWriteQualifiedName( writer, prefix_ptr, localname_ptr, ns_ptr, NULL ); + ok( hr == tests[i].hr, "%u: got %08x\n", i, hr ); + if (tests[i].hr == S_OK && hr == S_OK) check_output( writer, tests[i].result, __LINE__ ); + } + + WsFreeWriter( writer ); +} + START_TEST(writer) { test_WsCreateWriter(); @@ -3069,4 +3147,5 @@ START_TEST(writer) test_write_option(); test_datetime(); test_repeating_element(); + test_WsWriteQualifiedName(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index aa9b58f8a05..e63b8056598 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -180,7 +180,7 @@ @ stdcall WsWriteMessageEnd(ptr ptr ptr ptr) @ stdcall WsWriteMessageStart(ptr ptr ptr ptr) @ stdcall WsWriteNode(ptr ptr ptr) -@ stub WsWriteQualifiedName +@ stdcall WsWriteQualifiedName(ptr ptr ptr ptr ptr) @ stdcall WsWriteStartAttribute(ptr ptr ptr ptr long ptr) @ stdcall WsWriteStartCData(ptr ptr) @ stdcall WsWriteStartElement(ptr ptr ptr ptr ptr) diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index 4c9f1a91d10..4fd112642f2 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -2800,6 +2800,90 @@ HRESULT WINAPI WsWriteXmlnsAttribute( WS_XML_WRITER *handle, const WS_XML_STRING return hr; } +static HRESULT find_prefix( struct writer *writer, const WS_XML_STRING *ns, const WS_XML_STRING **prefix ) +{ + const struct node *node; + for (node = writer->current; node_type( node ) == WS_XML_NODE_TYPE_ELEMENT; node = node->parent) + { + const WS_XML_ELEMENT_NODE *elem = &node->hdr; + ULONG i; + for (i = 0; i < elem->attributeCount; i++) + { + if (!elem->attributes[i]->isXmlNs) continue; + if (WsXmlStringEquals( elem->attributes[i]->ns, ns, NULL ) != S_OK) continue; + *prefix = elem->attributes[i]->prefix; + return S_OK; + } + } + return WS_E_INVALID_FORMAT; +} + +static HRESULT write_qualified_name( struct writer *writer, const WS_XML_STRING *prefix, + const WS_XML_STRING *localname ) +{ + HRESULT hr; + if (prefix->length) + { + if ((hr = write_grow_buffer( writer, prefix->length + localname->length + 1 )) != S_OK) return hr; + write_bytes( writer, prefix->bytes, prefix->length ); + write_char( writer, ':' ); + } + else if ((hr = write_grow_buffer( writer, localname->length )) != S_OK) return hr; + write_bytes( writer, localname->bytes, localname->length ); + return S_OK; +} + +/************************************************************************** + * WsWriteQualifiedName [webservices.@] + */ +HRESULT WINAPI WsWriteQualifiedName( WS_XML_WRITER *handle, const WS_XML_STRING *prefix, + const WS_XML_STRING *localname, const WS_XML_STRING *ns, + WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + HRESULT hr; + + TRACE( "%p %s %s %s %p\n", handle, debugstr_xmlstr(prefix), debugstr_xmlstr(localname), + debugstr_xmlstr(ns), error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer) return E_INVALIDARG; + + EnterCriticalSection( &writer->cs ); + + if (writer->magic != WRITER_MAGIC) + { + LeaveCriticalSection( &writer->cs ); + return E_INVALIDARG; + } + + if (!writer->output_type) + { + LeaveCriticalSection( &writer->cs ); + return WS_E_INVALID_OPERATION; + } + + if (writer->state != WRITER_STATE_STARTELEMENT) + { + LeaveCriticalSection( &writer->cs ); + return WS_E_INVALID_FORMAT; + } + + if (!localname || (!prefix && !ns)) + { + LeaveCriticalSection( &writer->cs ); + return E_INVALIDARG; + } + + if ((hr = write_flush( writer )) != S_OK) goto done; + if (!prefix && ((hr = find_prefix( writer, ns, &prefix )) != S_OK)) goto done; + hr = write_qualified_name( writer, prefix, localname ); + +done: + LeaveCriticalSection( &writer->cs ); + return hr; +} + static HRESULT write_move_to( struct writer *writer, WS_MOVE_TO move, BOOL *found ) { BOOL success = FALSE; diff --git a/include/webservices.h b/include/webservices.h index 783a6ae77b1..a0857f6bc80 100644 --- a/include/webservices.h +++ b/include/webservices.h @@ -1675,6 +1675,8 @@ HRESULT WINAPI WsWriteEnvelopeStart(WS_MESSAGE*, WS_XML_WRITER*, WS_MESSAGE_DONE HRESULT WINAPI WsWriteMessageStart(WS_CHANNEL*, WS_MESSAGE*, const WS_ASYNC_CONTEXT*, WS_ERROR*); HRESULT WINAPI WsWriteMessageEnd(WS_CHANNEL*, WS_MESSAGE*, const WS_ASYNC_CONTEXT*, WS_ERROR*); HRESULT WINAPI WsWriteNode(WS_XML_WRITER*, const WS_XML_NODE*, WS_ERROR*); +HRESULT WINAPI WsWriteQualifiedName(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*, + const WS_XML_STRING*, WS_ERROR*); HRESULT WINAPI WsWriteStartAttribute(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*, const WS_XML_STRING*, BOOL, WS_ERROR*); HRESULT WINAPI WsWriteStartCData(WS_XML_WRITER*, WS_ERROR*); -- 2.11.4.GIT