/*
 *    MXWriter implementation
 *
 * Copyright 2011-2012 Nikolay Sivov for CodeWeavers
 * Copyright 2011 Thomas Mullaly
 *
 * 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
 */

#define COBJMACROS
#include "config.h"

#include <stdarg.h>
#ifdef HAVE_LIBXML2
# include <libxml/parser.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "ole2.h"

#include "msxml6.h"

#include "wine/debug.h"

#include "msxml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
static const WCHAR emptyW[] = {0};
static const WCHAR spaceW[] = {' '};
static const WCHAR quotW[]  = {'\"'};

typedef enum
{
    XmlEncoding_UTF8,
    XmlEncoding_UTF16,
    XmlEncoding_Unknown
} xml_encoding;

typedef enum
{
    OutputBuffer_Native  = 0x001,
    OutputBuffer_Encoded = 0x010,
    OutputBuffer_Both    = 0x100
} output_mode;

typedef enum
{
    MXWriter_BOM = 0,
    MXWriter_DisableEscaping,
    MXWriter_Indent,
    MXWriter_OmitXmlDecl,
    MXWriter_Standalone,
    MXWriter_LastProp
} mxwriter_prop;

typedef enum
{
    EscapeValue,
    EscapeText
} escape_mode;

typedef struct
{
    char *data;
    unsigned int allocated;
    unsigned int written;
} encoded_buffer;

typedef struct
{
    encoded_buffer utf16;
    encoded_buffer encoded;
    UINT code_page;
} output_buffer;

typedef struct
{
    DispatchEx dispex;
    IMXWriter IMXWriter_iface;
    ISAXContentHandler ISAXContentHandler_iface;
    ISAXLexicalHandler ISAXLexicalHandler_iface;
    ISAXDeclHandler    ISAXDeclHandler_iface;

    LONG ref;
    MSXML_VERSION class_version;

    VARIANT_BOOL props[MXWriter_LastProp];
    BOOL prop_changed;
    BOOL cdata;

    BSTR version;

    BSTR encoding; /* exact property value */
    xml_encoding xml_enc;

    /* contains a pending (or not closed yet) element name or NULL if
       we don't have to close */
    BSTR element;

    IStream *dest;
    ULONG dest_written;

    output_buffer *buffer;
} mxwriter;

typedef struct
{
    BSTR qname;
    BSTR local;
    BSTR uri;
    BSTR type;
    BSTR value;
} mxattribute;

typedef struct
{
    DispatchEx dispex;
    IMXAttributes IMXAttributes_iface;
    ISAXAttributes ISAXAttributes_iface;
    IVBSAXAttributes IVBSAXAttributes_iface;
    LONG ref;

    MSXML_VERSION class_version;

    mxattribute *attr;
    int length;
    int allocated;
} mxattributes;

static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
{
    return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
}

static inline mxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
{
    return CONTAINING_RECORD(iface, mxattributes, ISAXAttributes_iface);
}

static inline mxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
{
    return CONTAINING_RECORD(iface, mxattributes, IVBSAXAttributes_iface);
}

static HRESULT mxattributes_grow(mxattributes *This)
{
    if (This->length < This->allocated) return S_OK;

    This->allocated *= 2;
    This->attr = heap_realloc(This->attr, This->allocated*sizeof(mxattribute));

    return This->attr ? S_OK : E_OUTOFMEMORY;
}

static xml_encoding parse_encoding_name(const WCHAR *encoding)
{
    static const WCHAR utf8W[]  = {'U','T','F','-','8',0};
    if (!strcmpiW(encoding, utf8W))  return XmlEncoding_UTF8;
    if (!strcmpiW(encoding, utf16W)) return XmlEncoding_UTF16;
    return XmlEncoding_Unknown;
}

static HRESULT init_encoded_buffer(encoded_buffer *buffer)
{
    const int initial_len = 0x2000;
    buffer->data = heap_alloc(initial_len);
    if (!buffer->data) return E_OUTOFMEMORY;

    memset(buffer->data, 0, 4);
    buffer->allocated = initial_len;
    buffer->written = 0;

    return S_OK;
}

static void free_encoded_buffer(encoded_buffer *buffer)
{
    heap_free(buffer->data);
}

static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
{
    switch (encoding)
    {
    case XmlEncoding_UTF8:
        *cp = CP_UTF8;
        break;
    case XmlEncoding_UTF16:
        *cp = ~0;
        break;
    default:
        FIXME("unsupported encoding %d\n", encoding);
        return E_NOTIMPL;
    }

    return S_OK;
}

static HRESULT alloc_output_buffer(xml_encoding encoding, output_buffer **buffer)
{
    output_buffer *ret;
    HRESULT hr;

    ret = heap_alloc(sizeof(*ret));
    if (!ret) return E_OUTOFMEMORY;

    hr = get_code_page(encoding, &ret->code_page);
    if (hr != S_OK) {
        heap_free(ret);
        return hr;
    }

    hr = init_encoded_buffer(&ret->utf16);
    if (hr != S_OK) {
        heap_free(ret);
        return hr;
    }

    if (ret->code_page == CP_UTF8) {
        hr = init_encoded_buffer(&ret->encoded);
        if (hr != S_OK) {
            free_encoded_buffer(&ret->utf16);
            heap_free(ret);
            return hr;
        }
    }
    else
        memset(&ret->encoded, 0, sizeof(ret->encoded));

    *buffer = ret;

    return S_OK;
}

static void free_output_buffer(output_buffer *buffer)
{
    free_encoded_buffer(&buffer->encoded);
    free_encoded_buffer(&buffer->utf16);
    heap_free(buffer);
}

static void grow_buffer(encoded_buffer *buffer, int length)
{
    /* grow if needed, plus 4 bytes to be sure null terminator will fit in */
    if (buffer->allocated < buffer->written + length + 4)
    {
        int grown_size = max(2*buffer->allocated, buffer->allocated + length);
        buffer->data = heap_realloc(buffer->data, grown_size);
        buffer->allocated = grown_size;
    }
}

static HRESULT write_output_buffer_mode(output_buffer *buffer, output_mode mode, const WCHAR *data, int len)
{
    int length;
    char *ptr;

    if (mode & (OutputBuffer_Encoded | OutputBuffer_Both)) {
        if (buffer->code_page == CP_UTF8)
        {
            length = WideCharToMultiByte(buffer->code_page, 0, data, len, NULL, 0, NULL, NULL);
            grow_buffer(&buffer->encoded, length);
            ptr = buffer->encoded.data + buffer->encoded.written;
            length = WideCharToMultiByte(buffer->code_page, 0, data, len, ptr, length, NULL, NULL);
            buffer->encoded.written += len == -1 ? length-1 : length;
        }
    }

    if (mode & (OutputBuffer_Native | OutputBuffer_Both)) {
        /* WCHAR data just copied */
        length = len == -1 ? strlenW(data) : len;
        if (length)
        {
            length *= sizeof(WCHAR);

            grow_buffer(&buffer->utf16, length);
            ptr = buffer->utf16.data + buffer->utf16.written;

            memcpy(ptr, data, length);
            buffer->utf16.written += length;
            ptr += length;
            /* null termination */
            memset(ptr, 0, sizeof(WCHAR));
        }
    }

    return S_OK;
}

