mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 12:54:13 +00:00
msxml3: Support startDTD()/endDTD() in MXWriter.
This commit is contained in:
parent
23c3d90866
commit
6106afe359
2 changed files with 153 additions and 13 deletions
|
@ -41,6 +41,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
||||||
|
|
||||||
static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
|
static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
|
||||||
static const WCHAR emptyW[] = {0};
|
static const WCHAR emptyW[] = {0};
|
||||||
|
static const WCHAR spaceW[] = {' '};
|
||||||
|
static const WCHAR quotW[] = {'\"'};
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -266,10 +268,10 @@ static void close_output_buffer(mxwriter *This)
|
||||||
*/
|
*/
|
||||||
static WCHAR *get_escaped_string(const WCHAR *str, int *len)
|
static WCHAR *get_escaped_string(const WCHAR *str, int *len)
|
||||||
{
|
{
|
||||||
static const WCHAR ltW[] = {'&','l','t',';'};
|
static const WCHAR ltW[] = {'&','l','t',';'};
|
||||||
static const WCHAR ampW[] = {'&','a','m','p',';'};
|
static const WCHAR ampW[] = {'&','a','m','p',';'};
|
||||||
static const WCHAR quotW[] = {'&','q','u','o','t',';'};
|
static const WCHAR equotW[] = {'&','q','u','o','t',';'};
|
||||||
static const WCHAR gtW[] = {'&','g','t',';'};
|
static const WCHAR gtW[] = {'&','g','t',';'};
|
||||||
|
|
||||||
const int default_alloc = 100;
|
const int default_alloc = 100;
|
||||||
const int grow_thresh = 10;
|
const int grow_thresh = 10;
|
||||||
|
@ -301,8 +303,8 @@ static WCHAR *get_escaped_string(const WCHAR *str, int *len)
|
||||||
ptr += sizeof(ampW)/sizeof(WCHAR);
|
ptr += sizeof(ampW)/sizeof(WCHAR);
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
memcpy(ptr, quotW, sizeof(quotW));
|
memcpy(ptr, equotW, sizeof(equotW));
|
||||||
ptr += sizeof(quotW)/sizeof(WCHAR);
|
ptr += sizeof(equotW)/sizeof(WCHAR);
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
memcpy(ptr, gtW, sizeof(gtW));
|
memcpy(ptr, gtW, sizeof(gtW));
|
||||||
|
@ -330,7 +332,6 @@ static void write_prolog_buffer(const mxwriter *This)
|
||||||
static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
|
static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
|
||||||
static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
|
static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
|
||||||
static const WCHAR noW[] = {'n','o','\"','?','>'};
|
static const WCHAR noW[] = {'n','o','\"','?','>'};
|
||||||
static const WCHAR quotW[] = {'\"'};
|
|
||||||
static const WCHAR crlfW[] = {'\r','\n'};
|
static const WCHAR crlfW[] = {'\r','\n'};
|
||||||
|
|
||||||
/* version */
|
/* version */
|
||||||
|
@ -951,9 +952,7 @@ static HRESULT WINAPI SAXContentHandler_startElement(
|
||||||
|
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
static const WCHAR spaceW[] = {' '};
|
|
||||||
static const WCHAR eqqW[] = {'=','\"'};
|
static const WCHAR eqqW[] = {'=','\"'};
|
||||||
static const WCHAR quotW[] = {'\"'};
|
|
||||||
const WCHAR *str;
|
const WCHAR *str;
|
||||||
WCHAR *escaped;
|
WCHAR *escaped;
|
||||||
INT len = 0;
|
INT len = 0;
|
||||||
|
@ -1114,17 +1113,72 @@ static HRESULT WINAPI SAXLexicalHandler_startDTD(ISAXLexicalHandler *iface,
|
||||||
const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
|
const WCHAR *name, int name_len, const WCHAR *publicId, int publicId_len,
|
||||||
const WCHAR *systemId, int systemId_len)
|
const WCHAR *systemId, int systemId_len)
|
||||||
{
|
{
|
||||||
|
static const WCHAR doctypeW[] = {'<','!','D','O','C','T','Y','P','E',' '};
|
||||||
|
static const WCHAR openintW[] = {'[','\r','\n'};
|
||||||
|
|
||||||
mxwriter *This = impl_from_ISAXLexicalHandler( iface );
|
mxwriter *This = impl_from_ISAXLexicalHandler( iface );
|
||||||
FIXME("(%p)->(%s %s %s): stub\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
|
|
||||||
|
TRACE("(%p)->(%s %s %s)\n", This, debugstr_wn(name, name_len), debugstr_wn(publicId, publicId_len),
|
||||||
debugstr_wn(systemId, systemId_len));
|
debugstr_wn(systemId, systemId_len));
|
||||||
return E_NOTIMPL;
|
|
||||||
|
if (!name) return E_INVALIDARG;
|
||||||
|
|
||||||
|
write_output_buffer(This->buffer, doctypeW, sizeof(doctypeW)/sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (*name)
|
||||||
|
{
|
||||||
|
write_output_buffer(This->buffer, name, name_len);
|
||||||
|
write_output_buffer(This->buffer, spaceW, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (publicId)
|
||||||
|
{
|
||||||
|
static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
|
||||||
|
|
||||||
|
write_output_buffer(This->buffer, publicW, sizeof(publicW)/sizeof(WCHAR));
|
||||||
|
write_output_buffer(This->buffer, quotW, 1);
|
||||||
|
write_output_buffer(This->buffer, publicId, publicId_len);
|
||||||
|
write_output_buffer(This->buffer, quotW, 1);
|
||||||
|
|
||||||
|
if (!systemId) return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (*publicId)
|
||||||
|
write_output_buffer(This->buffer, spaceW, 1);
|
||||||
|
|
||||||
|
write_output_buffer(This->buffer, quotW, 1);
|
||||||
|
write_output_buffer(This->buffer, systemId, systemId_len);
|
||||||
|
write_output_buffer(This->buffer, quotW, 1);
|
||||||
|
|
||||||
|
if (*systemId)
|
||||||
|
write_output_buffer(This->buffer, spaceW, 1);
|
||||||
|
}
|
||||||
|
else if (systemId)
|
||||||
|
{
|
||||||
|
static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
|
||||||
|
|
||||||
|
write_output_buffer(This->buffer, systemW, sizeof(systemW)/sizeof(WCHAR));
|
||||||
|
write_output_buffer(This->buffer, quotW, 1);
|
||||||
|
write_output_buffer(This->buffer, systemId, systemId_len);
|
||||||
|
write_output_buffer(This->buffer, quotW, 1);
|
||||||
|
if (*systemId)
|
||||||
|
write_output_buffer(This->buffer, spaceW, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_output_buffer(This->buffer, openintW, sizeof(openintW)/sizeof(WCHAR));
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
|
static HRESULT WINAPI SAXLexicalHandler_endDTD(ISAXLexicalHandler *iface)
|
||||||
{
|
{
|
||||||
mxwriter *This = impl_from_ISAXLexicalHandler( iface );
|
mxwriter *This = impl_from_ISAXLexicalHandler( iface );
|
||||||
FIXME("(%p): stub\n", This);
|
static const WCHAR closedtdW[] = {']','>','\r','\n'};
|
||||||
return E_NOTIMPL;
|
|
||||||
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
|
write_output_buffer(This->buffer, closedtdW, sizeof(closedtdW)/sizeof(WCHAR));
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
|
static HRESULT WINAPI SAXLexicalHandler_startEntity(ISAXLexicalHandler *iface, const WCHAR *name, int len)
|
||||||
|
|
|
@ -2956,7 +2956,92 @@ static void test_mxwriter_cdata(void)
|
||||||
ISAXLexicalHandler_Release(lexical);
|
ISAXLexicalHandler_Release(lexical);
|
||||||
IMXWriter_Release(writer);
|
IMXWriter_Release(writer);
|
||||||
free_bstrs();
|
free_bstrs();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_mxwriter_dtd(void)
|
||||||
|
{
|
||||||
|
static const WCHAR nameW[] = {'n','a','m','e'};
|
||||||
|
static const WCHAR pubW[] = {'p','u','b'};
|
||||||
|
static const WCHAR sysW[] = {'s','y','s'};
|
||||||
|
ISAXContentHandler *content;
|
||||||
|
ISAXLexicalHandler *lexical;
|
||||||
|
IMXWriter *writer;
|
||||||
|
VARIANT dest;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IMXWriter, (void**)&writer);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
hr = IMXWriter_QueryInterface(writer, &IID_ISAXLexicalHandler, (void**)&lexical);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
hr = ISAXContentHandler_startDocument(content);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
hr = ISAXLexicalHandler_startDTD(lexical, NULL, 0, NULL, 0, NULL, 0);
|
||||||
|
EXPECT_HR(hr, E_INVALIDARG);
|
||||||
|
|
||||||
|
hr = ISAXLexicalHandler_startDTD(lexical, NULL, 0, pubW, sizeof(pubW)/sizeof(WCHAR), NULL, 0);
|
||||||
|
EXPECT_HR(hr, E_INVALIDARG);
|
||||||
|
|
||||||
|
hr = ISAXLexicalHandler_startDTD(lexical, NULL, 0, NULL, 0, sysW, sizeof(sysW)/sizeof(WCHAR));
|
||||||
|
EXPECT_HR(hr, E_INVALIDARG);
|
||||||
|
|
||||||
|
hr = ISAXLexicalHandler_startDTD(lexical, NULL, 0, pubW, sizeof(pubW)/sizeof(WCHAR), sysW, sizeof(sysW)/sizeof(WCHAR));
|
||||||
|
EXPECT_HR(hr, E_INVALIDARG);
|
||||||
|
|
||||||
|
hr = ISAXLexicalHandler_startDTD(lexical, nameW, sizeof(nameW)/sizeof(WCHAR), NULL, 0, NULL, 0);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
V_VT(&dest) = VT_EMPTY;
|
||||||
|
hr = IMXWriter_get_output(writer, &dest);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
|
||||||
|
ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
|
||||||
|
VariantClear(&dest);
|
||||||
|
|
||||||
|
/* system id is required if public is present */
|
||||||
|
hr = ISAXLexicalHandler_startDTD(lexical, nameW, sizeof(nameW)/sizeof(WCHAR), pubW, sizeof(pubW)/sizeof(WCHAR), NULL, 0);
|
||||||
|
EXPECT_HR(hr, E_INVALIDARG);
|
||||||
|
|
||||||
|
hr = ISAXLexicalHandler_startDTD(lexical, nameW, sizeof(nameW)/sizeof(WCHAR),
|
||||||
|
pubW, sizeof(pubW)/sizeof(WCHAR), sysW, sizeof(sysW)/sizeof(WCHAR));
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
V_VT(&dest) = VT_EMPTY;
|
||||||
|
hr = IMXWriter_get_output(writer, &dest);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
|
||||||
|
ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n<!DOCTYPE name PUBLIC \"pub\""
|
||||||
|
"<!DOCTYPE name PUBLIC \"pub\" \"sys\" [\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
|
||||||
|
VariantClear(&dest);
|
||||||
|
|
||||||
|
hr = ISAXLexicalHandler_endDTD(lexical);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
hr = ISAXLexicalHandler_endDTD(lexical);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
V_VT(&dest) = VT_EMPTY;
|
||||||
|
hr = IMXWriter_get_output(writer, &dest);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
|
||||||
|
ok(!lstrcmpW(_bstr_("<!DOCTYPE name [\r\n<!DOCTYPE name PUBLIC \"pub\""
|
||||||
|
"<!DOCTYPE name PUBLIC \"pub\" \"sys\" [\r\n]>\r\n]>\r\n"),
|
||||||
|
V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
|
||||||
|
VariantClear(&dest);
|
||||||
|
|
||||||
|
ISAXContentHandler_Release(content);
|
||||||
|
ISAXLexicalHandler_Release(lexical);
|
||||||
|
IMXWriter_Release(writer);
|
||||||
|
free_bstrs();
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(saxreader)
|
START_TEST(saxreader)
|
||||||
|
@ -2996,6 +3081,7 @@ START_TEST(saxreader)
|
||||||
test_mxwriter_characters();
|
test_mxwriter_characters();
|
||||||
test_mxwriter_comment();
|
test_mxwriter_comment();
|
||||||
test_mxwriter_cdata();
|
test_mxwriter_cdata();
|
||||||
|
test_mxwriter_dtd();
|
||||||
test_mxwriter_properties();
|
test_mxwriter_properties();
|
||||||
test_mxwriter_flush();
|
test_mxwriter_flush();
|
||||||
test_mxwriter_stream();
|
test_mxwriter_stream();
|
||||||
|
|
Loading…
Reference in a new issue