[04/10] webservices: Add support for reading double values.

Hans Leidekker hans at codeweavers.com
Fri Apr 22 02:42:41 CDT 2016


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/reader.c       | 69 +++++++++++++++++++++++++++++++++++++++++
 dlls/webservices/tests/reader.c | 22 +++++++++++++
 2 files changed, 91 insertions(+)

diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index e30864d..b1a120c 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -17,6 +17,7 @@
  */
 
 #include <stdarg.h>
+#include <stdlib.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -1881,6 +1882,18 @@ static HRESULT str_to_uint64( const unsigned char *str, ULONG len, UINT64 max, U
     return S_OK;
 }
 
+static HRESULT str_to_double( const unsigned char *bytes, ULONG len, double *ret )
+{
+    char *end, *str = heap_alloc( len + 1 ); /* FIXME */
+    if (!str) return E_OUTOFMEMORY;
+    memcpy( str, bytes, len );
+    str[len] = 0;
+    *ret = strtod( str, &end );
+    heap_free( str );
+    if (!*ret && end == str) return WS_E_INVALID_FORMAT;
+    return S_OK;
+}
+
 static HRESULT read_get_node_text( struct reader *reader, WS_XML_UTF8_TEXT **ret )
 {
     WS_XML_TEXT_NODE *text;
@@ -2570,6 +2583,53 @@ static HRESULT read_type_enum( struct reader *reader, WS_TYPE_MAPPING mapping,
     return S_OK;
 }
 
+static HRESULT read_type_double( struct reader *reader, WS_TYPE_MAPPING mapping,
+                                 const WS_XML_STRING *localname, const WS_XML_STRING *ns,
+                                 const WS_DOUBLE_DESCRIPTION *desc, WS_READ_OPTION option,
+                                 WS_HEAP *heap, void *ret, ULONG size )
+{
+    WS_XML_UTF8_TEXT *utf8;
+    HRESULT hr;
+    double val = 0.0;
+    BOOL found;
+
+    if (desc) FIXME( "ignoring description\n" );
+
+    if ((hr = read_get_text( reader, mapping, localname, ns, &utf8, &found )) != S_OK) return hr;
+    if (found && (hr = str_to_double( utf8->value.bytes, utf8->value.length, &val )) != S_OK) return hr;
+
+    switch (option)
+    {
+    case WS_READ_REQUIRED_VALUE:
+        if (!found) return WS_E_INVALID_FORMAT;
+        if (size != sizeof(double)) return E_INVALIDARG;
+        *(double *)ret = val;
+        break;
+
+    case WS_READ_REQUIRED_POINTER:
+        if (!found) return WS_E_INVALID_FORMAT;
+        /* fall through */
+
+    case WS_READ_OPTIONAL_POINTER:
+    {
+        double *heap_val = NULL;
+        if (size != sizeof(heap_val)) return E_INVALIDARG;
+        if (found)
+        {
+            if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
+            *heap_val = val;
+        }
+        *(double **)ret = heap_val;
+        break;
+    }
+    default:
+        FIXME( "read option %u not supported\n", option );
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
 static BOOL is_empty_text_node( const struct node *node )
 {
     const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node;
@@ -2643,6 +2703,9 @@ static ULONG get_type_size( WS_TYPE type, const WS_STRUCT_DESCRIPTION *desc )
     case WS_UINT64_TYPE:
         return sizeof(INT64);
 
+    case WS_DOUBLE_TYPE:
+        return sizeof(double);
+
     case WS_WSZ_TYPE:
         return sizeof(WCHAR *);
 
@@ -2745,6 +2808,7 @@ static WS_READ_OPTION map_field_options( WS_TYPE type, ULONG options )
     case WS_UINT16_TYPE:
     case WS_UINT32_TYPE:
     case WS_UINT64_TYPE:
+    case WS_DOUBLE_TYPE:
     case WS_ENUM_TYPE:
         return WS_READ_REQUIRED_VALUE;
 
@@ -2979,6 +3043,11 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP
             return hr;
         break;
 
+    case WS_DOUBLE_TYPE:
+        if ((hr = read_type_double( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
+            return hr;
+        break;
+
     default:
         FIXME( "type %u not supported\n", type );
         return E_NOTIMPL;
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 5c94fef..a20ac71 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -1330,6 +1330,7 @@ static void test_WsReadType(void)
     WS_ENUM_VALUE enum_values[] = { { ONE, &one }, { TWO, &two } };
     WS_ENUM_DESCRIPTION enum_desc;
     int val_enum;
+    double val_double;
     WCHAR *val_str;
     BOOL val_bool;
     INT8 val_int8;
@@ -1579,6 +1580,27 @@ static void test_WsReadType(void)
     ok( hr == S_OK, "got %08x\n", hr );
     ok( val_enum == 1, "got %d\n", val_enum );
 
+    val_double = 0.0;
+    prepare_type_test( reader, "<t>0.333333</t>", sizeof("<t>0.333333</t>") - 1 );
+    hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
+                     WS_READ_REQUIRED_VALUE, heap, &val_double, sizeof(val_double), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( val_double == 0.333333, "got %f\n", val_double );
+
+    val_double = 1.0;
+    prepare_type_test( reader, "<t>0.0</t>", sizeof("<t>0.0</t>") - 1 );
+    hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
+                     WS_READ_REQUIRED_VALUE, heap, &val_double, sizeof(val_double), NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( val_double == 0.0, "got %f\n", val_double );
+
+    val_double = 0.0;
+    prepare_type_test( reader, "<t>nodouble</t>", sizeof("<t>nodouble</t>") - 1 );
+    hr = WsReadType( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, WS_DOUBLE_TYPE, NULL,
+                     WS_READ_REQUIRED_VALUE, heap, &val_double, sizeof(val_double), NULL );
+    ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+    ok( val_double == 0.0, "got %f\n", val_double );
+
     WsFreeReader( reader );
     WsFreeHeap( heap );
 }
-- 
2.8.0.rc3




More information about the wine-patches mailing list