static HRESULT write_output_buffer(output_buffer *buffer, const WCHAR *data, int len)
{
    return write_output_buffer_mode(buffer, OutputBuffer_Both, data, len);
}

static HRESULT write_output_buffer_quoted(output_buffer *buffer, const WCHAR *data, int len)
{
    write_output_buffer(buffer, quotW, 1);
    write_output_buffer(buffer, data, len);
    write_output_buffer(buffer, quotW, 1);

    return S_OK;
}

/* frees buffer data, reallocates with a default lengths */
static void close_output_buffer(mxwriter *This)
{
    heap_free(This->buffer->utf16.data);
    heap_free(This->buffer->encoded.data);
    init_encoded_buffer(&This->buffer->utf16);
    init_encoded_buffer(&This->buffer->encoded);
    get_code_page(This->xml_enc, &This->buffer->code_page);
}

/* escapes special characters like:
   '<' -> "&lt;"
   '&' -> "&amp;"
   '"' -> "&quot;"
   '>' -> "&gt;"
*/
static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
{
    static const WCHAR ltW[]    = {'&','l','t',';'};
    static const WCHAR ampW[]   = {'&','a','m','p',';'};
    static const WCHAR equotW[] = {'&','q','u','o','t',';'};
    static const WCHAR gtW[]    = {'&','g','t',';'};

    const int default_alloc = 100;
    const int grow_thresh = 10;
    int p = *len, conv_len;
    WCHAR *ptr, *ret;

    /* default buffer size to something if length is unknown */
    conv_len = *len == -1 ? default_alloc : max(2**len, default_alloc);
    ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));

    while (*str && p)
    {
        if (ptr - ret > conv_len - grow_thresh)
        {
            int written = ptr - ret;
            conv_len *= 2;
            ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
            ptr += written;
        }

        switch (*str)
        {
        case '<':
            memcpy(ptr, ltW, sizeof(ltW));
            ptr += sizeof(ltW)/sizeof(WCHAR);
            break;
        case '&':
            memcpy(ptr, ampW, sizeof(ampW));
            ptr += sizeof(ampW)/sizeof(WCHAR);
            break;
        case '>':
            memcpy(ptr, gtW, sizeof(gtW));
            ptr += sizeof(gtW)/sizeof(WCHAR);
            break;
        case '"':
            if (mode == EscapeValue)
            {
                memcpy(ptr, equotW, sizeof(equotW));
                ptr += sizeof(equotW)/sizeof(WCHAR);
                break;
            }
            /* fallthrough for text mode */
        default:
            *ptr++ = *str;
            break;
        }

        str++;
        if (*len != -1) p--;
    }

    if (*len != -1) *len = ptr-ret;
    *++ptr = 0;

    return ret;
}

static void write_prolog_buffer(const mxwriter *This)
{
    static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
    static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
    static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
    static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
    static const WCHAR noW[] = {'n','o','\"','?','>'};
    static const WCHAR crlfW[] = {'\r','\n'};

    /* version */
    write_output_buffer(This->buffer, versionW, sizeof(versionW)/sizeof(WCHAR));
    write_output_buffer_quoted(This->buffer, This->version, -1);

    /* encoding */
    write_output_buffer(This->buffer, encodingW, sizeof(encodingW)/sizeof(WCHAR));

    /* always write UTF-16 to WCHAR buffer */
    write_output_buffer_mode(This->buffer, OutputBuffer_Native, utf16W, sizeof(utf16W)/sizeof(WCHAR) - 1);
    write_output_buffer_mode(This->buffer, OutputBuffer_Encoded, This->encoding, -1);
    write_output_buffer(This->buffer, quotW, 1);

    /* standalone */
    write_output_buffer(This->buffer, standaloneW, sizeof(standaloneW)/sizeof(WCHAR));
    if (This->props[MXWriter_Standalone] == VARIANT_TRUE)
        write_output_buffer(This->buffer, yesW, sizeof(yesW)/sizeof(WCHAR));
    else
        write_output_buffer(This->buffer, noW, sizeof(noW)/sizeof(WCHAR));

    write_output_buffer(This->buffer, crlfW, sizeof(crlfW)/sizeof(WCHAR));
}

/* Attempts to the write data from the mxwriter's buffer to
 * the destination stream (if there is one).
 */
static HRESULT write_data_to_stream(mxwriter *This)
{
    encoded_buffer *buffer;
    ULONG written = 0;
    HRESULT hr;

    if (!This->dest)
        return S_OK;

    if (This->xml_enc != XmlEncoding_UTF16)
        buffer = &This->buffer->encoded;
    else
        buffer = &This->buffer->utf16;

    if (This->dest_written > buffer->written) {
        ERR("Failed sanity check! Not sure what to do... (%d > %d)\n", This->dest_written, buffer->written);
        return E_FAIL;
    } else if (This->dest_written == buffer->written && This->xml_enc != XmlEncoding_UTF8)
        /* Windows seems to make an empty write call when the encoding is UTF-8 and
         * all the data has been written to the stream. It doesn't seem make this call
         * for any other encodings.
         */
        return S_OK;

    /* Write the current content from the output buffer into 'dest'.
     * TODO: Check what Windows does if the IStream doesn't write all of
     *       the data we give it at once.
     */
    hr = IStream_Write(This->dest, buffer->data+This->dest_written,
                         buffer->written-This->dest_written, &written);
    if (FAILED(hr)) {
        WARN("Failed to write data to IStream (0x%08x)\n", hr);
        return hr;
    }

    This->dest_written += written;
    return hr;
}

/* Newly added element start tag left unclosed cause for empty elements
   we have to close it differently. */
static void close_element_starttag(const mxwriter *This)
{
    static const WCHAR gtW[] = {'>'};
    if (!This->element) return;
    write_output_buffer(This->buffer, gtW, 1);
}

static void set_element_name(mxwriter *This, const WCHAR *name, int len)
{
    SysFreeString(This->element);
    This->element = name ? SysAllocStringLen(name, len) : NULL;
}

static inline HRESULT flush_output_buffer(mxwriter *This)
{
    close_element_starttag(This);
    set_element_name(This, NULL, 0);
    This->cdata = FALSE;
    return write_data_to_stream(This);
}

/* Resets the mxwriter's output buffer by closing it, then creating a new
 * output buffer using the given encoding.
 */
static inline void reset_output_buffer(mxwriter *This)
{
    close_output_buffer(This);
    This->dest_written = 0;
}

static HRESULT writer_set_property(mxwriter *writer, mxwriter_prop property, VARIANT_BOOL value)
{
    writer->props[property] = value;
    writer->prop_changed = TRUE;
    return S_OK;
}

static HRESULT writer_get_property(const mxwriter *writer, mxwriter_prop property, VARIANT_BOOL *value)
{
    if (!value) return E_POINTER;
    *value = writer->props[property];
    return S_OK;
}

static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
{
    return CONTAINING_RECORD(iface, mxwriter, IMXWriter_iface);
}

static inline mxwriter *impl_from_ISAXContentHandler(ISAXContentHandler *iface)
{
    return CONTAINING_RECORD(iface, mxwriter, ISAXContentHandler_iface);
}

static inline mxwriter *impl_from_ISAXLexicalHandler(ISAXLexicalHandler *iface)
{
    return CONTAINING_RECORD(iface, mxwriter, ISAXLexicalHandler_iface);
}

static inline mxwriter *impl_from_ISAXDeclHandler(ISAXDeclHandler *iface)
{
    return CONTAINING_RECORD(iface, mxwriter, ISAXDeclHandler_iface);
}

static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, void **obj)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
         IsEqualGUID( riid, &IID_IDispatch ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *obj = &This->IMXWriter_iface;
    }
    else if ( IsEqualGUID( riid, &IID_ISAXContentHandler ) )
    {
        *obj = &This->ISAXContentHandler_iface;
    }
    else if ( IsEqualGUID( riid, &IID_ISAXLexicalHandler ) )
    {
        *obj = &This->ISAXLexicalHandler_iface;
    }
    else if ( IsEqualGUID( riid, &IID_ISAXDeclHandler ) )
    {
        *obj = &This->ISAXDeclHandler_iface;
    }
    else if (dispex_query_interface(&This->dispex, riid, obj))
    {
        return *obj ? S_OK : E_NOINTERFACE;
    }
    else
    {
        ERR("interface %s not implemented\n", debugstr_guid(riid));
        *obj = NULL;
        return E_NOINTERFACE;
    }

    IMXWriter_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI mxwriter_AddRef(IMXWriter *iface)
{
    mxwriter *This = impl_from_IMXWriter( iface );
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    return ref;
}

static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
{
    mxwriter *This = impl_from_IMXWriter( iface );
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    if(!ref)
    {
        /* Windows flushes the buffer when the interface is destroyed. */
        flush_output_buffer(This);
        free_output_buffer(This->buffer);

        if (This->dest) IStream_Release(This->dest);
        SysFreeString(This->version);
        SysFreeString(This->encoding);

        SysFreeString(This->element);
        release_dispex(&This->dispex);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
{
    mxwriter *This = impl_from_IMXWriter( iface );
    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
}

static HRESULT WINAPI mxwriter_GetTypeInfo(
    IMXWriter *iface,
    UINT iTInfo, LCID lcid,
    ITypeInfo** ppTInfo )
{
    mxwriter *This = impl_from_IMXWriter( iface );
    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
        iTInfo, lcid, ppTInfo);
}

static HRESULT WINAPI mxwriter_GetIDsOfNames(
    IMXWriter *iface,
    REFIID riid, LPOLESTR* rgszNames,
    UINT cNames, LCID lcid, DISPID* rgDispId )
{
    mxwriter *This = impl_from_IMXWriter( iface );
    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
        riid, rgszNames, cNames, lcid, rgDispId);
}

static HRESULT WINAPI mxwriter_Invoke(
    IMXWriter *iface,
    DISPID dispIdMember, REFIID riid, LCID lcid,
    WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
    EXCEPINFO* pExcepInfo, UINT* puArgErr )
{
    mxwriter *This = impl_from_IMXWriter( iface );
    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
        dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}

static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
{
    mxwriter *This = impl_from_IMXWriter( iface );
    HRESULT hr;

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&dest));

    hr = flush_output_buffer(This);
    if (FAILED(hr))
        return hr;

    switch (V_VT(&dest))
    {
    case VT_EMPTY:
    {
        if (This->dest) IStream_Release(This->dest);
        This->dest = NULL;
        reset_output_buffer(This);
        break;
    }
    case VT_UNKNOWN:
    {
        IStream *stream;

        hr = IUnknown_QueryInterface(V_UNKNOWN(&dest), &IID_IStream, (void**)&stream);
        if (hr == S_OK)
        {
            /* Recreate the output buffer to make sure it's using the correct encoding. */
            reset_output_buffer(This);

            if (This->dest) IStream_Release(This->dest);
            This->dest = stream;
            break;
        }

        FIXME("unhandled interface type for VT_UNKNOWN destination\n");
        return E_NOTIMPL;
    }
    default:
        FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
        return E_NOTIMPL;
    }

    return S_OK;
}

static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%p)\n", This, dest);

    if (!This->dest)
    {
        HRESULT hr = flush_output_buffer(This);
        if (FAILED(hr))
            return hr;

        V_VT(dest)   = VT_BSTR;
        V_BSTR(dest) = SysAllocString((WCHAR*)This->buffer->utf16.data);

        return S_OK;
    }
    else
        FIXME("not implemented when stream is set up\n");

    return E_NOTIMPL;
}

static HRESULT WINAPI mxwriter_put_encoding(IMXWriter *iface, BSTR encoding)
{
    mxwriter *This = impl_from_IMXWriter( iface );
    xml_encoding enc;
    HRESULT hr;

    TRACE("(%p)->(%s)\n", This, debugstr_w(encoding));

    enc = parse_encoding_name(encoding);
    if (enc == XmlEncoding_Unknown)
    {
        FIXME("unsupported encoding %s\n", debugstr_w(encoding));
        return E_INVALIDARG;
    }

    hr = flush_output_buffer(This);
    if (FAILED(hr))
        return hr;

    SysReAllocString(&This->encoding, encoding);
    This->xml_enc = enc;

    TRACE("got encoding %d\n", This->xml_enc);
    reset_output_buffer(This);
    return S_OK;
}

static HRESULT WINAPI mxwriter_get_encoding(IMXWriter *iface, BSTR *encoding)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%p)\n", This, encoding);

    if (!encoding) return E_POINTER;

    *encoding = SysAllocString(This->encoding);
    if (!*encoding) return E_OUTOFMEMORY;

    return S_OK;
}

static HRESULT WINAPI mxwriter_put_byteOrderMark(IMXWriter *iface, VARIANT_BOOL value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%d)\n", This, value);
    return writer_set_property(This, MXWriter_BOM, value);
}

static HRESULT WINAPI mxwriter_get_byteOrderMark(IMXWriter *iface, VARIANT_BOOL *value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%p)\n", This, value);
    return writer_get_property(This, MXWriter_BOM, value);
}

static HRESULT WINAPI mxwriter_put_indent(IMXWriter *iface, VARIANT_BOOL value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%d)\n", This, value);
    return writer_set_property(This, MXWriter_Indent, value);
}

static HRESULT WINAPI mxwriter_get_indent(IMXWriter *iface, VARIANT_BOOL *value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%p)\n", This, value);
    return writer_get_property(This, MXWriter_Indent, value);
}

static HRESULT WINAPI mxwriter_put_standalone(IMXWriter *iface, VARIANT_BOOL value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%d)\n", This, value);
    return writer_set_property(This, MXWriter_Standalone, value);
}

static HRESULT WINAPI mxwriter_get_standalone(IMXWriter *iface, VARIANT_BOOL *value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%p)\n", This, value);
    return writer_get_property(This, MXWriter_Standalone, value);
}

static HRESULT WINAPI mxwriter_put_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%d)\n", This, value);
    return writer_set_property(This, MXWriter_OmitXmlDecl, value);
}

static HRESULT WINAPI mxwriter_get_omitXMLDeclaration(IMXWriter *iface, VARIANT_BOOL *value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%p)\n", This, value);
    return writer_get_property(This, MXWriter_OmitXmlDecl, value);
}

static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%s)\n", This, debugstr_w(version));

    if (!version) return E_INVALIDARG;

    SysFreeString(This->version);
    This->version = SysAllocString(version);

    return S_OK;
}

