/*
 * Copyright 2015, 2016 Hans Leidekker for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include <stdarg.h>
#include <stdio.h>
#include <math.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "webservices.h"

#include "wine/debug.h"
#include "wine/list.h"
#include "wine/unicode.h"
#include "webservices_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(webservices);

static const struct prop_desc writer_props[] =
{
    { sizeof(ULONG), FALSE },       /* WS_XML_WRITER_PROPERTY_MAX_DEPTH */
    { sizeof(BOOL), FALSE },        /* WS_XML_WRITER_PROPERTY_ALLOW_FRAGMENT */
    { sizeof(ULONG), FALSE },       /* WS_XML_READER_PROPERTY_MAX_ATTRIBUTES */
    { sizeof(BOOL), FALSE },        /* WS_XML_WRITER_PROPERTY_WRITE_DECLARATION */
    { sizeof(ULONG), FALSE },       /* WS_XML_WRITER_PROPERTY_INDENT */
    { sizeof(ULONG), FALSE },       /* WS_XML_WRITER_PROPERTY_BUFFER_TRIM_SIZE */
    { sizeof(WS_CHARSET), FALSE },  /* WS_XML_WRITER_PROPERTY_CHARSET */
    { sizeof(WS_BUFFERS), FALSE },  /* WS_XML_WRITER_PROPERTY_BUFFERS */
    { sizeof(ULONG), FALSE },       /* WS_XML_WRITER_PROPERTY_BUFFER_MAX_SIZE */
    { sizeof(WS_BYTES), FALSE },    /* WS_XML_WRITER_PROPERTY_BYTES */
    { sizeof(BOOL), TRUE },         /* WS_XML_WRITER_PROPERTY_IN_ATTRIBUTE */
    { sizeof(ULONG), FALSE },       /* WS_XML_WRITER_PROPERTY_MAX_MIME_PARTS_BUFFER_SIZE */
    { sizeof(WS_BYTES), FALSE },    /* WS_XML_WRITER_PROPERTY_INITIAL_BUFFER */
    { sizeof(BOOL), FALSE },        /* WS_XML_WRITER_PROPERTY_ALLOW_INVALID_CHARACTER_REFERENCES */
    { sizeof(ULONG), FALSE },       /* WS_XML_WRITER_PROPERTY_MAX_NAMESPACES */
    { sizeof(ULONG), TRUE },        /* WS_XML_WRITER_PROPERTY_BYTES_WRITTEN */
    { sizeof(ULONG), TRUE },        /* WS_XML_WRITER_PROPERTY_BYTES_TO_CLOSE */
    { sizeof(BOOL), FALSE },        /* WS_XML_WRITER_PROPERTY_COMPRESS_EMPTY_ELEMENTS */
    { sizeof(BOOL), FALSE }         /* WS_XML_WRITER_PROPERTY_EMIT_UNCOMPRESSED_EMPTY_ELEMENTS */
};

enum writer_state
{
    WRITER_STATE_INITIAL,
    WRITER_STATE_STARTELEMENT,
    WRITER_STATE_STARTATTRIBUTE,
    WRITER_STATE_STARTCDATA,
    WRITER_STATE_ENDSTARTELEMENT,
    WRITER_STATE_TEXT,
    WRITER_STATE_COMMENT,
    WRITER_STATE_ENDELEMENT,
    WRITER_STATE_ENDCDATA
};

struct writer
{
    ULONG                     write_pos;
    unsigned char            *write_bufptr;
    enum writer_state         state;
    struct node              *root;
    struct node              *current;
    WS_XML_STRING            *current_ns;
    WS_XML_WRITER_OUTPUT_TYPE output_type;
    struct xmlbuf            *output_buf;
    WS_HEAP                  *output_heap;
    ULONG                     prop_count;
    struct prop               prop[sizeof(writer_props)/sizeof(writer_props[0])];
};

static struct writer *alloc_writer(void)
{
    static const ULONG count = sizeof(writer_props)/sizeof(writer_props[0]);
    struct writer *ret;
    ULONG size = sizeof(*ret) + prop_size( writer_props, count );

    if (!(ret = heap_alloc_zero( size ))) return NULL;
    prop_init( writer_props, count, ret->prop, &ret[1] );
    ret->prop_count = count;
    return ret;
}

static void free_writer( struct writer *writer )
{
    if (!writer) return;
    destroy_nodes( writer->root );
    heap_free( writer->current_ns );
    WsFreeHeap( writer->output_heap );
    heap_free( writer );
}

static void write_insert_eof( struct writer *writer, struct node *eof )
{
    if (!writer->root) writer->root = eof;
    else
    {
        eof->parent = writer->root;
        list_add_tail( &writer->root->children, &eof->entry );
    }
    writer->current = eof;
}

static void write_insert_bof( struct writer *writer, struct node *bof )
{
    writer->root->parent = bof;
    list_add_tail( &bof->children, &writer->root->entry );
    writer->current = writer->root = bof;
}

static void write_insert_node( struct writer *writer, struct node *parent, struct node *node )
{
    node->parent = parent;
    list_add_before( list_tail( &parent->children ), &node->entry );
    writer->current = node;
}

static struct node *find_parent( struct writer *writer )
{
    if (is_valid_parent( writer->current )) return writer->current;
    if (is_valid_parent( writer->current->parent )) return writer->current->parent;
    return NULL;
}

static HRESULT write_init_state( struct writer *writer )
{
    struct node *node;

    heap_free( writer->current_ns );
    writer->current_ns = NULL;
    destroy_nodes( writer->root );
    writer->root = NULL;

    if (!(node = alloc_node( WS_XML_NODE_TYPE_EOF ))) return E_OUTOFMEMORY;
    write_insert_eof( writer, node );
    writer->state = WRITER_STATE_INITIAL;
    return S_OK;
}

/**************************************************************************
 *          WsCreateWriter		[webservices.@]
 */
HRESULT WINAPI WsCreateWriter( const WS_XML_WRITER_PROPERTY *properties, ULONG count,
                               WS_XML_WRITER **handle, WS_ERROR *error )
{
    struct writer *writer;
    ULONG i, max_depth = 32, max_attrs = 128, trim_size = 4096, max_size = 65536, max_ns = 32;
    WS_CHARSET charset = WS_CHARSET_UTF8;
    HRESULT hr;

    TRACE( "%p %u %p %p\n", properties, count, handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!handle) return E_INVALIDARG;
    if (!(writer = alloc_writer())) return E_OUTOFMEMORY;

    prop_set( writer->prop, writer->prop_count, WS_XML_WRITER_PROPERTY_MAX_DEPTH, &max_depth, sizeof(max_depth) );
    prop_set( writer->prop, writer->prop_count, WS_XML_WRITER_PROPERTY_MAX_ATTRIBUTES, &max_attrs, sizeof(max_attrs) );
    prop_set( writer->prop, writer->prop_count, WS_XML_WRITER_PROPERTY_BUFFER_TRIM_SIZE, &trim_size, sizeof(trim_size) );
    prop_set( writer->prop, writer->prop_count, WS_XML_WRITER_PROPERTY_CHARSET, &charset, sizeof(charset) );
    prop_set( writer->prop, writer->prop_count, WS_XML_WRITER_PROPERTY_BUFFER_MAX_SIZE, &max_size, sizeof(max_size) );
    prop_set( writer->prop, writer->prop_count, WS_XML_WRITER_PROPERTY_MAX_MIME_PARTS_BUFFER_SIZE, &max_size, sizeof(max_size) );
    prop_set( writer->prop, writer->prop_count, WS_XML_WRITER_PROPERTY_MAX_NAMESPACES, &max_ns, sizeof(max_ns) );

    for (i = 0; i < count; i++)
    {
        hr = prop_set( writer->prop, writer->prop_count, properties[i].id, properties[i].value,
                       properties[i].valueSize );
        if (hr != S_OK)
        {
            free_writer( writer );
            return hr;
        }
    }

    hr = prop_get( writer->prop, writer->prop_count, WS_XML_WRITER_PROPERTY_BUFFER_MAX_SIZE,
                   &max_size, sizeof(max_size) );
    if (hr != S_OK)
    {
        free_writer( writer );
        return hr;
    }

    hr = WsCreateHeap( max_size, 0, NULL, 0, &writer->output_heap, NULL );
    if (hr != S_OK)
    {
        free_writer( writer );
        return hr;
    }

    hr = write_init_state( writer );
    if (hr != S_OK)
    {
        free_writer( writer );
        return hr;
    }

    *handle = (WS_XML_WRITER *)writer;
    return S_OK;
}

/**************************************************************************
 *          WsFreeWriter		[webservices.@]
 */
void WINAPI WsFreeWriter( WS_XML_WRITER *handle )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p\n", handle );
    free_writer( writer );
}

#define XML_BUFFER_INITIAL_ALLOCATED_SIZE 256
static struct xmlbuf *alloc_xmlbuf( WS_HEAP *heap )
{
    struct xmlbuf *ret;

    if (!(ret = ws_alloc( heap, sizeof(*ret) ))) return NULL;
    if (!(ret->ptr = ws_alloc( heap, XML_BUFFER_INITIAL_ALLOCATED_SIZE )))
    {
        ws_free( heap, ret );
        return NULL;
    }
    ret->heap           = heap;
    ret->size_allocated = XML_BUFFER_INITIAL_ALLOCATED_SIZE;
    ret->size           = 0;
    return ret;
}

static void free_xmlbuf( struct xmlbuf *xmlbuf )
{
    if (!xmlbuf) return;
    ws_free( xmlbuf->heap, xmlbuf->ptr );
    ws_free( xmlbuf->heap, xmlbuf );
}

/**************************************************************************
 *          WsCreateXmlBuffer		[webservices.@]
 */
HRESULT WINAPI WsCreateXmlBuffer( WS_HEAP *heap, const WS_XML_BUFFER_PROPERTY *properties,
                                  ULONG count, WS_XML_BUFFER **handle, WS_ERROR *error )
{
    struct xmlbuf *xmlbuf;

    if (!heap || !handle) return E_INVALIDARG;
    if (count) FIXME( "properties not implemented\n" );

    if (!(xmlbuf = alloc_xmlbuf( heap ))) return E_OUTOFMEMORY;

    *handle = (WS_XML_BUFFER *)xmlbuf;
    return S_OK;
}

/**************************************************************************
 *          WsGetWriterProperty		[webservices.@]
 */
HRESULT WINAPI WsGetWriterProperty( WS_XML_WRITER *handle, WS_XML_WRITER_PROPERTY_ID id,
                                    void *buf, ULONG size, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer->output_type) return WS_E_INVALID_OPERATION;

    switch (id)
    {
    case WS_XML_WRITER_PROPERTY_BYTES:
    {
        WS_BYTES *bytes = buf;
        if (size != sizeof(*bytes)) return E_INVALIDARG;
        bytes->bytes  = writer->output_buf->ptr;
        bytes->length = writer->output_buf->size;
        return S_OK;
    }
    default:
        return prop_get( writer->prop, writer->prop_count, id, buf, size );
    }
}

static void set_output_buffer( struct writer *writer, struct xmlbuf *xmlbuf )
{
    /* free current buffer if it's ours */
    if (writer->output_buf && writer->output_buf->heap == writer->output_heap)
    {
        free_xmlbuf( writer->output_buf );
    }
    writer->output_buf   = xmlbuf;
    writer->output_type  = WS_XML_WRITER_OUTPUT_TYPE_BUFFER;
    writer->write_bufptr = xmlbuf->ptr;
    writer->write_pos    = 0;
}

/**************************************************************************
 *          WsSetOutput		[webservices.@]
 */
HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING *encoding,
                            const WS_XML_WRITER_OUTPUT *output, const WS_XML_WRITER_PROPERTY *properties,
                            ULONG count, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    struct node *node;
    HRESULT hr;
    ULONG i;

    TRACE( "%p %p %p %p %u %p\n", handle, encoding, output, properties, count, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;

    for (i = 0; i < count; i++)
    {
        hr = prop_set( writer->prop, writer->prop_count, properties[i].id, properties[i].value,
                       properties[i].valueSize );
        if (hr != S_OK) return hr;
    }

    if ((hr = write_init_state( writer )) != S_OK) return hr;

    switch (encoding->encodingType)
    {
    case WS_XML_WRITER_ENCODING_TYPE_TEXT:
    {
        WS_XML_WRITER_TEXT_ENCODING *text = (WS_XML_WRITER_TEXT_ENCODING *)encoding;
        if (text->charSet != WS_CHARSET_UTF8)
        {
            FIXME( "charset %u not supported\n", text->charSet );
            return E_NOTIMPL;
        }
        break;
    }
    default:
        FIXME( "encoding type %u not supported\n", encoding->encodingType );
        return E_NOTIMPL;
    }
    switch (output->outputType)
    {
    case WS_XML_WRITER_OUTPUT_TYPE_BUFFER:
    {
        struct xmlbuf *xmlbuf;

        if (!(xmlbuf = alloc_xmlbuf( writer->output_heap ))) return E_OUTOFMEMORY;
        set_output_buffer( writer, xmlbuf );
        break;
    }
    default:
        FIXME( "output type %u not supported\n", output->outputType );
        return E_NOTIMPL;
    }

    if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
    write_insert_bof( writer, node );
    return S_OK;
}

/**************************************************************************
 *          WsSetOutputToBuffer		[webservices.@]
 */
HRESULT WINAPI WsSetOutputToBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer,
                                    const WS_XML_WRITER_PROPERTY *properties, ULONG count,
                                    WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
    struct node *node;
    HRESULT hr;
    ULONG i;

    TRACE( "%p %p %p %u %p\n", handle, buffer, properties, count, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !xmlbuf) return E_INVALIDARG;

    for (i = 0; i < count; i++)
    {
        hr = prop_set( writer->prop, writer->prop_count, properties[i].id, properties[i].value,
                       properties[i].valueSize );
        if (hr != S_OK) return hr;
    }

    if ((hr = write_init_state( writer )) != S_OK) return hr;
    set_output_buffer( writer, xmlbuf );

    if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) return E_OUTOFMEMORY;
    write_insert_bof( writer, node );
    return S_OK;
}

static HRESULT write_grow_buffer( struct writer *writer, ULONG size )
{
    struct xmlbuf *buf = writer->output_buf;
    SIZE_T new_size;
    void *tmp;

    if (buf->size_allocated >= writer->write_pos + size)
    {
        buf->size = writer->write_pos + size;
        return S_OK;
    }
    new_size = max( buf->size_allocated * 2, writer->write_pos + size );
    if (!(tmp = ws_realloc( buf->heap, buf->ptr, new_size ))) return E_OUTOFMEMORY;
    writer->write_bufptr = buf->ptr = tmp;
    buf->size_allocated = new_size;
    buf->size = writer->write_pos + size;
    return S_OK;
}

static inline void write_char( struct writer *writer, unsigned char ch )
{
    writer->write_bufptr[writer->write_pos++] = ch;
}

static inline void write_bytes( struct writer *writer, const BYTE *bytes, ULONG len )
{
    memcpy( writer->write_bufptr + writer->write_pos, bytes, len );
    writer->write_pos += len;
}

struct escape
{
    char        ch;
    const char *entity;
    ULONG       len;
};
static const struct escape escape_lt = { '<', "&lt;", 4 };
static const struct escape escape_gt = { '>', "&gt;", 4 };
static const struct escape escape_amp = { '&', "&amp;", 5 };
static const struct escape escape_apos = { '\'', "&apos;", 6 };
static const struct escape escape_quot = { '"', "&quot;", 6 };

static HRESULT write_bytes_escape( struct writer *writer, const BYTE *bytes, ULONG len,
                                   const struct escape **escapes, ULONG nb_escapes )
{
    ULONG i, j, size;
    const BYTE *ptr;
    HRESULT hr;

    for (i = 0; i < len; i++)
    {
        ptr = &bytes[i];
        size = 1;
        for (j = 0; j < nb_escapes; j++)
        {
            if (bytes[i] == escapes[j]->ch)
            {
                ptr = (const BYTE *)escapes[j]->entity;
                size = escapes[j]->len;
                break;
            }
        }
        if ((hr = write_grow_buffer( writer, size )) != S_OK) return hr;
        write_bytes( writer, ptr, size );
    }

    return S_OK;
}

static HRESULT write_attribute( struct writer *writer, WS_XML_ATTRIBUTE *attr )
{
    WS_XML_UTF8_TEXT *text = (WS_XML_UTF8_TEXT *)attr->value;
    unsigned char quote = attr->singleQuote ? '\'' : '"';
    const WS_XML_STRING *prefix;
    ULONG size;
    HRESULT hr;

    if (attr->prefix) prefix = attr->prefix;
    else prefix = writer->current->hdr.prefix;

    /* ' prefix:attr="value"' */

    size = attr->localName->length + 4 /* ' =""' */;
    if (prefix) size += prefix->length + 1 /* ':' */;
    if (text) size += text->value.length;
    if ((hr = write_grow_buffer( writer, size )) != S_OK) return hr;

    write_char( writer, ' ' );
    if (prefix)
    {
        write_bytes( writer, prefix->bytes, prefix->length );
        write_char( writer, ':' );
    }
    write_bytes( writer, attr->localName->bytes, attr->localName->length );
    write_char( writer, '=' );
    write_char( writer, quote );
    if (text)
    {
        const struct escape *escapes[3];
        escapes[0] = attr->singleQuote ? &escape_apos : &escape_quot;
        escapes[1] = &escape_lt;
        escapes[2] = &escape_amp;
        hr = write_bytes_escape( writer, text->value.bytes, text->value.length, escapes, 3 );
    }
    write_char( writer, quote );

    return hr;
}

static inline BOOL is_current_namespace( struct writer *writer, const WS_XML_STRING *ns )
{
    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;
    if (!(str = alloc_xml_string( ns->bytes, ns->length ))) return E_OUTOFMEMORY;
    heap_free( writer->current_ns );
    writer->current_ns = str;
    return S_OK;
}

static HRESULT write_namespace_attribute( struct writer *writer, WS_XML_ATTRIBUTE *attr )
{
    unsigned char quote = attr->singleQuote ? '\'' : '"';
    ULONG size;
    HRESULT hr;

    /* ' xmlns:prefix="namespace"' */

    size = attr->ns->length + 9 /* ' xmlns=""' */;
    if (attr->prefix) size += attr->prefix->length + 1 /* ':' */;
    if ((hr = write_grow_buffer( writer, size )) != S_OK) return hr;

    write_bytes( writer, (const BYTE *)" xmlns", 6 );
    if (attr->prefix)
    {
        write_char( writer, ':' );
        write_bytes( writer, attr->prefix->bytes, attr->prefix->length );
    }
    write_char( writer, '=' );
    write_char( writer, quote );
    write_bytes( writer, attr->ns->bytes, attr->ns->length );
    write_char( writer, quote );

    return S_OK;
}

static HRESULT write_add_namespace_attribute( struct writer *writer, const WS_XML_STRING *prefix,
                                              const WS_XML_STRING *ns, BOOL single )
{
    WS_XML_ATTRIBUTE *attr;
    WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
    HRESULT hr;

    if (!(attr = heap_alloc_zero( sizeof(*attr) ))) return E_OUTOFMEMORY;

    attr->singleQuote = !!single;
    attr->isXmlNs = 1;
    if (prefix && !(attr->prefix = alloc_xml_string( prefix->bytes, prefix->length )))
    {
        free_attribute( attr );
        return E_OUTOFMEMORY;
    }
    if (!(attr->ns = alloc_xml_string( ns->bytes, ns->length )))
    {
        free_attribute( attr );
        return E_OUTOFMEMORY;
    }
    if ((hr = append_attribute( elem, attr )) != S_OK)
    {
        free_attribute( attr );
        return hr;
    }
    return S_OK;
}

static inline BOOL str_equal( const WS_XML_STRING *str1, const WS_XML_STRING *str2 )
{
    if (!str1 && !str2) return TRUE;
    return WsXmlStringEquals( str1, str2, NULL ) == S_OK;
}

static BOOL namespace_in_scope( const WS_XML_ELEMENT_NODE *elem, const WS_XML_STRING *prefix,
                                const WS_XML_STRING *ns )
{
    ULONG i;
    const struct node *node;

    for (node = (const struct node *)elem; node; node = node->parent)
    {
        if (node_type( node ) != WS_XML_NODE_TYPE_ELEMENT) break;

        elem = &node->hdr;
        for (i = 0; i < elem->attributeCount; i++)
        {
            if (!elem->attributes[i]->isXmlNs) continue;
            if (str_equal( elem->attributes[i]->prefix, prefix ) &&
                str_equal( elem->attributes[i]->ns, ns )) return TRUE;
        }
    }
    return FALSE;
}

static HRESULT write_set_element_namespace( struct writer *writer )
{
    WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
    HRESULT hr;

    if (!elem->ns->length || namespace_in_scope( elem, elem->prefix, elem->ns )) return S_OK;

    if ((hr = write_add_namespace_attribute( writer, elem->prefix, elem->ns, FALSE )) != S_OK)
        return hr;

    return set_current_namespace( writer, elem->ns );
}

/**************************************************************************
 *          WsWriteEndAttribute		[webservices.@]
 */
HRESULT WINAPI WsWriteEndAttribute( WS_XML_WRITER *handle, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %p\n", handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;

    writer->state = WRITER_STATE_STARTELEMENT;
    return S_OK;
}

