On 4/14/2019 7:29 AM, Nikolay Sivov wrote:
Hi, Jefferson. Please see comments below.
@@ -344,10 +355,10 @@ static HRESULT write_output_buffer(mxwriter *writer, const WCHAR *data, int len) if (!avail) { - IStream_Write(writer->dest, buff->data, buff->written, &written); + IStream_Write(writer->dest_stream, buff->data, buff->written, &written); buff->written = 0; if (src_len >= buff->allocated) - IStream_Write(writer->dest, data, src_len, &written); + IStream_Write(writer->dest_stream, data, src_len, &written); else if (src_len) { memcpy(buff->data, data, src_len); @@ -371,7 +382,7 @@ static HRESULT write_output_buffer(mxwriter *writer, const WCHAR *data, int len) /* drain what we go so far */ if (buff->written) { - IStream_Write(writer->dest, buff->data, buff->written, &written); + IStream_Write(writer->dest_stream, buff->data, buff->written, &written); buff->written = 0; avail = buff->allocated; }
I don't think this is a way to deal with that case. When writer output is set to DOM document what will probably happen is a complete tree created and accumulated during SAX calls, and then cloned back to said document on endDocument(). That means we'll simply have to skip over any writing call, both for existing stream or BSTR path, and create nodes instead.
Indeed, I was thinking that instead of calling write_output_buffer at all when the destination is a DOMDocument, the DOMDocument's createNode etc. functions would be called instead. Perhaps the mxwriter would need to hold a reference to an IXMLDOMNode for in-progress nodes whose attributes and child nodes are presently being assigned.
Note that presently even though write_output_buffer is called when the destination is a DOMDocument, it now contains the code
+ else { + FIXME("unsupported destination type for writing %d\n", writer->dest_type); + }
which would be called if the destination were set to a DOMDocument.
It's not clear without tests whether the entire result is cloned back on endDocument, or whether the DOMDocument is built progressively in response to events sent to the SAXContentHandler.
+ case VT_DISPATCH: + { + IXMLDOMDocument *doc; + hr = IUnknown_QueryInterface(V_DISPATCH(&dest), &IID_IXMLDOMDocument, (void**)&doc); + if (hr == S_OK) + { + This->dest_type = MXWriterDestDocument; + This->dest_document = doc; + break; + } + FIXME("unhandled interface type for VT_DISPATCH destination\n"); + return E_NOTIMPL; + }
It's impossible to tell if this is correct without tests, e.g. VT_UNKNOWN could also be passed with document pointer, it's valid in VARIANT sense.
Will write tests ASAP.