xmllite/writer: Implement ByteOrderMark property.
This commit is contained in:
parent
9a2177ff53
commit
086a1e3709
@ -405,6 +405,78 @@ static void test_omitxmldeclaration(void)
|
|||||||
IXmlWriter_Release(writer);
|
IXmlWriter_Release(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_bom(void)
|
||||||
|
{
|
||||||
|
static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
|
||||||
|
static const WCHAR utf16W[] = {'u','t','f','-','1','6',0};
|
||||||
|
static const WCHAR xmlW[] = {'x','m','l',0};
|
||||||
|
IXmlWriterOutput *output;
|
||||||
|
unsigned char *ptr;
|
||||||
|
IXmlWriter *writer;
|
||||||
|
IStream *stream;
|
||||||
|
HGLOBAL hglobal;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = pCreateXmlWriterOutputWithEncodingName((IUnknown*)stream, NULL, utf16W, &output);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
|
||||||
|
hr = pCreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
|
||||||
|
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_SetOutput(writer, output);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* BOM is on by default */
|
||||||
|
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(ptr[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]);
|
||||||
|
GlobalUnlock(hglobal);
|
||||||
|
|
||||||
|
IStream_Release(stream);
|
||||||
|
IUnknown_Release(output);
|
||||||
|
|
||||||
|
/* start with PI */
|
||||||
|
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = pCreateXmlWriterOutputWithEncodingName((IUnknown*)stream, NULL, utf16W, &output);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
|
||||||
|
hr = IXmlWriter_SetOutput(writer, output);
|
||||||
|
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_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[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]);
|
||||||
|
GlobalUnlock(hglobal);
|
||||||
|
|
||||||
|
IUnknown_Release(output);
|
||||||
|
IXmlWriter_Release(writer);
|
||||||
|
IStream_Release(stream);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(writer)
|
START_TEST(writer)
|
||||||
{
|
{
|
||||||
if (!init_pointers())
|
if (!init_pointers())
|
||||||
@ -415,4 +487,5 @@ START_TEST(writer)
|
|||||||
test_writestartdocument();
|
test_writestartdocument();
|
||||||
test_flush();
|
test_flush();
|
||||||
test_omitxmldeclaration();
|
test_omitxmldeclaration();
|
||||||
|
test_bom();
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ typedef struct _xmlwriter
|
|||||||
BOOL omitxmldecl;
|
BOOL omitxmldecl;
|
||||||
XmlConformanceLevel conformance;
|
XmlConformanceLevel conformance;
|
||||||
XmlWriterState state;
|
XmlWriterState state;
|
||||||
|
BOOL bomwritten;
|
||||||
} xmlwriter;
|
} xmlwriter;
|
||||||
|
|
||||||
static inline xmlwriter *impl_from_IXmlWriter(IXmlWriter *iface)
|
static inline xmlwriter *impl_from_IXmlWriter(IXmlWriter *iface)
|
||||||
@ -272,6 +273,26 @@ static HRESULT writeroutput_flush_stream(xmlwriteroutput *output)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT write_encoding_bom(xmlwriter *writer)
|
||||||
|
{
|
||||||
|
if (!writer->bom || writer->bomwritten) return S_OK;
|
||||||
|
|
||||||
|
if (writer->output->encoding == XmlEncoding_UTF16) {
|
||||||
|
static const char utf16bom[] = {0xff, 0xfe};
|
||||||
|
struct output_buffer *buffer = &writer->output->buffer;
|
||||||
|
int len = sizeof(utf16bom);
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = grow_output_buffer(writer->output, len);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
memcpy(buffer->data + buffer->written, utf16bom, len);
|
||||||
|
buffer->written += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer->bomwritten = TRUE;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject)
|
static HRESULT WINAPI xmlwriter_QueryInterface(IXmlWriter *iface, REFIID riid, void **ppvObject)
|
||||||
{
|
{
|
||||||
xmlwriter *This = impl_from_IXmlWriter(iface);
|
xmlwriter *This = impl_from_IXmlWriter(iface);
|
||||||
@ -329,6 +350,7 @@ static HRESULT WINAPI xmlwriter_SetOutput(IXmlWriter *iface, IUnknown *output)
|
|||||||
writeroutput_release_stream(This->output);
|
writeroutput_release_stream(This->output);
|
||||||
IUnknown_Release(&This->output->IXmlWriterOutput_iface);
|
IUnknown_Release(&This->output->IXmlWriterOutput_iface);
|
||||||
This->output = NULL;
|
This->output = NULL;
|
||||||
|
This->bomwritten = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* just reset current output */
|
/* just reset current output */
|
||||||
@ -400,6 +422,9 @@ static HRESULT WINAPI xmlwriter_SetProperty(IXmlWriter *iface, UINT property, LO
|
|||||||
|
|
||||||
switch (property)
|
switch (property)
|
||||||
{
|
{
|
||||||
|
case XmlWriterProperty_ByteOrderMark:
|
||||||
|
This->bom = !!value;
|
||||||
|
break;
|
||||||
case XmlWriterProperty_OmitXmlDeclaration:
|
case XmlWriterProperty_OmitXmlDeclaration:
|
||||||
This->omitxmldecl = !!value;
|
This->omitxmldecl = !!value;
|
||||||
break;
|
break;
|
||||||
@ -574,6 +599,7 @@ static HRESULT WINAPI xmlwriter_WriteProcessingInstruction(IXmlWriter *iface, LP
|
|||||||
if (This->state == XmlWriterState_DocStarted && !strcmpW(name, xmlW))
|
if (This->state == XmlWriterState_DocStarted && !strcmpW(name, xmlW))
|
||||||
return WR_E_INVALIDACTION;
|
return WR_E_INVALIDACTION;
|
||||||
|
|
||||||
|
write_encoding_bom(This);
|
||||||
write_output_buffer(This->output, openpiW, sizeof(openpiW)/sizeof(WCHAR));
|
write_output_buffer(This->output, openpiW, sizeof(openpiW)/sizeof(WCHAR));
|
||||||
write_output_buffer(This->output, name, -1);
|
write_output_buffer(This->output, name, -1);
|
||||||
write_output_buffer(This->output, spaceW, 1);
|
write_output_buffer(This->output, spaceW, 1);
|
||||||
@ -635,6 +661,7 @@ static HRESULT WINAPI xmlwriter_WriteStartDocument(IXmlWriter *iface, XmlStandal
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_encoding_bom(This);
|
||||||
This->state = XmlWriterState_DocStarted;
|
This->state = XmlWriterState_DocStarted;
|
||||||
if (This->omitxmldecl) return S_OK;
|
if (This->omitxmldecl) return S_OK;
|
||||||
|
|
||||||
@ -833,6 +860,7 @@ HRESULT WINAPI CreateXmlWriter(REFIID riid, void **obj, IMalloc *imalloc)
|
|||||||
writer->omitxmldecl = FALSE;
|
writer->omitxmldecl = FALSE;
|
||||||
writer->conformance = XmlConformanceLevel_Document;
|
writer->conformance = XmlConformanceLevel_Document;
|
||||||
writer->state = XmlWriterState_Initial;
|
writer->state = XmlWriterState_Initial;
|
||||||
|
writer->bomwritten = FALSE;
|
||||||
|
|
||||||
*obj = &writer->IXmlWriter_iface;
|
*obj = &writer->IXmlWriter_iface;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user