static HRESULT write_startelement( struct writer *writer )
{
    WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
    ULONG size, i;
    HRESULT hr;

    /* '<prefix:localname prefix:attr="value"... xmlns:prefix="ns"'... */

    size = elem->localName->length + 1 /* '<' */;
    if (elem->prefix) size += elem->prefix->length + 1 /* ':' */;
    if ((hr = write_grow_buffer( writer, size )) != S_OK) return hr;

    write_char( writer, '<' );
    if (elem->prefix)
    {
        write_bytes( writer, elem->prefix->bytes, elem->prefix->length );
        write_char( writer, ':' );
    }
    write_bytes( writer, elem->localName->bytes, elem->localName->length );
    for (i = 0; i < elem->attributeCount; i++)
    {
        if (elem->attributes[i]->isXmlNs) continue;
        if ((hr = write_attribute( writer, elem->attributes[i] )) != S_OK) return hr;
    }
    for (i = 0; i < elem->attributeCount; i++)
    {
        if (!elem->attributes[i]->isXmlNs || !elem->attributes[i]->prefix) continue;
        if ((hr = write_namespace_attribute( writer, elem->attributes[i] )) != S_OK) return hr;
    }
    for (i = 0; i < elem->attributeCount; i++)
    {
        if (!elem->attributes[i]->isXmlNs || elem->attributes[i]->prefix) continue;
        if ((hr = write_namespace_attribute( writer, elem->attributes[i] )) != S_OK) return hr;
    }
    return S_OK;
}

static struct node *write_find_startelement( struct writer *writer )
{
    struct node *node;
    for (node = writer->current; node; node = node->parent)
    {
        if (node_type( node ) == WS_XML_NODE_TYPE_ELEMENT) return node;
    }
    return NULL;
}

static inline BOOL is_empty_element( const struct node *node )
{
    const struct node *head = LIST_ENTRY( list_head( &node->children ), struct node, entry );
    return node_type( head ) == WS_XML_NODE_TYPE_END_ELEMENT;
}

static HRESULT write_endelement( struct writer *writer, const WS_XML_ELEMENT_NODE *elem )
{
    ULONG size;
    HRESULT hr;

    /* '/>' */

    if (elem->isEmpty && writer->state != WRITER_STATE_ENDSTARTELEMENT)
    {
        if ((hr = write_grow_buffer( writer, 2 )) != S_OK) return hr;
        write_char( writer, '/' );
        write_char( writer, '>' );
        return S_OK;
    }

    /* '</prefix:localname>' */

    size = elem->localName->length + 3 /* '</>' */;
    if (elem->prefix) size += elem->prefix->length + 1 /* ':' */;
    if ((hr = write_grow_buffer( writer, size )) != S_OK) return hr;

    write_char( writer, '<' );
    write_char( writer, '/' );
    if (elem->prefix)
    {
        write_bytes( writer, elem->prefix->bytes, elem->prefix->length );
        write_char( writer, ':' );
    }
    write_bytes( writer, elem->localName->bytes, elem->localName->length );
    write_char( writer, '>' );
    return S_OK;
}

static HRESULT write_close_element( struct writer *writer, struct node *node )
{
    WS_XML_ELEMENT_NODE *elem = &node->hdr;
    elem->isEmpty = is_empty_element( node );
    return write_endelement( writer, elem );
}

static HRESULT write_endelement_node( struct writer *writer )
{
    struct node *node;
    HRESULT hr;

    if (!(node = write_find_startelement( writer ))) return WS_E_INVALID_FORMAT;
    if (writer->state == WRITER_STATE_STARTELEMENT)
    {
        if ((hr = write_set_element_namespace( writer )) != S_OK) return hr;
        if ((hr = write_startelement( writer )) != S_OK) return hr;
    }
    if ((hr = write_close_element( writer, node )) != S_OK) return hr;
    writer->current = node->parent;
    writer->state   = WRITER_STATE_ENDELEMENT;
    return S_OK;
}

/**************************************************************************
 *          WsWriteEndElement		[webservices.@]
 */
HRESULT WINAPI WsWriteEndElement( WS_XML_WRITER *handle, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %p\n", handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;
    return write_endelement_node( writer );
}

static HRESULT write_endstartelement( struct writer *writer )
{
    HRESULT hr;
    if ((hr = write_grow_buffer( writer, 1 )) != S_OK) return hr;
    write_char( writer, '>' );
    return S_OK;
}

/**************************************************************************
 *          WsWriteEndStartElement		[webservices.@]
 */
HRESULT WINAPI WsWriteEndStartElement( WS_XML_WRITER *handle, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    HRESULT hr;

    TRACE( "%p %p\n", handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;
    if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;

    if ((hr = write_set_element_namespace( writer )) != S_OK) return hr;
    if ((hr = write_startelement( writer )) != S_OK) return hr;
    if ((hr = write_endstartelement( writer )) != S_OK) return hr;

    writer->state = WRITER_STATE_ENDSTARTELEMENT;
    return S_OK;
}

static HRESULT write_add_attribute( struct writer *writer, const WS_XML_STRING *prefix,
                                    const WS_XML_STRING *localname, const WS_XML_STRING *ns,
                                    BOOL single )
{
    WS_XML_ATTRIBUTE *attr;
    WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
    HRESULT hr;

    if (!(attr = heap_alloc_zero( sizeof(*attr) ))) return E_OUTOFMEMORY;

    if (!prefix) prefix = elem->prefix;

    attr->singleQuote = !!single;
    if (prefix && !(attr->prefix = alloc_xml_string( prefix->bytes, prefix->length )))
    {
        free_attribute( attr );
        return E_OUTOFMEMORY;
    }
    if (!(attr->localName = alloc_xml_string( localname->bytes, localname->length )))
    {
        free_attribute( attr );
        return E_OUTOFMEMORY;
    }
    if (!(attr->ns = alloc_xml_string( ns->bytes, ns->length )))
    {
        free_attribute( attr );
        return E_OUTOFMEMORY;
    }
    if ((hr = append_attribute( elem, attr )) != S_OK)
    {
        free_attribute( attr );
        return hr;
    }
    return S_OK;
}

/**************************************************************************
 *          WsWriteStartAttribute		[webservices.@]
 */
HRESULT WINAPI WsWriteStartAttribute( WS_XML_WRITER *handle, const WS_XML_STRING *prefix,
                                      const WS_XML_STRING *localname, const WS_XML_STRING *ns,
                                      BOOL single, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    HRESULT hr;

    TRACE( "%p %s %s %s %d %p\n", handle, debugstr_xmlstr(prefix), debugstr_xmlstr(localname),
           debugstr_xmlstr(ns), single, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !localname || !ns) return E_INVALIDARG;

    if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;

    if ((hr = write_add_attribute( writer, prefix, localname, ns, single )) != S_OK) return hr;
    writer->state = WRITER_STATE_STARTATTRIBUTE;
    return S_OK;
}

/* flush current start element if necessary */
static HRESULT write_flush( struct writer *writer )
{
    if (writer->state == WRITER_STATE_STARTELEMENT)
    {
        HRESULT hr;
        if ((hr = write_set_element_namespace( writer )) != S_OK) return hr;
        if ((hr = write_startelement( writer )) != S_OK) return hr;
        if ((hr = write_endstartelement( writer )) != S_OK) return hr;
        writer->state = WRITER_STATE_ENDSTARTELEMENT;
    }
    return S_OK;
}

static HRESULT write_add_cdata_node( struct writer *writer )
{
    struct node *node, *parent;
    if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT;
    if (!(node = alloc_node( WS_XML_NODE_TYPE_CDATA ))) return E_OUTOFMEMORY;
    write_insert_node( writer, parent, node );
    return S_OK;
}

static HRESULT write_add_endcdata_node( struct writer *writer )
{
    struct node *node;
    if (!(node = alloc_node( WS_XML_NODE_TYPE_END_CDATA ))) return E_OUTOFMEMORY;
    node->parent = writer->current;
    list_add_tail( &node->parent->children, &node->entry );
    return S_OK;
}

static HRESULT write_cdata( struct writer *writer )
{
    HRESULT hr;
    if ((hr = write_grow_buffer( writer, 9 )) != S_OK) return hr;
    write_bytes( writer, (const BYTE *)"<![CDATA[", 9 );
    return S_OK;
}

static HRESULT write_cdata_node( struct writer *writer )
{
    HRESULT hr;
    if ((hr = write_flush( writer )) != S_OK) return hr;
    if ((hr = write_add_cdata_node( writer )) != S_OK) return hr;
    if ((hr = write_add_endcdata_node( writer )) != S_OK) return hr;
    if ((hr = write_cdata( writer )) != S_OK) return hr;
    writer->state = WRITER_STATE_STARTCDATA;
    return S_OK;
}

/**************************************************************************
 *          WsWriteStartCData		[webservices.@]
 */
HRESULT WINAPI WsWriteStartCData( WS_XML_WRITER *handle, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %p\n", handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;
    return write_cdata_node( writer );
}

static HRESULT write_endcdata( struct writer *writer )
{
    HRESULT hr;
    if ((hr = write_grow_buffer( writer, 3 )) != S_OK) return hr;
    write_bytes( writer, (const BYTE *)"]]>", 3 );
    return S_OK;
}

static HRESULT write_endcdata_node( struct writer *writer )
{
    HRESULT hr;
    if ((hr = write_endcdata( writer )) != S_OK) return hr;
    writer->current = writer->current->parent;
    writer->state = WRITER_STATE_ENDCDATA;
    return S_OK;
}

/**************************************************************************
 *          WsWriteEndCData		[webservices.@]
 */
HRESULT WINAPI WsWriteEndCData( WS_XML_WRITER *handle, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %p\n", handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;
    if (writer->state != WRITER_STATE_TEXT) return WS_E_INVALID_OPERATION;

    return write_endcdata_node( writer );
}

static HRESULT write_add_element_node( struct writer *writer, const WS_XML_STRING *prefix,
                                       const WS_XML_STRING *localname, const WS_XML_STRING *ns )
{
    struct node *node, *parent;
    WS_XML_ELEMENT_NODE *elem;

    if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT;

    if (!prefix && node_type( parent ) == WS_XML_NODE_TYPE_ELEMENT)
    {
        elem = &parent->hdr;
        if (WsXmlStringEquals( ns, elem->ns, NULL ) == S_OK) prefix = elem->prefix;
    }

    if (!(node = alloc_node( WS_XML_NODE_TYPE_ELEMENT ))) return E_OUTOFMEMORY;
    elem = &node->hdr;

    if (prefix && !(elem->prefix = alloc_xml_string( prefix->bytes, prefix->length )))
    {
        free_node( node );
        return E_OUTOFMEMORY;
    }
    if (!(elem->localName = alloc_xml_string( localname->bytes, localname->length )))
    {
        free_node( node );
        return E_OUTOFMEMORY;
    }
    if (!(elem->ns = alloc_xml_string( ns->bytes, ns->length )))
    {
        free_node( node );
        return E_OUTOFMEMORY;
    }
    write_insert_node( writer, parent, node );
    return S_OK;
}

static HRESULT write_add_endelement_node( struct writer *writer, struct node *parent )
{
    struct node *node;
    if (!(node = alloc_node( WS_XML_NODE_TYPE_END_ELEMENT ))) return E_OUTOFMEMORY;
    node->parent = parent;
    list_add_tail( &parent->children, &node->entry );
    return S_OK;
}

static HRESULT write_element_node( struct writer *writer, const WS_XML_STRING *prefix,
                                   const WS_XML_STRING *localname, const WS_XML_STRING *ns )
{
    HRESULT hr;
    if ((hr = write_flush( writer )) != S_OK) return hr;
    if ((hr = write_add_element_node( writer, prefix, localname, ns )) != S_OK) return hr;
    if ((hr = write_add_endelement_node( writer, writer->current )) != S_OK) return hr;
    writer->state = WRITER_STATE_STARTELEMENT;
    return S_OK;
}

/**************************************************************************
 *          WsWriteStartElement		[webservices.@]
 */
HRESULT WINAPI WsWriteStartElement( 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;

    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 || !localname || !ns) return E_INVALIDARG;
    return write_element_node( writer, prefix, localname, ns );
}

static ULONG format_bool( const BOOL *ptr, unsigned char *buf )
{
    static const unsigned char bool_true[] = {'t','r','u','e'}, bool_false[] = {'f','a','l','s','e'};
    if (*ptr)
    {
        memcpy( buf, bool_true, sizeof(bool_true) );
        return sizeof(bool_true);
    }
    memcpy( buf, bool_false, sizeof(bool_false) );
    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 );
}

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 );
}

static ULONG format_double( const double *ptr, unsigned char *buf )
{
#ifdef HAVE_POWL
    static const long double precision = 0.0000000000000001;
    unsigned char *p = buf;
    long double val = *ptr;
    int neg, mag, mag2, use_exp;

    if (isnan( val ))
    {
        memcpy( buf, "NaN", 3 );
        return 3;
    }
    if (isinf( val ))
    {
        if (val < 0)
        {
            memcpy( buf, "-INF", 4 );
            return 4;
        }
        memcpy( buf, "INF", 3 );
        return 3;
    }
    if (val == 0.0)
    {
        *p = '0';
        return 1;
    }

    if ((neg = val < 0))
    {
        *p++ = '-';
        val = -val;
    }

    mag = log10l( val );
    use_exp = (mag >= 15 || (neg && mag >= 1) || mag <= -1);
    if (use_exp)
    {
        if (mag < 0) mag -= 1;
        val = val / powl( 10.0, mag );
        mag2 = mag;
        mag = 0;
    }
    else if (mag < 1) mag = 0;

    while (val > precision || mag >= 0)
    {
        long double weight = powl( 10.0, mag );
        if (weight > 0 && !isinf( weight ))
        {
            int digit = floorl( val / weight );
            val -= digit * weight;
            *(p++) = '0' + digit;
        }
        if (!mag && val > precision) *(p++) = '.';
        mag--;
    }

    if (use_exp)
    {
        int i, j;
        *(p++) = 'E';
        if (mag2 > 0) *(p++) = '+';
        else
        {
            *(p++) = '-';
            mag2 = -mag2;
        }
        mag = 0;
        while (mag2 > 0)
        {
            *(p++) = '0' + mag2 % 10;
            mag2 /= 10;
            mag++;
        }
        for (i = -mag, j = -1; i < j; i++, j--)
        {
            p[i] ^= p[j];
            p[j] ^= p[i];
            p[i] ^= p[j];
        }
    }

    return p - buf;
#else
    FIXME( "powl not found at build time\n" );
    return 0;
#endif
}

static inline int year_size( int year )
{
    return leap_year( year ) ? 366 : 365;
}

#define TZ_OFFSET 8
static ULONG format_datetime( const WS_DATETIME *ptr, unsigned char *buf )
{
    static const char fmt[] = "%04u-%02u-%02uT%02u:%02u:%02u";
    int day, hour, min, sec, sec_frac, month = 1, year = 1, tz_hour;
    unsigned __int64 ticks, day_ticks;
    ULONG len;

    if (ptr->format == WS_DATETIME_FORMAT_LOCAL &&
        ptr->ticks >= TICKS_1601_01_01 + TZ_OFFSET * TICKS_PER_HOUR)
    {
        ticks = ptr->ticks - TZ_OFFSET * TICKS_PER_HOUR;
        tz_hour = TZ_OFFSET;
    }
    else
    {
        ticks = ptr->ticks;
        tz_hour = 0;
    }
    day = ticks / TICKS_PER_DAY;
    day_ticks = ticks % TICKS_PER_DAY;
    hour = day_ticks / TICKS_PER_HOUR;
    min = (day_ticks % TICKS_PER_HOUR) / TICKS_PER_MIN;
    sec = (day_ticks % TICKS_PER_MIN) / TICKS_PER_SEC;
    sec_frac = day_ticks % TICKS_PER_SEC;

    while (day >= year_size( year ))
    {
        day -= year_size( year );
        year++;
    }
    while (day >= month_days[leap_year( year )][month])
    {
        day -= month_days[leap_year( year )][month];
        month++;
    }
    day++;

    len = sprintf( (char *)buf, fmt, year, month, day, hour, min, sec );
    if (sec_frac)
    {
        static const char fmt_frac[] = ".%07u";
        len += sprintf( (char *)buf + len, fmt_frac, sec_frac );
        while (buf[len - 1] == '0') len--;
    }
    if (ptr->format == WS_DATETIME_FORMAT_UTC)
    {
        buf[len++] = 'Z';
    }
    else if (ptr->format == WS_DATETIME_FORMAT_LOCAL)
    {
        static const char fmt_tz[] = "%c%02u:00";
        len += sprintf( (char *)buf + len, fmt_tz, tz_hour ? '-' : '+', tz_hour );
    }

    return len;
}

static ULONG format_guid( const GUID *ptr, unsigned char *buf )
{
    static const char fmt[] = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
    return sprintf( (char *)buf, fmt, ptr->Data1, ptr->Data2, ptr->Data3,
                    ptr->Data4[0], ptr->Data4[1], ptr->Data4[2], ptr->Data4[3],
                    ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] );
}

static ULONG format_urn( const GUID *ptr, unsigned char *buf )
{
    static const char fmt[] = "urn:uuid:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
    return sprintf( (char *)buf, fmt, ptr->Data1, ptr->Data2, ptr->Data3,
                    ptr->Data4[0], ptr->Data4[1], ptr->Data4[2], ptr->Data4[3],
                    ptr->Data4[4], ptr->Data4[5], ptr->Data4[6], ptr->Data4[7] );
}

static ULONG encode_base64( const unsigned char *bin, ULONG len, unsigned char *buf )
{
    static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    ULONG i = 0, x;

    while (len > 0)
    {
        buf[i++] = base64[(bin[0] & 0xfc) >> 2];
        x = (bin[0] & 3) << 4;
        if (len == 1)
        {
            buf[i++] = base64[x];
            buf[i++] = '=';
            buf[i++] = '=';
            break;
        }
        buf[i++] = base64[x | ((bin[1] & 0xf0) >> 4)];
        x = (bin[1] & 0x0f) << 2;
        if (len == 2)
        {
            buf[i++] = base64[x];
            buf[i++] = '=';
            break;
        }
        buf[i++] = base64[x | ((bin[2] & 0xc0) >> 6)];
        buf[i++] = base64[bin[2] & 0x3f];
        bin += 3;
        len -= 3;
    }
    return i;
}

static HRESULT text_to_utf8text( const WS_XML_TEXT *text, WS_XML_UTF8_TEXT **ret )
{
    switch (text->textType)
    {
    case WS_XML_TEXT_TYPE_UTF8:
    {
        const WS_XML_UTF8_TEXT *src = (const WS_XML_UTF8_TEXT *)text;
        if (!(*ret = alloc_utf8_text( src->value.bytes, src->value.length ))) return E_OUTOFMEMORY;
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_UTF16:
    {
        const WS_XML_UTF16_TEXT *src = (const WS_XML_UTF16_TEXT *)text;
        const WCHAR *str = (const WCHAR *)src->bytes;
        ULONG len = src->byteCount / sizeof(WCHAR), len_utf8;

        if (src->byteCount % sizeof(WCHAR)) return E_INVALIDARG;
        len_utf8 = WideCharToMultiByte( CP_UTF8, 0, str, len, NULL, 0, NULL, NULL );
        if (!(*ret = alloc_utf8_text( NULL, len_utf8 ))) return E_OUTOFMEMORY;
        WideCharToMultiByte( CP_UTF8, 0, str, len, (char *)(*ret)->value.bytes, (*ret)->value.length, NULL, NULL );
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_BASE64:
    {
        const WS_XML_BASE64_TEXT *base64 = (const WS_XML_BASE64_TEXT *)text;
        ULONG len = ((4 * base64->length / 3) + 3) & ~3;
        if (!(*ret = alloc_utf8_text( NULL, len ))) return E_OUTOFMEMORY;
        (*ret)->value.length = encode_base64( base64->bytes, base64->length, (*ret)->value.bytes );
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_BOOL:
    {
        const WS_XML_BOOL_TEXT *bool_text = (const WS_XML_BOOL_TEXT *)text;
        if (!(*ret = alloc_utf8_text( NULL, 5 ))) return E_OUTOFMEMORY;
        (*ret)->value.length = format_bool( &bool_text->value, (*ret)->value.bytes );
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_INT32:
    {
        const WS_XML_INT32_TEXT *int32_text = (const WS_XML_INT32_TEXT *)text;
        unsigned char buf[12]; /* "-2147483648" */
        ULONG len = format_int32( &int32_text->value, buf );
        if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_INT64:
    {
        const WS_XML_INT64_TEXT *int64_text = (const WS_XML_INT64_TEXT *)text;
        unsigned char buf[21]; /* "-9223372036854775808" */
        ULONG len = format_int64( &int64_text->value, buf );
        if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_UINT64:
    {
        const WS_XML_UINT64_TEXT *uint64_text = (const WS_XML_UINT64_TEXT *)text;
        unsigned char buf[21]; /* "18446744073709551615" */
        ULONG len = format_uint64( &uint64_text->value, buf );
        if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_DOUBLE:
    {
        const WS_XML_DOUBLE_TEXT *double_text = (const WS_XML_DOUBLE_TEXT *)text;
        unsigned char buf[32]; /* "-1.1111111111111111E-308", oversized to address Valgrind limitations */
        unsigned short fpword;
        ULONG len;

        if (!set_fpword( 0x37f, &fpword )) return E_NOTIMPL;
        len = format_double( &double_text->value, buf );
        restore_fpword( fpword );
        if (!len) return E_NOTIMPL;
        if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_GUID:
    {
        const WS_XML_GUID_TEXT *id = (const WS_XML_GUID_TEXT *)text;
        if (!(*ret = alloc_utf8_text( NULL, 37 ))) return E_OUTOFMEMORY;
        (*ret)->value.length = format_guid( &id->value, (*ret)->value.bytes );
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_UNIQUE_ID:
    {
        const WS_XML_UNIQUE_ID_TEXT *id = (const WS_XML_UNIQUE_ID_TEXT *)text;
        if (!(*ret = alloc_utf8_text( NULL, 46 ))) return E_OUTOFMEMORY;
        (*ret)->value.length = format_urn( &id->value, (*ret)->value.bytes );
        return S_OK;
    }
    case WS_XML_TEXT_TYPE_DATETIME:
    {
        const WS_XML_DATETIME_TEXT *dt = (const WS_XML_DATETIME_TEXT *)text;
        if (!(*ret = alloc_utf8_text( NULL, 34 ))) return E_OUTOFMEMORY;
        (*ret)->value.length = format_datetime( &dt->value, (*ret)->value.bytes );
        return S_OK;
    }
    default:
        FIXME( "unhandled text type %u\n", text->textType );
        return E_NOTIMPL;
    }
}

static HRESULT write_set_attribute_value( struct writer *writer, const WS_XML_TEXT *value )
{
    WS_XML_ELEMENT_NODE *elem = &writer->current->hdr;
    WS_XML_UTF8_TEXT *utf8;
    HRESULT hr;

    if ((hr = text_to_utf8text( value, &utf8 )) != S_OK) return hr;
    elem->attributes[elem->attributeCount - 1]->value = &utf8->text;
    return S_OK;
}

static HRESULT write_add_text_node( struct writer *writer, const WS_XML_TEXT *value )
{
    struct node *node;
    WS_XML_TEXT_NODE *text;
    WS_XML_UTF8_TEXT *utf8;
    HRESULT hr;

    if (node_type( writer->current ) != WS_XML_NODE_TYPE_ELEMENT &&
        node_type( writer->current ) != WS_XML_NODE_TYPE_BOF &&
        node_type( writer->current ) != WS_XML_NODE_TYPE_CDATA) return WS_E_INVALID_FORMAT;

    if (!(node = alloc_node( WS_XML_NODE_TYPE_TEXT ))) return E_OUTOFMEMORY;
    if ((hr = text_to_utf8text( value, &utf8 )) != S_OK)
    {
        heap_free( node );
        return hr;
    }
    text = (WS_XML_TEXT_NODE *)node;
    text->text = &utf8->text;

    write_insert_node( writer, writer->current, node );
    return S_OK;
}

static HRESULT write_text( struct writer *writer )
{
    const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)writer->current;
    const WS_XML_UTF8_TEXT *utf8 = (const WS_XML_UTF8_TEXT *)text->text;
    HRESULT hr;

    if (!writer->current->parent) return WS_E_INVALID_FORMAT;
    if (node_type( writer->current->parent ) == WS_XML_NODE_TYPE_ELEMENT)
    {
        const struct escape *escapes[3] = { &escape_lt, &escape_gt, &escape_amp };
        return write_bytes_escape( writer, utf8->value.bytes, utf8->value.length, escapes, 3 );
    }
    else if (node_type( writer->current->parent ) == WS_XML_NODE_TYPE_CDATA)
    {
        if ((hr = write_grow_buffer( writer, utf8->value.length )) != S_OK) return hr;
        write_bytes( writer, utf8->value.bytes, utf8->value.length );
        return S_OK;
    }

    return WS_E_INVALID_FORMAT;
}

static HRESULT write_text_node( struct writer *writer, const WS_XML_TEXT *text )
{
    HRESULT hr;
    if ((hr = write_flush( writer )) != S_OK) return hr;
    if ((hr = write_add_text_node( writer, text )) != S_OK) return hr;
    if ((hr = write_text( writer )) != S_OK) return hr;
    writer->state = WRITER_STATE_TEXT;
    return S_OK;
}

/**************************************************************************
 *          WsWriteText		[webservices.@]
 */
HRESULT WINAPI WsWriteText( WS_XML_WRITER *handle, const WS_XML_TEXT *text, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %p %p\n", handle, text, error );

    if (!writer || !text) return E_INVALIDARG;

    if (writer->state == WRITER_STATE_STARTATTRIBUTE) return write_set_attribute_value( writer, text );
    return write_text_node( writer, text );
}

static HRESULT write_type_text( struct writer *writer, WS_TYPE_MAPPING mapping, const WS_XML_TEXT *text )
{
    switch (mapping)
    {
    case WS_ELEMENT_TYPE_MAPPING:
    case WS_ELEMENT_CONTENT_TYPE_MAPPING:
        return write_text_node( writer, text );

    case WS_ATTRIBUTE_TYPE_MAPPING:
        return write_set_attribute_value( writer, text );

    case WS_ANY_ELEMENT_TYPE_MAPPING:
        switch (writer->state)
        {
        case WRITER_STATE_STARTATTRIBUTE:
            return write_set_attribute_value( writer, text );

        case WRITER_STATE_STARTELEMENT:
            return write_text_node( writer, text );

        default:
            FIXME( "writer state %u not handled\n", writer->state );
            return E_NOTIMPL;
        }

    default:
        FIXME( "mapping %u not implemented\n", mapping );
        return E_NOTIMPL;
    }
}

static HRESULT write_add_nil_attribute( struct writer *writer )
{
    static const WS_XML_STRING prefix = {1, (BYTE *)"a"};
    static const WS_XML_STRING localname = {3, (BYTE *)"nil"};
    static const WS_XML_STRING ns = {41, (BYTE *)"http://www.w3.org/2001/XMLSchema-instance"};
    static const WS_XML_UTF8_TEXT value = {{WS_XML_TEXT_TYPE_UTF8}, {4, (BYTE *)"true"}};
    HRESULT hr;

    if ((hr = write_add_attribute( writer, &prefix, &localname, &ns, FALSE )) != S_OK) return hr;
    if ((hr = write_set_attribute_value( writer, &value.text )) != S_OK) return hr;
    return write_add_namespace_attribute( writer, &prefix, &ns, FALSE );
}

static HRESULT get_value_ptr( WS_WRITE_OPTION option, const void *value, ULONG size, ULONG expected_size,
                              const void **ptr )
{
    switch (option)
    {
    case WS_WRITE_REQUIRED_VALUE:
    case WS_WRITE_NILLABLE_VALUE:
        if (!value || size != expected_size) return E_INVALIDARG;
        *ptr = value;
        return S_OK;

    case WS_WRITE_REQUIRED_POINTER:
        if (size != sizeof(const void *) || !(*ptr = *(const void **)value)) return E_INVALIDARG;
        return S_OK;

    case WS_WRITE_NILLABLE_POINTER:
        if (size != sizeof(const void *)) return E_INVALIDARG;
        *ptr = *(const void **)value;
        return S_OK;

    default:
        return E_INVALIDARG;
    }
}

static HRESULT write_type_bool( struct writer *writer, WS_TYPE_MAPPING mapping,
                                const WS_BOOL_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                const BOOL *value, ULONG size )
{
    WS_XML_UTF8_TEXT utf8;
    unsigned char buf[6]; /* "false" */
    const BOOL *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    if ((hr = get_value_ptr( option, value, size, sizeof(BOOL), (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_bool( ptr, buf );
    return write_type_text( writer, mapping, &utf8.text );
}

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" */
    const INT8 *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    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 );
}

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" */
    const INT16 *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    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 );
}

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" */
    const INT32 *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    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 );
}

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" */
    const INT64 *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    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 );
}

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" */
    const UINT8 *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    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 );
}

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" */
    const UINT16 *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    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 );
}

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" */
    const UINT32 *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    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 );
}

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" */
    const UINT64 *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    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 );
}

static HRESULT write_type_datetime( struct writer *writer, WS_TYPE_MAPPING mapping,
                                    const WS_DATETIME_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                    const void *value, ULONG size )
{
    WS_XML_UTF8_TEXT utf8;
    unsigned char buf[34]; /* "0000-00-00T00:00:00.0000000-00:00" */
    const WS_DATETIME *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    if ((hr = get_value_ptr( option, value, size, sizeof(WS_DATETIME), (const void **)&ptr )) != S_OK) return hr;
    if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
    if (ptr->ticks > TICKS_MAX || ptr->format > WS_DATETIME_FORMAT_NONE) return WS_E_INVALID_FORMAT;

    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
    utf8.value.bytes   = buf;
    utf8.value.length  = format_datetime( ptr, buf );
    return write_type_text( writer, mapping, &utf8.text );
}

static HRESULT write_type_guid( struct writer *writer, WS_TYPE_MAPPING mapping,
                                const WS_GUID_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                const void *value, ULONG size )
{
    WS_XML_UTF8_TEXT utf8;
    unsigned char buf[37]; /* "00000000-0000-0000-0000-000000000000" */
    const GUID *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    if ((hr = get_value_ptr( option, value, size, sizeof(GUID), (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_guid( ptr, buf );
    return write_type_text( writer, mapping, &utf8.text );
}

static HRESULT write_type_string( struct writer *writer, WS_TYPE_MAPPING mapping,
                                  const WS_STRING_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                  const void *value, ULONG size )
{
    WS_XML_UTF16_TEXT utf16;
    const WS_STRING *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option) return E_INVALIDARG;
    if ((hr = get_value_ptr( option, value, size, sizeof(WS_STRING), (const void **)&ptr )) != S_OK) return hr;
    if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
    if (!ptr->length) return S_OK;

    utf16.text.textType = WS_XML_TEXT_TYPE_UTF16;
    utf16.bytes         = (BYTE *)ptr->chars;
    utf16.byteCount     = ptr->length * sizeof(WCHAR);
    return write_type_text( writer, mapping, &utf16.text );
}

static HRESULT write_type_wsz( struct writer *writer, WS_TYPE_MAPPING mapping,
                               const WS_WSZ_DESCRIPTION *desc, WS_WRITE_OPTION option,
                               const void *value, ULONG size )
{
    WS_XML_UTF16_TEXT utf16;
    const WCHAR *ptr;
    HRESULT hr;
    int len;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option || option == WS_WRITE_REQUIRED_VALUE || option == WS_WRITE_NILLABLE_VALUE) return E_INVALIDARG;
    if ((hr = get_value_ptr( option, value, size, 0, (const void **)&ptr )) != S_OK) return hr;
    if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
    if (!(len = strlenW( ptr ))) return S_OK;

    utf16.text.textType = WS_XML_TEXT_TYPE_UTF16;
    utf16.bytes         = (BYTE *)ptr;
    utf16.byteCount     = len * sizeof(WCHAR);
    return write_type_text( writer, mapping, &utf16.text );
}

static HRESULT write_type_bytes( struct writer *writer, WS_TYPE_MAPPING mapping,
                                 const WS_BYTES_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                 const void *value, ULONG size )
{
    WS_XML_BASE64_TEXT base64;
    const WS_BYTES *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option) return E_INVALIDARG;
    if ((hr = get_value_ptr( option, value, size, sizeof(WS_BYTES), (const void **)&ptr )) != S_OK) return hr;
    if ((option == WS_WRITE_NILLABLE_VALUE && is_nil_value( value, size )) ||
        (option == WS_WRITE_NILLABLE_POINTER && !ptr)) return write_add_nil_attribute( writer );
    if (!ptr->length) return S_OK;

    base64.text.textType = WS_XML_TEXT_TYPE_BASE64;
    base64.bytes         = ptr->bytes;
    base64.length        = ptr->length;
    return write_type_text( writer, mapping, &base64.text );
}

static HRESULT write_type_xml_string( struct writer *writer, WS_TYPE_MAPPING mapping,
                                      const WS_XML_STRING_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                      const void *value, ULONG size )
{
    WS_XML_UTF8_TEXT utf8;
    const WS_XML_STRING *ptr;
    HRESULT hr;

    if (desc)
    {
        FIXME( "description not supported\n" );
        return E_NOTIMPL;
    }

    if (!option) return E_INVALIDARG;
    if ((hr = get_value_ptr( option, value, size, sizeof(WS_XML_STRING), (const void **)&ptr )) != S_OK) return hr;
    if (option == WS_WRITE_NILLABLE_POINTER && !ptr) return write_add_nil_attribute( writer );
    if (option == WS_WRITE_NILLABLE_VALUE && is_nil_value( value, size )) return write_add_nil_attribute( writer );
    if (!ptr->length) return S_OK;

    utf8.text.textType = WS_XML_TEXT_TYPE_UTF8;
    utf8.value.bytes   = ptr->bytes;
    utf8.value.length  = ptr->length;
    return write_type_text( writer, mapping, &utf8.text );
}

static WS_WRITE_OPTION get_field_write_option( WS_TYPE type, ULONG options )
{
    if (options & WS_FIELD_POINTER)
    {
        if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_WRITE_NILLABLE_POINTER;
        return WS_WRITE_REQUIRED_POINTER;
    }

    switch (type)
    {
    case WS_BOOL_TYPE:
    case WS_INT8_TYPE:
    case WS_INT16_TYPE:
    case WS_INT32_TYPE:
    case WS_INT64_TYPE:
    case WS_UINT8_TYPE:
    case WS_UINT16_TYPE:
    case WS_UINT32_TYPE:
    case WS_UINT64_TYPE:
    case WS_DOUBLE_TYPE:
    case WS_DATETIME_TYPE:
    case WS_GUID_TYPE:
    case WS_STRING_TYPE:
    case WS_BYTES_TYPE:
    case WS_XML_STRING_TYPE:
    case WS_STRUCT_TYPE:
    case WS_ENUM_TYPE:
        if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_WRITE_NILLABLE_VALUE;
        return WS_WRITE_REQUIRED_VALUE;

    case WS_WSZ_TYPE:
    case WS_DESCRIPTION_TYPE:
        if (options & (WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE)) return WS_WRITE_NILLABLE_POINTER;
        return WS_WRITE_REQUIRED_POINTER;

    default:
        FIXME( "unhandled type %u\n", type );
        return 0;
    }
}

static HRESULT write_type( struct writer *, WS_TYPE_MAPPING, WS_TYPE, const void *, WS_WRITE_OPTION,
                           const void *, ULONG );

static HRESULT write_type_repeating_element( struct writer *writer, const WS_FIELD_DESCRIPTION *desc,
                                             const char *buf, ULONG count )
{
    HRESULT hr = S_OK;
    ULONG i, size, offset = 0;
    WS_WRITE_OPTION option;

    if (!(option = get_field_write_option( desc->type, desc->options ))) return E_INVALIDARG;

    /* wrapper element */
    if (desc->localName && ((hr = write_element_node( writer, NULL, desc->localName, desc->ns )) != S_OK))
        return hr;

    if (option == WS_WRITE_REQUIRED_VALUE || option == WS_WRITE_NILLABLE_VALUE)
        size = get_type_size( desc->type, desc->typeDescription );
    else
        size = sizeof(const void *);

    for (i = 0; i < count; i++)
    {
        if ((hr = write_element_node( writer, NULL, desc->itemLocalName, desc->itemNs )) != S_OK) return hr;
        if ((hr = write_type( writer, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->typeDescription, option,
                              buf + offset, size )) != S_OK) return hr;
        if ((hr = write_endelement_node( writer )) != S_OK) return hr;
        offset += size;
    }

    if (desc->localName) hr = write_endelement_node( writer );
    return hr;
}

static HRESULT write_type_struct_field( struct writer *writer, const WS_FIELD_DESCRIPTION *desc,
                                        const char *buf, ULONG offset )
{
    HRESULT hr;
    WS_TYPE_MAPPING mapping;
    WS_WRITE_OPTION option;
    ULONG count, size, field_options = desc->options;
    const char *ptr = buf + offset;

    if (field_options & ~(WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE))
    {
        FIXME( "options 0x%x not supported\n", desc->options );
        return E_NOTIMPL;
    }

    /*  zero-terminated strings are always pointers */
    if (desc->type == WS_WSZ_TYPE) field_options |= WS_FIELD_POINTER;

    if (field_options & WS_FIELD_POINTER)
        size = sizeof(const void *);
    else
        size = get_type_size( desc->type, desc->typeDescription );

    if (is_nil_value( ptr, size ))
    {
        if (field_options & WS_FIELD_OPTIONAL) return S_OK;
        if (field_options & WS_FIELD_NILLABLE)
        {
            if (field_options & WS_FIELD_POINTER) option = WS_WRITE_NILLABLE_POINTER;
            else option = WS_WRITE_NILLABLE_VALUE;
        }
        else return E_INVALIDARG;
    }
    else
    {
        if (field_options & WS_FIELD_POINTER) option = WS_WRITE_REQUIRED_POINTER;
        else option = WS_WRITE_REQUIRED_VALUE;
    }

    switch (desc->mapping)
    {
    case WS_ATTRIBUTE_FIELD_MAPPING:
        if (!desc->localName || !desc->ns) return E_INVALIDARG;
        if ((hr = write_add_attribute( writer, NULL, desc->localName, desc->ns, FALSE )) != S_OK)
            return hr;
        writer->state = WRITER_STATE_STARTATTRIBUTE;

        mapping = WS_ATTRIBUTE_TYPE_MAPPING;
        break;

    case WS_ELEMENT_FIELD_MAPPING:
        if ((hr = write_element_node( writer, NULL, desc->localName, desc->ns )) != S_OK) return hr;
        mapping = WS_ELEMENT_TYPE_MAPPING;
        break;

    case WS_REPEATING_ELEMENT_FIELD_MAPPING:
        count = *(const ULONG *)(buf + desc->countOffset);
        return write_type_repeating_element( writer, desc, *(const char **)ptr, count );

    case WS_TEXT_FIELD_MAPPING:
        switch (writer->state)
        {
        case WRITER_STATE_STARTELEMENT:
            mapping = WS_ELEMENT_CONTENT_TYPE_MAPPING;
            break;

        case WRITER_STATE_STARTATTRIBUTE:
            mapping = WS_ATTRIBUTE_TYPE_MAPPING;
            break;

        default:
            FIXME( "unhandled writer state %u\n", writer->state );
            return E_NOTIMPL;
        }
        break;

    default:
        FIXME( "field mapping %u not supported\n", desc->mapping );
        return E_NOTIMPL;
    }

    if ((hr = write_type( writer, mapping, desc->type, desc->typeDescription, option, ptr, size )) != S_OK)
        return hr;

    switch (mapping)
    {
    case WS_ATTRIBUTE_TYPE_MAPPING:
        writer->state = WRITER_STATE_STARTELEMENT;
        break;

    case WS_ELEMENT_TYPE_MAPPING:
        if ((hr = write_endelement_node( writer )) != S_OK) return hr;
        break;

    default: break;
    }

    return S_OK;
}

static HRESULT write_type_struct( struct writer *writer, WS_TYPE_MAPPING mapping,
                                  const WS_STRUCT_DESCRIPTION *desc, WS_WRITE_OPTION option,
                                  const void *value, ULONG size )
{
    ULONG i, offset;
    const void *ptr;
    HRESULT hr;

    if (!desc) return E_INVALIDARG;
    if (desc->structOptions) FIXME( "struct options 0x%x not supported\n", desc->structOptions );

    if ((hr = get_value_ptr( option, value, size, desc->size, &ptr )) != S_OK) return hr;

    for (i = 0; i < desc->fieldCount; i++)
    {
        offset = desc->fields[i]->offset;
        if ((hr = write_type_struct_field( writer, desc->fields[i], ptr, offset )) != S_OK)
            return hr;
    }

    return S_OK;
}


static HRESULT write_type( struct writer *writer, WS_TYPE_MAPPING mapping, WS_TYPE type,
                           const void *desc, WS_WRITE_OPTION option, const void *value,
                           ULONG size )
{
    switch (type)
    {
    case WS_BOOL_TYPE:
        return write_type_bool( writer, mapping, desc, option, value, size );

    case WS_INT8_TYPE:
        return write_type_int8( writer, mapping, desc, option, value, size );

    case WS_INT16_TYPE:
        return write_type_int16( writer, mapping, desc, option, value, size );

    case WS_INT32_TYPE:
        return write_type_int32( writer, mapping, desc, option, value, size );

    case WS_INT64_TYPE:
        return write_type_int64( writer, mapping, desc, option, value, size );

    case WS_UINT8_TYPE:
        return write_type_uint8( writer, mapping, desc, option, value, size );

    case WS_UINT16_TYPE:
        return write_type_uint16( writer, mapping, desc, option, value, size );

    case WS_UINT32_TYPE:
        return write_type_uint32( writer, mapping, desc, option, value, size );

    case WS_UINT64_TYPE:
        return write_type_uint64( writer, mapping, desc, option, value, size );

    case WS_DATETIME_TYPE:
        return write_type_datetime( writer, mapping, desc, option, value, size );

    case WS_GUID_TYPE:
        return write_type_guid( writer, mapping, desc, option, value, size );

    case WS_STRING_TYPE:
        return write_type_string( writer, mapping, desc, option, value, size );

    case WS_WSZ_TYPE:
        return write_type_wsz( writer, mapping, desc, option, value, size );

    case WS_BYTES_TYPE:
        return write_type_bytes( writer, mapping, desc, option, value, size );

    case WS_XML_STRING_TYPE:
        return write_type_xml_string( writer, mapping, desc, option, value, size );

    case WS_STRUCT_TYPE:
        return write_type_struct( writer, mapping, desc, option, value, size );

    default:
        FIXME( "type %u not supported\n", type );
        return E_NOTIMPL;
    }
}

/**************************************************************************
 *          WsWriteAttribute		[webservices.@]
 */
HRESULT WINAPI WsWriteAttribute( WS_XML_WRITER *handle, const WS_ATTRIBUTE_DESCRIPTION *desc,
                                 WS_WRITE_OPTION option, const void *value, ULONG size,
                                 WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    HRESULT hr;

    TRACE( "%p %p %u %p %u %p\n", handle, desc, option, value, size, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !desc || !desc->attributeLocalName || !desc->attributeNs || !value)
        return E_INVALIDARG;

    if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;

    if ((hr = write_add_attribute( writer, NULL, desc->attributeLocalName, desc->attributeNs,
                                   FALSE )) != S_OK) return hr;
    writer->state = WRITER_STATE_STARTATTRIBUTE;

    return write_type( writer, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->typeDescription,
                       option, value, size );
}

/**************************************************************************
 *          WsWriteElement		[webservices.@]
 */
HRESULT WINAPI WsWriteElement( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION *desc,
                               WS_WRITE_OPTION option, const void *value, ULONG size,
                               WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    HRESULT hr;

    TRACE( "%p %p %u %p %u %p\n", handle, desc, option, value, size, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !desc || !desc->elementLocalName || !desc->elementNs || !value)
        return E_INVALIDARG;

    if ((hr = write_element_node( writer, NULL, desc->elementLocalName, desc->elementNs )) != S_OK) return hr;

    if ((hr = write_type( writer, WS_ANY_ELEMENT_TYPE_MAPPING, desc->type, desc->typeDescription,
                          option, value, size )) != S_OK) return hr;

    return write_endelement_node( writer );
}

/**************************************************************************
 *          WsWriteType		[webservices.@]
 */
HRESULT WINAPI WsWriteType( WS_XML_WRITER *handle, WS_TYPE_MAPPING mapping, WS_TYPE type,
                            const void *desc, WS_WRITE_OPTION option, const void *value,
                            ULONG size, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    HRESULT hr;

    TRACE( "%p %u %u %p %u %p %u %p\n", handle, mapping, type, desc, option, value,
           size, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !value) return E_INVALIDARG;

    switch (mapping)
    {
    case WS_ATTRIBUTE_TYPE_MAPPING:
        if (writer->state != WRITER_STATE_STARTATTRIBUTE) return WS_E_INVALID_FORMAT;
        hr = write_type( writer, mapping, type, desc, option, value, size );
        break;

    case WS_ELEMENT_TYPE_MAPPING:
    case WS_ELEMENT_CONTENT_TYPE_MAPPING:
        if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_FORMAT;
        hr = write_type( writer, mapping, type, desc, option, value, size );
        break;

    case WS_ANY_ELEMENT_TYPE_MAPPING:
        hr = write_type( writer, mapping, type, desc, option, value, size );
        break;

    default:
        FIXME( "mapping %u not implemented\n", mapping );
        return E_NOTIMPL;
    }

    return hr;
}

WS_TYPE map_value_type( WS_VALUE_TYPE type )
{
    switch (type)
    {
    case WS_BOOL_VALUE_TYPE:     return WS_BOOL_TYPE;
    case WS_INT8_VALUE_TYPE:     return WS_INT8_TYPE;
    case WS_INT16_VALUE_TYPE:    return WS_INT16_TYPE;
    case WS_INT32_VALUE_TYPE:    return WS_INT32_TYPE;
    case WS_INT64_VALUE_TYPE:    return WS_INT64_TYPE;
    case WS_UINT8_VALUE_TYPE:    return WS_UINT8_TYPE;
    case WS_UINT16_VALUE_TYPE:   return WS_UINT16_TYPE;
    case WS_UINT32_VALUE_TYPE:   return WS_UINT32_TYPE;
    case WS_UINT64_VALUE_TYPE:   return WS_UINT64_TYPE;
    case WS_FLOAT_VALUE_TYPE:    return WS_FLOAT_TYPE;
    case WS_DOUBLE_VALUE_TYPE:   return WS_DOUBLE_TYPE;
    case WS_DECIMAL_VALUE_TYPE:  return WS_DECIMAL_TYPE;
    case WS_DATETIME_VALUE_TYPE: return WS_DATETIME_TYPE;
    case WS_TIMESPAN_VALUE_TYPE: return WS_TIMESPAN_TYPE;
    case WS_GUID_VALUE_TYPE:     return WS_GUID_TYPE;
    default:
        FIXME( "unhandled type %u\n", type );
        return ~0u;
    }
}

/**************************************************************************
 *          WsWriteValue		[webservices.@]
 */
HRESULT WINAPI WsWriteValue( WS_XML_WRITER *handle, WS_VALUE_TYPE value_type, const void *value,
                             ULONG size, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    WS_TYPE_MAPPING mapping;
    WS_TYPE type;

    TRACE( "%p %u %p %u %p\n", handle, value_type, value, size, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !value || (type = map_value_type( value_type )) == ~0u) return E_INVALIDARG;

    switch (writer->state)
    {
    case WRITER_STATE_STARTATTRIBUTE:
        mapping = WS_ATTRIBUTE_TYPE_MAPPING;
        break;

    case WRITER_STATE_STARTELEMENT:
        mapping = WS_ELEMENT_TYPE_MAPPING;
        break;

    default:
        return WS_E_INVALID_FORMAT;
    }

    return write_type( writer, mapping, type, NULL, WS_WRITE_REQUIRED_VALUE, value, size );
}

/**************************************************************************
 *          WsWriteArray		[webservices.@]
 */
HRESULT WINAPI WsWriteArray( WS_XML_WRITER *handle, const WS_XML_STRING *localname, const WS_XML_STRING *ns,
                             WS_VALUE_TYPE value_type, const void *array, ULONG size, ULONG offset,
                             ULONG count, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    WS_TYPE type;
    ULONG type_size, i;
    HRESULT hr;

    TRACE( "%p %s %s %u %p %u %u %u %p\n", handle, debugstr_xmlstr(localname), debugstr_xmlstr(ns),
           value_type, array, size, offset, count, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;
    if (!writer->output_type) return WS_E_INVALID_OPERATION;
    if (!localname || !ns || (type = map_value_type( value_type )) == ~0u) return E_INVALIDARG;

    type_size = get_type_size( type, NULL );
    if (size % type_size || (offset + count) * type_size > size || (count && !array)) return E_INVALIDARG;

    for (i = offset; i < count; i++)
    {
        const char *ptr = (const char *)array + (offset + i) * type_size;
        if ((hr = write_element_node( writer, NULL, localname, ns )) != S_OK) return hr;
        if ((hr = write_type( writer, WS_ELEMENT_TYPE_MAPPING, type, NULL, WS_WRITE_REQUIRED_POINTER,
                              &ptr, sizeof(ptr) )) != S_OK) return hr;
        if ((hr = write_endelement_node( writer )) != S_OK) return hr;
    }

    return S_OK;
}

/**************************************************************************
 *          WsWriteXmlBuffer		[webservices.@]
 */
HRESULT WINAPI WsWriteXmlBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
    HRESULT hr;

    TRACE( "%p %p %p\n", handle, buffer, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !xmlbuf) return E_INVALIDARG;

    if ((hr = write_flush( writer )) != S_OK) return hr;
    if ((hr = write_grow_buffer( writer, xmlbuf->size )) != S_OK) return hr;
    write_bytes( writer, xmlbuf->ptr, xmlbuf->size );
    return S_OK;
}

/**************************************************************************
 *          WsWriteXmlBufferToBytes		[webservices.@]
 */
HRESULT WINAPI WsWriteXmlBufferToBytes( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer,
                                        const WS_XML_WRITER_ENCODING *encoding,
                                        const WS_XML_WRITER_PROPERTY *properties, ULONG count,
                                        WS_HEAP *heap, void **bytes, ULONG *size, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    struct xmlbuf *xmlbuf = (struct xmlbuf *)buffer;
    HRESULT hr;
    char *buf;
    ULONG i;

    TRACE( "%p %p %p %p %u %p %p %p %p\n", handle, buffer, encoding, properties, count, heap,
           bytes, size, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !xmlbuf || !heap || !bytes) return E_INVALIDARG;

    if (encoding && encoding->encodingType != WS_XML_WRITER_ENCODING_TYPE_TEXT)
    {
        FIXME( "encoding type %u not supported\n", encoding->encodingType );
        return E_NOTIMPL;
    }

    for (i = 0; i < count; i++)
    {
        hr = prop_set( writer->prop, writer->prop_count, properties[i].id, properties[i].value,
                       properties[i].valueSize );
        if (hr != S_OK) return hr;
    }

    if (!(buf = ws_alloc( heap, xmlbuf->size ))) return WS_E_QUOTA_EXCEEDED;
    memcpy( buf, xmlbuf->ptr, xmlbuf->size );
    *bytes = buf;
    *size = xmlbuf->size;
    return S_OK;
}

/**************************************************************************
 *          WsWriteXmlnsAttribute		[webservices.@]
 */
HRESULT WINAPI WsWriteXmlnsAttribute( WS_XML_WRITER *handle, const WS_XML_STRING *prefix,
                                      const WS_XML_STRING *ns, BOOL single, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %s %s %d %p\n", handle, debugstr_xmlstr(prefix), debugstr_xmlstr(ns),
           single, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !ns) return E_INVALIDARG;
    if (writer->state != WRITER_STATE_STARTELEMENT) return WS_E_INVALID_OPERATION;

    if (namespace_in_scope( &writer->current->hdr, prefix, ns )) return S_OK;
    return write_add_namespace_attribute( writer, prefix, ns, single );
}