static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%p)\n", This, version);

    if (!version) return E_POINTER;

    return return_bstr(This->version, version);
}

static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%d)\n", This, value);
    return writer_set_property(This, MXWriter_DisableEscaping, value);
}

static HRESULT WINAPI mxwriter_get_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL *value)
{
    mxwriter *This = impl_from_IMXWriter( iface );

    TRACE("(%p)->(%p)\n", This, value);
    return writer_get_property(This, MXWriter_DisableEscaping, value);
}

static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
{
    mxwriter *This = impl_from_IMXWriter( iface );
    TRACE("(%p)\n", This);
    return flush_output_buffer(This);
}

static const struct IMXWriterVtbl MXWriterVtbl =
{
    mxwriter_QueryInterface,
    mxwriter_AddRef,
    mxwriter_Release,
    mxwriter_GetTypeInfoCount,
    mxwriter_GetTypeInfo,
    mxwriter_GetIDsOfNames,
    mxwriter_Invoke,
    mxwriter_put_output,
    mxwriter_get_output,
    mxwriter_put_encoding,
    mxwriter_get_encoding,
    mxwriter_put_byteOrderMark,
    mxwriter_get_byteOrderMark,
    mxwriter_put_indent,
    mxwriter_get_indent,
    mxwriter_put_standalone,
    mxwriter_get_standalone,
    mxwriter_put_omitXMLDeclaration,
    mxwriter_get_omitXMLDeclaration,
    mxwriter_put_version,
    mxwriter_get_version,
    mxwriter_put_disableOutputEscaping,
    mxwriter_get_disableOutputEscaping,
    mxwriter_flush
};

/*** ISAXContentHandler ***/
static HRESULT WINAPI SAXContentHandler_QueryInterface(
    ISAXContentHandler *iface,
    REFIID riid,
    void **obj)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
}

static ULONG WINAPI SAXContentHandler_AddRef(ISAXContentHandler *iface)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    return IMXWriter_AddRef(&This->IMXWriter_iface);
}

static ULONG WINAPI SAXContentHandler_Release(ISAXContentHandler *iface)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    return IMXWriter_Release(&This->IMXWriter_iface);
}

static HRESULT WINAPI SAXContentHandler_putDocumentLocator(
    ISAXContentHandler *iface,
    ISAXLocator *locator)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    FIXME("(%p)->(%p)\n", This, locator);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXContentHandler_startDocument(ISAXContentHandler *iface)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );

    TRACE("(%p)\n", This);

    /* If properties have been changed since the last "endDocument" call
     * we need to reset the output buffer. If we don't the output buffer
     * could end up with multiple XML documents in it, plus this seems to
     * be how Windows works.
     */
    if (This->prop_changed) {
        reset_output_buffer(This);
        This->prop_changed = FALSE;
    }

    if (This->props[MXWriter_OmitXmlDecl] == VARIANT_TRUE) return S_OK;

    write_prolog_buffer(This);

    if (This->dest && This->xml_enc == XmlEncoding_UTF16) {
        static const char utf16BOM[] = {0xff,0xfe};

        if (This->props[MXWriter_BOM] == VARIANT_TRUE)
            /* Windows passes a NULL pointer as the pcbWritten parameter and
             * ignores any error codes returned from this Write call.
             */
            IStream_Write(This->dest, utf16BOM, sizeof(utf16BOM), NULL);
    }

    return S_OK;
}

static HRESULT WINAPI SAXContentHandler_endDocument(ISAXContentHandler *iface)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    TRACE("(%p)\n", This);
    This->prop_changed = FALSE;
    return flush_output_buffer(This);
}

static HRESULT WINAPI SAXContentHandler_startPrefixMapping(
    ISAXContentHandler *iface,
    const WCHAR *prefix,
    int nprefix,
    const WCHAR *uri,
    int nuri)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    FIXME("(%p)->(%s %s)\n", This, debugstr_wn(prefix, nprefix), debugstr_wn(uri, nuri));
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXContentHandler_endPrefixMapping(
    ISAXContentHandler *iface,
    const WCHAR *prefix,
    int nprefix)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    FIXME("(%p)->(%s)\n", This, debugstr_wn(prefix, nprefix));
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXContentHandler_startElement(
    ISAXContentHandler *iface,
    const WCHAR *namespaceUri,
    int nnamespaceUri,
    const WCHAR *local_name,
    int nlocal_name,
    const WCHAR *QName,
    int nQName,
    ISAXAttributes *attr)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    static const WCHAR ltW[] = {'<'};

    TRACE("(%p)->(%s %s %s %p)\n", This, debugstr_wn(namespaceUri, nnamespaceUri),
        debugstr_wn(local_name, nlocal_name), debugstr_wn(QName, nQName), attr);

    if ((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6)
        return E_INVALIDARG;

    close_element_starttag(This);
    set_element_name(This, QName ? QName  : emptyW,
                           QName ? nQName : 0);

    write_output_buffer(This->buffer, ltW, 1);
    write_output_buffer(This->buffer, QName, nQName);

    if (attr)
    {
        HRESULT hr;
        INT length;
        INT i;

        hr = ISAXAttributes_getLength(attr, &length);
        if (FAILED(hr)) return hr;

        for (i = 0; i < length; i++)
        {
            static const WCHAR eqW[] = {'='};
            const WCHAR *str;
            WCHAR *escaped;
            INT len = 0;

            hr = ISAXAttributes_getQName(attr, i, &str, &len);
            if (FAILED(hr)) return hr;

            /* space separator in front of every attribute */
            write_output_buffer(This->buffer, spaceW, 1);
            write_output_buffer(This->buffer, str, len);

            write_output_buffer(This->buffer, eqW, 1);

            len = 0;
            hr = ISAXAttributes_getValue(attr, i, &str, &len);
            if (FAILED(hr)) return hr;

            escaped = get_escaped_string(str, EscapeValue, &len);
            write_output_buffer_quoted(This->buffer, escaped, len);
            heap_free(escaped);
        }
    }

    return S_OK;
}

static HRESULT WINAPI SAXContentHandler_endElement(
    ISAXContentHandler *iface,
    const WCHAR *namespaceUri,
    int nnamespaceUri,
    const WCHAR * local_name,
    int nlocal_name,
    const WCHAR *QName,
    int nQName)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );

    TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(namespaceUri, nnamespaceUri), nnamespaceUri,
        debugstr_wn(local_name, nlocal_name), nlocal_name, debugstr_wn(QName, nQName), nQName);

    if ((!namespaceUri || !local_name || !QName) && This->class_version != MSXML6)
        return E_INVALIDARG;

    if (This->element && QName && !strncmpW(This->element, QName, nQName))
    {
        static const WCHAR closeW[] = {'/','>'};

        write_output_buffer(This->buffer, closeW, 2);
    }
    else
    {
        static const WCHAR closetagW[] = {'<','/'};
        static const WCHAR gtW[] = {'>'};

        write_output_buffer(This->buffer, closetagW, 2);
        write_output_buffer(This->buffer, QName, nQName);
        write_output_buffer(This->buffer, gtW, 1);
    }

    set_element_name(This, NULL, 0);

    return S_OK;
}

