Commit 22c9af71 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

xmllite/writer: Implement WriteAttributes().

parent 5de86e12
......@@ -32,6 +32,41 @@
#include "initguid.h"
DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
static IStream *create_stream_on_data(const void *data, unsigned int size)
{
IStream *stream = NULL;
HGLOBAL hglobal;
void *ptr;
HRESULT hr;
hglobal = GlobalAlloc(GHND, size);
ptr = GlobalLock(hglobal);
memcpy(ptr, data, size);
hr = CreateStreamOnHGlobal(hglobal, TRUE, &stream);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(stream != NULL, "Expected non-NULL stream\n");
GlobalUnlock(hglobal);
return stream;
}
#define reader_set_input(a, b) _reader_set_input(__LINE__, a, b)
static void _reader_set_input(unsigned line, IXmlReader *reader, const char *xml)
{
IStream *stream;
HRESULT hr;
stream = create_stream_on_data(xml, strlen(xml));
hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
ok_(__FILE__,line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
IStream_Release(stream);
}
#define EXPECT_REF(obj, ref) _expect_ref((IUnknown *)obj, ref, __LINE__)
static void _expect_ref(IUnknown *obj, ULONG ref, int line)
{
......@@ -2155,6 +2190,75 @@ static void test_WriteProcessingInstruction(void)
IXmlWriter_Release(writer);
}
static void test_WriteAttributes(void)
{
XmlNodeType node_type;
IXmlWriter *writer;
IXmlReader *reader;
const WCHAR *name;
IStream *stream;
HRESULT hr;
hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
/* No attributes. */
reader_set_input(reader, "<a/>");
stream = writer_set_output(writer);
hr = IXmlWriter_WriteAttributes(writer, reader, FALSE);
ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
hr = IXmlReader_Read(reader, NULL);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IXmlWriter_WriteAttributes(writer, reader, FALSE);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IXmlWriter_Flush(writer);
ok(hr == S_OK, "Failed to flush, hr %#lx.\n", hr);
CHECK_OUTPUT(stream, "");
IStream_Release(stream);
/* Position on element with attributes. */
reader_set_input(reader, "<a attr1=\'b\' attr2=\'c\' attr3=\'d\' />");
stream = writer_set_output(writer);
hr = IXmlReader_Read(reader, NULL);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IXmlWriter_WriteAttributes(writer, reader, FALSE);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IXmlReader_GetNodeType(reader, &node_type);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(node_type == XmlNodeType_Element, "Unexpected node type %d.\n", node_type);
hr = IXmlWriter_Flush(writer);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
CHECK_OUTPUT(stream, "<w attr1=\"b\" attr2=\"c\" attr3=\"d\"");
IStream_Release(stream);
/* Position on second attribute. */
hr = IXmlReader_MoveToAttributeByName(reader, L"attr2", NULL);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
stream = writer_set_output(writer);
hr = IXmlWriter_WriteStartElement(writer, NULL, L"w", NULL);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IXmlWriter_WriteAttributes(writer, reader, FALSE);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IXmlReader_GetNodeType(reader, &node_type);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(node_type == XmlNodeType_Attribute, "Unexpected node type %d.\n", node_type);
hr = IXmlReader_GetLocalName(reader, &name, NULL);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(!wcscmp(name, L"attr3"), "Unexpected node %s.\n", debugstr_w(name));
hr = IXmlWriter_Flush(writer);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
CHECK_OUTPUT(stream, "<w attr2=\"c\" attr3=\"d\"");
IStream_Release(stream);
IXmlWriter_Release(writer);
IXmlReader_Release(reader);
}
START_TEST(writer)
{
test_writer_create();
......@@ -2179,4 +2283,5 @@ START_TEST(writer)
test_WriteDocType();
test_WriteWhitespace();
test_WriteProcessingInstruction();
test_WriteAttributes();
}
......@@ -845,14 +845,54 @@ static HRESULT WINAPI xmlwriter_SetProperty(IXmlWriter *iface, UINT property, LO
return S_OK;
}
static HRESULT WINAPI xmlwriter_WriteAttributes(IXmlWriter *iface, IXmlReader *pReader,
BOOL fWriteDefaultAttributes)
static HRESULT writer_write_attribute(IXmlWriter *writer, IXmlReader *reader, BOOL write_default_attributes)
{
xmlwriter *This = impl_from_IXmlWriter(iface);
const WCHAR *prefix, *local, *uri, *value;
HRESULT hr;
FIXME("%p %p %d\n", This, pReader, fWriteDefaultAttributes);
if (IXmlReader_IsDefault(reader) && !write_default_attributes)
return S_OK;
return E_NOTIMPL;
if (FAILED(hr = IXmlReader_GetPrefix(reader, &prefix, NULL))) return hr;
if (FAILED(hr = IXmlReader_GetLocalName(reader, &local, NULL))) return hr;
if (FAILED(hr = IXmlReader_GetNamespaceUri(reader, &uri, NULL))) return hr;
if (FAILED(hr = IXmlReader_GetValue(reader, &value, NULL))) return hr;
return IXmlWriter_WriteAttributeString(writer, prefix, local, uri, value);
}
static HRESULT WINAPI xmlwriter_WriteAttributes(IXmlWriter *iface, IXmlReader *reader, BOOL write_default_attributes)
{
XmlNodeType node_type;
HRESULT hr = S_OK;
TRACE("%p, %p, %d.\n", iface, reader, write_default_attributes);
if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr;
switch (node_type)
{
case XmlNodeType_Element:
case XmlNodeType_XmlDeclaration:
case XmlNodeType_Attribute:
if (node_type != XmlNodeType_Attribute)
{
if (FAILED(hr = IXmlReader_MoveToFirstAttribute(reader))) return hr;
if (hr == S_FALSE) return S_OK;
}
if (FAILED(hr = writer_write_attribute(iface, reader, write_default_attributes))) return hr;
while (IXmlReader_MoveToNextAttribute(reader) == S_OK)
{
if (FAILED(hr = writer_write_attribute(iface, reader, write_default_attributes))) break;
}
if (node_type != XmlNodeType_Attribute && SUCCEEDED(hr))
hr = IXmlReader_MoveToElement(reader);
break;
default:
WARN("Unexpected node type %d.\n", node_type);
return E_UNEXPECTED;
}
return hr;
}
static void write_output_attribute(xmlwriter *writer, const WCHAR *prefix, int prefix_len,
......
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