diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c index 6f2232e27e6..ead914597fa 100644 --- a/dlls/xmllite/tests/writer.c +++ b/dlls/xmllite/tests/writer.c @@ -880,6 +880,67 @@ static void test_WriteCData(void) IStream_Release(stream); } +static void test_WriteRaw(void) +{ + static const WCHAR rawW[] = {'a','<',':',0}; + IXmlWriter *writer; + IStream *stream; + HGLOBAL hglobal; + HRESULT hr; + char *ptr; + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = pCreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + + hr = IXmlWriter_WriteRaw(writer, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteRaw(writer, rawW); + ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr); + + hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteRaw(writer, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteRaw(writer, rawW); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes); + ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteComment(writer, rawW); + ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteEndDocument(writer); + ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr); + + hr = IXmlWriter_WriteRaw(writer, rawW); + ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = GetHGlobalFromStream(stream, &hglobal); + ok(hr == S_OK, "got 0x%08x\n", hr); + + ptr = GlobalLock(hglobal); + ok(ptr != NULL, "got %p\n", ptr); + + ok(!strncmp(ptr, + "" + "a<:", 41), "got %s\n", ptr); + + GlobalUnlock(hglobal); + + IXmlWriter_Release(writer); + IStream_Release(stream); +} + START_TEST(writer) { if (!init_pointers()) @@ -896,4 +957,5 @@ START_TEST(writer) test_writeenddocument(); test_WriteComment(); test_WriteCData(); + test_WriteRaw(); } diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c index 3e74389020b..dac7f0410da 100644 --- a/dlls/xmllite/writer.c +++ b/dlls/xmllite/writer.c @@ -372,6 +372,40 @@ static HRESULT write_encoding_bom(xmlwriter *writer) return S_OK; } +static HRESULT write_xmldecl(xmlwriter *writer, XmlStandalone standalone) +{ + static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"'}; + static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','='}; + + write_encoding_bom(writer); + writer->state = XmlWriterState_DocStarted; + if (writer->omitxmldecl) return S_OK; + + /* version */ + write_output_buffer(writer->output, versionW, ARRAY_SIZE(versionW)); + + /* encoding */ + write_output_buffer(writer->output, encodingW, ARRAY_SIZE(encodingW)); + write_output_buffer_quoted(writer->output, get_encoding_name(writer->output->encoding), -1); + + /* standalone */ + if (standalone == XmlStandalone_Omit) + write_output_buffer(writer->output, closepiW, ARRAY_SIZE(closepiW)); + else { + 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','\"','?','>'}; + + write_output_buffer(writer->output, standaloneW, ARRAY_SIZE(standaloneW)); + if (standalone == XmlStandalone_Yes) + write_output_buffer(writer->output, yesW, ARRAY_SIZE(yesW)); + else + write_output_buffer(writer->output, noW, ARRAY_SIZE(noW)); + } + + return S_OK; +} + static HRESULT writer_close_starttag(xmlwriter *writer) { HRESULT hr; @@ -890,13 +924,32 @@ static HRESULT WINAPI xmlwriter_WriteQualifiedName(IXmlWriter *iface, LPCWSTR pw return E_NOTIMPL; } -static HRESULT WINAPI xmlwriter_WriteRaw(IXmlWriter *iface, LPCWSTR pwszData) +static HRESULT WINAPI xmlwriter_WriteRaw(IXmlWriter *iface, LPCWSTR data) { xmlwriter *This = impl_from_IXmlWriter(iface); - FIXME("%p %s\n", This, wine_dbgstr_w(pwszData)); + TRACE("%p %s\n", This, debugstr_w(data)); - return E_NOTIMPL; + if (!data) + return S_OK; + + switch (This->state) + { + case XmlWriterState_Initial: + return E_UNEXPECTED; + case XmlWriterState_Ready: + write_xmldecl(This, XmlStandalone_Omit); + /* fallthrough */ + case XmlWriterState_DocStarted: + case XmlWriterState_PIDocStarted: + break; + default: + return WR_E_INVALIDACTION; + } + + write_output_buffer(This->output, data, -1); + This->state = XmlWriterState_DocClosed; + return S_OK; } static HRESULT WINAPI xmlwriter_WriteRawChars(IXmlWriter *iface, const WCHAR *pwch, UINT cwch) @@ -908,10 +961,9 @@ static HRESULT WINAPI xmlwriter_WriteRawChars(IXmlWriter *iface, const WCHAR *p return E_NOTIMPL; } + static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandalone standalone) { - static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"'}; - static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','='}; xmlwriter *This = impl_from_IXmlWriter(iface); TRACE("(%p)->(%d)\n", This, standalone); @@ -923,41 +975,13 @@ static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandal case XmlWriterState_PIDocStarted: This->state = XmlWriterState_DocStarted; return S_OK; - case XmlWriterState_DocStarted: - case XmlWriterState_ElemStarted: - case XmlWriterState_DocClosed: - return WR_E_INVALIDACTION; + case XmlWriterState_Ready: + break; default: - ; + return WR_E_INVALIDACTION; } - write_encoding_bom(This); - This->state = XmlWriterState_DocStarted; - if (This->omitxmldecl) return S_OK; - - /* version */ - write_output_buffer(This->output, versionW, ARRAY_SIZE(versionW)); - - /* encoding */ - write_output_buffer(This->output, encodingW, ARRAY_SIZE(encodingW)); - write_output_buffer_quoted(This->output, get_encoding_name(This->output->encoding), -1); - - /* standalone */ - if (standalone == XmlStandalone_Omit) - write_output_buffer(This->output, closepiW, ARRAY_SIZE(closepiW)); - else { - 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','\"','?','>'}; - - write_output_buffer(This->output, standaloneW, ARRAY_SIZE(standaloneW)); - if (standalone == XmlStandalone_Yes) - write_output_buffer(This->output, yesW, ARRAY_SIZE(yesW)); - else - write_output_buffer(This->output, noW, ARRAY_SIZE(noW)); - } - - return S_OK; + return write_xmldecl(This, standalone); } static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR prefix, LPCWSTR local_name, LPCWSTR uri)