>From cacf688ffb39f909f322c14ca71092300d56baa6 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Thu, 8 Mar 2012 12:03:27 +0300
Subject: [PATCH 2/3] Support element declaration output in MXWriter

---
 dlls/msxml3/mxwriter.c        |   22 ++++++++++++++++----
 dlls/msxml3/tests/saxreader.c |   43 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index 2519a75..55159e1 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -389,9 +389,6 @@ static HRESULT write_data_to_stream(mxwriter *This)
     if (!This->dest)
         return S_OK;
 
-    /* The xmlOutputBuffer doesn't copy its contents from its 'buffer' to the
-     * 'conv' buffer when UTF8 encoding is used.
-     */
     if (This->xml_enc != XmlEncoding_UTF16)
         buffer = &This->buffer->encoded;
     else
@@ -1312,10 +1309,25 @@ static ULONG WINAPI SAXDeclHandler_Release(ISAXDeclHandler *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 );
-    FIXME("(%p)->(%s:%d %s:%d): stub\n", This, debugstr_wn(name, n_name), n_name,
+
+    TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
         debugstr_wn(model, n_model), n_model);
-    return E_NOTIMPL;
+
+    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,
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 368dfeb..494d866 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -3124,11 +3124,13 @@ static void test_mxwriter_cdata(void)
 
 static void test_mxwriter_dtd(void)
 {
+    static const WCHAR contentW[] = {'c','o','n','t','e','n','t'};
     static const WCHAR nameW[] = {'n','a','m','e'};
     static const WCHAR pubW[] = {'p','u','b'};
     static const WCHAR sysW[] = {'s','y','s'};
     ISAXContentHandler *content;
     ISAXLexicalHandler *lexical;
+    ISAXDeclHandler *decl;
     IMXWriter *writer;
     VARIANT dest;
     HRESULT hr;
@@ -3143,6 +3145,9 @@ static void test_mxwriter_dtd(void)
     hr = IMXWriter_QueryInterface(writer, &IID_ISAXLexicalHandler, (void**)&lexical);
     EXPECT_HR(hr, S_OK);
 
+    hr = IMXWriter_QueryInterface(writer, &IID_ISAXDeclHandler, (void**)&decl);
+    EXPECT_HR(hr, S_OK);
+
     hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
     EXPECT_HR(hr, S_OK);
 
@@ -3202,8 +3207,46 @@ static void test_mxwriter_dtd(void)
         V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
     VariantClear(&dest);
 
+    /* element declaration */
+    V_VT(&dest) = VT_EMPTY;
+    hr = IMXWriter_put_output(writer, dest);
+    EXPECT_HR(hr, S_OK);
+
+    hr = ISAXDeclHandler_elementDecl(decl, NULL, 0, NULL, 0);
+    EXPECT_HR(hr, E_INVALIDARG);
+
+    hr = ISAXDeclHandler_elementDecl(decl, nameW, sizeof(nameW)/sizeof(WCHAR), NULL, 0);
+    EXPECT_HR(hr, E_INVALIDARG);
+
+    hr = ISAXDeclHandler_elementDecl(decl, nameW, sizeof(nameW)/sizeof(WCHAR), contentW, sizeof(contentW)/sizeof(WCHAR));
+    EXPECT_HR(hr, S_OK);
+
+    V_VT(&dest) = VT_EMPTY;
+    hr = IMXWriter_get_output(writer, &dest);
+    EXPECT_HR(hr, S_OK);
+    ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
+    ok(!lstrcmpW(_bstr_("<!ELEMENT name content>\r\n"),
+        V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
+    VariantClear(&dest);
+
+    V_VT(&dest) = VT_EMPTY;
+    hr = IMXWriter_put_output(writer, dest);
+    EXPECT_HR(hr, S_OK);
+
+    hr = ISAXDeclHandler_elementDecl(decl, nameW, sizeof(nameW)/sizeof(WCHAR), contentW, 0);
+    EXPECT_HR(hr, S_OK);
+
+    V_VT(&dest) = VT_EMPTY;
+    hr = IMXWriter_get_output(writer, &dest);
+    EXPECT_HR(hr, S_OK);
+    ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
+    ok(!lstrcmpW(_bstr_("<!ELEMENT name >\r\n"),
+        V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
+    VariantClear(&dest);
+
     ISAXContentHandler_Release(content);
     ISAXLexicalHandler_Release(lexical);
+    ISAXDeclHandler_Release(decl);
     IMXWriter_Release(writer);
     free_bstrs();
 }
-- 
1.5.6.5


