[05/10] webservices: Add support for integer records in the writer.

Hans Leidekker hans at codeweavers.com
Wed Jul 12 08:34:33 CDT 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/writer.c | 270 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 197 insertions(+), 73 deletions(-)

diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index d2ee285..1e97bce 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -17,6 +17,7 @@
  */
 
 #include "config.h"
+#include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <math.h>
@@ -673,12 +674,67 @@ static enum record_type get_attr_text_record_type( const WS_XML_TEXT *text )
         const WS_XML_BOOL_TEXT *text_bool = (const WS_XML_BOOL_TEXT *)text;
         return text_bool->value ? RECORD_TRUE_TEXT : RECORD_FALSE_TEXT;
     }
+    case WS_XML_TEXT_TYPE_INT32:
+    {
+        const WS_XML_INT32_TEXT *text_int32 = (const WS_XML_INT32_TEXT *)text;
+        if (!text_int32->value) return RECORD_ZERO_TEXT;
+        if (text_int32->value == 1) return RECORD_ONE_TEXT;
+        if (text_int32->value >= MIN_INT8 && text_int32->value <= MAX_INT8) return RECORD_INT8_TEXT;
+        if (text_int32->value >= MIN_INT16 && text_int32->value <= MAX_INT16) return RECORD_INT16_TEXT;
+        return RECORD_INT32_TEXT;
+    }
+    case WS_XML_TEXT_TYPE_INT64:
+    {
+        const WS_XML_INT64_TEXT *text_int64 = (const WS_XML_INT64_TEXT *)text;
+        if (!text_int64->value) return RECORD_ZERO_TEXT;
+        if (text_int64->value == 1) return RECORD_ONE_TEXT;
+        if (text_int64->value >= MIN_INT8 && text_int64->value <= MAX_INT8) return RECORD_INT8_TEXT;
+        if (text_int64->value >= MIN_INT16 && text_int64->value <= MAX_INT16) return RECORD_INT16_TEXT;
+        if (text_int64->value >= MIN_INT32 && text_int64->value <= MAX_INT32) return RECORD_INT32_TEXT;
+        return RECORD_INT64_TEXT;
+    }
+    case WS_XML_TEXT_TYPE_UINT64:
+    {
+        const WS_XML_UINT64_TEXT *text_uint64 = (const WS_XML_UINT64_TEXT *)text;
+        if (!text_uint64->value) return RECORD_ZERO_TEXT;
+        if (text_uint64->value == 1) return RECORD_ONE_TEXT;
+        if (text_uint64->value <= MAX_INT8) return RECORD_INT8_TEXT;
+        if (text_uint64->value <= MAX_INT16) return RECORD_INT16_TEXT;
+        if (text_uint64->value <= MAX_INT32) return RECORD_INT32_TEXT;
+        if (text_uint64->value <= MAX_INT64) return RECORD_INT64_TEXT;
+        return RECORD_UINT64_TEXT;
+    }
     default:
         FIXME( "unhandled text type %u\n", text->textType );
         return 0;
     }
 }
 
+static INT64 get_text_value_int( const WS_XML_TEXT *text )
+{
+    switch (text->textType)
+    {
+    case WS_XML_TEXT_TYPE_INT32:
+    {
+        const WS_XML_INT32_TEXT *text_int32 = (const WS_XML_INT32_TEXT *)text;
+        return text_int32->value;
+    }
+    case WS_XML_TEXT_TYPE_INT64:
+    {
+        const WS_XML_INT64_TEXT *text_int64 = (const WS_XML_INT64_TEXT *)text;
+        return text_int64->value;
+    }
+    case WS_XML_TEXT_TYPE_UINT64:
+    {
+        const WS_XML_UINT64_TEXT *text_uint64 = (const WS_XML_UINT64_TEXT *)text;
+        return text_uint64->value;
+    }
+    default:
+        ERR( "unhandled text type %u\n", text->textType );
+        assert(0);
+    }
+}
+
 static HRESULT write_attribute_value_bin( struct writer *writer, const WS_XML_TEXT *text )
 {
     enum record_type type = get_attr_text_record_type( text );
@@ -729,10 +785,47 @@ static HRESULT write_attribute_value_bin( struct writer *writer, const WS_XML_TE
         write_bytes( writer, text_base64->bytes, len );
         return S_OK;
     }
+    case RECORD_ZERO_TEXT:
+    case RECORD_ONE_TEXT:
     case RECORD_FALSE_TEXT:
     case RECORD_TRUE_TEXT:
         return S_OK;
 
+    case RECORD_INT8_TEXT:
+    {
+        INT8 val = get_text_value_int( text );
+        if ((hr = write_grow_buffer( writer, sizeof(val) )) != S_OK) return hr;
+        write_char( writer, val );
+        return S_OK;
+    }
+    case RECORD_INT16_TEXT:
+    {
+        INT16 val = get_text_value_int( text );
+        if ((hr = write_grow_buffer( writer, sizeof(val) )) != S_OK) return hr;
+        write_bytes( writer, (const BYTE *)&val, sizeof(val) );
+        return S_OK;
+    }
+    case RECORD_INT32_TEXT:
+    {
+        INT32 val = get_text_value_int( text );
+        if ((hr = write_grow_buffer( writer, sizeof(val) )) != S_OK) return hr;
+        write_bytes( writer, (const BYTE *)&val, sizeof(val) );
+        return S_OK;
+    }
+    case RECORD_INT64_TEXT:
+    {
+        INT64 val = get_text_value_int( text );
+        if ((hr = write_grow_buffer( writer, sizeof(val) )) != S_OK) return hr;
+        write_bytes( writer, (const BYTE *)&val, sizeof(val) );
+        return S_OK;
+    }
+    case RECORD_UINT64_TEXT:
+    {
+        WS_XML_UINT64_TEXT *text_uint64 = (WS_XML_UINT64_TEXT *)text;
+        if ((hr = write_grow_buffer( writer, sizeof(text_uint64->value) )) != S_OK) return hr;
+        write_bytes( writer, (const BYTE *)&text_uint64->value, sizeof(text_uint64->value) );
+        return S_OK;
+    }
     default:
         ERR( "unhandled record type %02x\n", type );
         return E_NOTIMPL;
@@ -1676,16 +1769,6 @@ static ULONG format_bool( const BOOL *ptr, unsigned char *buf )
     return sizeof(bool_false);
 }
 
-static ULONG format_int8( const INT8 *ptr, unsigned char *buf )
-{
-    return wsprintfA( (char *)buf, "%d", *ptr );
-}
-
-static ULONG format_int16( const INT16 *ptr, unsigned char *buf )
-{
-    return wsprintfA( (char *)buf, "%d", *ptr );
-}
-
 static ULONG format_int32( const INT32 *ptr, unsigned char *buf )
 {
     return wsprintfA( (char *)buf, "%d", *ptr );
@@ -1696,21 +1779,6 @@ static ULONG format_int64( const INT64 *ptr, unsigned char *buf )
     return wsprintfA( (char *)buf, "%I64d", *ptr );
 }
 
-static ULONG format_uint8( const UINT8 *ptr, unsigned char *buf )
-{
-    return wsprintfA( (char *)buf, "%u", *ptr );
-}
-
-static ULONG format_uint16( const UINT16 *ptr, unsigned char *buf )
-{
-    return wsprintfA( (char *)buf, "%u", *ptr );
-}
-
-static ULONG format_uint32( const UINT32 *ptr, unsigned char *buf )
-{
-    return wsprintfA( (char *)buf, "%u", *ptr );
-}
-
 static ULONG format_uint64( const UINT64 *ptr, unsigned char *buf )
 {
     return wsprintfA( (char *)buf, "%I64u", *ptr );
@@ -2346,6 +2414,36 @@ static enum record_type get_text_record_type( const WS_XML_TEXT *text )
         const WS_XML_BOOL_TEXT *text_bool = (const WS_XML_BOOL_TEXT *)text;
         return text_bool->value ? RECORD_TRUE_TEXT_WITH_ENDELEMENT : RECORD_FALSE_TEXT_WITH_ENDELEMENT;
     }
+    case WS_XML_TEXT_TYPE_INT32:
+    {
+        const WS_XML_INT32_TEXT *text_int32 = (const WS_XML_INT32_TEXT *)text;
+        if (!text_int32->value) return RECORD_ZERO_TEXT_WITH_ENDELEMENT;
+        if (text_int32->value == 1) return RECORD_ONE_TEXT_WITH_ENDELEMENT;
+        if (text_int32->value >= MIN_INT8 && text_int32->value <= MAX_INT8) return RECORD_INT8_TEXT_WITH_ENDELEMENT;
+        if (text_int32->value >= MIN_INT16 && text_int32->value <= MAX_INT16) return RECORD_INT16_TEXT_WITH_ENDELEMENT;
+        return RECORD_INT32_TEXT_WITH_ENDELEMENT;
+    }
+    case WS_XML_TEXT_TYPE_INT64:
+    {
+        const WS_XML_INT64_TEXT *text_int64 = (const WS_XML_INT64_TEXT *)text;
+        if (!text_int64->value) return RECORD_ZERO_TEXT_WITH_ENDELEMENT;
+        if (text_int64->value == 1) return RECORD_ONE_TEXT_WITH_ENDELEMENT; 
+        if (text_int64->value >= MIN_INT8 && text_int64->value <= MAX_INT8) return RECORD_INT8_TEXT_WITH_ENDELEMENT;
+        if (text_int64->value >= MIN_INT16 && text_int64->value <= MAX_INT16) return RECORD_INT16_TEXT_WITH_ENDELEMENT;
+        if (text_int64->value >= MIN_INT32 && text_int64->value <= MAX_INT32) return RECORD_INT32_TEXT_WITH_ENDELEMENT;
+        return RECORD_INT64_TEXT_WITH_ENDELEMENT;
+    }
+    case WS_XML_TEXT_TYPE_UINT64:
+    {
+        const WS_XML_UINT64_TEXT *text_uint64 = (const WS_XML_UINT64_TEXT *)text;
+        if (!text_uint64->value) return RECORD_ZERO_TEXT_WITH_ENDELEMENT;
+        if (text_uint64->value == 1) return RECORD_ONE_TEXT_WITH_ENDELEMENT;
+        if (text_uint64->value <= MAX_INT8) return RECORD_INT8_TEXT_WITH_ENDELEMENT;
+        if (text_uint64->value <= MAX_INT16) return RECORD_INT16_TEXT_WITH_ENDELEMENT;
+        if (text_uint64->value <= MAX_INT32) return RECORD_INT32_TEXT_WITH_ENDELEMENT;
+        if (text_uint64->value <= MAX_INT64) return RECORD_INT64_TEXT_WITH_ENDELEMENT;
+        return RECORD_UINT64_TEXT_WITH_ENDELEMENT;
+    }
     default:
         FIXME( "unhandled text type %u\n", text->textType );
         return 0;
@@ -2429,6 +2527,8 @@ static HRESULT write_text_bin( struct writer *writer, const WS_XML_TEXT *text, U
         }
         return S_OK;
     }
+    case RECORD_ZERO_TEXT_WITH_ENDELEMENT:
+    case RECORD_ONE_TEXT_WITH_ENDELEMENT:
     case RECORD_FALSE_TEXT_WITH_ENDELEMENT:
     case RECORD_TRUE_TEXT_WITH_ENDELEMENT:
     {
@@ -2436,6 +2536,46 @@ static HRESULT write_text_bin( struct writer *writer, const WS_XML_TEXT *text, U
         write_char( writer, type );
         return S_OK;
     }
+    case RECORD_INT8_TEXT_WITH_ENDELEMENT:
+    {
+        INT8 val = get_text_value_int( text );
+        if ((hr = write_grow_buffer( writer, 1 + sizeof(val) )) != S_OK) return hr;
+        write_char( writer, type );
+        write_char( writer, val );
+        return S_OK;
+    }
+    case RECORD_INT16_TEXT_WITH_ENDELEMENT:
+    {
+        INT16 val = get_text_value_int( text );
+        if ((hr = write_grow_buffer( writer, 1 + sizeof(val) )) != S_OK) return hr;
+        write_char( writer, type );
+        write_bytes( writer, (const BYTE *)&val, sizeof(val) );
+        return S_OK;
+    }
+    case RECORD_INT32_TEXT_WITH_ENDELEMENT:
+    {
+        INT32 val = get_text_value_int( text );
+        if ((hr = write_grow_buffer( writer, 1 + sizeof(val) )) != S_OK) return hr;
+        write_char( writer, type );
+        write_bytes( writer, (const BYTE *)&val, sizeof(val) );
+        return S_OK;
+    }
+    case RECORD_INT64_TEXT_WITH_ENDELEMENT:
+    {
+        INT64 val = get_text_value_int( text );
+        if ((hr = write_grow_buffer( writer, 1 + sizeof(val) )) != S_OK) return hr;
+        write_char( writer, type );
+        write_bytes( writer, (const BYTE *)&val, sizeof(val) );
+        return S_OK;
+    }
+    case RECORD_UINT64_TEXT_WITH_ENDELEMENT:
+    {
+        WS_XML_UINT64_TEXT *text_uint64 = (WS_XML_UINT64_TEXT *)text;
+        if ((hr = write_grow_buffer( writer, 1 + sizeof(text_uint64->value) )) != S_OK) return hr;
+        write_char( writer, type );
+        write_bytes( writer, (const BYTE *)&text_uint64->value, sizeof(text_uint64->value) );
+        return S_OK;
+    }
     default:
         FIXME( "unhandled record type %02x\n", type );
         return E_NOTIMPL;
@@ -2742,8 +2882,7 @@ static HRESULT write_type_int8( struct writer *writer, WS_TYPE_MAPPING mapping,
                                 const WS_INT8_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                 const BOOL *value, ULONG size )
 {
-    WS_XML_UTF8_TEXT utf8;
-    unsigned char buf[5]; /* "-128" */
+    WS_XML_INT32_TEXT text_int32;
     const INT8 *ptr;
     HRESULT hr;
 
@@ -2757,18 +2896,16 @@ static HRESULT write_type_int8( struct writer *writer, WS_TYPE_MAPPING mapping,
     if ((hr = get_value_ptr( option, value, size, sizeof(INT8), (const void **)&ptr )) != S_OK) return hr;
     if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
 
-    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
-    utf8.value.bytes   = buf;
-    utf8.value.length  = format_int8( ptr, buf );
-    return write_type_text( writer, mapping, &utf8.text );
+    text_int32.text.textType = WS_XML_TEXT_TYPE_INT32;
+    text_int32.value         = *ptr;
+    return write_type_text( writer, mapping, &text_int32.text );
 }
 
 static HRESULT write_type_int16( struct writer *writer, WS_TYPE_MAPPING mapping,
                                  const WS_INT16_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                  const BOOL *value, ULONG size )
 {
-    WS_XML_UTF8_TEXT utf8;
-    unsigned char buf[7]; /* "-32768" */
+    WS_XML_INT32_TEXT text_int32;
     const INT16 *ptr;
     HRESULT hr;
 
@@ -2782,18 +2919,16 @@ static HRESULT write_type_int16( struct writer *writer, WS_TYPE_MAPPING mapping,
     if ((hr = get_value_ptr( option, value, size, sizeof(INT16), (const void **)&ptr )) != S_OK) return hr;
     if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
 
-    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
-    utf8.value.bytes   = buf;
-    utf8.value.length  = format_int16( ptr, buf );
-    return write_type_text( writer, mapping, &utf8.text );
+    text_int32.text.textType = WS_XML_TEXT_TYPE_INT32;
+    text_int32.value         = *ptr;
+    return write_type_text( writer, mapping, &text_int32.text );
 }
 
 static HRESULT write_type_int32( struct writer *writer, WS_TYPE_MAPPING mapping,
                                  const WS_INT32_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                  const void *value, ULONG size )
 {
-    WS_XML_UTF8_TEXT utf8;
-    unsigned char buf[12]; /* "-2147483648" */
+    WS_XML_INT32_TEXT text_int32;
     const INT32 *ptr;
     HRESULT hr;
 
@@ -2807,18 +2942,16 @@ static HRESULT write_type_int32( struct writer *writer, WS_TYPE_MAPPING mapping,
     if ((hr = get_value_ptr( option, value, size, sizeof(INT32), (const void **)&ptr )) != S_OK) return hr;
     if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
 
-    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
-    utf8.value.bytes   = buf;
-    utf8.value.length  = format_int32( ptr, buf );
-    return write_type_text( writer, mapping, &utf8.text );
+    text_int32.text.textType = WS_XML_TEXT_TYPE_INT32;
+    text_int32.value         = *ptr;
+    return write_type_text( writer, mapping, &text_int32.text );
 }
 
 static HRESULT write_type_int64( struct writer *writer, WS_TYPE_MAPPING mapping,
                                  const WS_INT64_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                  const void *value, ULONG size )
 {
-    WS_XML_UTF8_TEXT utf8;
-    unsigned char buf[21]; /* "-9223372036854775808" */
+    WS_XML_INT64_TEXT text_int64;
     const INT64 *ptr;
     HRESULT hr;
 
@@ -2832,18 +2965,16 @@ static HRESULT write_type_int64( struct writer *writer, WS_TYPE_MAPPING mapping,
     if ((hr = get_value_ptr( option, value, size, sizeof(INT64), (const void **)&ptr )) != S_OK) return hr;
     if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
 
-    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
-    utf8.value.bytes   = buf;
-    utf8.value.length  = format_int64( ptr, buf );
-    return write_type_text( writer, mapping, &utf8.text );
+    text_int64.text.textType = WS_XML_TEXT_TYPE_INT64;
+    text_int64.value         = *ptr;
+    return write_type_text( writer, mapping, &text_int64.text );
 }
 
 static HRESULT write_type_uint8( struct writer *writer, WS_TYPE_MAPPING mapping,
                                  const WS_UINT8_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                  const void *value, ULONG size )
 {
-    WS_XML_UTF8_TEXT utf8;
-    unsigned char buf[4]; /* "255" */
+    WS_XML_UINT64_TEXT text_uint64;
     const UINT8 *ptr;
     HRESULT hr;
 
@@ -2857,18 +2988,16 @@ static HRESULT write_type_uint8( struct writer *writer, WS_TYPE_MAPPING mapping,
     if ((hr = get_value_ptr( option, value, size, sizeof(UINT8), (const void **)&ptr )) != S_OK) return hr;
     if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
 
-    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
-    utf8.value.bytes   = buf;
-    utf8.value.length  = format_uint8( ptr, buf );
-    return write_type_text( writer, mapping, &utf8.text );
+    text_uint64.text.textType = WS_XML_TEXT_TYPE_UINT64;
+    text_uint64.value         = *ptr;
+    return write_type_text( writer, mapping, &text_uint64.text );
 }
 
 static HRESULT write_type_uint16( struct writer *writer, WS_TYPE_MAPPING mapping,
                                   const WS_UINT16_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                   const void *value, ULONG size )
 {
-    WS_XML_UTF8_TEXT utf8;
-    unsigned char buf[6]; /* "65535" */
+    WS_XML_UINT64_TEXT text_uint64;
     const UINT16 *ptr;
     HRESULT hr;
 
@@ -2882,18 +3011,16 @@ static HRESULT write_type_uint16( struct writer *writer, WS_TYPE_MAPPING mapping
     if ((hr = get_value_ptr( option, value, size, sizeof(UINT16), (const void **)&ptr )) != S_OK) return hr;
     if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
 
-    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
-    utf8.value.bytes   = buf;
-    utf8.value.length  = format_uint16( ptr, buf );
-    return write_type_text( writer, mapping, &utf8.text );
+    text_uint64.text.textType = WS_XML_TEXT_TYPE_UINT64;
+    text_uint64.value         = *ptr;
+    return write_type_text( writer, mapping, &text_uint64.text );
 }
 
 static HRESULT write_type_uint32( struct writer *writer, WS_TYPE_MAPPING mapping,
                                   const WS_UINT32_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                   const void *value, ULONG size )
 {
-    WS_XML_UTF8_TEXT utf8;
-    unsigned char buf[11]; /* "4294967295" */
+    WS_XML_UINT64_TEXT text_uint64;
     const UINT32 *ptr;
     HRESULT hr;
 
@@ -2907,18 +3034,16 @@ static HRESULT write_type_uint32( struct writer *writer, WS_TYPE_MAPPING mapping
     if ((hr = get_value_ptr( option, value, size, sizeof(UINT32), (const void **)&ptr )) != S_OK) return hr;
     if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
 
-    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
-    utf8.value.bytes   = buf;
-    utf8.value.length  = format_uint32( ptr, buf );
-    return write_type_text( writer, mapping, &utf8.text );
+    text_uint64.text.textType = WS_XML_TEXT_TYPE_UINT64;
+    text_uint64.value         = *ptr;
+    return write_type_text( writer, mapping, &text_uint64.text );
 }
 
 static HRESULT write_type_uint64( struct writer *writer, WS_TYPE_MAPPING mapping,
                                   const WS_UINT64_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                   const void *value, ULONG size )
 {
-    WS_XML_UTF8_TEXT utf8;
-    unsigned char buf[21]; /* "18446744073709551615" */
+    WS_XML_UINT64_TEXT text_uint64;
     const UINT64 *ptr;
     HRESULT hr;
 
@@ -2932,10 +3057,9 @@ static HRESULT write_type_uint64( struct writer *writer, WS_TYPE_MAPPING mapping
     if ((hr = get_value_ptr( option, value, size, sizeof(UINT64), (const void **)&ptr )) != S_OK) return hr;
     if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
 
-    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
-    utf8.value.bytes   = buf;
-    utf8.value.length  = format_uint64( ptr, buf );
-    return write_type_text( writer, mapping, &utf8.text );
+    text_uint64.text.textType = WS_XML_TEXT_TYPE_UINT64;
+    text_uint64.value         = *ptr;
+    return write_type_text( writer, mapping, &text_uint64.text );
 }
 
 static HRESULT write_type_datetime( struct writer *writer, WS_TYPE_MAPPING mapping,
-- 
2.1.4




More information about the wine-patches mailing list