Nikolay Sivov : msxml3: Implement startElement() for writer' s IVBSAXContentHandler.

Alexandre Julliard julliard at winehq.org
Thu Mar 6 13:40:50 CST 2014


Module: wine
Branch: master
Commit: dc37ed1f7a176c794cf2f4d4ae02588d623a640d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dc37ed1f7a176c794cf2f4d4ae02588d623a640d

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Mar  6 09:22:19 2014 +0400

msxml3: Implement startElement() for writer's IVBSAXContentHandler.

---

 dlls/msxml3/mxwriter.c |  119 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 86 insertions(+), 33 deletions(-)

diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index 6fc3631..b0765c0 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -398,11 +398,14 @@ static void close_output_buffer(mxwriter *This)
     get_code_page(This->xml_enc, &This->buffer->code_page);
 }
 
-/* escapes special characters like:
+/* Escapes special characters like:
    '<' -> "<"
    '&' -> "&"
    '"' -> """
    '>' -> ">"
+
+   On call 'len' contains a length of 'str' in chars or -1 if it's null terminated.
+   After a call it's updated with actual new length if it wasn't -1 initially.
 */
 static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
 {
@@ -1169,6 +1172,40 @@ static HRESULT WINAPI SAXContentHandler_endPrefixMapping(
     return S_OK;
 }
 
+static void mxwriter_write_attribute(mxwriter *writer, const WCHAR *qname, int qname_len,
+    const WCHAR *value, int value_len, BOOL escape)
+{
+    static const WCHAR eqW[] = {'='};
+
+    /* space separator in front of every attribute */
+    write_output_buffer(writer->buffer, spaceW, 1);
+    write_output_buffer(writer->buffer, qname, qname_len);
+    write_output_buffer(writer->buffer, eqW, 1);
+
+    if (escape)
+    {
+        WCHAR *escaped = get_escaped_string(value, EscapeValue, &value_len);
+        write_output_buffer_quoted(writer->buffer, escaped, value_len);
+        heap_free(escaped);
+    }
+    else
+        write_output_buffer_quoted(writer->buffer, value, value_len);
+}
+
+static void mxwriter_write_starttag(mxwriter *writer, const WCHAR *qname, int len)
+{
+    static const WCHAR ltW[] = {'<'};
+
+    close_element_starttag(writer);
+    set_element_name(writer, qname ? qname : emptyW, qname ? len : 0);
+
+    write_node_indent(writer);
+
+    write_output_buffer(writer->buffer, ltW, 1);
+    write_output_buffer(writer->buffer, qname, len);
+    writer_inc_indent(writer);
+}
+
 static HRESULT WINAPI SAXContentHandler_startElement(
     ISAXContentHandler *iface,
     const WCHAR *namespaceUri,
@@ -1180,7 +1217,6 @@ static HRESULT WINAPI SAXContentHandler_startElement(
     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);
@@ -1189,15 +1225,7 @@ static HRESULT WINAPI SAXContentHandler_startElement(
         (nQName == -1 && This->class_version == MSXML6))
         return E_INVALIDARG;
 
-    close_element_starttag(This);
-    set_element_name(This, QName ? QName  : emptyW,
-                           QName ? nQName : 0);
-
-    write_node_indent(This);
-
-    write_output_buffer(This->buffer, ltW, 1);
-    write_output_buffer(This->buffer, QName, nQName);
-    writer_inc_indent(This);
+    mxwriter_write_starttag(This, QName, nQName);
 
     if (attr)
     {
@@ -1212,31 +1240,16 @@ static HRESULT WINAPI SAXContentHandler_startElement(
 
         for (i = 0; i < length; i++)
         {
-            static const WCHAR eqW[] = {'='};
-            const WCHAR *str;
-            int len = 0;
+            int qname_len = 0, value_len = 0;
+            const WCHAR *qname, *value;
 
-            hr = ISAXAttributes_getQName(attr, i, &str, &len);
+            hr = ISAXAttributes_getQName(attr, i, &qname, &qname_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);
+            hr = ISAXAttributes_getValue(attr, i, &value, &value_len);
             if (FAILED(hr)) return hr;
 
-            if (escape)
-            {
-                WCHAR *escaped = get_escaped_string(str, EscapeValue, &len);
-                write_output_buffer_quoted(This->buffer, escaped, len);
-                heap_free(escaped);
-            }
-            else
-                write_output_buffer_quoted(This->buffer, str, len);
+            mxwriter_write_attribute(This, qname, qname_len, value, value_len, escape);
         }
     }
 
@@ -2051,8 +2064,48 @@ static HRESULT WINAPI VBSAXContentHandler_startElement(IVBSAXContentHandler *ifa
     BSTR *namespaceURI, BSTR *localName, BSTR *QName, IVBSAXAttributes *attrs)
 {
     mxwriter *This = impl_from_IVBSAXContentHandler( iface );
-    FIXME("(%p)->(%p %p %p %p): stub\n", This, namespaceURI, localName, QName, attrs);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%p %p %p %p)\n", This, namespaceURI, localName, QName, attrs);
+
+    if (!namespaceURI || !localName || !QName)
+        return E_POINTER;
+
+    TRACE("(%s %s %s)\n", debugstr_w(*namespaceURI), debugstr_w(*localName), debugstr_w(*QName));
+
+    mxwriter_write_starttag(This, *QName, SysStringLen(*QName));
+
+    if (attrs)
+    {
+        int length, i, escape;
+        HRESULT hr;
+
+        hr = IVBSAXAttributes_get_length(attrs, &length);
+        if (FAILED(hr)) return hr;
+
+        escape = This->props[MXWriter_DisableEscaping] == VARIANT_FALSE ||
+            (This->class_version == MSXML4 || This->class_version == MSXML6);
+
+        for (i = 0; i < length; i++)
+        {
+            BSTR qname, value;
+
+            hr = IVBSAXAttributes_getQName(attrs, i, &qname);
+            if (FAILED(hr)) return hr;
+
+            hr = IVBSAXAttributes_getValue(attrs, i, &value);
+            if (FAILED(hr))
+            {
+                SysFreeString(qname);
+                return hr;
+            }
+
+            mxwriter_write_attribute(This, qname, SysStringLen(qname), value, SysStringLen(value), escape);
+            SysFreeString(qname);
+            SysFreeString(value);
+        }
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI VBSAXContentHandler_endElement(IVBSAXContentHandler *iface, BSTR *namespaceURI,




More information about the wine-cvs mailing list