static HRESULT write_move_to( struct writer *writer, WS_MOVE_TO move, BOOL *found )
{
    BOOL success = FALSE;
    struct node *node = writer->current;

    switch (move)
    {
    case WS_MOVE_TO_ROOT_ELEMENT:
        success = move_to_root_element( writer->root, &node );
        break;

    case WS_MOVE_TO_NEXT_ELEMENT:
        success = move_to_next_element( &node );
        break;

    case WS_MOVE_TO_PREVIOUS_ELEMENT:
        success = move_to_prev_element( &node );
        break;

    case WS_MOVE_TO_CHILD_ELEMENT:
        success = move_to_child_element( &node );
        break;

    case WS_MOVE_TO_END_ELEMENT:
        success = move_to_end_element( &node );
        break;

    case WS_MOVE_TO_PARENT_ELEMENT:
        success = move_to_parent_element( &node );
        break;

    case WS_MOVE_TO_FIRST_NODE:
        success = move_to_first_node( &node );
        break;

    case WS_MOVE_TO_NEXT_NODE:
        success = move_to_next_node( &node );
        break;

    case WS_MOVE_TO_PREVIOUS_NODE:
        success = move_to_prev_node( &node );
        break;

    case WS_MOVE_TO_CHILD_NODE:
        success = move_to_child_node( &node );
        break;

    case WS_MOVE_TO_BOF:
        success = move_to_bof( writer->root, &node );
        break;

    case WS_MOVE_TO_EOF:
        success = move_to_eof( writer->root, &node );
        break;

    default:
        FIXME( "unhandled move %u\n", move );
        return E_NOTIMPL;
    }

    if (success && node == writer->root) return E_INVALIDARG;
    writer->current = node;

    if (found)
    {
        *found = success;
        return S_OK;
    }
    return success ? S_OK : WS_E_INVALID_FORMAT;
}

/**************************************************************************
 *          WsMoveWriter		[webservices.@]
 */
HRESULT WINAPI WsMoveWriter( WS_XML_WRITER *handle, WS_MOVE_TO move, BOOL *found, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %u %p %p\n", handle, move, found, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;
    if (!writer->output_type) return WS_E_INVALID_OPERATION;

    return write_move_to( writer, move, found );
}

/**************************************************************************
 *          WsGetWriterPosition		[webservices.@]
 */
HRESULT WINAPI WsGetWriterPosition( WS_XML_WRITER *handle, WS_XML_NODE_POSITION *pos, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %p %p\n", handle, pos, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !pos) return E_INVALIDARG;
    if (!writer->output_type) return WS_E_INVALID_OPERATION;

    pos->buffer = (WS_XML_BUFFER *)writer->output_buf;
    pos->node   = writer->current;
    return S_OK;
}

/**************************************************************************
 *          WsSetWriterPosition		[webservices.@]
 */
HRESULT WINAPI WsSetWriterPosition( WS_XML_WRITER *handle, const WS_XML_NODE_POSITION *pos, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %p %p\n", handle, pos, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !pos || (struct xmlbuf *)pos->buffer != writer->output_buf) return E_INVALIDARG;
    if (!writer->output_type) return WS_E_INVALID_OPERATION;

    writer->current = pos->node;
    return S_OK;
}

static HRESULT write_add_comment_node( struct writer *writer, const WS_XML_STRING *value )
{
    struct node *node, *parent;
    WS_XML_COMMENT_NODE *comment;

    if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT;
    if (!(node = alloc_node( WS_XML_NODE_TYPE_COMMENT ))) return E_OUTOFMEMORY;
    comment = (WS_XML_COMMENT_NODE *)node;

    if (value->length && !(comment->value.bytes = heap_alloc( value->length )))
    {
        free_node( node );
        return E_OUTOFMEMORY;
    }
    memcpy( comment->value.bytes, value->bytes, value->length );
    comment->value.length = value->length;

    write_insert_node( writer, parent, node );
    return S_OK;
}

static HRESULT write_comment( struct writer *writer )
{
    const WS_XML_COMMENT_NODE *comment = (const WS_XML_COMMENT_NODE *)writer->current;
    HRESULT hr;

    if ((hr = write_grow_buffer( writer, comment->value.length + 7 )) != S_OK) return hr;
    write_bytes( writer, (const BYTE *)"<!--", 4 );
    write_bytes( writer, comment->value.bytes, comment->value.length );
    write_bytes( writer, (const BYTE *)"-->", 3 );
    return S_OK;
}

static HRESULT write_comment_node( struct writer *writer, const WS_XML_STRING *value )
{
    HRESULT hr;
    if ((hr = write_flush( writer )) != S_OK) return hr;
    if ((hr = write_add_comment_node( writer, value )) != S_OK) return hr;
    if ((hr = write_comment( writer )) != S_OK) return hr;
    writer->state = WRITER_STATE_COMMENT;
    return S_OK;
}

static HRESULT write_set_attributes( struct writer *writer, WS_XML_ATTRIBUTE **attrs, ULONG count )
{
    ULONG i;
    HRESULT hr;

    for (i = 0; i < count; i++)
    {
        if ((hr = write_add_attribute( writer, attrs[i]->prefix, attrs[i]->localName, attrs[i]->ns,
                                       attrs[i]->singleQuote )) != S_OK) return hr;
        if ((hr = write_set_attribute_value( writer, attrs[i]->value )) != S_OK) return hr;
    }
    return S_OK;
}

static HRESULT write_node( struct writer *writer, const WS_XML_NODE *node )
{
    HRESULT hr;

    switch (node->nodeType)
    {
    case WS_XML_NODE_TYPE_ELEMENT:
    {
        const WS_XML_ELEMENT_NODE *elem = (const WS_XML_ELEMENT_NODE *)node;
        if ((hr = write_element_node( writer, elem->prefix, elem->localName, elem->ns )) != S_OK) return hr;
        return write_set_attributes( writer, elem->attributes, elem->attributeCount );
    }
    case WS_XML_NODE_TYPE_TEXT:
    {
        const WS_XML_TEXT_NODE *text = (const WS_XML_TEXT_NODE *)node;
        return write_text_node( writer, text->text );
    }
    case WS_XML_NODE_TYPE_END_ELEMENT:
        return write_endelement_node( writer );

    case WS_XML_NODE_TYPE_COMMENT:
    {
        const WS_XML_COMMENT_NODE *comment = (const WS_XML_COMMENT_NODE *)node;
        return write_comment_node( writer, &comment->value );
    }
    case WS_XML_NODE_TYPE_CDATA:
        return write_cdata_node( writer );

    case WS_XML_NODE_TYPE_END_CDATA:
        return write_endcdata_node( writer );

    case WS_XML_NODE_TYPE_EOF:
    case WS_XML_NODE_TYPE_BOF:
        return S_OK;

    default:
        WARN( "unknown node type %u\n", node->nodeType );
        return E_INVALIDARG;
    }
}

/**************************************************************************
 *          WsWriteNode		[webservices.@]
 */
HRESULT WINAPI WsWriteNode( WS_XML_WRITER *handle, const WS_XML_NODE *node, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;

    TRACE( "%p %p %p\n", handle, node, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer || !node) return E_INVALIDARG;
    if (!writer->output_type) return WS_E_INVALID_OPERATION;

    return write_node( writer, node );
}

static HRESULT write_tree_node( struct writer *writer )
{
    HRESULT hr;

    switch (node_type( writer->current ))
    {
    case WS_XML_NODE_TYPE_ELEMENT:
        if (writer->state == WRITER_STATE_STARTELEMENT && (hr = write_endstartelement( writer )) != S_OK)
            return hr;
        if ((hr = write_startelement( writer )) != S_OK) return hr;
        writer->state = WRITER_STATE_STARTELEMENT;
        return S_OK;

    case WS_XML_NODE_TYPE_TEXT:
        if (writer->state == WRITER_STATE_STARTELEMENT && (hr = write_endstartelement( writer )) != S_OK)
            return hr;
        if ((hr = write_text( writer )) != S_OK) return hr;
        writer->state = WRITER_STATE_TEXT;
        return S_OK;

    case WS_XML_NODE_TYPE_END_ELEMENT:
        if ((hr = write_close_element( writer, writer->current->parent )) != S_OK) return hr;
        writer->state = WRITER_STATE_ENDELEMENT;
        return S_OK;

    case WS_XML_NODE_TYPE_COMMENT:
        if (writer->state == WRITER_STATE_STARTELEMENT && (hr = write_endstartelement( writer )) != S_OK)
            return hr;
        if ((hr = write_comment( writer )) != S_OK) return hr;
        writer->state = WRITER_STATE_COMMENT;
        return S_OK;

    case WS_XML_NODE_TYPE_CDATA:
        if (writer->state == WRITER_STATE_STARTELEMENT && (hr = write_endstartelement( writer )) != S_OK)
            return hr;
        if ((hr = write_cdata( writer )) != S_OK) return hr;
        writer->state = WRITER_STATE_STARTCDATA;
        return S_OK;

    case WS_XML_NODE_TYPE_END_CDATA:
        if ((hr = write_endcdata( writer )) != S_OK) return hr;
        writer->state = WRITER_STATE_ENDCDATA;
        return S_OK;

    case WS_XML_NODE_TYPE_EOF:
    case WS_XML_NODE_TYPE_BOF:
        return S_OK;

    default:
        ERR( "unknown node type %u\n", node_type(writer->current) );
        return E_INVALIDARG;
    }
}

static HRESULT write_tree( struct writer *writer )
{
    HRESULT hr;

    if ((hr = write_tree_node( writer )) != S_OK) return hr;
    for (;;)
    {
        if (node_type( writer->current ) == WS_XML_NODE_TYPE_EOF) break;
        if (move_to_child_node( &writer->current ))
        {
            if ((hr = write_tree_node( writer )) != S_OK) return hr;
            continue;
        }
        if (move_to_next_node( &writer->current ))
        {
            if ((hr = write_tree_node( writer )) != S_OK) return hr;
            continue;
        }
        if (!move_to_parent_node( &writer->current ) || !move_to_next_node( &writer->current ))
        {
            ERR( "invalid tree\n" );
            return WS_E_INVALID_FORMAT;
        }
        if ((hr = write_tree_node( writer )) != S_OK) return hr;
    }
    return S_OK;
}

static void write_rewind( struct writer *writer )
{
    writer->write_pos = 0;
    writer->current   = writer->root;
    writer->state     = WRITER_STATE_INITIAL;
}

/**************************************************************************
 *          WsCopyNode		[webservices.@]
 */
HRESULT WINAPI WsCopyNode( WS_XML_WRITER *handle, WS_XML_READER *reader, WS_ERROR *error )
{
    struct writer *writer = (struct writer *)handle;
    struct node *parent, *current = writer->current, *node = NULL;
    HRESULT hr;

    TRACE( "%p %p %p\n", handle, reader, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!writer) return E_INVALIDARG;
    if (!(parent = find_parent( writer ))) return WS_E_INVALID_FORMAT;

    if ((hr = copy_node( reader, &node )) != S_OK) return hr;
    write_insert_node( writer, parent, node );

    write_rewind( writer );
    if ((hr = write_tree( writer )) != S_OK) return hr;

    writer->current = current;
    return S_OK;
}

static HRESULT write_param( struct writer *writer, const WS_FIELD_DESCRIPTION *desc, const void *value )
{
    return write_type_struct_field( writer, desc, value, 0 );
}

static ULONG get_array_len( const WS_PARAMETER_DESCRIPTION *params, ULONG count, ULONG index, const void **args )
{
    ULONG i, ret = 0;
    for (i = 0; i < count; i++)
    {
        if (params[i].inputMessageIndex != index || params[i].parameterType != WS_PARAMETER_TYPE_ARRAY_COUNT)
            continue;
        if (args[i]) ret = *(const ULONG *)args[i];
        break;
    }
    return ret;
}

static HRESULT write_param_array( struct writer *writer, const WS_FIELD_DESCRIPTION *desc, const void *value,
                                  ULONG len )
{
    return write_type_repeating_element( writer, desc, value, len );
}

HRESULT write_input_params( WS_XML_WRITER *handle, const WS_ELEMENT_DESCRIPTION *desc,
                            const WS_PARAMETER_DESCRIPTION *params, ULONG count, const void **args )
{
    struct writer *writer = (struct writer *)handle;
    const WS_STRUCT_DESCRIPTION *desc_struct;
    const WS_FIELD_DESCRIPTION *desc_field;
    HRESULT hr;
    ULONG i;

    if (desc->type != WS_STRUCT_TYPE || !(desc_struct = desc->typeDescription)) return E_INVALIDARG;

    if ((hr = write_element_node( writer, NULL, desc->elementLocalName, desc->elementNs )) != S_OK) return hr;

    for (i = 0; i < count; i++)
    {
        if (params[i].inputMessageIndex == INVALID_PARAMETER_INDEX) continue;
        if (params[i].parameterType == WS_PARAMETER_TYPE_MESSAGES)
        {
            FIXME( "messages type not supported\n" );
            return E_NOTIMPL;
        }
        if ((hr = get_param_desc( desc_struct, params[i].inputMessageIndex, &desc_field )) != S_OK) return hr;
        if (params[i].parameterType == WS_PARAMETER_TYPE_NORMAL)
        {
            if ((hr = write_param( writer, desc_field, args[i] )) != S_OK) return hr;
        }
        else if (params[i].parameterType == WS_PARAMETER_TYPE_ARRAY)
        {
            const void *ptr = *(const void **)args[i];
            ULONG len = get_array_len( params, count, params[i].inputMessageIndex, args );
            if ((hr = write_param_array( writer, desc_field, ptr, len )) != S_OK) return hr;
        }
    }

    return write_endelement_node( writer );
}