static HRESULT WINAPI SAXContentHandler_characters(
    ISAXContentHandler *iface,
    const WCHAR *chars,
    int nchars)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );

    TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);

    if (!chars) return E_INVALIDARG;

    close_element_starttag(This);
    set_element_name(This, NULL, 0);

    if (nchars)
    {
        if (This->cdata)
            write_output_buffer(This->buffer, chars, nchars);
        else
        {
            int len = nchars;
            WCHAR *escaped;

            escaped = get_escaped_string(chars, EscapeText, &len);
            write_output_buffer(This->buffer, escaped, len);
            heap_free(escaped);
        }
    }

    return S_OK;
}

static HRESULT WINAPI SAXContentHandler_ignorableWhitespace(
    ISAXContentHandler *iface,
    const WCHAR *chars,
    int nchars)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    FIXME("(%p)->(%s)\n", This, debugstr_wn(chars, nchars));
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXContentHandler_processingInstruction(
    ISAXContentHandler *iface,
    const WCHAR *target,
    int ntarget,
    const WCHAR *data,
    int ndata)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    FIXME("(%p)->(%s %s)\n", This, debugstr_wn(target, ntarget), debugstr_wn(data, ndata));
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXContentHandler_skippedEntity(
    ISAXContentHandler *iface,
    const WCHAR *name,
    int nname)
{
    mxwriter *This = impl_from_ISAXContentHandler( iface );
    FIXME("(%p)->(%s)\n", This, debugstr_wn(name, nname));
    return E_NOTIMPL;
}

static const struct ISAXContentHandlerVtbl SAXContentHandlerVtbl =
{
    SAXContentHandler_QueryInterface,
    SAXContentHandler_AddRef,
    SAXContentHandler_Release,
    SAXContentHandler_putDocumentLocator,
    SAXContentHandler_startDocument,
    SAXContentHandler_endDocument,
    SAXContentHandler_startPrefixMapping,
    SAXContentHandler_endPrefixMapping,
    SAXContentHandler_startElement,
    SAXContentHandler_endElement,
    SAXContentHandler_characters,
    SAXContentHandler_ignorableWhitespace,
    SAXContentHandler_processingInstruction,
    SAXContentHandler_skippedEntity
};

/*** ISAXLexicalHandler ***/
static HRESULT WINAPI SAXLexicalHandler_QueryInterface(ISAXLexicalHandler *iface,
    REFIID riid, void **obj)
{
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );
    return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
}

static ULONG WINAPI SAXLexicalHandler_AddRef(ISAXLexicalHandler *iface)
{
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );
    return IMXWriter_AddRef(&This->IMXWriter_iface);
}

static ULONG WINAPI SAXLexicalHandler_Release(ISAXLexicalHandler *iface)
{
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );
    return IMXWriter_Release(&This->IMXWriter_iface);
}

static HRESULT WINAPI SAXLexicalHandler_startDTD(ISAXLexicalHandler *iface,
    const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
    const WCHAR *systemId, int systemId_len)
{
    static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
    static const WCHAR openintW[] = {'[','\r','\n'};

    mxwriter *This = impl_from_ISAXLexicalHandler( iface );

    TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
        debugstr_wn(systemId, systemId_len));

    if (!name) return E_INVALIDARG;

    write_output_buffer(This->buffer, doctypeW, sizeof(doctypeW)/sizeof(WCHAR));

    if (*name)
    {
        write_output_buffer(This->buffer, name, name_len);
        write_output_buffer(This->buffer, spaceW, 1);
    }

    if (publicId)
    {
        static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};

        write_output_buffer(This->buffer, publicW, sizeof(publicW)/sizeof(WCHAR));
        write_output_buffer_quoted(This->buffer, publicId, publicId_len);

        if (!systemId) return E_INVALIDARG;

        if (*publicId)
            write_output_buffer(This->buffer, spaceW, 1);

        write_output_buffer_quoted(This->buffer, systemId, systemId_len);

        if (*systemId)
            write_output_buffer(This->buffer, spaceW, 1);
    }
    else if (systemId)
    {
        static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};

        write_output_buffer(This->buffer, systemW, sizeof(systemW)/sizeof(WCHAR));
        write_output_buffer_quoted(This->buffer, systemId, systemId_len);
        if (*systemId)
            write_output_buffer(This->buffer, spaceW, 1);
    }

    write_output_buffer(This->buffer, openintW, sizeof(openintW)/sizeof(WCHAR));

    return S_OK;
}

static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
{
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );
    static const WCHAR closedtdW[] = {']','>','\r','\n'};

    TRACE("(%p)\n", This);

    write_output_buffer(This->buffer, closedtdW, sizeof(closedtdW)/sizeof(WCHAR));

    return S_OK;
}

static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
{
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );
    FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXLexicalHandler_endEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
{
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );
    FIXME("(%p)->(%s): stub\n", This, debugstr_wn(name, len));
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
{
    static const WCHAR scdataW[] = {'<','!','[','C','D','A','T','A','['};
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );

    TRACE("(%p)\n", This);

    write_output_buffer(This->buffer, scdataW, sizeof(scdataW)/sizeof(WCHAR));
    This->cdata = TRUE;

    return S_OK;
}

static HRESULT WINAPI SAXLexicalHandler_endCDATA(ISAXLexicalHandler *iface)
{
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );
    static const WCHAR ecdataW[] = {']',']','>'};

    TRACE("(%p)\n", This);

    write_output_buffer(This->buffer, ecdataW, sizeof(ecdataW)/sizeof(WCHAR));
    This->cdata = FALSE;

    return S_OK;
}

static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const WCHAR *chars, int nchars)
{
    mxwriter *This = impl_from_ISAXLexicalHandler( iface );
    static const WCHAR copenW[] = {'<','!','-','-'};
    static const WCHAR ccloseW[] = {'-','-','>','\r','\n'};

    TRACE("(%p)->(%s:%d)\n", This, debugstr_wn(chars, nchars), nchars);

    if (!chars) return E_INVALIDARG;

    close_element_starttag(This);

    write_output_buffer(This->buffer, copenW, sizeof(copenW)/sizeof(WCHAR));
    if (nchars)
        write_output_buffer(This->buffer, chars, nchars);
    write_output_buffer(This->buffer, ccloseW, sizeof(ccloseW)/sizeof(WCHAR));

    return S_OK;
}

static const struct ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
{
    SAXLexicalHandler_QueryInterface,
    SAXLexicalHandler_AddRef,
    SAXLexicalHandler_Release,
    SAXLexicalHandler_startDTD,
    SAXLexicalHandler_endDTD,
    SAXLexicalHandler_startEntity,
    SAXLexicalHandler_endEntity,
    SAXLexicalHandler_startCDATA,
    SAXLexicalHandler_endCDATA,
    SAXLexicalHandler_comment
};

/*** ISAXDeclHandler ***/
static HRESULT WINAPI SAXDeclHandler_QueryInterface(ISAXDeclHandler *iface,
    REFIID riid, void **obj)
{
    mxwriter *This = impl_from_ISAXDeclHandler( iface );
    return IMXWriter_QueryInterface(&This->IMXWriter_iface, riid, obj);
}

static ULONG WINAPI SAXDeclHandler_AddRef(ISAXDeclHandler *iface)
{
    mxwriter *This = impl_from_ISAXDeclHandler( iface );
    return IMXWriter_AddRef(&This->IMXWriter_iface);
}

