Commit 681b08b0 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

oledb32: Implement CanConvert.

parent fb68974d
...@@ -126,13 +126,238 @@ static HRESULT WINAPI convert_DataConvert(IDataConvert* iface, ...@@ -126,13 +126,238 @@ static HRESULT WINAPI convert_DataConvert(IDataConvert* iface,
return E_NOTIMPL; return E_NOTIMPL;
} }
static inline WORD get_dbtype_class(DBTYPE type)
{
switch(type)
{
case DBTYPE_I2:
case DBTYPE_R4:
case DBTYPE_R8:
case DBTYPE_I1:
case DBTYPE_UI1:
case DBTYPE_UI2:
return DBTYPE_I2;
case DBTYPE_I4:
case DBTYPE_UI4:
return DBTYPE_I4;
case DBTYPE_I8:
case DBTYPE_UI8:
return DBTYPE_I8;
case DBTYPE_BSTR:
case DBTYPE_STR:
case DBTYPE_WSTR:
return DBTYPE_BSTR;
case DBTYPE_DBDATE:
case DBTYPE_DBTIME:
case DBTYPE_DBTIMESTAMP:
return DBTYPE_DBDATE;
}
return type;
}
/* Many src types will convert to this group of dst types */
static inline BOOL common_class(WORD dst_class)
{
switch(dst_class)
{
case DBTYPE_EMPTY:
case DBTYPE_NULL:
case DBTYPE_I2:
case DBTYPE_I4:
case DBTYPE_BSTR:
case DBTYPE_BOOL:
case DBTYPE_VARIANT:
case DBTYPE_I8:
case DBTYPE_CY:
case DBTYPE_DECIMAL:
case DBTYPE_NUMERIC:
return TRUE;
}
return FALSE;
}
static inline BOOL array_type(DBTYPE type)
{
return (type >= DBTYPE_I2 && type <= DBTYPE_UI4);
}
static HRESULT WINAPI convert_CanConvert(IDataConvert* iface, static HRESULT WINAPI convert_CanConvert(IDataConvert* iface,
DBTYPE wSrcType, DBTYPE wDstType) DBTYPE src_type, DBTYPE dst_type)
{ {
convert *This = impl_from_IDataConvert(iface); convert *This = impl_from_IDataConvert(iface);
FIXME("(%p)->(%d, %d): stub\n", This, wSrcType, wDstType); DBTYPE src_base_type = src_type & 0x1ff;
DBTYPE dst_base_type = dst_type & 0x1ff;
WORD dst_class = get_dbtype_class(dst_base_type);
return E_NOTIMPL; TRACE("(%p)->(%d, %d)\n", This, src_type, dst_type);
if(src_type & DBTYPE_VECTOR || dst_type & DBTYPE_VECTOR) return S_FALSE;
if(src_type & DBTYPE_ARRAY)
{
if(!array_type(src_base_type)) return S_FALSE;
if(dst_type & DBTYPE_ARRAY)
{
if(src_type == dst_type) return S_OK;
return S_FALSE;
}
if(dst_type == DBTYPE_VARIANT) return S_OK;
return S_FALSE;
}
if(dst_type & DBTYPE_ARRAY)
{
if(!array_type(dst_base_type)) return S_FALSE;
if(src_type == DBTYPE_IDISPATCH || src_type == DBTYPE_VARIANT) return S_OK;
return S_FALSE;
}
if(dst_type & DBTYPE_BYREF)
if(dst_base_type != DBTYPE_BYTES && dst_base_type != DBTYPE_STR && dst_base_type != DBTYPE_WSTR)
return S_FALSE;
switch(get_dbtype_class(src_base_type))
{
case DBTYPE_EMPTY:
if(common_class(dst_class)) return S_OK;
switch(dst_class)
{
case DBTYPE_DATE:
case DBTYPE_GUID:
return S_OK;
default:
if(dst_base_type == DBTYPE_DBTIMESTAMP) return S_OK;
return S_FALSE;
}
case DBTYPE_NULL:
switch(dst_base_type)
{
case DBTYPE_NULL:
case DBTYPE_VARIANT: return S_OK;
default: return S_FALSE;
}
case DBTYPE_I4:
if(dst_base_type == DBTYPE_BYTES) return S_OK;
/* fall through */
case DBTYPE_I2:
if(dst_base_type == DBTYPE_DATE) return S_OK;
/* fall through */
case DBTYPE_DECIMAL:
if(common_class(dst_class)) return S_OK;
if(dst_class == DBTYPE_DBDATE) return S_OK;
return S_FALSE;
case DBTYPE_BOOL:
if(dst_base_type == DBTYPE_DATE) return S_OK;
case DBTYPE_NUMERIC:
case DBTYPE_CY:
if(common_class(dst_class)) return S_OK;
return S_FALSE;
case DBTYPE_I8:
if(common_class(dst_class)) return S_OK;
if(dst_base_type == DBTYPE_BYTES) return S_OK;
return S_FALSE;
case DBTYPE_DATE:
switch(dst_class)
{
case DBTYPE_EMPTY:
case DBTYPE_NULL:
case DBTYPE_I2:
case DBTYPE_I4:
case DBTYPE_BSTR:
case DBTYPE_BOOL:
case DBTYPE_VARIANT:
case DBTYPE_I8:
case DBTYPE_DATE:
case DBTYPE_DBDATE:
return S_OK;
default: return S_FALSE;
}
case DBTYPE_IDISPATCH:
case DBTYPE_VARIANT:
switch(dst_base_type)
{
case DBTYPE_IDISPATCH:
case DBTYPE_ERROR:
case DBTYPE_IUNKNOWN:
return S_OK;
}
/* fall through */
case DBTYPE_BSTR:
if(common_class(dst_class)) return S_OK;
switch(dst_class)
{
case DBTYPE_DATE:
case DBTYPE_GUID:
case DBTYPE_BYTES:
case DBTYPE_DBDATE:
return S_OK;
default: return S_FALSE;
}
case DBTYPE_ERROR:
switch(dst_base_type)
{
case DBTYPE_BSTR:
case DBTYPE_ERROR:
case DBTYPE_VARIANT:
case DBTYPE_WSTR:
return S_OK;
default: return S_FALSE;
}
case DBTYPE_IUNKNOWN:
switch(dst_base_type)
{
case DBTYPE_EMPTY:
case DBTYPE_NULL:
case DBTYPE_IDISPATCH:
case DBTYPE_VARIANT:
case DBTYPE_IUNKNOWN:
return S_OK;
default: return S_FALSE;
}
case DBTYPE_BYTES:
if(dst_class == DBTYPE_I4 || dst_class == DBTYPE_I8) return S_OK;
/* fall through */
case DBTYPE_GUID:
switch(dst_class)
{
case DBTYPE_EMPTY:
case DBTYPE_NULL:
case DBTYPE_BSTR:
case DBTYPE_VARIANT:
case DBTYPE_GUID:
case DBTYPE_BYTES:
return S_OK;
default: return S_FALSE;
}
case DBTYPE_DBDATE:
switch(dst_class)
{
case DBTYPE_EMPTY:
case DBTYPE_NULL:
case DBTYPE_DATE:
case DBTYPE_BSTR:
case DBTYPE_VARIANT:
case DBTYPE_DBDATE:
return S_OK;
default: return S_FALSE;
}
}
return S_FALSE;
} }
static HRESULT WINAPI convert_GetConversionSize(IDataConvert* iface, static HRESULT WINAPI convert_GetConversionSize(IDataConvert* iface,
......
...@@ -236,7 +236,6 @@ static void test_canconvert(void) ...@@ -236,7 +236,6 @@ static void test_canconvert(void)
hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type, simple_convert[dst_idx].type); hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type, simple_convert[dst_idx].type);
expect = simple_expect; expect = simple_expect;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type,
...@@ -245,7 +244,6 @@ todo_wine ...@@ -245,7 +244,6 @@ todo_wine
/* src DBTYPE_BYREF */ /* src DBTYPE_BYREF */
hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_BYREF, simple_convert[dst_idx].type); hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_BYREF, simple_convert[dst_idx].type);
expect = simple_expect; expect = simple_expect;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_BYREF, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_BYREF,
...@@ -259,7 +257,6 @@ todo_wine ...@@ -259,7 +257,6 @@ todo_wine
simple_convert[dst_idx].type == DBTYPE_STR || simple_convert[dst_idx].type == DBTYPE_STR ||
simple_convert[dst_idx].type == DBTYPE_WSTR)) simple_convert[dst_idx].type == DBTYPE_WSTR))
expect = TRUE; expect = TRUE;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type,
...@@ -273,7 +270,6 @@ todo_wine ...@@ -273,7 +270,6 @@ todo_wine
simple_convert[dst_idx].type == DBTYPE_STR || simple_convert[dst_idx].type == DBTYPE_STR ||
simple_convert[dst_idx].type == DBTYPE_WSTR)) simple_convert[dst_idx].type == DBTYPE_WSTR))
expect = TRUE; expect = TRUE;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_BYREF, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_BYREF,
...@@ -284,7 +280,6 @@ todo_wine ...@@ -284,7 +280,6 @@ todo_wine
expect = FALSE; expect = FALSE;
if(array_type(simple_convert[src_idx].type) && simple_convert[dst_idx].type == DBTYPE_VARIANT) if(array_type(simple_convert[src_idx].type) && simple_convert[dst_idx].type == DBTYPE_VARIANT)
expect = TRUE; expect = TRUE;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_ARRAY, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_ARRAY,
...@@ -297,7 +292,6 @@ todo_wine ...@@ -297,7 +292,6 @@ todo_wine
(simple_convert[src_idx].type == DBTYPE_IDISPATCH || (simple_convert[src_idx].type == DBTYPE_IDISPATCH ||
simple_convert[src_idx].type == DBTYPE_VARIANT)) simple_convert[src_idx].type == DBTYPE_VARIANT))
expect = TRUE; expect = TRUE;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type,
...@@ -309,7 +303,6 @@ todo_wine ...@@ -309,7 +303,6 @@ todo_wine
if(array_type(simple_convert[src_idx].type) && if(array_type(simple_convert[src_idx].type) &&
simple_convert[src_idx].type == simple_convert[dst_idx].type) simple_convert[src_idx].type == simple_convert[dst_idx].type)
expect = TRUE; expect = TRUE;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_ARRAY, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_ARRAY,
...@@ -318,7 +311,6 @@ todo_wine ...@@ -318,7 +311,6 @@ todo_wine
/* src DBTYPE_VECTOR */ /* src DBTYPE_VECTOR */
hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_VECTOR, simple_convert[dst_idx].type); hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_VECTOR, simple_convert[dst_idx].type);
expect = FALSE; expect = FALSE;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_VECTOR, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_VECTOR,
...@@ -327,7 +319,6 @@ todo_wine ...@@ -327,7 +319,6 @@ todo_wine
/* dst DBTYPE_VECTOR */ /* dst DBTYPE_VECTOR */
hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type, simple_convert[dst_idx].type | DBTYPE_VECTOR); hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type, simple_convert[dst_idx].type | DBTYPE_VECTOR);
expect = FALSE; expect = FALSE;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type,
...@@ -336,7 +327,6 @@ todo_wine ...@@ -336,7 +327,6 @@ todo_wine
/* src & dst DBTYPE_VECTOR */ /* src & dst DBTYPE_VECTOR */
hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_VECTOR, simple_convert[dst_idx].type | DBTYPE_VECTOR); hr = IDataConvert_CanConvert(convert, simple_convert[src_idx].type | DBTYPE_VECTOR, simple_convert[dst_idx].type | DBTYPE_VECTOR);
expect = FALSE; expect = FALSE;
todo_wine
ok((hr == S_OK && expect == TRUE) || ok((hr == S_OK && expect == TRUE) ||
(hr == S_FALSE && expect == FALSE), (hr == S_FALSE && expect == FALSE),
"%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_VECTOR, "%04x -> %04x: got %08x expect conversion to be %spossible\n", simple_convert[src_idx].type | DBTYPE_VECTOR,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment