oledb32: Add FIXME for DBTYPE_NUMERIC type.
[wine.git] / dlls / oledb32 / convert.c
blobd959f653fd2efa27be3c2d30077027451b0ca3ac
1 /* OLE DB Conversion library
3 * Copyright 2009 Huw Davies
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
22 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winnls.h"
27 #include "ole2.h"
28 #include "msdadc.h"
29 #include "oledberr.h"
31 #include "oledb_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(oledb);
37 typedef struct
39 IDataConvert IDataConvert_iface;
40 IDCInfo IDCInfo_iface;
42 LONG ref;
44 UINT version; /* Set by IDCInfo_SetInfo */
45 } convert;
47 static inline convert *impl_from_IDataConvert(IDataConvert *iface)
49 return CONTAINING_RECORD(iface, convert, IDataConvert_iface);
52 static inline convert *impl_from_IDCInfo(IDCInfo *iface)
54 return CONTAINING_RECORD(iface, convert, IDCInfo_iface);
57 static HRESULT WINAPI convert_QueryInterface(IDataConvert* iface,
58 REFIID riid,
59 void **obj)
61 convert *This = impl_from_IDataConvert(iface);
62 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
64 *obj = NULL;
66 if(IsEqualIID(riid, &IID_IUnknown) ||
67 IsEqualIID(riid, &IID_IDataConvert))
69 *obj = iface;
71 else if(IsEqualIID(riid, &IID_IDCInfo))
73 *obj = &This->IDCInfo_iface;
75 else
77 FIXME("interface %s not implemented\n", debugstr_guid(riid));
78 return E_NOINTERFACE;
81 IDataConvert_AddRef(iface);
82 return S_OK;
86 static ULONG WINAPI convert_AddRef(IDataConvert* iface)
88 convert *This = impl_from_IDataConvert(iface);
89 TRACE("(%p)\n", This);
91 return InterlockedIncrement(&This->ref);
95 static ULONG WINAPI convert_Release(IDataConvert* iface)
97 convert *This = impl_from_IDataConvert(iface);
98 LONG ref;
100 TRACE("(%p)\n", This);
102 ref = InterlockedDecrement(&This->ref);
103 if(ref == 0)
104 heap_free(This);
106 return ref;
109 static int get_length(DBTYPE type)
111 switch(type)
113 case DBTYPE_I1:
114 case DBTYPE_UI1:
115 return 1;
116 case DBTYPE_I2:
117 case DBTYPE_UI2:
118 return 2;
119 case DBTYPE_BOOL:
120 return sizeof(VARIANT_BOOL);
121 case DBTYPE_I4:
122 case DBTYPE_UI4:
123 case DBTYPE_R4:
124 return 4;
125 case DBTYPE_I8:
126 case DBTYPE_UI8:
127 case DBTYPE_R8:
128 case DBTYPE_DATE:
129 return 8;
130 case DBTYPE_DBDATE:
131 return sizeof(DBDATE);
132 case DBTYPE_DBTIMESTAMP:
133 return sizeof(DBTIMESTAMP);
134 case DBTYPE_CY:
135 return sizeof(CY);
136 case DBTYPE_BSTR:
137 return sizeof(BSTR);
138 case DBTYPE_FILETIME:
139 return sizeof(FILETIME);
140 case DBTYPE_GUID:
141 return sizeof(GUID);
142 case DBTYPE_NUMERIC:
143 return sizeof(DB_NUMERIC);
144 case DBTYPE_BYTES:
145 case DBTYPE_WSTR:
146 case DBTYPE_STR:
147 case DBTYPE_BYREF | DBTYPE_WSTR:
148 return 0;
149 case DBTYPE_VARIANT:
150 return sizeof(VARIANT);
151 default:
152 FIXME("Unhandled type %04x\n", type);
153 return 0;
157 static HRESULT WINAPI convert_DataConvert(IDataConvert* iface,
158 DBTYPE src_type, DBTYPE dst_type,
159 DBLENGTH src_len, DBLENGTH *dst_len,
160 void *src, void *dst,
161 DBLENGTH dst_max_len,
162 DBSTATUS src_status, DBSTATUS *dst_status,
163 BYTE precision, BYTE scale,
164 DBDATACONVERT flags)
166 convert *This = impl_from_IDataConvert(iface);
167 DBLENGTH dst_len_loc;
168 DBSTATUS dst_status_loc;
169 VARIANT tmp;
170 HRESULT hr;
172 TRACE("(%p)->(%d, %d, %ld, %p, %p, %p, %ld, %d, %p, %d, %d, %x)\n", This,
173 src_type, dst_type, src_len, dst_len, src, dst, dst_max_len,
174 src_status, dst_status, precision, scale, flags);
176 if (!dst_len) dst_len = &dst_len_loc;
177 if (!dst_status) dst_status = &dst_status_loc;
179 *dst_status = DBSTATUS_E_BADACCESSOR;
181 if(src_status == DBSTATUS_S_ISNULL)
183 *dst_status = DBSTATUS_S_ISNULL;
184 *dst_len = 0;
185 return S_OK;
188 if(src_type == DBTYPE_VARIANT && V_VT((VARIANT*)src) == VT_NULL)
190 if(dst_type == DBTYPE_VARIANT)
191 *dst_len = sizeof(VARIANT);
193 *dst_status = DBSTATUS_S_ISNULL;
194 return S_OK;
197 if(IDataConvert_CanConvert(iface, src_type, dst_type) != S_OK)
199 return DB_E_UNSUPPORTEDCONVERSION;
202 if(dst == NULL && get_length(dst_type) != 0)
204 *dst_len = get_length(src_type);
205 *dst_status = DBSTATUS_S_OK;
206 return S_OK;
209 if(src_type == DBTYPE_STR)
211 BSTR b;
212 DWORD len;
214 if(flags & DBDATACONVERT_LENGTHFROMNTS)
215 len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0) - 1;
216 else
217 len = MultiByteToWideChar(CP_ACP, 0, src, src_len, NULL, 0);
218 b = SysAllocStringLen(NULL, len);
219 if(!b) return E_OUTOFMEMORY;
220 if(flags & DBDATACONVERT_LENGTHFROMNTS)
221 MultiByteToWideChar(CP_ACP, 0, src, -1, b, len + 1);
222 else
223 MultiByteToWideChar(CP_ACP, 0, src, src_len, b, len);
225 hr = IDataConvert_DataConvert(iface, DBTYPE_BSTR, dst_type, 0, dst_len,
226 &b, dst, dst_max_len, src_status, dst_status,
227 precision, scale, flags);
229 SysFreeString(b);
230 return hr;
233 if(src_type == DBTYPE_WSTR)
235 BSTR b;
237 if(flags & DBDATACONVERT_LENGTHFROMNTS)
238 b = SysAllocString(src);
239 else
240 b = SysAllocStringLen(src, src_len / 2);
241 if(!b) return E_OUTOFMEMORY;
242 hr = IDataConvert_DataConvert(iface, DBTYPE_BSTR, dst_type, 0, dst_len,
243 &b, dst, dst_max_len, src_status, dst_status,
244 precision, scale, flags);
245 SysFreeString(b);
246 return hr;
249 switch(dst_type)
251 case DBTYPE_I2:
253 signed short *d = dst;
254 switch(src_type)
256 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
257 case DBTYPE_I2: *d = *(signed short*)src; hr = S_OK; break;
258 case DBTYPE_I4: hr = VarI2FromI4(*(signed int*)src, d); break;
259 case DBTYPE_R4: hr = VarI2FromR4(*(FLOAT*)src, d); break;
260 case DBTYPE_R8: hr = VarI2FromR8(*(double*)src, d); break;
261 case DBTYPE_CY: hr = VarI2FromCy(*(CY*)src, d); break;
262 case DBTYPE_DATE: hr = VarI2FromDate(*(DATE*)src, d); break;
263 case DBTYPE_BSTR: hr = VarI2FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
264 case DBTYPE_BOOL: hr = VarI2FromBool(*(VARIANT_BOOL*)src, d); break;
265 case DBTYPE_DECIMAL: hr = VarI2FromDec((DECIMAL*)src, d); break;
266 case DBTYPE_I1: hr = VarI2FromI1(*(signed char*)src, d); break;
267 case DBTYPE_UI1: hr = VarI2FromUI1(*(BYTE*)src, d); break;
268 case DBTYPE_UI2: hr = VarI2FromUI2(*(WORD*)src, d); break;
269 case DBTYPE_UI4: hr = VarI2FromUI4(*(DWORD*)src, d); break;
270 case DBTYPE_I8: hr = VarI2FromI8(*(LONGLONG*)src, d); break;
271 case DBTYPE_UI8: hr = VarI2FromUI8(*(ULONGLONG*)src, d); break;
272 case DBTYPE_VARIANT:
273 VariantInit(&tmp);
274 if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_I2)) == S_OK)
275 *d = V_I2(&tmp);
276 break;
277 default: FIXME("Unimplemented conversion %04x -> I2\n", src_type); return E_NOTIMPL;
279 break;
282 case DBTYPE_I4:
284 signed int *d = dst;
285 switch(src_type)
287 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
288 case DBTYPE_I2: hr = VarI4FromI2(*(signed short*)src, d); break;
289 case DBTYPE_I4: *d = *(signed int*)src; hr = S_OK; break;
290 case DBTYPE_R4: hr = VarI4FromR4(*(FLOAT*)src, d); break;
291 case DBTYPE_R8: hr = VarI4FromR8(*(double*)src, d); break;
292 case DBTYPE_CY: hr = VarI4FromCy(*(CY*)src, d); break;
293 case DBTYPE_DATE: hr = VarI4FromDate(*(DATE*)src, d); break;
294 case DBTYPE_BSTR: hr = VarI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
295 case DBTYPE_BOOL: hr = VarI4FromBool(*(VARIANT_BOOL*)src, d); break;
296 case DBTYPE_DECIMAL: hr = VarI4FromDec((DECIMAL*)src, d); break;
297 case DBTYPE_I1: hr = VarI4FromI1(*(signed char*)src, d); break;
298 case DBTYPE_UI1: hr = VarI4FromUI1(*(BYTE*)src, d); break;
299 case DBTYPE_UI2: hr = VarI4FromUI2(*(WORD*)src, d); break;
300 case DBTYPE_UI4: hr = VarI4FromUI4(*(DWORD*)src, d); break;
301 case DBTYPE_I8: hr = VarI4FromI8(*(LONGLONG*)src, d); break;
302 case DBTYPE_UI8: hr = VarI4FromUI8(*(ULONGLONG*)src, d); break;
303 case DBTYPE_VARIANT:
304 VariantInit(&tmp);
305 if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_I4)) == S_OK)
306 *d = V_I4(&tmp);
307 break;
308 default: FIXME("Unimplemented conversion %04x -> I4\n", src_type); return E_NOTIMPL;
310 break;
313 case DBTYPE_I8:
315 LONGLONG *d = dst;
316 switch(src_type)
318 case DBTYPE_BSTR: hr = VarI8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
319 case DBTYPE_I8: *d = *(LONGLONG*)src; hr = S_OK; break;
320 default: FIXME("Unimplemented conversion %04x -> I8\n", src_type); return E_NOTIMPL;
322 break;
325 case DBTYPE_R4:
327 FLOAT *d = dst;
328 switch(src_type)
330 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
331 case DBTYPE_I2: hr = VarR4FromI2(*(signed short*)src, d); break;
332 case DBTYPE_I4: hr = VarR4FromI4(*(signed int*)src, d); break;
333 case DBTYPE_R4: *d = *(FLOAT*)src; hr = S_OK; break;
334 case DBTYPE_R8: hr = VarR4FromR8(*(double*)src, d); break;
335 case DBTYPE_CY: hr = VarR4FromCy(*(CY*)src, d); break;
336 case DBTYPE_DATE: hr = VarR4FromDate(*(DATE*)src, d); break;
337 case DBTYPE_BSTR: hr = VarR4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
338 case DBTYPE_BOOL: hr = VarR4FromBool(*(VARIANT_BOOL*)src, d); break;
339 case DBTYPE_DECIMAL: hr = VarR4FromDec((DECIMAL*)src, d); break;
340 case DBTYPE_I1: hr = VarR4FromI1(*(signed char*)src, d); break;
341 case DBTYPE_UI1: hr = VarR4FromUI1(*(BYTE*)src, d); break;
342 case DBTYPE_UI2: hr = VarR4FromUI2(*(WORD*)src, d); break;
343 case DBTYPE_UI4: hr = VarR4FromUI4(*(DWORD*)src, d); break;
344 case DBTYPE_I8: hr = VarR4FromI8(*(LONGLONG*)src, d); break;
345 case DBTYPE_UI8: hr = VarR4FromUI8(*(ULONGLONG*)src, d); break;
346 default: FIXME("Unimplemented conversion %04x -> R4\n", src_type); return E_NOTIMPL;
348 break;
350 case DBTYPE_R8:
352 DOUBLE *d=dst;
353 switch (src_type)
355 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
356 case DBTYPE_I1: hr = VarR8FromI1(*(signed char*)src, d); break;
357 case DBTYPE_I2: hr = VarR8FromI2(*(signed short*)src, d); break;
358 case DBTYPE_I4: hr = VarR8FromI4(*(signed int*)src, d); break;
359 case DBTYPE_I8: hr = VarR8FromI8(*(LONGLONG*)src, d); break;
360 case DBTYPE_UI1: hr = VarR8FromUI1(*(BYTE*)src, d); break;
361 case DBTYPE_UI2: hr = VarR8FromUI2(*(WORD*)src, d); break;
362 case DBTYPE_UI4: hr = VarR8FromUI4(*(DWORD*)src, d); break;
363 case DBTYPE_UI8: hr = VarR8FromUI8(*(ULONGLONG*)src, d); break;
364 case DBTYPE_R4: hr = VarR8FromR4(*(FLOAT*)src, d); break;
365 case DBTYPE_R8: *d = *(DOUBLE*)src; hr = S_OK; break;
366 case DBTYPE_CY: hr = VarR8FromCy(*(CY*)src, d); break;
367 case DBTYPE_DATE: hr = VarR8FromDate(*(DATE*)src, d); break;
368 case DBTYPE_BSTR: hr = VarR8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
369 case DBTYPE_BOOL: hr = VarR8FromBool(*(VARIANT_BOOL*)src, d); break;
370 case DBTYPE_DECIMAL: hr = VarR8FromDec((DECIMAL*)src, d); break;
371 case DBTYPE_VARIANT:
372 VariantInit(&tmp);
373 if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_R8)) == S_OK)
374 *d = V_R8(&tmp);
375 break;
376 default: FIXME("Unimplemented conversion %04x -> R8\n", src_type); return E_NOTIMPL;
378 break;
380 case DBTYPE_BOOL:
382 VARIANT_BOOL *d=dst;
383 switch (src_type)
385 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
386 case DBTYPE_I1: hr = VarBoolFromI1(*(signed char*)src, d); break;
387 case DBTYPE_I2: hr = VarBoolFromI2(*(signed short*)src, d); break;
388 case DBTYPE_I4: hr = VarBoolFromI4(*(signed int*)src, d); break;
389 case DBTYPE_I8: hr = VarBoolFromI8(*(LONGLONG*)src, d); break;
390 case DBTYPE_UI1: hr = VarBoolFromUI1(*(BYTE*)src, d); break;
391 case DBTYPE_UI2: hr = VarBoolFromUI2(*(WORD*)src, d); break;
392 case DBTYPE_UI4: hr = VarBoolFromUI4(*(DWORD*)src, d); break;
393 case DBTYPE_UI8: hr = VarBoolFromUI8(*(ULONGLONG*)src, d); break;
394 case DBTYPE_R4: hr = VarBoolFromR4(*(FLOAT*)src, d); break;
395 case DBTYPE_R8: hr = VarBoolFromR8(*(DOUBLE*)src, d); break;
396 case DBTYPE_CY: hr = VarBoolFromCy(*(CY*)src, d); break;
397 case DBTYPE_DATE: hr = VarBoolFromDate(*(DATE*)src, d); break;
398 case DBTYPE_BSTR: hr = VarBoolFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
399 case DBTYPE_BOOL: *d = *(VARIANT_BOOL*)src; hr = S_OK; break;
400 case DBTYPE_DECIMAL: hr = VarBoolFromDec((DECIMAL*)src, d); break;
401 default: FIXME("Unimplemented conversion %04x -> BOOL\n", src_type); return E_NOTIMPL;
403 break;
405 case DBTYPE_DATE:
407 DATE *d=dst;
408 switch (src_type)
410 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
411 case DBTYPE_I1: hr = VarDateFromI1(*(signed char*)src, d); break;
412 case DBTYPE_I2: hr = VarDateFromI2(*(signed short*)src, d); break;
413 case DBTYPE_I4: hr = VarDateFromI4(*(signed int*)src, d); break;
414 case DBTYPE_I8: hr = VarDateFromI8(*(LONGLONG*)src, d); break;
415 case DBTYPE_UI1: hr = VarDateFromUI1(*(BYTE*)src, d); break;
416 case DBTYPE_UI2: hr = VarDateFromUI2(*(WORD*)src, d); break;
417 case DBTYPE_UI4: hr = VarDateFromUI4(*(DWORD*)src, d); break;
418 case DBTYPE_UI8: hr = VarDateFromUI8(*(ULONGLONG*)src, d); break;
419 case DBTYPE_R4: hr = VarDateFromR4(*(FLOAT*)src, d); break;
420 case DBTYPE_R8: hr = VarDateFromR8(*(DOUBLE*)src, d); break;
421 case DBTYPE_CY: hr = VarDateFromCy(*(CY*)src, d); break;
422 case DBTYPE_DATE: *d = *(DATE*)src; hr = S_OK; break;
423 case DBTYPE_BSTR: hr = VarDateFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
424 case DBTYPE_BOOL: hr = VarDateFromBool(*(VARIANT_BOOL*)src, d); break;
425 case DBTYPE_DECIMAL: hr = VarDateFromDec((DECIMAL*)src, d); break;
426 case DBTYPE_DBTIMESTAMP:
428 SYSTEMTIME st;
429 DBTIMESTAMP *ts=(DBTIMESTAMP*)src;
431 st.wYear = ts->year;
432 st.wMonth = ts->month;
433 st.wDay = ts->day;
434 st.wHour = ts->hour;
435 st.wMinute = ts->minute;
436 st.wSecond = ts->second;
437 st.wMilliseconds = ts->fraction/1000000;
438 hr = (SystemTimeToVariantTime(&st, d) ? S_OK : E_FAIL);
439 break;
441 default: FIXME("Unimplemented conversion %04x -> DATE\n", src_type); return E_NOTIMPL;
443 break;
445 case DBTYPE_DBDATE:
447 DBDATE *d=dst;
448 switch (src_type)
450 case DBTYPE_DBDATE: memcpy(d, src, sizeof(DBDATE)); hr = S_OK; break;
451 case DBTYPE_BSTR:
453 VARIANT var;
454 BSTR s = *(WCHAR**)src;
456 VariantInit(&var);
457 V_VT(&var) = VT_BSTR;
458 V_BSTR(&var) = SysAllocString(s);
460 if ((hr = VariantChangeType(&var, &var, 0, VT_DATE)) == S_OK)
462 SYSTEMTIME st;
463 hr = (VariantTimeToSystemTime( V_DATE(&var), &st) ? S_OK : E_FAIL);
464 d->year = st.wYear;
465 d->month = st.wMonth;
466 d->day = st.wDay;
469 VariantClear(&var);
471 break;
472 case DBTYPE_VARIANT:
473 if( V_VT((VARIANT*)src) == VT_DATE)
475 SYSTEMTIME st;
476 hr = (VariantTimeToSystemTime( V_DATE((VARIANT*)src), &st) ? S_OK : E_FAIL);
477 d->year = st.wYear;
478 d->month = st.wMonth;
479 d->day = st.wDay;
481 else
483 FIXME("Unimplemented variant type %d -> DBDATE\n", V_VT((VARIANT*)src));
484 return E_NOTIMPL;
486 break;
487 default: FIXME("Unimplemented conversion %04x -> DBDATE\n", src_type); return E_NOTIMPL;
489 break;
491 case DBTYPE_DBTIMESTAMP:
493 DBTIMESTAMP *d=dst;
494 switch (src_type)
496 case DBTYPE_EMPTY: memset(d, 0, sizeof(DBTIMESTAMP)); hr = S_OK; break;
497 case DBTYPE_DBTIMESTAMP: memcpy(d, src, sizeof(DBTIMESTAMP)); hr = S_OK; break;
498 case DBTYPE_BSTR:
500 VARIANT var;
501 BSTR s = *(WCHAR**)src;
503 VariantInit(&var);
504 V_VT(&var) = VT_BSTR;
505 V_BSTR(&var) = SysAllocString(s);
507 if ((hr = VariantChangeType(&var, &var, 0, VT_DATE)) == S_OK)
509 SYSTEMTIME st;
511 hr = (VariantTimeToSystemTime( V_DATE(&var), &st) ? S_OK : E_FAIL);
512 d->year = st.wYear;
513 d->month = st.wMonth;
514 d->day = st.wDay;
515 d->hour = st.wHour;
516 d->minute = st.wMinute;
517 d->second = st.wSecond;
518 d->fraction = st.wMilliseconds * 1000000;
521 VariantClear(&var);
523 break;
524 case DBTYPE_DATE:
526 SYSTEMTIME st;
527 hr = (VariantTimeToSystemTime(*(double*)src, &st) ? S_OK : E_FAIL);
528 d->year = st.wYear;
529 d->month = st.wMonth;
530 d->day = st.wDay;
531 d->hour = st.wHour;
532 d->minute = st.wMinute;
533 d->second = st.wSecond;
534 d->fraction = st.wMilliseconds * 1000000;
535 break;
537 case DBTYPE_VARIANT:
538 if( V_VT((VARIANT*)src) == VT_DATE)
540 SYSTEMTIME st;
541 hr = (VariantTimeToSystemTime( V_DATE((VARIANT*)src), &st) ? S_OK : E_FAIL);
542 d->year = st.wYear;
543 d->month = st.wMonth;
544 d->day = st.wDay;
545 d->hour = st.wHour;
546 d->minute = st.wMinute;
547 d->second = st.wSecond;
548 d->fraction = st.wMilliseconds * 1000000;
550 else
552 FIXME("Unimplemented variant type %d -> DBTIMESTAMP\n", V_VT((VARIANT*)src));
553 return E_NOTIMPL;
555 break;
556 default: FIXME("Unimplemented conversion %04x -> DBTIMESTAMP\n", src_type); return E_NOTIMPL;
558 break;
561 case DBTYPE_CY:
563 CY *d = dst;
564 switch(src_type)
566 case DBTYPE_EMPTY: d->int64 = 0; hr = S_OK; break;
567 case DBTYPE_I2: hr = VarCyFromI2(*(signed short*)src, d); break;
568 case DBTYPE_I4: hr = VarCyFromI4(*(signed int*)src, d); break;
569 case DBTYPE_R4: hr = VarCyFromR4(*(FLOAT*)src, d); break;
570 case DBTYPE_R8: hr = VarCyFromR8(*(double*)src, d); break;
571 case DBTYPE_CY: *d = *(CY*)src; hr = S_OK; break;
572 case DBTYPE_DATE: hr = VarCyFromDate(*(DATE*)src, d); break;
573 case DBTYPE_BSTR: hr = VarCyFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
574 case DBTYPE_BOOL: hr = VarCyFromBool(*(VARIANT_BOOL*)src, d); break;
575 case DBTYPE_DECIMAL: hr = VarCyFromDec((DECIMAL*)src, d); break;
576 case DBTYPE_I1: hr = VarCyFromI1(*(signed char*)src, d); break;
577 case DBTYPE_UI1: hr = VarCyFromUI1(*(BYTE*)src, d); break;
578 case DBTYPE_UI2: hr = VarCyFromUI2(*(WORD*)src, d); break;
579 case DBTYPE_UI4: hr = VarCyFromUI4(*(DWORD*)src, d); break;
580 case DBTYPE_I8: hr = VarCyFromI8(*(LONGLONG*)src, d); break;
581 case DBTYPE_UI8: hr = VarCyFromUI8(*(ULONGLONG*)src, d); break;
582 default: FIXME("Unimplemented conversion %04x -> CY\n", src_type); return E_NOTIMPL;
584 break;
587 case DBTYPE_BSTR:
589 BSTR *d = dst;
590 switch(src_type)
592 case DBTYPE_EMPTY: *d = SysAllocStringLen(NULL, 0); hr = *d ? S_OK : E_OUTOFMEMORY; break;
593 case DBTYPE_I2: hr = VarBstrFromI2(*(signed short*)src, LOCALE_USER_DEFAULT, 0, d); break;
594 case DBTYPE_I4: hr = VarBstrFromI4(*(signed int*)src, LOCALE_USER_DEFAULT, 0, d); break;
595 case DBTYPE_R4: hr = VarBstrFromR4(*(FLOAT*)src, LOCALE_USER_DEFAULT, 0, d); break;
596 case DBTYPE_R8: hr = VarBstrFromR8(*(double*)src, LOCALE_USER_DEFAULT, 0, d); break;
597 case DBTYPE_CY: hr = VarBstrFromCy(*(CY*)src, LOCALE_USER_DEFAULT, 0, d); break;
598 case DBTYPE_DATE: hr = VarBstrFromDate(*(DATE*)src, LOCALE_USER_DEFAULT, 0, d); break;
599 case DBTYPE_BSTR: *d = SysAllocStringLen(*(BSTR*)src, SysStringLen(*(BSTR*)src)); hr = *d ? S_OK : E_OUTOFMEMORY; break;
600 case DBTYPE_BOOL: hr = VarBstrFromBool(*(VARIANT_BOOL*)src, LOCALE_USER_DEFAULT, 0, d); break;
601 case DBTYPE_DECIMAL: hr = VarBstrFromDec((DECIMAL*)src, LOCALE_USER_DEFAULT, 0, d); break;
602 case DBTYPE_I1: hr = VarBstrFromI1(*(signed char*)src, LOCALE_USER_DEFAULT, 0, d); break;
603 case DBTYPE_UI1: hr = VarBstrFromUI1(*(BYTE*)src, LOCALE_USER_DEFAULT, 0, d); break;
604 case DBTYPE_UI2: hr = VarBstrFromUI2(*(WORD*)src, LOCALE_USER_DEFAULT, 0, d); break;
605 case DBTYPE_UI4: hr = VarBstrFromUI4(*(DWORD*)src, LOCALE_USER_DEFAULT, 0, d); break;
606 case DBTYPE_I8: hr = VarBstrFromI8(*(LONGLONG*)src, LOCALE_USER_DEFAULT, 0, d); break;
607 case DBTYPE_UI8: hr = VarBstrFromUI8(*(ULONGLONG*)src, LOCALE_USER_DEFAULT, 0, d); break;
608 case DBTYPE_GUID:
610 WCHAR szBuff[39];
611 const GUID *id = (const GUID *)src;
612 WCHAR format[] = {
613 '{','%','0','8','X','-','%','0','4','X','-','%','0','4','X','-',
614 '%','0','2','X','%','0','2','X','-',
615 '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','}',0};
616 wsprintfW(szBuff, format,
617 id->Data1, id->Data2, id->Data3,
618 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
619 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
620 *d = SysAllocString(szBuff);
621 hr = *d ? S_OK : E_OUTOFMEMORY;
623 break;
624 case DBTYPE_BYTES:
626 *d = SysAllocStringLen(NULL, 2 * src_len);
627 if (*d == NULL)
628 hr = E_OUTOFMEMORY;
629 else
631 const char hexchars[] = "0123456789ABCDEF";
632 WCHAR *s = *d;
633 unsigned char *p = src;
634 while (src_len > 0)
636 *s++ = hexchars[(*p >> 4) & 0x0F];
637 *s++ = hexchars[(*p) & 0x0F];
638 src_len--; p++;
640 hr = S_OK;
643 break;
644 case DBTYPE_VARIANT:
645 VariantInit(&tmp);
646 if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_BSTR)) == S_OK)
647 *d = V_BSTR(&tmp);
648 break;
649 default: FIXME("Unimplemented conversion %04x -> BSTR\n", src_type); return E_NOTIMPL;
651 break;
654 case DBTYPE_UI1:
656 BYTE *d = dst;
657 switch(src_type)
659 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
660 case DBTYPE_I2: hr = VarUI1FromI2(*(signed short*)src, d); break;
661 case DBTYPE_I4: hr = VarUI1FromI4(*(signed int*)src, d); break;
662 case DBTYPE_R4: hr = VarUI1FromR4(*(FLOAT*)src, d); break;
663 case DBTYPE_R8: hr = VarUI1FromR8(*(double*)src, d); break;
664 case DBTYPE_CY: hr = VarUI1FromCy(*(CY*)src, d); break;
665 case DBTYPE_DATE: hr = VarUI1FromDate(*(DATE*)src, d); break;
666 case DBTYPE_BSTR: hr = VarUI1FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
667 case DBTYPE_BOOL: hr = VarUI1FromBool(*(VARIANT_BOOL*)src, d); break;
668 case DBTYPE_DECIMAL: hr = VarUI1FromDec((DECIMAL*)src, d); break;
669 case DBTYPE_I1: hr = VarUI1FromI1(*(signed char*)src, d); break;
670 case DBTYPE_UI1: *d = *(BYTE*)src; hr = S_OK; break;
671 case DBTYPE_UI2: hr = VarUI1FromUI2(*(WORD*)src, d); break;
672 case DBTYPE_UI4: hr = VarUI1FromUI4(*(DWORD*)src, d); break;
673 case DBTYPE_I8: hr = VarUI1FromI8(*(LONGLONG*)src, d); break;
674 case DBTYPE_UI8: hr = VarUI1FromUI8(*(ULONGLONG*)src, d); break;
675 default: FIXME("Unimplemented conversion %04x -> UI1\n", src_type); return E_NOTIMPL;
677 break;
679 case DBTYPE_UI2:
681 WORD *d = dst;
682 switch(src_type)
684 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
685 case DBTYPE_I2: hr = VarUI2FromI2(*(signed short*)src, d); break;
686 case DBTYPE_I4: hr = VarUI2FromI4(*(signed int*)src, d); break;
687 case DBTYPE_R4: hr = VarUI2FromR4(*(FLOAT*)src, d); break;
688 case DBTYPE_R8: hr = VarUI2FromR8(*(double*)src, d); break;
689 case DBTYPE_CY: hr = VarUI2FromCy(*(CY*)src, d); break;
690 case DBTYPE_DATE: hr = VarUI2FromDate(*(DATE*)src, d); break;
691 case DBTYPE_BSTR: hr = VarUI2FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
692 case DBTYPE_BOOL: hr = VarUI2FromBool(*(VARIANT_BOOL*)src, d); break;
693 case DBTYPE_DECIMAL: hr = VarUI2FromDec((DECIMAL*)src, d); break;
694 case DBTYPE_I1: hr = VarUI2FromI1(*(signed char*)src, d); break;
695 case DBTYPE_UI1: hr = VarUI2FromUI1(*(BYTE*)src, d); break;
696 case DBTYPE_UI2: *d = *(WORD*)src; hr = S_OK; break;
697 case DBTYPE_UI4: hr = VarUI2FromUI4(*(DWORD*)src, d); break;
698 case DBTYPE_I8: hr = VarUI2FromI8(*(LONGLONG*)src, d); break;
699 case DBTYPE_UI8: hr = VarUI2FromUI8(*(ULONGLONG*)src, d); break;
700 default: FIXME("Unimplemented conversion %04x -> UI2\n", src_type); return E_NOTIMPL;
702 break;
705 case DBTYPE_UI4:
707 DWORD *d = dst;
708 switch(src_type)
710 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
711 case DBTYPE_I2: hr = VarUI4FromI2(*(signed short*)src, d); break;
712 case DBTYPE_I4: hr = VarUI4FromI4(*(signed int*)src, d); break;
713 case DBTYPE_R4: hr = VarUI4FromR4(*(FLOAT*)src, d); break;
714 case DBTYPE_R8: hr = VarUI4FromR8(*(double*)src, d); break;
715 case DBTYPE_CY: hr = VarUI4FromCy(*(CY*)src, d); break;
716 case DBTYPE_DATE: hr = VarUI4FromDate(*(DATE*)src, d); break;
717 case DBTYPE_BSTR: hr = VarUI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
718 case DBTYPE_BOOL: hr = VarUI4FromBool(*(VARIANT_BOOL*)src, d); break;
719 case DBTYPE_DECIMAL: hr = VarUI4FromDec((DECIMAL*)src, d); break;
720 case DBTYPE_I1: hr = VarUI4FromI1(*(signed char*)src, d); break;
721 case DBTYPE_UI1: hr = VarUI4FromUI1(*(BYTE*)src, d); break;
722 case DBTYPE_UI2: hr = VarUI4FromUI2(*(WORD*)src, d); break;
723 case DBTYPE_UI4: *d = *(DWORD*)src; hr = S_OK; break;
724 case DBTYPE_I8: hr = VarUI4FromI8(*(LONGLONG*)src, d); break;
725 case DBTYPE_UI8: hr = VarUI4FromUI8(*(ULONGLONG*)src, d); break;
726 case DBTYPE_VARIANT:
727 VariantInit(&tmp);
728 if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_UI4)) == S_OK)
729 *d = V_UI4(&tmp);
730 break;
731 default: FIXME("Unimplemented conversion %04x -> UI4\n", src_type); return E_NOTIMPL;
733 break;
736 case DBTYPE_UI8:
738 ULONGLONG *d = dst;
739 switch(src_type)
741 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
742 case DBTYPE_I2: hr = VarUI8FromI2(*(signed short*)src, d); break;
743 case DBTYPE_I4: {LONGLONG s = *(signed int*)src; hr = VarUI8FromI8(s, d); break;}
744 case DBTYPE_R4: hr = VarUI8FromR4(*(FLOAT*)src, d); break;
745 case DBTYPE_R8: hr = VarUI8FromR8(*(double*)src, d); break;
746 case DBTYPE_CY: hr = VarUI8FromCy(*(CY*)src, d); break;
747 case DBTYPE_DATE: hr = VarUI8FromDate(*(DATE*)src, d); break;
748 case DBTYPE_BSTR: hr = VarUI8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
749 case DBTYPE_BOOL: hr = VarUI8FromBool(*(VARIANT_BOOL*)src, d); break;
750 case DBTYPE_DECIMAL: hr = VarUI8FromDec((DECIMAL*)src, d); break;
751 case DBTYPE_I1: hr = VarUI8FromI1(*(signed char*)src, d); break;
752 case DBTYPE_UI1: hr = VarUI8FromUI1(*(BYTE*)src, d); break;
753 case DBTYPE_UI2: hr = VarUI8FromUI2(*(WORD*)src, d); break;
754 case DBTYPE_UI4: hr = VarUI8FromUI4(*(DWORD*)src, d); break;
755 case DBTYPE_I8: hr = VarUI8FromI8(*(LONGLONG*)src, d); break;
756 case DBTYPE_UI8: *d = *(ULONGLONG*)src; hr = S_OK; break;
757 default: FIXME("Unimplemented conversion %04x -> UI8\n", src_type); return E_NOTIMPL;
759 break;
762 case DBTYPE_FILETIME:
764 FILETIME *d = dst;
765 switch(src_type)
767 case DBTYPE_EMPTY: d->dwLowDateTime = d->dwHighDateTime = 0; hr = S_OK; break;
768 case DBTYPE_FILETIME: *d = *(FILETIME*)src; hr = S_OK; break;
769 default: FIXME("Unimplemented conversion %04x -> FILETIME\n", src_type); return E_NOTIMPL;
771 break;
774 case DBTYPE_GUID:
776 GUID *d = dst;
777 switch(src_type)
779 case DBTYPE_EMPTY: *d = GUID_NULL; hr = S_OK; break;
780 case DBTYPE_GUID: *d = *(GUID*)src; hr = S_OK; break;
781 default: FIXME("Unimplemented conversion %04x -> GUID\n", src_type); return E_NOTIMPL;
783 break;
786 case DBTYPE_WSTR:
788 BSTR b;
789 DBLENGTH bstr_len;
790 INT bytes_to_copy;
791 hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
792 src, &b, sizeof(BSTR), src_status, dst_status,
793 precision, scale, flags);
794 if(hr != S_OK || *dst_status == DBSTATUS_S_ISNULL)
795 return hr;
796 bstr_len = SysStringLen(b);
797 *dst_len = bstr_len * sizeof(WCHAR); /* Doesn't include size for '\0' */
798 *dst_status = DBSTATUS_S_OK;
799 bytes_to_copy = min(*dst_len + sizeof(WCHAR), dst_max_len);
800 if(dst)
802 if(bytes_to_copy >= sizeof(WCHAR))
804 memcpy(dst, b, bytes_to_copy - sizeof(WCHAR));
805 *((WCHAR*)dst + bytes_to_copy / sizeof(WCHAR) - 1) = 0;
806 if(bytes_to_copy < *dst_len + sizeof(WCHAR))
807 *dst_status = DBSTATUS_S_TRUNCATED;
809 else
811 *dst_status = DBSTATUS_E_DATAOVERFLOW;
812 hr = DB_E_ERRORSOCCURRED;
815 SysFreeString(b);
816 return hr;
819 case DBTYPE_STR:
821 BSTR b;
822 DBLENGTH length;
823 INT bytes_to_copy;
824 hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &length,
825 src, &b, sizeof(BSTR), src_status, dst_status,
826 precision, scale, flags);
827 if(hr != S_OK) return hr;
828 length = WideCharToMultiByte(CP_ACP, 0, b, SysStringLen(b), NULL, 0, NULL, NULL);
829 *dst_len = length; /* Doesn't include size for '\0' */
830 *dst_status = DBSTATUS_S_OK;
831 bytes_to_copy = min(length + 1, dst_max_len);
832 if(dst)
834 if(bytes_to_copy >= sizeof(char))
836 WideCharToMultiByte(CP_ACP, 0, b, SysStringLen(b), dst, bytes_to_copy - 1, NULL, NULL);
837 *((char *)dst + bytes_to_copy - 1) = 0;
838 if(bytes_to_copy < length + 1)
839 *dst_status = DBSTATUS_S_TRUNCATED;
841 else
843 *dst_status = DBSTATUS_E_DATAOVERFLOW;
844 hr = DB_E_ERRORSOCCURRED;
847 SysFreeString(b);
848 return hr;
851 case DBTYPE_BYREF | DBTYPE_WSTR:
853 BSTR b;
854 WCHAR **d = dst;
855 DBLENGTH bstr_len;
856 hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
857 src, &b, sizeof(BSTR), src_status, dst_status,
858 precision, scale, flags);
859 if(hr != S_OK) return hr;
861 bstr_len = SysStringLen(b) * sizeof(WCHAR);
862 *dst_len = bstr_len; /* Doesn't include size for '\0' */
864 *d = CoTaskMemAlloc(bstr_len + sizeof(WCHAR));
865 if(*d) memcpy(*d, b, bstr_len + sizeof(WCHAR));
866 else hr = E_OUTOFMEMORY;
867 SysFreeString(b);
868 return hr;
871 case DBTYPE_BYREF | DBTYPE_STR:
873 BSTR b;
874 char **d = dst;
875 DBLENGTH length;
876 hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &length,
877 src, &b, sizeof(BSTR), src_status, dst_status,
878 precision, scale, flags);
879 if(hr != S_OK) return hr;
881 length = WideCharToMultiByte(CP_ACP, 0, b, SysStringLen(b) + 1, NULL, 0, NULL, NULL);
882 *dst_len = length - 1; /* Doesn't include size for '\0' */
883 *dst_status = DBSTATUS_S_OK;
884 *d = CoTaskMemAlloc(length);
886 if(*d)
887 WideCharToMultiByte(CP_ACP, 0, b, SysStringLen(b) + 1, *d, length, NULL, NULL);
888 else
889 hr = E_OUTOFMEMORY;
890 SysFreeString(b);
892 return hr;
895 case DBTYPE_VARIANT:
897 VARIANT *v = dst;
899 switch(src_type)
901 case DBTYPE_BOOL:
902 V_VT(v) = VT_BOOL;
903 V_BOOL(v) = *(VARIANT_BOOL*)src;
904 hr = S_OK;
905 break;
906 case DBTYPE_I2:
907 V_VT(v) = VT_I2;
908 V_I2(v) = *(signed short*)src;
909 hr = S_OK;
910 break;
911 case DBTYPE_I4:
912 V_VT(v) = VT_I4;
913 V_I4(v) = *(signed int*)src;
914 hr = S_OK;
915 break;
916 case DBTYPE_I8:
917 V_VT(v) = VT_DECIMAL;
918 hr = VarDecFromI8( *(LONGLONG*)src, &V_DECIMAL(v));
919 break;
920 case DBTYPE_R4:
921 V_VT(v) = VT_R4;
922 V_R4(v) = *(FLOAT*)src;
923 hr = S_OK;
924 break;
925 case DBTYPE_R8:
926 V_VT(v) = VT_R8;
927 V_R8(v) = *(double*)src;
928 hr = S_OK;
929 break;
930 case DBTYPE_BSTR:
932 BSTR s = *(WCHAR**)src;
933 TRACE("%s\n", debugstr_w(s));
934 V_VT(v) = VT_BSTR;
935 V_BSTR(v) = SysAllocString(s);
936 hr = V_BSTR(v) ? S_OK : E_OUTOFMEMORY;
937 break;
939 case DBTYPE_DATE:
940 V_VT(v) = VT_DATE;
941 V_DATE(v) = *(DATE*)src;
942 hr = S_OK;
943 break;
944 case DBTYPE_DBDATE:
946 SYSTEMTIME st;
947 DBDATE *ts=(DBDATE*)src;
949 V_VT(v) = VT_DATE;
951 st.wYear = ts->year;
952 st.wMonth = ts->month;
953 st.wDay = ts->day;
954 st.wHour = 0;
955 st.wMinute = 0;
956 st.wSecond = 0;
957 st.wMilliseconds = 0;
958 hr = (SystemTimeToVariantTime(&st, &V_DATE(v)) ? S_OK : E_FAIL);
959 break;
961 case DBTYPE_DBTIMESTAMP:
963 SYSTEMTIME st;
964 DBTIMESTAMP *ts = (DBTIMESTAMP *)src;
966 V_VT(v) = VT_DATE;
968 st.wYear = ts->year;
969 st.wMonth = ts->month;
970 st.wDay = ts->day;
971 st.wHour = ts->hour;
972 st.wMinute = ts->minute;
973 st.wSecond = ts->second;
974 st.wMilliseconds = ts->fraction/1000000;
975 hr = SystemTimeToVariantTime(&st, &V_DATE(v)) ? S_OK : E_FAIL;
976 break;
978 case DBTYPE_CY:
979 V_VT(v) = VT_CY;
980 V_CY(v) = *(CY*)src;
981 hr = S_OK;
982 break;
983 case DBTYPE_BYTES:
985 LONG i;
986 SAFEARRAY *psa = NULL;
987 SAFEARRAYBOUND rgsabound[1];
988 unsigned char *p = src;
990 rgsabound[0].lLbound = 0;
991 rgsabound[0].cElements = src_len;
993 psa = SafeArrayCreate(VT_UI1,1,rgsabound);
994 for(i =0; i < src_len; i++,p++)
996 hr = SafeArrayPutElement(psa, &i, p);
997 if(FAILED(hr)) {
998 SafeArrayDestroy (psa);
999 return hr;
1003 V_VT(v) = VT_ARRAY|VT_UI1;
1004 V_ARRAY(v) = psa;
1005 hr = S_OK;
1006 break;
1008 default: FIXME("Unimplemented conversion %04x -> VARIANT\n", src_type); return E_NOTIMPL;
1010 break;
1012 case DBTYPE_BYTES:
1014 BYTE *d = dst;
1016 switch(src_type)
1018 case DBTYPE_BYTES:
1019 if( src_len > dst_max_len)
1020 *dst_status = DBSTATUS_S_TRUNCATED;
1021 else
1022 *dst_status = DBSTATUS_S_OK;
1024 *dst_len = src_len;
1025 memcpy(d, src, min(src_len, dst_max_len));
1027 return S_OK;
1028 case DBTYPE_VARIANT:
1030 switch(V_VT((VARIANT*)src))
1032 case VT_UI1 | VT_ARRAY:
1034 LONG l;
1035 BYTE *data = NULL;
1037 hr = SafeArrayGetUBound(V_ARRAY((VARIANT*)src), 1, &l);
1038 if(FAILED(hr))
1039 return hr;
1041 hr = SafeArrayAccessData(V_ARRAY((VARIANT*)src), (VOID**)&data);
1042 if(FAILED(hr))
1044 ERR("SafeArrayAccessData Failed = 0x%08x\n", hr);
1045 return hr;
1048 *dst_len = l+1;
1049 *dst_status = DBSTATUS_S_OK;
1050 memcpy(d, data, *dst_len);
1052 SafeArrayUnaccessData(V_ARRAY((VARIANT*)src));
1053 return S_OK;
1055 break;
1056 default:
1057 FIXME("Unimplemented variant type %d -> BYTES\n", V_VT((VARIANT*)src));
1058 return E_NOTIMPL;
1061 break;
1062 default: FIXME("Unimplemented conversion %04x -> DBTYPE_BYTES\n", src_type); return E_NOTIMPL;
1064 break;
1066 case DBTYPE_BYTES | DBTYPE_BYREF:
1068 BYTE **d = dst;
1070 switch(src_type)
1072 case DBTYPE_BYTES:
1073 *d = CoTaskMemAlloc(src_len);
1074 if(*d) memcpy(*d, src, src_len);
1075 else hr = E_OUTOFMEMORY;
1077 *dst_len = src_len;
1078 *dst_status = DBSTATUS_S_OK;
1079 return S_OK;
1080 default: FIXME("Unimplemented conversion %04x -> DBTYPE_BYTES | DBTYPE_BYREF\n", src_type); return E_NOTIMPL;
1082 break;
1085 case DBTYPE_NUMERIC:
1086 FIXME("Unimplemented conversion %04x -> DBTYPE_NUMERIC\n", src_type);
1087 return E_NOTIMPL;
1089 default:
1090 FIXME("Unimplemented conversion %04x -> %04x\n", src_type, dst_type);
1091 return E_NOTIMPL;
1094 if(hr == DISP_E_OVERFLOW)
1096 *dst_status = DBSTATUS_E_DATAOVERFLOW;
1097 *dst_len = get_length(dst_type);
1098 hr = DB_E_ERRORSOCCURRED;
1100 else if(hr == S_OK)
1102 *dst_status = DBSTATUS_S_OK;
1103 *dst_len = get_length(dst_type);
1106 return hr;
1109 static inline WORD get_dbtype_class(DBTYPE type)
1111 switch(type)
1113 case DBTYPE_I2:
1114 case DBTYPE_R4:
1115 case DBTYPE_R8:
1116 case DBTYPE_I1:
1117 case DBTYPE_UI1:
1118 case DBTYPE_UI2:
1119 return DBTYPE_I2;
1121 case DBTYPE_I4:
1122 case DBTYPE_UI4:
1123 return DBTYPE_I4;
1125 case DBTYPE_I8:
1126 case DBTYPE_UI8:
1127 return DBTYPE_I8;
1129 case DBTYPE_BSTR:
1130 case DBTYPE_STR:
1131 case DBTYPE_WSTR:
1132 return DBTYPE_BSTR;
1134 case DBTYPE_DBDATE:
1135 case DBTYPE_DBTIME:
1136 case DBTYPE_DBTIMESTAMP:
1137 return DBTYPE_DBDATE;
1139 return type;
1142 /* Many src types will convert to this group of dst types */
1143 static inline BOOL common_class(WORD dst_class)
1145 switch(dst_class)
1147 case DBTYPE_EMPTY:
1148 case DBTYPE_NULL:
1149 case DBTYPE_I2:
1150 case DBTYPE_I4:
1151 case DBTYPE_BSTR:
1152 case DBTYPE_BOOL:
1153 case DBTYPE_VARIANT:
1154 case DBTYPE_I8:
1155 case DBTYPE_CY:
1156 case DBTYPE_DECIMAL:
1157 case DBTYPE_NUMERIC:
1158 return TRUE;
1160 return FALSE;
1163 static inline BOOL array_type(DBTYPE type)
1165 return (type >= DBTYPE_I2 && type <= DBTYPE_UI4);
1168 static HRESULT WINAPI convert_CanConvert(IDataConvert* iface,
1169 DBTYPE src_type, DBTYPE dst_type)
1171 convert *This = impl_from_IDataConvert(iface);
1172 DBTYPE src_base_type = src_type & 0x1ff;
1173 DBTYPE dst_base_type = dst_type & 0x1ff;
1174 WORD dst_class = get_dbtype_class(dst_base_type);
1176 TRACE("(%p)->(%d, %d)\n", This, src_type, dst_type);
1178 if(src_type & DBTYPE_VECTOR || dst_type & DBTYPE_VECTOR) return S_FALSE;
1180 if(src_type & DBTYPE_ARRAY)
1182 if(!array_type(src_base_type)) return S_FALSE;
1183 if(dst_type & DBTYPE_ARRAY)
1185 if(src_type == dst_type) return S_OK;
1186 return S_FALSE;
1188 if(dst_type == DBTYPE_VARIANT) return S_OK;
1189 return S_FALSE;
1192 if(dst_type & DBTYPE_ARRAY)
1194 if(!array_type(dst_base_type)) return S_FALSE;
1195 if(src_type == DBTYPE_IDISPATCH || src_type == DBTYPE_VARIANT) return S_OK;
1196 return S_FALSE;
1199 if(dst_type & DBTYPE_BYREF)
1200 if(dst_base_type != DBTYPE_BYTES && dst_base_type != DBTYPE_STR && dst_base_type != DBTYPE_WSTR)
1201 return S_FALSE;
1203 switch(get_dbtype_class(src_base_type))
1205 case DBTYPE_EMPTY:
1206 if(common_class(dst_class)) return S_OK;
1207 switch(dst_class)
1209 case DBTYPE_DATE:
1210 case DBTYPE_GUID:
1211 case DBTYPE_FILETIME:
1212 return S_OK;
1213 default:
1214 if(dst_base_type == DBTYPE_DBTIMESTAMP) return S_OK;
1215 return S_FALSE;
1218 case DBTYPE_NULL:
1219 switch(dst_base_type)
1221 case DBTYPE_NULL:
1222 case DBTYPE_VARIANT:
1223 case DBTYPE_FILETIME: return S_OK;
1224 default: return S_FALSE;
1227 case DBTYPE_I4:
1228 if(dst_base_type == DBTYPE_BYTES) return S_OK;
1229 /* fall through */
1230 case DBTYPE_I2:
1231 if(dst_base_type == DBTYPE_DATE) return S_OK;
1232 /* fall through */
1233 case DBTYPE_DECIMAL:
1234 if(common_class(dst_class)) return S_OK;
1235 if(dst_class == DBTYPE_DBDATE) return S_OK;
1236 return S_FALSE;
1238 case DBTYPE_BOOL:
1239 if(dst_base_type == DBTYPE_DATE) return S_OK;
1240 /* fall through */
1241 case DBTYPE_NUMERIC:
1242 case DBTYPE_CY:
1243 if(common_class(dst_class)) return S_OK;
1244 return S_FALSE;
1246 case DBTYPE_I8:
1247 if(common_class(dst_class)) return S_OK;
1248 switch(dst_base_type)
1250 case DBTYPE_BYTES:
1251 case DBTYPE_FILETIME: return S_OK;
1252 default: return S_FALSE;
1255 case DBTYPE_DATE:
1256 switch(dst_class)
1258 case DBTYPE_EMPTY:
1259 case DBTYPE_NULL:
1260 case DBTYPE_I2:
1261 case DBTYPE_I4:
1262 case DBTYPE_BSTR:
1263 case DBTYPE_BOOL:
1264 case DBTYPE_VARIANT:
1265 case DBTYPE_I8:
1266 case DBTYPE_DATE:
1267 case DBTYPE_DBDATE:
1268 case DBTYPE_FILETIME:
1269 return S_OK;
1270 default: return S_FALSE;
1273 case DBTYPE_IDISPATCH:
1274 case DBTYPE_VARIANT:
1275 switch(dst_base_type)
1277 case DBTYPE_IDISPATCH:
1278 case DBTYPE_ERROR:
1279 case DBTYPE_IUNKNOWN:
1280 return S_OK;
1282 /* fall through */
1283 case DBTYPE_BSTR:
1284 if(common_class(dst_class)) return S_OK;
1285 switch(dst_class)
1287 case DBTYPE_DATE:
1288 case DBTYPE_GUID:
1289 case DBTYPE_BYTES:
1290 case DBTYPE_DBDATE:
1291 case DBTYPE_FILETIME:
1292 return S_OK;
1293 default: return S_FALSE;
1296 case DBTYPE_ERROR:
1297 switch(dst_base_type)
1299 case DBTYPE_BSTR:
1300 case DBTYPE_ERROR:
1301 case DBTYPE_VARIANT:
1302 case DBTYPE_WSTR:
1303 return S_OK;
1304 default: return S_FALSE;
1307 case DBTYPE_IUNKNOWN:
1308 switch(dst_base_type)
1310 case DBTYPE_EMPTY:
1311 case DBTYPE_NULL:
1312 case DBTYPE_IDISPATCH:
1313 case DBTYPE_VARIANT:
1314 case DBTYPE_IUNKNOWN:
1315 return S_OK;
1316 default: return S_FALSE;
1319 case DBTYPE_BYTES:
1320 if(dst_class == DBTYPE_I4 || dst_class == DBTYPE_I8) return S_OK;
1321 /* fall through */
1322 case DBTYPE_GUID:
1323 switch(dst_class)
1325 case DBTYPE_EMPTY:
1326 case DBTYPE_NULL:
1327 case DBTYPE_BSTR:
1328 case DBTYPE_VARIANT:
1329 case DBTYPE_GUID:
1330 case DBTYPE_BYTES:
1331 return S_OK;
1332 default: return S_FALSE;
1335 case DBTYPE_FILETIME:
1336 if(dst_class == DBTYPE_I8) return S_OK;
1337 /* fall through */
1338 case DBTYPE_DBDATE:
1339 switch(dst_class)
1341 case DBTYPE_EMPTY:
1342 case DBTYPE_NULL:
1343 case DBTYPE_DATE:
1344 case DBTYPE_BSTR:
1345 case DBTYPE_VARIANT:
1346 case DBTYPE_DBDATE:
1347 case DBTYPE_FILETIME:
1348 return S_OK;
1349 default: return S_FALSE;
1353 return S_FALSE;
1356 static HRESULT WINAPI convert_GetConversionSize(IDataConvert* iface,
1357 DBTYPE src_type, DBTYPE dst_type,
1358 DBLENGTH *src_len, DBLENGTH *dst_len,
1359 void *src)
1361 convert *This = impl_from_IDataConvert(iface);
1362 HRESULT hr;
1364 TRACE("(%p)->(%d, %d, %p, %p, %p)\n", This, src_type, dst_type, src_len, dst_len, src);
1366 hr = IDataConvert_CanConvert(iface, src_type, dst_type);
1367 if (hr != S_OK)
1368 return DB_E_UNSUPPORTEDCONVERSION;
1370 if (!dst_len)
1371 return E_INVALIDARG;
1373 /* for some types we don't need to look into source data */
1374 if ((*dst_len = get_length(dst_type)))
1375 return S_OK;
1377 *dst_len = 110;
1379 if(src_type == DBTYPE_VARIANT && V_VT((VARIANT*)src) == VT_NULL)
1380 return S_OK;
1382 switch (dst_type)
1384 case DBTYPE_STR:
1385 switch (src_type)
1387 case DBTYPE_VARIANT:
1389 VARIANT v;
1391 VariantInit(&v);
1392 if ((hr = VariantChangeType(&v, (VARIANT*)src, 0, VT_BSTR)) == S_OK)
1394 *dst_len = WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), -1, NULL, 0, NULL, NULL);
1395 VariantClear(&v);
1397 else
1398 return hr;
1400 break;
1401 case DBTYPE_DATE:
1402 case DBTYPE_DECIMAL:
1403 case DBTYPE_EMPTY:
1404 case DBTYPE_I1:
1405 case DBTYPE_I2:
1406 case DBTYPE_UI2:
1407 case DBTYPE_I4:
1408 case DBTYPE_UI4:
1409 case DBTYPE_I8:
1410 case DBTYPE_UI8:
1411 case DBTYPE_R4:
1412 break;
1413 default:
1414 FIXME("unimplemented for %04x -> DBTYPE_STR\n", src_type);
1415 return E_NOTIMPL;
1417 break;
1418 case DBTYPE_WSTR:
1419 switch (src_type)
1421 case DBTYPE_VARIANT:
1423 VARIANT v;
1425 VariantInit(&v);
1426 if ((hr = VariantChangeType(&v, (VARIANT*)src, 0, VT_BSTR)) == S_OK)
1428 *dst_len = (SysStringLen(V_BSTR(&v))+1) * sizeof(WCHAR);
1429 VariantClear(&v);
1432 break;
1433 case DBTYPE_STR:
1434 if(src_len)
1435 *dst_len = (*src_len + 1) * sizeof(WCHAR);
1436 else
1437 *dst_len = (strlen(src) + 1) * sizeof(WCHAR);
1438 break;
1439 case DBTYPE_WSTR:
1440 if(src_len)
1441 *dst_len = (*src_len) + sizeof(WCHAR);
1442 else
1443 *dst_len = (lstrlenW(src) + 1) * sizeof(WCHAR);
1444 break;
1445 case DBTYPE_DATE:
1446 case DBTYPE_DECIMAL:
1447 case DBTYPE_EMPTY:
1448 case DBTYPE_I1:
1449 case DBTYPE_I2:
1450 case DBTYPE_UI2:
1451 case DBTYPE_I4:
1452 case DBTYPE_UI4:
1453 case DBTYPE_I8:
1454 case DBTYPE_UI8:
1455 case DBTYPE_R4:
1456 break;
1457 default:
1458 FIXME("unimplemented for %04x -> DBTYPE_WSTR\n", src_type);
1459 return E_NOTIMPL;
1461 break;
1462 case DBTYPE_BYTES:
1463 switch (src_type)
1465 case DBTYPE_VARIANT:
1466 if(V_VT((VARIANT*)src) == VT_BSTR)
1467 *dst_len = (SysStringLen(V_BSTR((VARIANT*)src))) / sizeof(WCHAR);
1468 else
1470 switch(V_VT((VARIANT*)src))
1472 case VT_UI1 | VT_ARRAY:
1474 LONG l;
1476 hr = SafeArrayGetUBound(V_ARRAY((VARIANT*)src), 1, &l);
1477 if(FAILED(hr))
1478 return hr;
1479 *dst_len = l+1;
1481 break;
1483 default:
1484 WARN("DBTYPE_VARIANT(%d)->DBTYPE_BYTES unimplemented\n", V_VT((VARIANT*)src));
1487 break;
1488 default:
1489 FIXME("unimplemented for %04x -> DBTYPE_BYTES\n", src_type);
1490 return E_NOTIMPL;
1492 break;
1493 default:
1494 FIXME("unimplemented for conversion %d->%d\n", src_type, dst_type);
1495 return E_NOTIMPL;
1498 return S_OK;
1501 static const struct IDataConvertVtbl convert_vtbl =
1503 convert_QueryInterface,
1504 convert_AddRef,
1505 convert_Release,
1506 convert_DataConvert,
1507 convert_CanConvert,
1508 convert_GetConversionSize
1511 static HRESULT WINAPI dcinfo_QueryInterface(IDCInfo* iface, REFIID riid, void **obj)
1513 convert *This = impl_from_IDCInfo(iface);
1515 return IDataConvert_QueryInterface(&This->IDataConvert_iface, riid, obj);
1518 static ULONG WINAPI dcinfo_AddRef(IDCInfo* iface)
1520 convert *This = impl_from_IDCInfo(iface);
1522 return IDataConvert_AddRef(&This->IDataConvert_iface);
1525 static ULONG WINAPI dcinfo_Release(IDCInfo* iface)
1527 convert *This = impl_from_IDCInfo(iface);
1529 return IDataConvert_Release(&This->IDataConvert_iface);
1532 static HRESULT WINAPI dcinfo_GetInfo(IDCInfo *iface, ULONG num, DCINFOTYPE types[], DCINFO **info_ptr)
1534 convert *This = impl_from_IDCInfo(iface);
1535 ULONG i;
1536 DCINFO *infos;
1538 TRACE("(%p)->(%d, %p, %p)\n", This, num, types, info_ptr);
1540 *info_ptr = infos = CoTaskMemAlloc(num * sizeof(*infos));
1541 if(!infos) return E_OUTOFMEMORY;
1543 for(i = 0; i < num; i++)
1545 infos[i].eInfoType = types[i];
1546 VariantInit(&infos[i].vData);
1548 switch(types[i])
1550 case DCINFOTYPE_VERSION:
1551 V_VT(&infos[i].vData) = VT_UI4;
1552 V_UI4(&infos[i].vData) = This->version;
1553 break;
1557 return S_OK;
1560 static HRESULT WINAPI dcinfo_SetInfo(IDCInfo* iface, ULONG num, DCINFO info[])
1562 convert *This = impl_from_IDCInfo(iface);
1563 ULONG i;
1564 HRESULT hr = S_OK;
1566 TRACE("(%p)->(%d, %p)\n", This, num, info);
1568 for(i = 0; i < num; i++)
1570 switch(info[i].eInfoType)
1572 case DCINFOTYPE_VERSION:
1573 if(V_VT(&info[i].vData) != VT_UI4)
1575 FIXME("VERSION with vt %x\n", V_VT(&info[i].vData));
1576 hr = DB_S_ERRORSOCCURRED;
1577 break;
1579 This->version = V_UI4(&info[i].vData);
1580 break;
1582 default:
1583 FIXME("Unhandled info type %d (vt %x)\n", info[i].eInfoType, V_VT(&info[i].vData));
1586 return hr;
1589 static const struct IDCInfoVtbl dcinfo_vtbl =
1591 dcinfo_QueryInterface,
1592 dcinfo_AddRef,
1593 dcinfo_Release,
1594 dcinfo_GetInfo,
1595 dcinfo_SetInfo
1598 HRESULT create_oledb_convert(IUnknown *outer, void **obj)
1600 convert *This;
1602 TRACE("(%p, %p)\n", outer, obj);
1604 *obj = NULL;
1606 if(outer) return CLASS_E_NOAGGREGATION;
1608 This = heap_alloc(sizeof(*This));
1609 if(!This) return E_OUTOFMEMORY;
1611 This->IDataConvert_iface.lpVtbl = &convert_vtbl;
1612 This->IDCInfo_iface.lpVtbl = &dcinfo_vtbl;
1613 This->ref = 1;
1614 This->version = 0x110;
1616 *obj = &This->IDataConvert_iface;
1618 return S_OK;