Module: wine Branch: master Commit: 2b5203bdcdc8be9d07f645a038926bff8c34dcf4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2b5203bdcdc8be9d07f645a038...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);