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