static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *iface)
{
    mxwriter *This = impl_from_ISAXDeclHandler( iface );
    return IMXWriter_Release(&This->IMXWriter_iface);
}

static HRESULT WINAPI SAXDeclHandler_elementDecl(ISAXDeclHandler *iface,
    const WCHAR *name, int n_name, const WCHAR *model, int n_model)
{
    static const WCHAR elementW[] = {'<','!','E','L','E','M','E','N','T',' '};
    static const WCHAR closeelementW[] = {'>','\r','\n'};
    mxwriter *This = impl_from_ISAXDeclHandler( iface );

    TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
        debugstr_wn(model, n_model), n_model);

    if (!name || !model) return E_INVALIDARG;

    write_output_buffer(This->buffer, elementW, sizeof(elementW)/sizeof(WCHAR));
    if (n_name) {
        write_output_buffer(This->buffer, name, n_name);
        write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
    }
    if (n_model)
        write_output_buffer(This->buffer, model, n_model);
    write_output_buffer(This->buffer, closeelementW, sizeof(closeelementW)/sizeof(WCHAR));

    return S_OK;
}

static HRESULT WINAPI SAXDeclHandler_attributeDecl(ISAXDeclHandler *iface,
    const WCHAR *element, int n_element, const WCHAR *attr, int n_attr,
    const WCHAR *type, int n_type, const WCHAR *Default, int n_default,
    const WCHAR *value, int n_value)
{
    mxwriter *This = impl_from_ISAXDeclHandler( iface );
    FIXME("(%p)->(%s:%d %s:%d %s:%d %s:%d %s:%d): stub\n", This, debugstr_wn(element, n_element), n_element,
        debugstr_wn(attr, n_attr), n_attr, debugstr_wn(type, n_type), n_type, debugstr_wn(Default, n_default), n_default,
        debugstr_wn(value, n_value), n_value);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface,
    const WCHAR *name, int n_name, const WCHAR *value, int n_value)
{
    mxwriter *This = impl_from_ISAXDeclHandler( iface );
    FIXME("(%p)->(%s:%d %s:%d): stub\n", This, debugstr_wn(name, n_name), n_name,
        debugstr_wn(value, n_value), n_value);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface,
    const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
    const WCHAR *systemId, int n_systemId)
{
    mxwriter *This = impl_from_ISAXDeclHandler( iface );
    FIXME("(%p)->(%s:%d %s:%d %s:%d): stub\n", This, debugstr_wn(name, n_name), n_name,
        debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId);
    return E_NOTIMPL;
}

static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
    SAXDeclHandler_QueryInterface,
    SAXDeclHandler_AddRef,
    SAXDeclHandler_Release,
    SAXDeclHandler_elementDecl,
    SAXDeclHandler_attributeDecl,
    SAXDeclHandler_internalEntityDecl,
    SAXDeclHandler_externalEntityDecl
};

static const tid_t mxwriter_iface_tids[] = {
    IMXWriter_tid,
    0
};

static dispex_static_data_t mxwriter_dispex = {
    NULL,
    IMXWriter_tid,
    NULL,
    mxwriter_iface_tids
};

HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *outer, void **ppObj)
{
    static const WCHAR version10W[] = {'1','.','0',0};
    mxwriter *This;
    HRESULT hr;

    TRACE("(%p, %p)\n", outer, ppObj);

    if (outer) FIXME("support aggregation, outer\n");

    This = heap_alloc( sizeof (*This) );
    if(!This)
        return E_OUTOFMEMORY;

    This->IMXWriter_iface.lpVtbl = &MXWriterVtbl;
    This->ISAXContentHandler_iface.lpVtbl = &SAXContentHandlerVtbl;
    This->ISAXLexicalHandler_iface.lpVtbl = &SAXLexicalHandlerVtbl;
    This->ISAXDeclHandler_iface.lpVtbl = &SAXDeclHandlerVtbl;
    This->ref = 1;
    This->class_version = version;

    This->props[MXWriter_BOM] = VARIANT_TRUE;
    This->props[MXWriter_DisableEscaping] = VARIANT_FALSE;
    This->props[MXWriter_Indent] = VARIANT_FALSE;
    This->props[MXWriter_OmitXmlDecl] = VARIANT_FALSE;
    This->props[MXWriter_Standalone] = VARIANT_FALSE;
    This->prop_changed = FALSE;
    This->encoding = SysAllocString(utf16W);
    This->version  = SysAllocString(version10W);
    This->xml_enc  = XmlEncoding_UTF16;

    This->element = NULL;
    This->cdata = FALSE;

    This->dest = NULL;
    This->dest_written = 0;

    hr = alloc_output_buffer(This->xml_enc, &This->buffer);
    if (hr != S_OK) {
        SysFreeString(This->encoding);
        SysFreeString(This->version);
        heap_free(This);
        return hr;
    }

    init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);

    *ppObj = &This->IMXWriter_iface;

    TRACE("returning iface %p\n", *ppObj);

    return S_OK;
}

static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
{
    mxattributes *This = impl_from_IMXAttributes( iface );

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);

    *ppObj = NULL;

    if ( IsEqualGUID( riid, &IID_IUnknown )  ||
         IsEqualGUID( riid, &IID_IDispatch ) ||
         IsEqualGUID( riid, &IID_IMXAttributes ))
    {
        *ppObj = iface;
    }
    else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
    {
        *ppObj = &This->ISAXAttributes_iface;
    }
    else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
    {
        *ppObj = &This->IVBSAXAttributes_iface;
    }
    else if (dispex_query_interface(&This->dispex, riid, ppObj))
    {
        return *ppObj ? S_OK : E_NOINTERFACE;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IMXAttributes_AddRef( iface );

    return S_OK;
}

static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    ULONG ref = InterlockedIncrement( &This->ref );
    TRACE("(%p)->(%d)\n", This, ref );
    return ref;
}

static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    LONG ref = InterlockedDecrement( &This->ref );

    TRACE("(%p)->(%d)\n", This, ref);

    if (ref == 0)
    {
        int i;

        for (i = 0; i < This->length; i++)
        {
            SysFreeString(This->attr[i].qname);
            SysFreeString(This->attr[i].local);
            SysFreeString(This->attr[i].uri);
            SysFreeString(This->attr[i].type);
            SysFreeString(This->attr[i].value);
        }

        release_dispex(&This->dispex);
        heap_free(This->attr);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
}

static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
}

static HRESULT WINAPI MXAttributes_GetIDsOfNames(
    IMXAttributes *iface,
    REFIID riid,
    LPOLESTR* rgszNames,
    UINT cNames,
    LCID lcid,
    DISPID* rgDispId)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
        riid, rgszNames, cNames, lcid, rgDispId);
}

static HRESULT WINAPI MXAttributes_Invoke(
    IMXAttributes *iface,
    DISPID dispIdMember,
    REFIID riid,
    LCID lcid,
    WORD wFlags,
    DISPPARAMS* pDispParams,
    VARIANT* pVarResult,
    EXCEPINFO* pExcepInfo,
    UINT* puArgErr)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
        dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}

