Module: wine Branch: master Commit: 0d78a883c00f60010db254d14c82e7ac26f92d08 URL: http://source.winehq.org/git/wine.git/?a=commit;h=0d78a883c00f60010db254d14c...
Author: Piotr Caban piotr.caban@gmail.com Date: Wed Nov 18 00:51:40 2009 +0100
msxml3: Implemented xmlnode_get_nodeTypedValue date related data types handling.
---
dlls/msxml3/node.c | 67 ++++++++++++++++++++++++++++++++++++++++ dlls/msxml3/tests/domdoc.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 0 deletions(-)
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index f293154..4910605 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -957,6 +957,73 @@ inline HRESULT VARIANT_from_xmlChar(xmlChar *str, VARIANT *v, BSTR type) if(!V_BSTR(v)) return E_OUTOFMEMORY; } + else if(!lstrcmpiW(type, szDateTime) || !lstrcmpiW(type, szDateTimeTZ) || + !lstrcmpiW(type, szDate) || !lstrcmpiW(type, szTime) || + !lstrcmpiW(type, szTimeTZ)) + { + VARIANT src; + WCHAR *p, *e; + SYSTEMTIME st; + DOUBLE date = 0.0; + + st.wYear = 1899; + st.wMonth = 12; + st.wDay = 30; + st.wDayOfWeek = st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0; + + V_VT(&src) = VT_BSTR; + V_BSTR(&src) = bstr_from_xmlChar(str); + + if(!V_BSTR(&src)) + return E_OUTOFMEMORY; + + p = V_BSTR(&src); + e = p + SysStringLen(V_BSTR(&src)); + + if(p+4<e && *(p+4)=='-') /* parse date (yyyy-mm-dd) */ + { + st.wYear = atoiW(p); + st.wMonth = atoiW(p+5); + st.wDay = atoiW(p+8); + p += 10; + + if(*p == 'T') p++; + } + + if(p+2<e && *(p+2)==':') /* parse time (hh:mm:ss.?) */ + { + st.wHour = atoiW(p); + st.wMinute = atoiW(p+3); + st.wSecond = atoiW(p+6); + p += 8; + + if(*p == '.') + { + int ms; + + p++; + ms = (*(p++) - '0') * 10; + if(isdigitW(*p)) ms += *(p++) - '0'; + ms *= 10; + if(isdigitW(*p)) ms += *(p++) - '0'; + + st.wMilliseconds = ms; + + while(isdigitW(*p)) p++; + } + } + + SystemTimeToVariantTime(&st, &date); + V_VT(v) = VT_DATE; + V_DATE(v) = date; + + if(*p == '+') /* parse timezone offset (+hh:mm) */ + V_DATE(v) += (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440; + else if(*p == '-') /* parse timezone offset (-hh:mm) */ + V_DATE(v) -= (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440; + + VariantClear(&src); + } else { VARIANT src; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 8efbddd..7c8fddf 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -156,6 +156,11 @@ static const CHAR szTypeValueXML[] = " <int dt:dt="int">-13</int>\n" " <fixed dt:dt="fixed.14.4">7322.9371</fixed>\n" " <bool dt:dt="boolean">1</bool>\n" +" <datetime dt:dt="datetime">2009-11-18T03:21:33.12</datetime>\n" +" <datetimetz dt:dt="datetime.tz">2003-07-11T11:13:57+03:00</datetimetz>\n" +" <date dt:dt="date">3721-11-01</date>\n" +" <time dt:dt="time">13:57:12.31321</time>\n" +" <timetz dt:dt="time.tz">23:21:01.13+03:21</timetz>\n" "</root>";
static const CHAR szBasicTransformSSXMLPart1[] = @@ -252,6 +257,8 @@ static WCHAR szStrangeChars[] = {'&','x',' ',0x2103, 0}; ok(r == (expect), #expr " returned %x, expected %x\n", r, expect); \ }
+#define double_eq(x, y) ok((x)-(y)<=1e-14*(x) && (x)-(y)>=-1e-14*(x), "expected %.16g, got %.16g\n", x, y) + static BSTR alloc_str_from_narrow(const char *str) { int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); @@ -4087,6 +4094,71 @@ static void test_NodeTypeValue(void)
IXMLDOMNode_Release(pNode); } + + hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/datetime"), &pNode); + ok(hr == S_OK, "ret %08x\n", hr ); + if(hr == S_OK) + { + hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v); + ok(hr == S_OK, "ret %08x\n", hr ); + ok(V_VT(&v) == VT_DATE, "incorrect type\n"); + double_eq(40135.13996666666, V_DATE(&v)); + VariantClear( &v ); + + IXMLDOMNode_Release(pNode); + } + + hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/datetimetz"), &pNode); + ok(hr == S_OK, "ret %08x\n", hr ); + if(hr == S_OK) + { + hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v); + ok(hr == S_OK, "ret %08x\n", hr ); + ok(V_VT(&v) == VT_DATE, "incorrect type\n"); + double_eq(37813.59302083334, V_DATE(&v)); + VariantClear( &v ); + + IXMLDOMNode_Release(pNode); + } + + hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/date"), &pNode); + ok(hr == S_OK, "ret %08x\n", hr ); + if(hr == S_OK) + { + hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v); + ok(hr == S_OK, "ret %08x\n", hr ); + ok(V_VT(&v) == VT_DATE, "incorrect type\n"); + double_eq(665413.0, V_DATE(&v)); + VariantClear( &v ); + + IXMLDOMNode_Release(pNode); + } + + hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/time"), &pNode); + ok(hr == S_OK, "ret %08x\n", hr ); + if(hr == S_OK) + { + hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v); + ok(hr == S_OK, "ret %08x\n", hr ); + ok(V_VT(&v) == VT_DATE, "incorrect type\n"); + double_eq(0.581392511574074, V_DATE(&v)); + VariantClear( &v ); + + IXMLDOMNode_Release(pNode); + } + + hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("root/timetz"), &pNode); + ok(hr == S_OK, "ret %08x\n", hr ); + if(hr == S_OK) + { + hr = IXMLDOMNode_get_nodeTypedValue(pNode, &v); + ok(hr == S_OK, "ret %08x\n", hr ); + ok(V_VT(&v) == VT_DATE, "incorrect type\n"); + double_eq(1.112513078703703, V_DATE(&v)); + VariantClear( &v ); + + IXMLDOMNode_Release(pNode); + } }
IXMLDOMDocument2_Release(doc);