Nikolay Sivov : xmllite/writer: Initial support of output buffer creation.
Alexandre Julliard
julliard at winehq.org
Thu May 15 15:14:30 CDT 2014
Module: wine
Branch: master
Commit: 71ab66efa04f80ef788a485295f10dd9e0d48191
URL: http://source.winehq.org/git/wine.git/?a=commit;h=71ab66efa04f80ef788a485295f10dd9e0d48191
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Thu May 15 18:47:26 2014 +0400
xmllite/writer: Initial support of output buffer creation.
---
dlls/xmllite/reader.c | 2 +-
dlls/xmllite/tests/writer.c | 83 ++++++++++++++++++++++++++++++++++++++++
dlls/xmllite/writer.c | 48 +++++++++++++++++++++++
dlls/xmllite/xmllite_private.h | 3 +-
4 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index d8b81ea..e772a08 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -554,7 +554,7 @@ static void free_encoded_buffer(xmlreaderinput *input, encoded_buffer *buffer)
readerinput_free(input, buffer->data);
}
-static HRESULT get_code_page(xml_encoding encoding, UINT *cp)
+HRESULT get_code_page(xml_encoding encoding, UINT *cp)
{
if (encoding == XmlEncoding_Unknown)
{
diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c
index 738844f..0f86fb9 100644
--- a/dlls/xmllite/tests/writer.c
+++ b/dlls/xmllite/tests/writer.c
@@ -143,6 +143,88 @@ static void test_writeroutput(void)
IUnknown_Release(output);
}
+static void test_writestartdocument(void)
+{
+ static const char fullprolog[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
+ static const char prologversion[] = "<?xml version=\"1.0\"?>";
+ static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
+ static const WCHAR xmlW[] = {'x','m','l',0};
+ IXmlWriter *writer;
+ HGLOBAL hglobal;
+ IStream *stream;
+ HRESULT hr;
+ char *ptr;
+
+ hr = pCreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
+ ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+ /* output not set */
+ hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
+todo_wine
+ ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
+ if (hr == E_NOTIMPL) {
+ IXmlWriter_Release(writer);
+ return;
+ }
+
+ hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
+ ok(hr == S_OK, "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(!strncmp(ptr, fullprolog, strlen(fullprolog)), "got %s, expected %s\n", ptr, fullprolog);
+ GlobalUnlock(hglobal);
+
+ /* one more time */
+ hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
+ ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
+ IStream_Release(stream);
+
+ /* now add PI manually, and try to start a document */
+ hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
+ 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);
+
+ /* another attempt to add 'xml' PI */
+ hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
+ 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(!strncmp(ptr, prologversion, strlen(prologversion)), "got %s\n", ptr);
+ GlobalUnlock(hglobal);
+
+ IStream_Release(stream);
+ IXmlWriter_Release(writer);
+}
+
START_TEST(writer)
{
if (!init_pointers())
@@ -150,4 +232,5 @@ START_TEST(writer)
test_writer_create();
test_writeroutput();
+ test_writestartdocument();
}
diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c
index 2432602..10d73cb 100644
--- a/dlls/xmllite/writer.c
+++ b/dlls/xmllite/writer.c
@@ -34,6 +34,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(xmllite);
/* not defined in public headers */
DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
+struct output_buffer
+{
+ char *data;
+ unsigned int allocated;
+ unsigned int written;
+ UINT codepage;
+};
+
typedef struct
{
IXmlWriterOutput IXmlWriterOutput_iface;
@@ -42,6 +50,7 @@ typedef struct
ISequentialStream *stream;
IMalloc *imalloc;
xml_encoding encoding;
+ struct output_buffer buffer;
} xmlwriteroutput;
static const struct IUnknownVtbl xmlwriteroutputvtbl;
@@ -107,6 +116,36 @@ static inline void writer_free(xmlwriter *writer, void *mem)
m_free(writer->imalloc, mem);
}
+static HRESULT init_output_buffer(xmlwriteroutput *output)
+{
+ struct output_buffer *buffer = &output->buffer;
+ const int initial_len = 0x2000;
+ HRESULT hr;
+ UINT cp;
+
+ hr = get_code_page(output->encoding, &cp);
+ if (FAILED(hr)) return hr;
+
+ buffer->data = writeroutput_alloc(output, initial_len);
+ if (!buffer->data) return E_OUTOFMEMORY;
+
+ memset(buffer->data, 0, 4);
+ buffer->allocated = initial_len;
+ buffer->written = 0;
+ buffer->codepage = cp;
+
+ return S_OK;
+}
+
+static void free_output_buffer(xmlwriteroutput *output)
+{
+ struct output_buffer *buffer = &output->buffer;
+ writeroutput_free(output, buffer->data);
+ buffer->data = NULL;
+ buffer->allocated = 0;
+ buffer->written = 0;
+}
+
static void writeroutput_release_stream(xmlwriteroutput *writeroutput)
{
if (writeroutput->stream) {
@@ -572,6 +611,7 @@ static ULONG WINAPI xmlwriteroutput_Release(IXmlWriterOutput *iface)
IMalloc *imalloc = This->imalloc;
if (This->output) IUnknown_Release(This->output);
if (This->stream) ISequentialStream_Release(This->stream);
+ free_output_buffer(This);
writeroutput_free(This, This);
if (imalloc) IMalloc_Release(imalloc);
}
@@ -627,11 +667,14 @@ HRESULT WINAPI CreateXmlWriterOutputWithEncodingName(IUnknown *stream,
IXmlWriterOutput **output)
{
xmlwriteroutput *writeroutput;
+ HRESULT hr;
TRACE("%p %p %s %p\n", stream, imalloc, debugstr_w(encoding), output);
if (!stream || !output) return E_INVALIDARG;
+ *output = NULL;
+
if (imalloc)
writeroutput = IMalloc_Alloc(imalloc, sizeof(*writeroutput));
else
@@ -644,6 +687,11 @@ HRESULT WINAPI CreateXmlWriterOutputWithEncodingName(IUnknown *stream,
if (imalloc) IMalloc_AddRef(imalloc);
writeroutput->encoding = parse_encoding_name(encoding, -1);
writeroutput->stream = NULL;
+ hr = init_output_buffer(writeroutput);
+ if (FAILED(hr)) {
+ IUnknown_Release(&writeroutput->IXmlWriterOutput_iface);
+ return hr;
+ }
IUnknown_QueryInterface(stream, &IID_IUnknown, (void**)&writeroutput->output);
diff --git a/dlls/xmllite/xmllite_private.h b/dlls/xmllite/xmllite_private.h
index 96a78fa..642aabe 100644
--- a/dlls/xmllite/xmllite_private.h
+++ b/dlls/xmllite/xmllite_private.h
@@ -60,6 +60,7 @@ typedef enum
XmlEncoding_Unknown
} xml_encoding;
-xml_encoding parse_encoding_name(const WCHAR *name, int len) DECLSPEC_HIDDEN;
+xml_encoding parse_encoding_name(const WCHAR*,int) DECLSPEC_HIDDEN;
+HRESULT get_code_page(xml_encoding,UINT*) DECLSPEC_HIDDEN;
#endif /* __XMLLITE_PRIVATE__ */
More information about the wine-cvs
mailing list