static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
    BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    mxattribute *attr;
    HRESULT hr;

    TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(uri), debugstr_w(localName),
        debugstr_w(QName), debugstr_w(type), debugstr_w(value));

    if ((!uri || !localName || !QName || !type || !value) && This->class_version != MSXML6)
        return E_INVALIDARG;

    /* ensure array is large enough */
    hr = mxattributes_grow(This);
    if (hr != S_OK) return hr;

    attr = &This->attr[This->length];

    attr->qname = SysAllocString(QName);
    attr->local = SysAllocString(localName);
    attr->uri   = SysAllocString(uri);
    attr->type  = SysAllocString(type ? type : emptyW);
    attr->value = SysAllocString(value);
    This->length++;

    return S_OK;
}

static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface,
    VARIANT atts, int index)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
    return E_NOTIMPL;
}

static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p)->(%d): stub\n", This, index);
    return E_NOTIMPL;
}

static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
    BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri),
        debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value));
    return E_NOTIMPL;
}

static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
    return E_NOTIMPL;
}

static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
    BSTR localName)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(localName));
    return E_NOTIMPL;
}

static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(QName));
    return E_NOTIMPL;
}

static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(uri));
    return E_NOTIMPL;
}

static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
{
    mxattributes *This = impl_from_IMXAttributes( iface );
    FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(value));
    return E_NOTIMPL;
}

static const IMXAttributesVtbl MXAttributesVtbl = {
    MXAttributes_QueryInterface,
    MXAttributes_AddRef,
    MXAttributes_Release,
    MXAttributes_GetTypeInfoCount,
    MXAttributes_GetTypeInfo,
    MXAttributes_GetIDsOfNames,
    MXAttributes_Invoke,
    MXAttributes_addAttribute,
    MXAttributes_addAttributeFromIndex,
    MXAttributes_clear,
    MXAttributes_removeAttribute,
    MXAttributes_setAttribute,
    MXAttributes_setAttributes,
    MXAttributes_setLocalName,
    MXAttributes_setQName,
    MXAttributes_setURI,
    MXAttributes_setValue
};

static HRESULT WINAPI SAXAttributes_QueryInterface(ISAXAttributes *iface, REFIID riid, void **ppObj)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    return IMXAttributes_QueryInterface(&This->IMXAttributes_iface, riid, ppObj);
}

static ULONG WINAPI SAXAttributes_AddRef(ISAXAttributes *iface)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    return IMXAttributes_AddRef(&This->IMXAttributes_iface);
}

static ULONG WINAPI SAXAttributes_Release(ISAXAttributes *iface)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    return IMXAttributes_Release(&This->IMXAttributes_iface);
}

static HRESULT WINAPI SAXAttributes_getLength(ISAXAttributes *iface, int *length)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    TRACE("(%p)->(%p)\n", This, length);

    if (!length && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
       return E_POINTER;

    *length = This->length;

    return S_OK;
}

static HRESULT WINAPI SAXAttributes_getURI(ISAXAttributes *iface, int nIndex, const WCHAR **pUrl,
    int *pUriSize)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    FIXME("(%p)->(%d %p %p): stub\n", This, nIndex, pUrl, pUriSize);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXAttributes_getLocalName(ISAXAttributes *iface, int nIndex, const WCHAR **localName,
    int *length)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    FIXME("(%p)->(%d %p %p): stub\n", This, nIndex, localName, length);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXAttributes_getQName(ISAXAttributes *iface, int index, const WCHAR **qname, int *length)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );

    TRACE("(%p)->(%d %p %p)\n", This, index, qname, length);

    if (index >= This->length) return E_INVALIDARG;
    if (!qname || !length) return E_POINTER;

    *qname = This->attr[index].qname;
    *length = SysStringLen(This->attr[index].qname);

    return S_OK;
}

static HRESULT WINAPI SAXAttributes_getName(ISAXAttributes *iface, int nIndex, const WCHAR **pUri, int *pUriLength,
    const WCHAR ** pLocalName, int * pLocalNameSize, const WCHAR ** pQName, int * pQNameLength)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    FIXME("(%p)->(%d %p %p %p %p %p %p): stub\n", This, nIndex, pUri, pUriLength, pLocalName, pLocalNameSize,
        pQName, pQNameLength);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXAttributes_getIndexFromName(ISAXAttributes *iface, const WCHAR * pUri, int cUriLength,
    const WCHAR * pLocalName, int cocalNameLength, int * index)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    FIXME("(%p)->(%s:%d %s:%d %p): stub\n", This, debugstr_wn(pUri, cUriLength), cUriLength,
        debugstr_wn(pLocalName, cocalNameLength), cocalNameLength, index);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXAttributes_getIndexFromQName(ISAXAttributes *iface, const WCHAR *qname,
    int len, int *index)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    int i;

    TRACE("(%p)->(%s:%d %p)\n", This, debugstr_wn(qname, len), len, index);

    if (!index && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
        return E_POINTER;

    if (!qname || !index || !len) return E_INVALIDARG;

    for (i = 0; i < This->length; i++)
    {
        if (len != SysStringLen(This->attr[i].qname)) continue;
        if (strncmpW(qname, This->attr[i].qname, len)) continue;

        *index = i;
        return S_OK;
    }

    return E_INVALIDARG;
}

static HRESULT WINAPI SAXAttributes_getType(ISAXAttributes *iface, int index, const WCHAR **type,
    int *len)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );

    TRACE("(%p)->(%d %p %p)\n", This, index, type, len);

    if (index >= This->length) return E_INVALIDARG;

    if ((!type || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
       return E_POINTER;

    *type = This->attr[index].type;
    *len = SysStringLen(This->attr[index].type);

    return S_OK;
}

static HRESULT WINAPI SAXAttributes_getTypeFromName(ISAXAttributes *iface, const WCHAR * pUri, int nUri,
    const WCHAR * pLocalName, int nLocalName, const WCHAR ** pType, int * nType)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This, debugstr_wn(pUri, nUri), nUri,
        debugstr_wn(pLocalName, nLocalName), nLocalName, pType, nType);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, const WCHAR * pQName,
    int nQName, const WCHAR ** pType, int * nType)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    FIXME("(%p)->(%s:%d %p %p): stub\n", This, debugstr_wn(pQName, nQName), nQName, pType, nType);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
    int *len)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );

    TRACE("(%p)->(%d %p %p)\n", This, index, value, len);

    if (index >= This->length) return E_INVALIDARG;

    if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
       return E_POINTER;

    *value = This->attr[index].value;
    *len = SysStringLen(This->attr[index].value);

    return S_OK;
}

static HRESULT WINAPI SAXAttributes_getValueFromName(ISAXAttributes *iface, const WCHAR * pUri,
    int nUri, const WCHAR * pLocalName, int nLocalName, const WCHAR ** pValue, int * nValue)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    FIXME("(%p)->(%s:%d %s:%d %p %p): stub\n", This, debugstr_wn(pUri, nUri), nUri,
        debugstr_wn(pLocalName, nLocalName), nLocalName, pValue, nValue);
    return E_NOTIMPL;
}

static HRESULT WINAPI SAXAttributes_getValueFromQName(ISAXAttributes *iface, const WCHAR *qname,
    int qname_len, const WCHAR **value, int *value_len)
{
    mxattributes *This = impl_from_ISAXAttributes( iface );
    HRESULT hr;
    int index;

    TRACE("(%p)->(%s:%d %p %p)\n", This, debugstr_wn(qname, qname_len), qname_len, value, value_len);

    if (!qname || !value || !value_len)
        return (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3) ? E_POINTER : E_INVALIDARG;

    hr = ISAXAttributes_getIndexFromQName(iface, qname, qname_len, &index);
    if (hr == S_OK)
        hr = ISAXAttributes_getValue(iface, index, value, value_len);

    return hr;
}

