msxml3: Read stream data until Read fails or returns 0 bytes.
This commit is contained in:
parent
3e033bb130
commit
76ce1f1679
|
@ -2413,7 +2413,7 @@ static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream,
|
||||||
saxlocator *locator;
|
saxlocator *locator;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
ULONG dataRead;
|
ULONG dataRead;
|
||||||
char data[1024];
|
char data[2048];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dataRead = 0;
|
dataRead = 0;
|
||||||
|
@ -2434,32 +2434,21 @@ static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream,
|
||||||
|
|
||||||
This->isParsing = TRUE;
|
This->isParsing = TRUE;
|
||||||
|
|
||||||
if(dataRead != sizeof(data))
|
do {
|
||||||
|
dataRead = 0;
|
||||||
|
hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
|
||||||
|
if (FAILED(hr) || !dataRead) break;
|
||||||
|
|
||||||
|
ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
|
||||||
|
hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
|
||||||
|
}while(hr == S_OK);
|
||||||
|
|
||||||
|
if(SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
|
ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
|
||||||
hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
|
hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
dataRead = 0;
|
|
||||||
hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead);
|
|
||||||
if (FAILED(hr)) break;
|
|
||||||
|
|
||||||
ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
|
|
||||||
hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
|
|
||||||
|
|
||||||
if (hr != S_OK) break;
|
|
||||||
|
|
||||||
if (dataRead != sizeof(data))
|
|
||||||
{
|
|
||||||
ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
|
|
||||||
hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
This->isParsing = FALSE;
|
This->isParsing = FALSE;
|
||||||
|
|
||||||
|
|
|
@ -376,40 +376,47 @@ static void ok_sequence_(struct call_sequence **seq, int sequence_index,
|
||||||
{
|
{
|
||||||
if (expected->id == actual->id)
|
if (expected->id == actual->id)
|
||||||
{
|
{
|
||||||
/* always test position data */
|
if (expected->line != -1)
|
||||||
if (expected->line != actual->line && todo)
|
|
||||||
{
|
{
|
||||||
todo_wine
|
/* always test position data */
|
||||||
|
if (expected->line != actual->line && todo)
|
||||||
{
|
{
|
||||||
failcount++;
|
todo_wine
|
||||||
ok_(file, line) (FALSE,
|
{
|
||||||
|
failcount++;
|
||||||
|
ok_(file, line) (FALSE,
|
||||||
|
"%s: in event %s expecting line %d got %d\n",
|
||||||
|
context, get_event_name(actual->id), expected->line, actual->line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok_(file, line) (expected->line == actual->line,
|
||||||
"%s: in event %s expecting line %d got %d\n",
|
"%s: in event %s expecting line %d got %d\n",
|
||||||
context, get_event_name(actual->id), expected->line, actual->line);
|
context, get_event_name(actual->id), expected->line, actual->line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ok_(file, line) (expected->line == actual->line,
|
|
||||||
"%s: in event %s expecting line %d got %d\n",
|
|
||||||
context, get_event_name(actual->id), expected->line, actual->line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expected->column != actual->column && todo)
|
|
||||||
|
if (expected->column != -1)
|
||||||
{
|
{
|
||||||
todo_wine
|
if (expected->column != actual->column && todo)
|
||||||
{
|
{
|
||||||
failcount++;
|
todo_wine
|
||||||
ok_(file, line) (FALSE,
|
{
|
||||||
|
failcount++;
|
||||||
|
ok_(file, line) (FALSE,
|
||||||
|
"%s: in event %s expecting column %d got %d\n",
|
||||||
|
context, get_event_name(actual->id), expected->column, actual->column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok_(file, line) (expected->column == actual->column,
|
||||||
"%s: in event %s expecting column %d got %d\n",
|
"%s: in event %s expecting column %d got %d\n",
|
||||||
context, get_event_name(actual->id), expected->column, actual->column);
|
context, get_event_name(actual->id), expected->column, actual->column);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ok_(file, line) (expected->column == actual->column,
|
|
||||||
"%s: in event %s expecting column %d got %d\n",
|
|
||||||
context, get_event_name(actual->id), expected->column, actual->column);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (actual->id)
|
switch (actual->id)
|
||||||
{
|
{
|
||||||
|
@ -1001,6 +1008,32 @@ static struct call_entry cdata_test3_alt[] = {
|
||||||
{ CH_ENDTEST }
|
{ CH_ENDTEST }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct attribute_entry read_test_attrs[] = {
|
||||||
|
{ "", "attr", "attr", "val" },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct call_entry read_test_seq[] = {
|
||||||
|
{ CH_PUTDOCUMENTLOCATOR, -1, 0, S_OK },
|
||||||
|
{ CH_STARTDOCUMENT, -1, -1, S_OK },
|
||||||
|
{ CH_STARTELEMENT, -1, -1, S_OK, "", "rootelem", "rootelem" },
|
||||||
|
{ CH_STARTELEMENT, -1, -1, S_OK, "", "elem", "elem", read_test_attrs },
|
||||||
|
{ CH_CHARACTERS, -1, -1, S_OK, "text" },
|
||||||
|
{ CH_ENDELEMENT, -1, -1, S_OK, "", "elem", "elem" },
|
||||||
|
{ CH_STARTELEMENT, -1, -1, S_OK, "", "elem", "elem", read_test_attrs },
|
||||||
|
{ CH_CHARACTERS, -1, -1, S_OK, "text" },
|
||||||
|
{ CH_ENDELEMENT, -1, -1, S_OK, "", "elem", "elem" },
|
||||||
|
{ CH_STARTELEMENT, -1, -1, S_OK, "", "elem", "elem", read_test_attrs },
|
||||||
|
{ CH_CHARACTERS, -1, -1, S_OK, "text" },
|
||||||
|
{ CH_ENDELEMENT, -1, -1, S_OK, "", "elem", "elem" },
|
||||||
|
{ CH_STARTELEMENT, -1, -1, S_OK, "", "elem", "elem", read_test_attrs },
|
||||||
|
{ CH_CHARACTERS, -1, -1, S_OK, "text" },
|
||||||
|
{ CH_ENDELEMENT, -1, -1, S_OK, "", "elem", "elem" },
|
||||||
|
{ CH_ENDELEMENT, -1, -1, S_OK, "", "rootelem", "rootelem" },
|
||||||
|
{ CH_ENDDOCUMENT, -1, -1, S_OK},
|
||||||
|
{ CH_ENDTEST }
|
||||||
|
};
|
||||||
|
|
||||||
static const char xmlspace_attr[] =
|
static const char xmlspace_attr[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
|
"<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
|
||||||
"<a xml:space=\"preserve\"> Some text data </a>";
|
"<a xml:space=\"preserve\"> Some text data </a>";
|
||||||
|
@ -1884,31 +1917,8 @@ static HRESULT WINAPI istream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pc
|
||||||
|
|
||||||
static HRESULT WINAPI istream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
|
static HRESULT WINAPI istream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
|
||||||
{
|
{
|
||||||
BOOL fail = FALSE;
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
ok(pv != NULL, "pv == NULL\n");
|
|
||||||
|
|
||||||
if(current_write_test->last) {
|
|
||||||
ok(0, "Too many Write calls made on test %d\n", current_stream_test_index);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fail = current_write_test->fail_write;
|
|
||||||
|
|
||||||
ok(current_write_test->cb == cb, "Expected %d, but got %d on test %d\n",
|
|
||||||
current_write_test->cb, cb, current_stream_test_index);
|
|
||||||
|
|
||||||
if(!pcbWritten)
|
|
||||||
ok(current_write_test->null_written, "pcbWritten was NULL on test %d\n", current_stream_test_index);
|
|
||||||
else
|
|
||||||
ok(!memcmp(current_write_test->data, pv, cb), "Unexpected data on test %d\n", current_stream_test_index);
|
|
||||||
|
|
||||||
++current_write_test;
|
|
||||||
|
|
||||||
if(pcbWritten)
|
|
||||||
*pcbWritten = cb;
|
|
||||||
|
|
||||||
return fail ? E_FAIL : S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin,
|
static HRESULT WINAPI istream_Seek(IStream *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin,
|
||||||
|
@ -1969,11 +1979,80 @@ static HRESULT WINAPI istream_Clone(IStream *iface, IStream **ppstm)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IStreamVtbl StreamVtbl = {
|
static HRESULT WINAPI mxstream_Write(IStream *iface, const void *pv, ULONG cb, ULONG *pcbWritten)
|
||||||
|
{
|
||||||
|
BOOL fail = FALSE;
|
||||||
|
|
||||||
|
ok(pv != NULL, "pv == NULL\n");
|
||||||
|
|
||||||
|
if(current_write_test->last) {
|
||||||
|
ok(0, "Too many Write calls made on test %d\n", current_stream_test_index);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail = current_write_test->fail_write;
|
||||||
|
|
||||||
|
ok(current_write_test->cb == cb, "Expected %d, but got %d on test %d\n",
|
||||||
|
current_write_test->cb, cb, current_stream_test_index);
|
||||||
|
|
||||||
|
if(!pcbWritten)
|
||||||
|
ok(current_write_test->null_written, "pcbWritten was NULL on test %d\n", current_stream_test_index);
|
||||||
|
else
|
||||||
|
ok(!memcmp(current_write_test->data, pv, cb), "Unexpected data on test %d\n", current_stream_test_index);
|
||||||
|
|
||||||
|
++current_write_test;
|
||||||
|
|
||||||
|
if(pcbWritten)
|
||||||
|
*pcbWritten = cb;
|
||||||
|
|
||||||
|
return fail ? E_FAIL : S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IStreamVtbl mxstreamVtbl = {
|
||||||
istream_QueryInterface,
|
istream_QueryInterface,
|
||||||
istream_AddRef,
|
istream_AddRef,
|
||||||
istream_Release,
|
istream_Release,
|
||||||
istream_Read,
|
istream_Read,
|
||||||
|
mxstream_Write,
|
||||||
|
istream_Seek,
|
||||||
|
istream_SetSize,
|
||||||
|
istream_CopyTo,
|
||||||
|
istream_Commit,
|
||||||
|
istream_Revert,
|
||||||
|
istream_LockRegion,
|
||||||
|
istream_UnlockRegion,
|
||||||
|
istream_Stat,
|
||||||
|
istream_Clone
|
||||||
|
};
|
||||||
|
|
||||||
|
static IStream mxstream = { &mxstreamVtbl };
|
||||||
|
|
||||||
|
static int read_cnt;
|
||||||
|
|
||||||
|
static HRESULT WINAPI instream_Read(IStream *iface, void *pv, ULONG cb, ULONG *pcbRead)
|
||||||
|
{
|
||||||
|
static const char *ret_str;
|
||||||
|
|
||||||
|
if(!read_cnt)
|
||||||
|
ret_str = "<?xml version=\"1.0\" ?>\n<rootelem>";
|
||||||
|
else if(read_cnt < 5)
|
||||||
|
ret_str = "<elem attr=\"val\">text</elem>";
|
||||||
|
else if(read_cnt == 5)
|
||||||
|
ret_str = "</rootelem>\n";
|
||||||
|
else
|
||||||
|
ret_str = "";
|
||||||
|
|
||||||
|
read_cnt++;
|
||||||
|
strcpy(pv, ret_str);
|
||||||
|
*pcbRead = strlen(ret_str);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IStreamVtbl instreamVtbl = {
|
||||||
|
istream_QueryInterface,
|
||||||
|
istream_AddRef,
|
||||||
|
istream_Release,
|
||||||
|
instream_Read,
|
||||||
istream_Write,
|
istream_Write,
|
||||||
istream_Seek,
|
istream_Seek,
|
||||||
istream_SetSize,
|
istream_SetSize,
|
||||||
|
@ -1986,7 +2065,7 @@ static const IStreamVtbl StreamVtbl = {
|
||||||
istream_Clone
|
istream_Clone
|
||||||
};
|
};
|
||||||
|
|
||||||
static IStream mxstream = { &StreamVtbl };
|
static IStream instream = { &instreamVtbl };
|
||||||
|
|
||||||
static struct msxmlsupported_data_t reader_support_data[] =
|
static struct msxmlsupported_data_t reader_support_data[] =
|
||||||
{
|
{
|
||||||
|
@ -2157,6 +2236,17 @@ static void test_saxreader(void)
|
||||||
|
|
||||||
IStream_Release(stream);
|
IStream_Release(stream);
|
||||||
|
|
||||||
|
V_VT(&var) = VT_UNKNOWN;
|
||||||
|
V_UNKNOWN(&var) = (IUnknown*)&instream;
|
||||||
|
|
||||||
|
test_seq = read_test_seq;
|
||||||
|
read_cnt = 0;
|
||||||
|
set_expected_seq(test_seq);
|
||||||
|
hr = ISAXXMLReader_parse(reader, var);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(read_cnt == 7, "read_cnt = %d\n", read_cnt);
|
||||||
|
ok_sequence(sequences, CONTENT_HANDLER_INDEX, test_seq, "Read call test", FALSE);
|
||||||
|
|
||||||
V_VT(&var) = VT_BSTR;
|
V_VT(&var) = VT_BSTR;
|
||||||
V_BSTR(&var) = SysAllocString(carriage_ret_test);
|
V_BSTR(&var) = SysAllocString(carriage_ret_test);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue