diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 0e67eaf7a83..446fa1dcc28 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -1211,6 +1211,98 @@ static void test_WsWriteXmlnsAttribute(void) WsFreeWriter( writer ); } +static void prepare_prefix_test( WS_XML_WRITER *writer ) +{ + const WS_XML_STRING p = {1, (BYTE *)"p"}, localname = {1, (BYTE *)"t"}, ns = {2, (BYTE *)"ns"}; + HRESULT hr; + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, &p, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndStartElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); +} + +static void test_WsGetPrefixFromNamespace(void) +{ + const WS_XML_STRING p = {1, (BYTE *)"p"}, localname = {1, (BYTE *)"t"}, *prefix; + const WS_XML_STRING ns = {2, (BYTE *)"ns"}, ns2 = {3, (BYTE *)"ns2"}; + WS_XML_WRITER *writer; + HRESULT hr; + + hr = WsCreateWriter( NULL, 0, &writer, NULL ) ; + ok( hr == S_OK, "got %08x\n", hr ); + + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, &p, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetPrefixFromNamespace( NULL, NULL, FALSE, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsGetPrefixFromNamespace( NULL, NULL, FALSE, &prefix, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsGetPrefixFromNamespace( writer, NULL, FALSE, &prefix, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + /* element must be committed */ + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, &p, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsGetPrefixFromNamespace( writer, &ns, TRUE, &prefix, NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + /* but writer can't be positioned on end element node */ + hr = set_output( writer ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteStartElement( writer, &p, &localname, &ns, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsWriteEndElement( writer, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + hr = WsGetPrefixFromNamespace( writer, &ns, TRUE, &prefix, NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + + /* required = TRUE */ + prefix = NULL; + prepare_prefix_test( writer ); + hr = WsGetPrefixFromNamespace( writer, &ns, TRUE, &prefix, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( prefix != NULL, "prefix not set\n" ); + if (prefix) + { + ok( prefix->length == 1, "got %u\n", prefix->length ); + ok( !memcmp( prefix->bytes, "p", 1 ), "wrong prefix\n" ); + } + + prefix = (const WS_XML_STRING *)0xdeadbeef; + hr = WsGetPrefixFromNamespace( writer, &ns2, TRUE, &prefix, NULL ); + ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr ); + ok( prefix == (const WS_XML_STRING *)0xdeadbeef, "prefix set\n" ); + + /* required = FALSE */ + prefix = NULL; + prepare_prefix_test( writer ); + hr = WsGetPrefixFromNamespace( writer, &ns, FALSE, &prefix, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( prefix != NULL, "prefix not set\n" ); + if (prefix) + { + ok( prefix->length == 1, "got %u\n", prefix->length ); + ok( !memcmp( prefix->bytes, "p", 1 ), "wrong prefix\n" ); + } + + prefix = (const WS_XML_STRING *)0xdeadbeef; + hr = WsGetPrefixFromNamespace( writer, &ns2, FALSE, &prefix, NULL ); + ok( hr == S_FALSE, "got %08x\n", hr ); + ok( prefix == NULL, "prefix not set\n" ); + + WsFreeWriter( writer ); +} + START_TEST(writer) { test_WsCreateWriter(); @@ -1227,4 +1319,5 @@ START_TEST(writer) test_WsWriteAttribute(); test_WsWriteStartCData(); test_WsWriteXmlnsAttribute(); + test_WsGetPrefixFromNamespace(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index 3b0f1fc6c2d..f0a843ae3a5 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -79,7 +79,7 @@ @ stub WsGetOperationContextProperty @ stub WsGetPolicyAlternativeCount @ stub WsGetPolicyProperty -@ stub WsGetPrefixFromNamespace +@ stdcall WsGetPrefixFromNamespace(ptr ptr long ptr ptr) @ stdcall WsGetReaderNode(ptr ptr ptr) @ stub WsGetReaderPosition @ stdcall WsGetReaderProperty(ptr long ptr long ptr) diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index f55f6440a73..14bddfbd758 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -493,6 +493,37 @@ static inline BOOL is_current_namespace( struct writer *writer, const WS_XML_STR return (WsXmlStringEquals( writer->current_ns, ns, NULL ) == S_OK); } +/************************************************************************** + * WsGetPrefixFromNamespace [webservices.@] + */ +HRESULT WINAPI WsGetPrefixFromNamespace( WS_XML_WRITER *handle, const WS_XML_STRING *ns, + BOOL required, const WS_XML_STRING **prefix, + WS_ERROR *error ) +{ + struct writer *writer = (struct writer *)handle; + WS_XML_ELEMENT_NODE *elem; + BOOL found = FALSE; + + TRACE( "%p %s %d %p %p\n", handle, debugstr_xmlstr(ns), required, prefix, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!writer || !ns || !prefix) return E_INVALIDARG; + + elem = &writer->current->hdr; + if (elem->prefix && is_current_namespace( writer, ns )) + { + *prefix = elem->prefix; + found = TRUE; + } + if (!found) + { + if (required) return WS_E_INVALID_FORMAT; + *prefix = NULL; + return S_FALSE; + } + return S_OK; +} + static HRESULT set_current_namespace( struct writer *writer, const WS_XML_STRING *ns ) { WS_XML_STRING *str; diff --git a/include/webservices.h b/include/webservices.h index 73b7f0a688b..cd82cb750e4 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 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*); HRESULT WINAPI WsGetReaderPosition(WS_XML_READER*, WS_XML_NODE_POSITION*, WS_ERROR*); HRESULT WINAPI WsGetReaderProperty(WS_XML_READER*, WS_XML_READER_PROPERTY_ID, void*, ULONG, WS_ERROR*);