static const ISAXAttributesVtbl SAXAttributesVtbl = {
    SAXAttributes_QueryInterface,
    SAXAttributes_AddRef,
    SAXAttributes_Release,
    SAXAttributes_getLength,
    SAXAttributes_getURI,
    SAXAttributes_getLocalName,
    SAXAttributes_getQName,
    SAXAttributes_getName,
    SAXAttributes_getIndexFromName,
    SAXAttributes_getIndexFromQName,
    SAXAttributes_getType,
    SAXAttributes_getTypeFromName,
    SAXAttributes_getTypeFromQName,
    SAXAttributes_getValue,
    SAXAttributes_getValueFromName,
    SAXAttributes_getValueFromQName
};

static HRESULT WINAPI VBSAXAttributes_QueryInterface(
        IVBSAXAttributes* iface,
        REFIID riid,
        void **ppvObject)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
    return ISAXAttributes_QueryInterface(&This->ISAXAttributes_iface, riid, ppvObject);
}

static ULONG WINAPI VBSAXAttributes_AddRef(IVBSAXAttributes* iface)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    return ISAXAttributes_AddRef(&This->ISAXAttributes_iface);
}

static ULONG WINAPI VBSAXAttributes_Release(IVBSAXAttributes* iface)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    return ISAXAttributes_Release(&This->ISAXAttributes_iface);
}

static HRESULT WINAPI VBSAXAttributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );

    TRACE("(%p)->(%p)\n", This, pctinfo);

    *pctinfo = 1;

    return S_OK;
}

static HRESULT WINAPI VBSAXAttributes_GetTypeInfo(
    IVBSAXAttributes *iface,
    UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
}

static HRESULT WINAPI VBSAXAttributes_GetIDsOfNames(
    IVBSAXAttributes *iface,
    REFIID riid,
    LPOLESTR* rgszNames,
    UINT cNames,
    LCID lcid,
    DISPID* rgDispId)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
          lcid, rgDispId);

    if(!rgszNames || cNames == 0 || !rgDispId)
        return E_INVALIDARG;

    hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI VBSAXAttributes_Invoke(
    IVBSAXAttributes *iface,
    DISPID dispIdMember,
    REFIID riid,
    LCID lcid,
    WORD wFlags,
    DISPPARAMS* pDispParams,
    VARIANT* pVarResult,
    EXCEPINFO* pExcepInfo,
    UINT* puArgErr)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
          lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI VBSAXAttributes_get_length(IVBSAXAttributes* iface, int *len)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    return ISAXAttributes_getLength(&This->ISAXAttributes_iface, len);
}

static HRESULT WINAPI VBSAXAttributes_getURI(IVBSAXAttributes* iface, int index, BSTR *uri)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getURI(&This->ISAXAttributes_iface, index, (const WCHAR**)uri, &len);
}

static HRESULT WINAPI VBSAXAttributes_getLocalName(IVBSAXAttributes* iface, int index, BSTR *name)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, index, (const WCHAR**)name, &len);
}

static HRESULT WINAPI VBSAXAttributes_getQName(IVBSAXAttributes* iface, int index, BSTR *qname)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getQName(&This->ISAXAttributes_iface, index, (const WCHAR**)qname, &len);
}

static HRESULT WINAPI VBSAXAttributes_getIndexFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name, int *index)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
            name, SysStringLen(name), index);
}

static HRESULT WINAPI VBSAXAttributes_getIndexFromQName(IVBSAXAttributes* iface, BSTR qname, int *index)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, qname,
            SysStringLen(qname), index);
}

static HRESULT WINAPI VBSAXAttributes_getType(IVBSAXAttributes* iface, int index,BSTR *type)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getType(&This->ISAXAttributes_iface, index, (const WCHAR**)type, &len);
}

static HRESULT WINAPI VBSAXAttributes_getTypeFromName(IVBSAXAttributes* iface, BSTR uri,
    BSTR name, BSTR *type)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
            name, SysStringLen(name), (const WCHAR**)type, &len);
}

static HRESULT WINAPI VBSAXAttributes_getTypeFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *type)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
            (const WCHAR**)type, &len);
}

static HRESULT WINAPI VBSAXAttributes_getValue(IVBSAXAttributes* iface, int index, BSTR *value)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getValue(&This->ISAXAttributes_iface, index, (const WCHAR**)value, &len);
}

static HRESULT WINAPI VBSAXAttributes_getValueFromName(IVBSAXAttributes* iface, BSTR uri, BSTR name,
    BSTR *value)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
            name, SysStringLen(name), (const WCHAR**)value, &len);
}

static HRESULT WINAPI VBSAXAttributes_getValueFromQName(IVBSAXAttributes* iface, BSTR qname, BSTR *value)
{
    mxattributes *This = impl_from_IVBSAXAttributes( iface );
    int len;

    return ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, qname, SysStringLen(qname),
        (const WCHAR**)value, &len);
}

static const struct IVBSAXAttributesVtbl VBSAXAttributesVtbl =
{
    VBSAXAttributes_QueryInterface,
    VBSAXAttributes_AddRef,
    VBSAXAttributes_Release,
    VBSAXAttributes_GetTypeInfoCount,
    VBSAXAttributes_GetTypeInfo,
    VBSAXAttributes_GetIDsOfNames,
    VBSAXAttributes_Invoke,
    VBSAXAttributes_get_length,
    VBSAXAttributes_getURI,
    VBSAXAttributes_getLocalName,
    VBSAXAttributes_getQName,
    VBSAXAttributes_getIndexFromName,
    VBSAXAttributes_getIndexFromQName,
    VBSAXAttributes_getType,
    VBSAXAttributes_getTypeFromName,
    VBSAXAttributes_getTypeFromQName,
    VBSAXAttributes_getValue,
    VBSAXAttributes_getValueFromName,
    VBSAXAttributes_getValueFromQName
};

static const tid_t mxattrs_iface_tids[] = {
    IMXAttributes_tid,
    0
};

static dispex_static_data_t mxattrs_dispex = {
    NULL,
    IMXAttributes_tid,
    NULL,
    mxattrs_iface_tids
};

HRESULT SAXAttributes_create(MSXML_VERSION version, IUnknown *outer, void **ppObj)
{
    static const int default_count = 10;
    mxattributes *This;

    TRACE("(%p, %p)\n", outer, ppObj);

    This = heap_alloc( sizeof (*This) );
    if( !This )
        return E_OUTOFMEMORY;

    This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
    This->ISAXAttributes_iface.lpVtbl = &SAXAttributesVtbl;
    This->IVBSAXAttributes_iface.lpVtbl = &VBSAXAttributesVtbl;
    This->ref = 1;

    This->class_version = version;

    This->attr = heap_alloc(default_count*sizeof(mxattribute));
    This->length = 0;
    This->allocated = default_count;

    *ppObj = &This->IMXAttributes_iface;

    init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);

    TRACE("returning iface %p\n", *ppObj);

    return S_OK;
}
