Jacek Caban : xmllite: Fixed ReadValueChunk implementation.
Alexandre Julliard
julliard at winehq.org
Wed Mar 22 15:52:35 CDT 2017
Module: wine
Branch: master
Commit: 2b5203bdcdc8be9d07f645a038926bff8c34dcf4
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2b5203bdcdc8be9d07f645a038926bff8c34dcf4
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Mar 21 16:19:24 2017 +0100
xmllite: Fixed ReadValueChunk implementation.
Mostly copy all characters to output buffer, but also minor fixes to
returned values found by tests.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/xmllite/reader.c | 11 ++++---
dlls/xmllite/tests/reader.c | 72 +++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 74 insertions(+), 9 deletions(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index c33d9bf..478830d 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -3328,18 +3328,17 @@ static HRESULT WINAPI xmlreader_ReadValueChunk(IXmlReader* iface, WCHAR *buffer,
TRACE("(%p)->(%p %u %p)\n", reader, buffer, chunk_size, read);
/* Value is already allocated, chunked reads are not possible. */
- if (val->str) return S_FALSE;
+ len = !val->str && val->len ? min(chunk_size, val->len) : 0;
+ if (read) *read = len;
- if (val->len)
+ if (len)
{
- len = min(chunk_size, val->len);
- memcpy(buffer, reader_get_ptr2(reader, val->start), len);
+ memcpy(buffer, reader_get_ptr2(reader, val->start), len*sizeof(WCHAR));
val->start += len;
val->len -= len;
- if (read) *read = len;
}
- return S_OK;
+ return len || !chunk_size ? S_OK : S_FALSE;
}
static HRESULT WINAPI xmlreader_GetBaseUri(IXmlReader* iface,
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index 47192f9..e91383f 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -46,6 +46,14 @@ static void free_str(WCHAR *str)
HeapFree(GetProcessHeap(), 0, str);
}
+static int strcmp_wa(const WCHAR *str1, const char *stra)
+{
+ WCHAR *str2 = a2w(stra);
+ int r = lstrcmpW(str1, str2);
+ free_str(str2);
+ return r;
+}
+
static const char xmldecl_full[] = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
static const char xmldecl_short[] = "<?xml version=\"1.0\"?><RegistrationInfo/>";
@@ -1643,11 +1651,12 @@ todo_wine
static void test_readvaluechunk(void)
{
- static const char testA[] = "<!-- comment1 -->";
+ static const char testA[] = "<!-- comment1 --><!-- comment2 -->";
IXmlReader *reader;
XmlNodeType type;
IStream *stream;
const WCHAR *value;
+ WCHAR buf[64];
WCHAR b;
HRESULT hr;
UINT c;
@@ -1661,6 +1670,7 @@ static void test_readvaluechunk(void)
hr = IXmlReader_Read(reader, &type);
ok(hr == S_OK, "got %08x\n", hr);
+ ok(type == XmlNodeType_Comment, "type = %u\n", type);
c = 0;
b = 0;
@@ -1669,11 +1679,18 @@ static void test_readvaluechunk(void)
ok(c == 1, "got %u\n", c);
ok(b == ' ', "got %x\n", b);
+ c = 0;
+ b = 0xffff;
+ hr = IXmlReader_ReadValueChunk(reader, &b, 1, &c);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(c == 1, "got %u\n", c);
+ ok(b == 'c', "got %x\n", b);
+
/* portion read as chunk is skipped from resulting node value */
value = NULL;
hr = IXmlReader_GetValue(reader, &value, NULL);
ok(hr == S_OK, "got %08x\n", hr);
- ok(value[0] == 'c', "got %s\n", wine_dbgstr_w(value));
+ ok(!strcmp_wa(value, "omment1 "), "got %s\n", wine_dbgstr_w(value));
/* once value is returned/allocated it's not possible to read by chunk */
c = 0;
@@ -1683,10 +1700,59 @@ static void test_readvaluechunk(void)
ok(c == 0, "got %u\n", c);
ok(b == 0, "got %x\n", b);
+ c = 0xdeadbeef;
+ hr = IXmlReader_ReadValueChunk(reader, buf, 0, &c);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(!c, "c = %u\n", c);
+
+ value = NULL;
+ hr = IXmlReader_GetValue(reader, &value, NULL);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(!strcmp_wa(value, "omment1 "), "got %s\n", wine_dbgstr_w(value));
+
+ /* read comment2 */
+ hr = IXmlReader_Read(reader, &type);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(type == XmlNodeType_Comment, "type = %u\n", type);
+
+ c = 0xdeadbeef;
+ hr = IXmlReader_ReadValueChunk(reader, buf, 0, &c);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(!c, "c = %u\n", c);
+
+ c = 0xdeadbeef;
+ memset(buf, 0xcc, sizeof(buf));
+ hr = IXmlReader_ReadValueChunk(reader, buf, sizeof(buf)/sizeof(WCHAR), &c);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(c == 10, "got %u\n", c);
+ ok(buf[c] == 0xcccc, "buffer overflow\n");
+ buf[c] = 0;
+ ok(!strcmp_wa(buf, " comment2 "), "buf = %s\n", wine_dbgstr_w(buf));
+
+ c = 0xdeadbeef;
+ memset(buf, 0xcc, sizeof(buf));
+ hr = IXmlReader_ReadValueChunk(reader, buf, sizeof(buf)/sizeof(WCHAR), &c);
+ ok(hr == S_FALSE, "got %08x\n", hr);
+ ok(!c, "got %u\n", c);
+
+ /* portion read as chunk is skipped from resulting node value */
+ value = NULL;
+ hr = IXmlReader_GetValue(reader, &value, NULL);
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(!*value, "got %s\n", wine_dbgstr_w(value));
+
+ /* once value is returned/allocated it's not possible to read by chunk */
+ c = 0xdeadbeef;
+ b = 0xffff;
+ hr = IXmlReader_ReadValueChunk(reader, &b, 1, &c);
+ ok(hr == S_FALSE, "got %08x\n", hr);
+ ok(c == 0, "got %u\n", c);
+ ok(b == 0xffff, "got %x\n", b);
+
value = NULL;
hr = IXmlReader_GetValue(reader, &value, NULL);
ok(hr == S_OK, "got %08x\n", hr);
- ok(value[0] == 'c', "got %s\n", wine_dbgstr_w(value));
+ ok(!*value, "got %s\n", wine_dbgstr_w(value));
IXmlReader_Release(reader);
IStream_Release(stream);
More information about the wine-cvs
mailing list