Module: wine Branch: master Commit: 03a63781fa47d50a05e29c907d32817aba5e40df URL: http://source.winehq.org/git/wine.git/?a=commit;h=03a63781fa47d50a05e29c907d...
Author: Hans Leidekker hans@codeweavers.com Date: Tue Jun 6 09:55:57 2017 +0200
webservices: Implement WsGetCustomHeader.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/webservices/msg.c | 91 ++++++++++++++++++++++++++++++++++----- dlls/webservices/tests/msg.c | 68 +++++++++++++++++++++++++++++ dlls/webservices/webservices.spec | 2 +- 3 files changed, 149 insertions(+), 12 deletions(-)
diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c index 6d61aa0..74c6fd1 100644 --- a/dlls/webservices/msg.c +++ b/dlls/webservices/msg.c @@ -1081,23 +1081,16 @@ done: return hr; }
-static HRESULT get_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYPE value_type, - WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size ) +static HRESULT find_header( WS_XML_READER *reader, const WS_XML_STRING *localname, const WS_XML_STRING *ns ) { - const WS_XML_STRING *localname = get_header_name( type ); - const WS_XML_STRING *ns = get_addr_namespace( msg->version_addr ); - const WS_XML_ELEMENT_NODE *elem; const WS_XML_NODE *node; + const WS_XML_ELEMENT_NODE *elem; HRESULT hr;
- if (!heap) heap = msg->heap; - if (!msg->reader && (hr = WsCreateReader( NULL, 0, &msg->reader, NULL )) != S_OK) return hr; - if ((hr = WsSetInputToBuffer( msg->reader, msg->buf, NULL, 0, NULL )) != S_OK) return hr; - for (;;) { - if ((hr = WsReadNode( msg->reader, NULL )) != S_OK) return hr; - if ((hr = WsGetReaderNode( msg->reader, &node, NULL )) != S_OK) return hr; + if ((hr = WsReadNode( reader, NULL )) != S_OK) return hr; + if ((hr = WsGetReaderNode( reader, &node, NULL )) != S_OK) return hr; if (node->nodeType == WS_XML_NODE_TYPE_EOF) return WS_E_INVALID_FORMAT; if (node->nodeType != WS_XML_NODE_TYPE_ELEMENT) continue;
@@ -1106,6 +1099,21 @@ static HRESULT get_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYP WsXmlStringEquals( elem->ns, ns, NULL ) == S_OK) break; }
+ return S_OK; +} + +static HRESULT get_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYPE value_type, + WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size ) +{ + const WS_XML_STRING *localname = get_header_name( type ); + const WS_XML_STRING *ns = get_addr_namespace( msg->version_addr ); + HRESULT hr; + + if (!heap) heap = msg->heap; + if (!msg->reader && (hr = WsCreateReader( NULL, 0, &msg->reader, NULL )) != S_OK) return hr; + if ((hr = WsSetInputToBuffer( msg->reader, msg->buf, NULL, 0, NULL )) != S_OK) return hr; + + if ((hr = find_header( msg->reader, localname, ns )) != S_OK) return hr; return read_header( msg->reader, localname, ns, value_type, NULL, option, heap, value, size ); }
@@ -1463,6 +1471,67 @@ done: return hr; }
+static HRESULT get_custom_header( struct msg *msg, const WS_ELEMENT_DESCRIPTION *desc, WS_READ_OPTION option, + WS_HEAP *heap, void *value, ULONG size ) +{ + HRESULT hr; + if (!heap) heap = msg->heap; + if (!msg->reader && (hr = WsCreateReader( NULL, 0, &msg->reader, NULL )) != S_OK) return hr; + if ((hr = WsSetInputToBuffer( msg->reader, msg->buf, NULL, 0, NULL )) != S_OK) return hr; + + if ((hr = find_header( msg->reader, desc->elementLocalName, desc->elementNs )) != S_OK) return hr; + return read_header( msg->reader, desc->elementLocalName, desc->elementNs, desc->type, desc->typeDescription, + option, heap, value, size ); +} + +/************************************************************************** + * WsGetCustomHeader [webservices.@] + */ +HRESULT WINAPI WsGetCustomHeader( WS_MESSAGE *handle, const WS_ELEMENT_DESCRIPTION *desc, + WS_REPEATING_HEADER_OPTION repeat_option, ULONG index, WS_READ_OPTION option, + WS_HEAP *heap, void *value, ULONG size, ULONG *attrs, WS_ERROR *error ) +{ + struct msg *msg = (struct msg *)handle; + HRESULT hr; + + TRACE( "%p %p %08x %u %08x %p %p %u %p %p\n", handle, desc, repeat_option, index, option, heap, value, + size, attrs, error ); + if (error) FIXME( "ignoring error parameter\n" ); + + if (!msg || !desc || repeat_option < WS_REPEATING_HEADER || repeat_option > WS_SINGLETON_HEADER || + (repeat_option == WS_SINGLETON_HEADER && index)) return E_INVALIDARG; + + if (repeat_option == WS_REPEATING_HEADER) + { + FIXME( "repeating header not supported\n" ); + return E_NOTIMPL; + } + if (attrs) + { + FIXME( "attributes not supported\n" ); + return E_NOTIMPL; + } + + EnterCriticalSection( &msg->cs ); + + if (msg->magic != MSG_MAGIC) + { + LeaveCriticalSection( &msg->cs ); + return E_INVALIDARG; + } + + if (msg->state < WS_MESSAGE_STATE_INITIALIZED) + { + LeaveCriticalSection( &msg->cs ); + return WS_E_INVALID_OPERATION; + } + + hr = get_custom_header( msg, desc, option, heap, value, size ); + + LeaveCriticalSection( &msg->cs ); + return hr; +} + /************************************************************************** * WsRemoveCustomHeader [webservices.@] */ diff --git a/dlls/webservices/tests/msg.c b/dlls/webservices/tests/msg.c index 4b33b55..d26293b 100644 --- a/dlls/webservices/tests/msg.c +++ b/dlls/webservices/tests/msg.c @@ -1268,6 +1268,73 @@ static void test_WsGetHeader(void) WsFreeMessage( msg ); }
+static void test_WsGetCustomHeader(void) +{ + static char expected[] = + "<Envelope><Header><Custom xmlns="ns">value</Custom></Header><Body/></Envelope>"; + static WS_XML_STRING custom = {6, (BYTE *)"Custom"}, ns = {2, (BYTE *)"ns"}; + static WCHAR valueW[] = {'v','a','l','u','e',0}; + WS_ELEMENT_DESCRIPTION desc; + WS_STRUCT_DESCRIPTION s; + WS_FIELD_DESCRIPTION f, *fields[1]; + WS_MESSAGE *msg; + HRESULT hr; + struct header + { + const WCHAR *value; + } test; + + hr = WsGetCustomHeader( NULL, NULL, 0, 0, 0, NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsCreateMessage( WS_ENVELOPE_VERSION_NONE, WS_ADDRESSING_VERSION_TRANSPORT, NULL, 0, &msg, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = WsGetCustomHeader( msg, NULL, 0, 0, 0, NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + memset( &f, 0, sizeof(f) ); + f.mapping = WS_TEXT_FIELD_MAPPING; + f.type = WS_WSZ_TYPE; + fields[0] = &f; + + memset( &s, 0, sizeof(s) ); + s.size = sizeof(struct header); + s.alignment = TYPE_ALIGNMENT(struct header); + s.fields = fields; + s.fieldCount = 1; + + desc.elementLocalName = &custom; + desc.elementNs = &ns; + desc.type = WS_STRUCT_TYPE; + desc.typeDescription = &s; + + test.value = valueW; + hr = WsAddCustomHeader( msg, &desc, WS_WRITE_REQUIRED_VALUE, &test, sizeof(test), 0, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + check_output_header( msg, expected, -1, 0, 0, __LINE__ ); + + hr = WsGetCustomHeader( msg, &desc, 0, 0, 0, NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsGetCustomHeader( msg, &desc, WS_SINGLETON_HEADER, 1, 0, NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + hr = WsGetCustomHeader( msg, &desc, WS_SINGLETON_HEADER, 0, WS_READ_REQUIRED_VALUE, NULL, NULL, 0, NULL, NULL ); + ok( hr == E_INVALIDARG, "got %08x\n", hr ); + + memset( &test, 0, sizeof(test) ); + hr = WsGetCustomHeader( msg, &desc, WS_SINGLETON_HEADER, 0, WS_READ_REQUIRED_VALUE, NULL, &test, sizeof(test), + NULL, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + ok( test.value != NULL, "value not set\n" ); + ok( !memcmp( test.value, valueW, sizeof(valueW) ), "wrong value\n" ); + WsFreeMessage( msg ); +} + START_TEST(msg) { test_WsCreateMessage(); @@ -1288,4 +1355,5 @@ START_TEST(msg) test_WsReadBody(); test_WsResetMessage(); test_WsGetHeader(); + test_WsGetCustomHeader(); } diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec index b6f246c..3e77436 100644 --- a/dlls/webservices/webservices.spec +++ b/dlls/webservices/webservices.spec @@ -60,7 +60,7 @@ @ stdcall WsFreeServiceProxy(ptr) @ stdcall WsFreeWriter(ptr) @ stdcall WsGetChannelProperty(ptr long ptr long ptr) -@ stub WsGetCustomHeader +@ stdcall WsGetCustomHeader(ptr ptr long long long ptr ptr long ptr ptr) @ stdcall WsGetDictionary(long ptr ptr) @ stdcall WsGetErrorProperty(ptr long ptr long) @ stdcall WsGetErrorString(ptr long ptr)