diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c
index 45f618694e9..8c407bd7819 100644
--- a/dlls/msxml3/saxreader.c
+++ b/dlls/msxml3/saxreader.c
@@ -2413,7 +2413,7 @@ static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream,
saxlocator *locator;
HRESULT hr;
ULONG dataRead;
- char data[1024];
+ char data[2048];
int ret;
dataRead = 0;
@@ -2434,32 +2434,21 @@ static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream,
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);
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;
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 8778bb618fa..05f6b916462 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -376,40 +376,47 @@ static void ok_sequence_(struct call_sequence **seq, int sequence_index,
{
if (expected->id == actual->id)
{
- /* always test position data */
- if (expected->line != actual->line && todo)
+ if (expected->line != -1)
{
- todo_wine
+ /* always test position data */
+ if (expected->line != actual->line && todo)
{
- failcount++;
- ok_(file, line) (FALSE,
+ todo_wine
+ {
+ 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",
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++;
- ok_(file, line) (FALSE,
+ todo_wine
+ {
+ 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",
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)
{
@@ -1001,6 +1008,32 @@ static struct call_entry cdata_test3_alt[] = {
{ 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[] =
""
" Some text data ";
@@ -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)
{
- 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;
+ ok(0, "unexpected call\n");
+ return E_NOTIMPL;
}
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;
}
-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_AddRef,
istream_Release,
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 = "\n";
+ else if(read_cnt < 5)
+ ret_str = "text";
+ else if(read_cnt == 5)
+ ret_str = "\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_Seek,
istream_SetSize,
@@ -1986,7 +2065,7 @@ static const IStreamVtbl StreamVtbl = {
istream_Clone
};
-static IStream mxstream = { &StreamVtbl };
+static IStream instream = { &instreamVtbl };
static struct msxmlsupported_data_t reader_support_data[] =
{
@@ -2157,6 +2236,17 @@ static void test_saxreader(void)
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_BSTR(&var) = SysAllocString(carriage_ret_test);