Commit 71ab66ef authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

xmllite/writer: Initial support of output buffer creation.

parent 0ae578b7
......@@ -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)
{
......
......@@ -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();
}
......@@ -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);
......
......@@ -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__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment