gdiplus: Implement transform matrix for line gradient brushes.
[wine.git] / dlls / oledb32 / convert.c
blob7fa4c81e483a316ea0a2eaf712d8dd7f187971b9
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_DBTIMESTAMP:
646 WCHAR szBuff[64];
647 static const WCHAR format1[] = {
648 '%','0','4','d','-','%','0','2','d','-','%','0','2','d',' ','%','0','2','d',':','%','0','2','d',
649 ':','%','0','2','d', 0};
650 static const WCHAR format2[] = {
651 '%','0','4','d','-','%','0','2','d','-','%','0','2','d',' ','%','0','2','d',':','%','0','2','d',
652 ':','%','0','2','d','.','%','0','9','d', 0};
653 DBTIMESTAMP *ts = (DBTIMESTAMP *)src;
655 if(ts->fraction == 0)
656 wsprintfW(szBuff, format1, ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second);
657 else
658 wsprintfW(szBuff, format2, ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second, ts->fraction );
659 *d = SysAllocString(szBuff);
660 hr = *d ? S_OK : E_OUTOFMEMORY;
661 break;
663 case DBTYPE_VARIANT:
664 VariantInit(&tmp);
665 if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_BSTR)) == S_OK)
666 *d = V_BSTR(&tmp);
667 break;
668 default: FIXME("Unimplemented conversion %04x -> BSTR\n", src_type); return E_NOTIMPL;
670 break;
673 case DBTYPE_UI1:
675 BYTE *d = dst;
676 switch(src_type)
678 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
679 case DBTYPE_I2: hr = VarUI1FromI2(*(signed short*)src, d); break;
680 case DBTYPE_I4: hr = VarUI1FromI4(*(signed int*)src, d); break;
681 case DBTYPE_R4: hr = VarUI1FromR4(*(FLOAT*)src, d); break;
682 case DBTYPE_R8: hr = VarUI1FromR8(*(double*)src, d); break;
683 case DBTYPE_CY: hr = VarUI1FromCy(*(CY*)src, d); break;
684 case DBTYPE_DATE: hr = VarUI1FromDate(*(DATE*)src, d); break;
685 case DBTYPE_BSTR: hr = VarUI1FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
686 case DBTYPE_BOOL: hr = VarUI1FromBool(*(VARIANT_BOOL*)src, d); break;
687 case DBTYPE_DECIMAL: hr = VarUI1FromDec((DECIMAL*)src, d); break;
688 case DBTYPE_I1: hr = VarUI1FromI1(*(signed char*)src, d); break;
689 case DBTYPE_UI1: *d = *(BYTE*)src; hr = S_OK; break;
690 case DBTYPE_UI2: hr = VarUI1FromUI2(*(WORD*)src, d); break;
691 case DBTYPE_UI4: hr = VarUI1FromUI4(*(DWORD*)src, d); break;
692 case DBTYPE_I8: hr = VarUI1FromI8(*(LONGLONG*)src, d); break;
693 case DBTYPE_UI8: hr = VarUI1FromUI8(*(ULONGLONG*)src, d); break;
694 default: FIXME("Unimplemented conversion %04x -> UI1\n", src_type); return E_NOTIMPL;
696 break;
698 case DBTYPE_UI2:
700 WORD *d = dst;
701 switch(src_type)
703 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
704 case DBTYPE_I2: hr = VarUI2FromI2(*(signed short*)src, d); break;
705 case DBTYPE_I4: hr = VarUI2FromI4(*(signed int*)src, d); break;
706 case DBTYPE_R4: hr = VarUI2FromR4(*(FLOAT*)src, d); break;
707 case DBTYPE_R8: hr = VarUI2FromR8(*(double*)src, d); break;
708 case DBTYPE_CY: hr = VarUI2FromCy(*(CY*)src, d); break;
709 case DBTYPE_DATE: hr = VarUI2FromDate(*(DATE*)src, d); break;
710 case DBTYPE_BSTR: hr = VarUI2FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
711 case DBTYPE_BOOL: hr = VarUI2FromBool(*(VARIANT_BOOL*)src, d); break;
712 case DBTYPE_DECIMAL: hr = VarUI2FromDec((DECIMAL*)src, d); break;
713 case DBTYPE_I1: hr = VarUI2FromI1(*(signed char*)src, d); break;
714 case DBTYPE_UI1: hr = VarUI2FromUI1(*(BYTE*)src, d); break;
715 case DBTYPE_UI2: *d = *(WORD*)src; hr = S_OK; break;
716 case DBTYPE_UI4: hr = VarUI2FromUI4(*(DWORD*)src, d); break;
717 case DBTYPE_I8: hr = VarUI2FromI8(*(LONGLONG*)src, d); break;
718 case DBTYPE_UI8: hr = VarUI2FromUI8(*(ULONGLONG*)src, d); break;
719 default: FIXME("Unimplemented conversion %04x -> UI2\n", src_type); return E_NOTIMPL;
721 break;
724 case DBTYPE_UI4:
726 DWORD *d = dst;
727 switch(src_type)
729 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
730 case DBTYPE_I2: hr = VarUI4FromI2(*(signed short*)src, d); break;
731 case DBTYPE_I4: hr = VarUI4FromI4(*(signed int*)src, d); break;
732 case DBTYPE_R4: hr = VarUI4FromR4(*(FLOAT*)src, d); break;
733 case DBTYPE_R8: hr = VarUI4FromR8(*(double*)src, d); break;
734 case DBTYPE_CY: hr = VarUI4FromCy(*(CY*)src, d); break;
735 case DBTYPE_DATE: hr = VarUI4FromDate(*(DATE*)src, d); break;
736 case DBTYPE_BSTR: hr = VarUI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
737 case DBTYPE_BOOL: hr = VarUI4FromBool(*(VARIANT_BOOL*)src, d); break;
738 case DBTYPE_DECIMAL: hr = VarUI4FromDec((DECIMAL*)src, d); break;
739 case DBTYPE_I1: hr = VarUI4FromI1(*(signed char*)src, d); break;
740 case DBTYPE_UI1: hr = VarUI4FromUI1(*(BYTE*)src, d); break;
741 case DBTYPE_UI2: hr = VarUI4FromUI2(*(WORD*)src, d); break;
742 case DBTYPE_UI4: *d = *(DWORD*)src; hr = S_OK; break;
743 case DBTYPE_I8: hr = VarUI4FromI8(*(LONGLONG*)src, d); break;
744 case DBTYPE_UI8: hr = VarUI4FromUI8(*(ULONGLONG*)src, d); break;
745 case DBTYPE_VARIANT:
746 VariantInit(&tmp);
747 if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_UI4)) == S_OK)
748 *d = V_UI4(&tmp);
749 break;
750 default: FIXME("Unimplemented conversion %04x -> UI4\n", src_type); return E_NOTIMPL;
752 break;
755 case DBTYPE_UI8:
757 ULONGLONG *d = dst;
758 switch(src_type)
760 case DBTYPE_EMPTY: *d = 0; hr = S_OK; break;
761 case DBTYPE_I2: hr = VarUI8FromI2(*(signed short*)src, d); break;
762 case DBTYPE_I4: {LONGLONG s = *(signed int*)src; hr = VarUI8FromI8(s, d); break;}
763 case DBTYPE_R4: hr = VarUI8FromR4(*(FLOAT*)src, d); break;
764 case DBTYPE_R8: hr = VarUI8FromR8(*(double*)src, d); break;
765 case DBTYPE_CY: hr = VarUI8FromCy(*(CY*)src, d); break;
766 case DBTYPE_DATE: hr = VarUI8FromDate(*(DATE*)src, d); break;
767 case DBTYPE_BSTR: hr = VarUI8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
768 case DBTYPE_BOOL: hr = VarUI8FromBool(*(VARIANT_BOOL*)src, d); break;
769 case DBTYPE_DECIMAL: hr = VarUI8FromDec((DECIMAL*)src, d); break;
770 case DBTYPE_I1: hr = VarUI8FromI1(*(signed char*)src, d); break;
771 case DBTYPE_UI1: hr = VarUI8FromUI1(*(BYTE*)src, d); break;
772 case DBTYPE_UI2: hr = VarUI8FromUI2(*(WORD*)src, d); break;
773 case DBTYPE_UI4: hr = VarUI8FromUI4(*(DWORD*)src, d); break;
774 case DBTYPE_I8: hr = VarUI8FromI8(*(LONGLONG*)src, d); break;
775 case DBTYPE_UI8: *d = *(ULONGLONG*)src; hr = S_OK; break;
776 default: FIXME("Unimplemented conversion %04x -> UI8\n", src_type); return E_NOTIMPL;
778 break;
781 case DBTYPE_FILETIME:
783 FILETIME *d = dst;
784 switch(src_type)
786 case DBTYPE_EMPTY: d->dwLowDateTime = d->dwHighDateTime = 0; hr = S_OK; break;
787 case DBTYPE_FILETIME: *d = *(FILETIME*)src; hr = S_OK; break;
788 default: FIXME("Unimplemented conversion %04x -> FILETIME\n", src_type); return E_NOTIMPL;
790 break;
793 case DBTYPE_GUID:
795 GUID *d = dst;
796 switch(src_type)
798 case DBTYPE_EMPTY: *d = GUID_NULL; hr = S_OK; break;
799 case DBTYPE_GUID: *d = *(GUID*)src; hr = S_OK; break;
800 default: FIXME("Unimplemented conversion %04x -> GUID\n", src_type); return E_NOTIMPL;
802 break;
805 case DBTYPE_WSTR:
807 BSTR b;
808 DBLENGTH bstr_len;
809 INT bytes_to_copy;
810 hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
811 src, &b, sizeof(BSTR), src_status, dst_status,
812 precision, scale, flags);
813 if(hr != S_OK || *dst_status == DBSTATUS_S_ISNULL)
814 return hr;
815 bstr_len = SysStringLen(b);
816 *dst_len = bstr_len * sizeof(WCHAR); /* Doesn't include size for '\0' */
817 *dst_status = DBSTATUS_S_OK;
818 bytes_to_copy = min(*dst_len + sizeof(WCHAR), dst_max_len);
819 if(dst)
821 if(bytes_to_copy >= sizeof(WCHAR))
823 memcpy(dst, b, bytes_to_copy - sizeof(WCHAR));
824 *((WCHAR*)dst + bytes_to_copy / sizeof(WCHAR) - 1) = 0;
825 if(bytes_to_copy < *dst_len + sizeof(WCHAR))
826 *dst_status = DBSTATUS_S_TRUNCATED;
828 else
830 *dst_status = DBSTATUS_E_DATAOVERFLOW;
831 hr = DB_E_ERRORSOCCURRED;
834 SysFreeString(b);
835 return hr;
838 case DBTYPE_STR:
840 BSTR b;
841 DBLENGTH length;
842 INT bytes_to_copy;
843 hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &length,
844 src, &b, sizeof(BSTR), src_status, dst_status,
845 precision, scale, flags);
846 if(hr != S_OK) return hr;
847 length = WideCharToMultiByte(CP_ACP, 0, b, SysStringLen(b), NULL, 0, NULL, NULL);
848 *dst_len = length; /* Doesn't include size for '\0' */
849 *dst_status = DBSTATUS_S_OK;
850 bytes_to_copy = min(length + 1, dst_max_len);
851 if(dst)
853 if(bytes_to_copy >= sizeof(char))
855 WideCharToMultiByte(CP_ACP, 0, b, SysStringLen(b), dst, bytes_to_copy - 1, NULL, NULL);
856 *((char *)dst + bytes_to_copy - 1) = 0;
857 if(bytes_to_copy < length + 1)
858 *dst_status = DBSTATUS_S_TRUNCATED;
860 else
862 *dst_status = DBSTATUS_E_DATAOVERFLOW;
863 hr = DB_E_ERRORSOCCURRED;
866 SysFreeString(b);
867 return hr;
870 case DBTYPE_BYREF | DBTYPE_WSTR:
872 BSTR b;
873 WCHAR **d = dst;
874 DBLENGTH bstr_len;
875 hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
876 src, &b, sizeof(BSTR), src_status, dst_status,
877 precision, scale, flags);
878 if(hr != S_OK) return hr;
880 bstr_len = SysStringLen(b) * sizeof(WCHAR);
881 *dst_len = bstr_len; /* Doesn't include size for '\0' */
883 *d = CoTaskMemAlloc(bstr_len + sizeof(WCHAR));
884 if(*d) memcpy(*d, b, bstr_len + sizeof(WCHAR));
885 else hr = E_OUTOFMEMORY;
886 SysFreeString(b);
887 return hr;
890 case DBTYPE_BYREF | DBTYPE_STR:
892 BSTR b;
893 char **d = dst;
894 DBLENGTH length;
895 hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &length,
896 src, &b, sizeof(BSTR), src_status, dst_status,
897 precision, scale, flags);
898 if(hr != S_OK) return hr;
900 length = WideCharToMultiByte(CP_ACP, 0, b, SysStringLen(b) + 1, NULL, 0, NULL, NULL);
901 *dst_len = length - 1; /* Doesn't include size for '\0' */
902 *dst_status = DBSTATUS_S_OK;
903 *d = CoTaskMemAlloc(length);
905 if(*d)
906 WideCharToMultiByte(CP_ACP, 0, b, SysStringLen(b) + 1, *d, length, NULL, NULL);
907 else
908 hr = E_OUTOFMEMORY;
909 SysFreeString(b);
911 return hr;
914 case DBTYPE_VARIANT:
916 VARIANT *v = dst;
918 switch(src_type)
920 case DBTYPE_BOOL:
921 V_VT(v) = VT_BOOL;
922 V_BOOL(v) = *(VARIANT_BOOL*)src;
923 hr = S_OK;
924 break;
925 case DBTYPE_I2:
926 V_VT(v) = VT_I2;
927 V_I2(v) = *(signed short*)src;
928 hr = S_OK;
929 break;
930 case DBTYPE_I4:
931 V_VT(v) = VT_I4;
932 V_I4(v) = *(signed int*)src;
933 hr = S_OK;
934 break;
935 case DBTYPE_I8:
936 V_VT(v) = VT_DECIMAL;
937 hr = VarDecFromI8( *(LONGLONG*)src, &V_DECIMAL(v));
938 break;
939 case DBTYPE_R4:
940 V_VT(v) = VT_R4;
941 V_R4(v) = *(FLOAT*)src;
942 hr = S_OK;
943 break;
944 case DBTYPE_R8:
945 V_VT(v) = VT_R8;
946 V_R8(v) = *(double*)src;
947 hr = S_OK;
948 break;
949 case DBTYPE_BSTR:
951 BSTR s = *(WCHAR**)src;
952 TRACE("%s\n", debugstr_w(s));
953 V_VT(v) = VT_BSTR;
954 V_BSTR(v) = SysAllocString(s);
955 hr = V_BSTR(v) ? S_OK : E_OUTOFMEMORY;
956 break;
958 case DBTYPE_DATE:
959 V_VT(v) = VT_DATE;
960 V_DATE(v) = *(DATE*)src;
961 hr = S_OK;
962 break;
963 case DBTYPE_DBDATE:
965 SYSTEMTIME st;
966 DBDATE *ts=(DBDATE*)src;
968 V_VT(v) = VT_DATE;
970 st.wYear = ts->year;
971 st.wMonth = ts->month;
972 st.wDay = ts->day;
973 st.wHour = 0;
974 st.wMinute = 0;
975 st.wSecond = 0;
976 st.wMilliseconds = 0;
977 hr = (SystemTimeToVariantTime(&st, &V_DATE(v)) ? S_OK : E_FAIL);
978 break;
980 case DBTYPE_DBTIMESTAMP:
982 SYSTEMTIME st;
983 DBTIMESTAMP *ts = (DBTIMESTAMP *)src;
985 V_VT(v) = VT_DATE;
987 st.wYear = ts->year;
988 st.wMonth = ts->month;
989 st.wDay = ts->day;
990 st.wHour = ts->hour;
991 st.wMinute = ts->minute;
992 st.wSecond = ts->second;
993 st.wMilliseconds = ts->fraction/1000000;
994 hr = SystemTimeToVariantTime(&st, &V_DATE(v)) ? S_OK : E_FAIL;
995 break;
997 case DBTYPE_CY:
998 V_VT(v) = VT_CY;
999 V_CY(v) = *(CY*)src;
1000 hr = S_OK;
1001 break;
1002 case DBTYPE_BYTES:
1004 LONG i;
1005 SAFEARRAY *psa = NULL;
1006 SAFEARRAYBOUND rgsabound[1];
1007 unsigned char *p = src;
1009 rgsabound[0].lLbound = 0;
1010 rgsabound[0].cElements = src_len;
1012 psa = SafeArrayCreate(VT_UI1,1,rgsabound);
1013 for(i =0; i < src_len; i++,p++)
1015 hr = SafeArrayPutElement(psa, &i, p);
1016 if(FAILED(hr)) {
1017 SafeArrayDestroy (psa);
1018 return hr;
1022 V_VT(v) = VT_ARRAY|VT_UI1;
1023 V_ARRAY(v) = psa;
1024 hr = S_OK;
1025 break;
1027 default: FIXME("Unimplemented conversion %04x -> VARIANT\n", src_type); return E_NOTIMPL;
1029 break;
1031 case DBTYPE_BYTES:
1033 BYTE *d = dst;
1035 switch(src_type)
1037 case DBTYPE_BYTES:
1038 if( src_len > dst_max_len)
1039 *dst_status = DBSTATUS_S_TRUNCATED;
1040 else
1041 *dst_status = DBSTATUS_S_OK;
1043 *dst_len = src_len;
1044 memcpy(d, src, min(src_len, dst_max_len));
1046 return S_OK;
1047 case DBTYPE_VARIANT:
1049 switch(V_VT((VARIANT*)src))
1051 case VT_UI1 | VT_ARRAY:
1053 LONG l;
1054 BYTE *data = NULL;
1056 hr = SafeArrayGetUBound(V_ARRAY((VARIANT*)src), 1, &l);
1057 if(FAILED(hr))
1058 return hr;
1060 hr = SafeArrayAccessData(V_ARRAY((VARIANT*)src), (VOID**)&data);
1061 if(FAILED(hr))
1063 ERR("SafeArrayAccessData Failed = 0x%08x\n", hr);
1064 return hr;
1067 *dst_len = l+1;
1068 *dst_status = DBSTATUS_S_OK;
1069 memcpy(d, data, *dst_len);
1071 SafeArrayUnaccessData(V_ARRAY((VARIANT*)src));
1072 return S_OK;
1074 break;
1075 default:
1076 FIXME("Unimplemented variant type %d -> BYTES\n", V_VT((VARIANT*)src));
1077 return E_NOTIMPL;
1080 break;
1081 default: FIXME("Unimplemented conversion %04x -> DBTYPE_BYTES\n", src_type); return E_NOTIMPL;
1083 break;
1085 case DBTYPE_BYTES | DBTYPE_BYREF:
1087 BYTE **d = dst;
1089 switch(src_type)
1091 case DBTYPE_BYTES:
1092 *d = CoTaskMemAlloc(src_len);
1093 if(*d) memcpy(*d, src, src_len);
1094 else hr = E_OUTOFMEMORY;
1096 *dst_len = src_len;
1097 *dst_status = DBSTATUS_S_OK;
1098 return S_OK;
1099 default: FIXME("Unimplemented conversion %04x -> DBTYPE_BYTES | DBTYPE_BYREF\n", src_type); return E_NOTIMPL;
1101 break;
1104 case DBTYPE_NUMERIC:
1105 FIXME("Unimplemented conversion %04x -> DBTYPE_NUMERIC\n", src_type);
1106 return E_NOTIMPL;
1108 default:
1109 FIXME("Unimplemented conversion %04x -> %04x\n", src_type, dst_type);
1110 return E_NOTIMPL;
1113 if(hr == DISP_E_OVERFLOW)
1115 *dst_status = DBSTATUS_E_DATAOVERFLOW;
1116 *dst_len = get_length(dst_type);
1117 hr = DB_E_ERRORSOCCURRED;
1119 else if(hr == S_OK)
1121 *dst_status = DBSTATUS_S_OK;
1122 *dst_len = get_length(dst_type);
1125 return hr;
1128 static inline WORD get_dbtype_class(DBTYPE type)
1130 switch(type)
1132 case DBTYPE_I2:
1133 case DBTYPE_R4:
1134 case DBTYPE_R8:
1135 case DBTYPE_I1:
1136 case DBTYPE_UI1:
1137 case DBTYPE_UI2:
1138 return DBTYPE_I2;
1140 case DBTYPE_I4:
1141 case DBTYPE_UI4:
1142 return DBTYPE_I4;
1144 case DBTYPE_I8:
1145 case DBTYPE_UI8:
1146 return DBTYPE_I8;
1148 case DBTYPE_BSTR:
1149 case DBTYPE_STR:
1150 case DBTYPE_WSTR:
1151 return DBTYPE_BSTR;
1153 case DBTYPE_DBDATE:
1154 case DBTYPE_DBTIME:
1155 case DBTYPE_DBTIMESTAMP:
1156 return DBTYPE_DBDATE;
1158 return type;
1161 /* Many src types will convert to this group of dst types */
1162 static inline BOOL common_class(WORD dst_class)
1164 switch(dst_class)
1166 case DBTYPE_EMPTY:
1167 case DBTYPE_NULL:
1168 case DBTYPE_I2:
1169 case DBTYPE_I4:
1170 case DBTYPE_BSTR:
1171 case DBTYPE_BOOL:
1172 case DBTYPE_VARIANT:
1173 case DBTYPE_I8:
1174 case DBTYPE_CY:
1175 case DBTYPE_DECIMAL:
1176 case DBTYPE_NUMERIC:
1177 return TRUE;
1179 return FALSE;
1182 static inline BOOL array_type(DBTYPE type)
1184 return (type >= DBTYPE_I2 && type <= DBTYPE_UI4);
1187 static HRESULT WINAPI convert_CanConvert(IDataConvert* iface,
1188 DBTYPE src_type, DBTYPE dst_type)
1190 convert *This = impl_from_IDataConvert(iface);
1191 DBTYPE src_base_type = src_type & 0x1ff;
1192 DBTYPE dst_base_type = dst_type & 0x1ff;
1193 WORD dst_class = get_dbtype_class(dst_base_type);
1195 TRACE("(%p)->(%d, %d)\n", This, src_type, dst_type);
1197 if(src_type & DBTYPE_VECTOR || dst_type & DBTYPE_VECTOR) return S_FALSE;
1199 if(src_type & DBTYPE_ARRAY)
1201 if(!array_type(src_base_type)) return S_FALSE;
1202 if(dst_type & DBTYPE_ARRAY)
1204 if(src_type == dst_type) return S_OK;
1205 return S_FALSE;
1207 if(dst_type == DBTYPE_VARIANT) return S_OK;
1208 return S_FALSE;
1211 if(dst_type & DBTYPE_ARRAY)
1213 if(!array_type(dst_base_type)) return S_FALSE;
1214 if(src_type == DBTYPE_IDISPATCH || src_type == DBTYPE_VARIANT) return S_OK;
1215 return S_FALSE;
1218 if(dst_type & DBTYPE_BYREF)
1219 if(dst_base_type != DBTYPE_BYTES && dst_base_type != DBTYPE_STR && dst_base_type != DBTYPE_WSTR)
1220 return S_FALSE;
1222 switch(get_dbtype_class(src_base_type))
1224 case DBTYPE_EMPTY:
1225 if(common_class(dst_class)) return S_OK;
1226 switch(dst_class)
1228 case DBTYPE_DATE:
1229 case DBTYPE_GUID:
1230 case DBTYPE_FILETIME:
1231 return S_OK;
1232 default:
1233 if(dst_base_type == DBTYPE_DBTIMESTAMP) return S_OK;
1234 return S_FALSE;
1237 case DBTYPE_NULL:
1238 switch(dst_base_type)
1240 case DBTYPE_NULL:
1241 case DBTYPE_VARIANT:
1242 case DBTYPE_FILETIME: return S_OK;
1243 default: return S_FALSE;
1246 case DBTYPE_I4:
1247 if(dst_base_type == DBTYPE_BYTES) return S_OK;
1248 /* fall through */
1249 case DBTYPE_I2:
1250 if(dst_base_type == DBTYPE_DATE) return S_OK;
1251 /* fall through */
1252 case DBTYPE_DECIMAL:
1253 if(common_class(dst_class)) return S_OK;
1254 if(dst_class == DBTYPE_DBDATE) return S_OK;
1255 return S_FALSE;
1257 case DBTYPE_BOOL:
1258 if(dst_base_type == DBTYPE_DATE) return S_OK;
1259 /* fall through */
1260 case DBTYPE_NUMERIC:
1261 case DBTYPE_CY:
1262 if(common_class(dst_class)) return S_OK;
1263 return S_FALSE;
1265 case DBTYPE_I8:
1266 if(common_class(dst_class)) return S_OK;
1267 switch(dst_base_type)
1269 case DBTYPE_BYTES:
1270 case DBTYPE_FILETIME: return S_OK;
1271 default: return S_FALSE;
1274 case DBTYPE_DATE:
1275 switch(dst_class)
1277 case DBTYPE_EMPTY:
1278 case DBTYPE_NULL:
1279 case DBTYPE_I2:
1280 case DBTYPE_I4:
1281 case DBTYPE_BSTR:
1282 case DBTYPE_BOOL:
1283 case DBTYPE_VARIANT:
1284 case DBTYPE_I8:
1285 case DBTYPE_DATE:
1286 case DBTYPE_DBDATE:
1287 case DBTYPE_FILETIME:
1288 return S_OK;
1289 default: return S_FALSE;
1292 case DBTYPE_IDISPATCH:
1293 case DBTYPE_VARIANT:
1294 switch(dst_base_type)
1296 case DBTYPE_IDISPATCH:
1297 case DBTYPE_ERROR:
1298 case DBTYPE_IUNKNOWN:
1299 return S_OK;
1301 /* fall through */
1302 case DBTYPE_BSTR:
1303 if(common_class(dst_class)) return S_OK;
1304 switch(dst_class)
1306 case DBTYPE_DATE:
1307 case DBTYPE_GUID:
1308 case DBTYPE_BYTES:
1309 case DBTYPE_DBDATE:
1310 case DBTYPE_FILETIME:
1311 return S_OK;
1312 default: return S_FALSE;
1315 case DBTYPE_ERROR:
1316 switch(dst_base_type)
1318 case DBTYPE_BSTR:
1319 case DBTYPE_ERROR:
1320 case DBTYPE_VARIANT:
1321 case DBTYPE_WSTR:
1322 return S_OK;
1323 default: return S_FALSE;
1326 case DBTYPE_IUNKNOWN:
1327 switch(dst_base_type)
1329 case DBTYPE_EMPTY:
1330 case DBTYPE_NULL:
1331 case DBTYPE_IDISPATCH:
1332 case DBTYPE_VARIANT:
1333 case DBTYPE_IUNKNOWN:
1334 return S_OK;
1335 default: return S_FALSE;
1338 case DBTYPE_BYTES:
1339 if(dst_class == DBTYPE_I4 || dst_class == DBTYPE_I8) return S_OK;
1340 /* fall through */
1341 case DBTYPE_GUID:
1342 switch(dst_class)
1344 case DBTYPE_EMPTY:
1345 case DBTYPE_NULL:
1346 case DBTYPE_BSTR:
1347 case DBTYPE_VARIANT:
1348 case DBTYPE_GUID:
1349 case DBTYPE_BYTES:
1350 return S_OK;
1351 default: return S_FALSE;
1354 case DBTYPE_FILETIME:
1355 if(dst_class == DBTYPE_I8) return S_OK;
1356 /* fall through */
1357 case DBTYPE_DBDATE:
1358 switch(dst_class)
1360 case DBTYPE_EMPTY:
1361 case DBTYPE_NULL:
1362 case DBTYPE_DATE:
1363 case DBTYPE_BSTR:
1364 case DBTYPE_VARIANT:
1365 case DBTYPE_DBDATE:
1366 case DBTYPE_FILETIME:
1367 return S_OK;
1368 default: return S_FALSE;
1372 return S_FALSE;
1375 static HRESULT WINAPI convert_GetConversionSize(IDataConvert* iface,
1376 DBTYPE src_type, DBTYPE dst_type,
1377 DBLENGTH *src_len, DBLENGTH *dst_len,
1378 void *src)
1380 convert *This = impl_from_IDataConvert(iface);
1381 HRESULT hr;
1383 TRACE("(%p)->(%d, %d, %p, %p, %p)\n", This, src_type, dst_type, src_len, dst_len, src);
1385 hr = IDataConvert_CanConvert(iface, src_type, dst_type);
1386 if (hr != S_OK)
1387 return DB_E_UNSUPPORTEDCONVERSION;
1389 if (!dst_len)
1390 return E_INVALIDARG;
1392 /* for some types we don't need to look into source data */
1393 if ((*dst_len = get_length(dst_type)))
1394 return S_OK;
1396 *dst_len = 110;
1398 if(src_type == DBTYPE_VARIANT && V_VT((VARIANT*)src) == VT_NULL)
1399 return S_OK;
1401 switch (dst_type)
1403 case DBTYPE_STR:
1404 switch (src_type)
1406 case DBTYPE_VARIANT:
1408 VARIANT v;
1410 VariantInit(&v);
1411 if ((hr = VariantChangeType(&v, (VARIANT*)src, 0, VT_BSTR)) == S_OK)
1413 *dst_len = WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), -1, NULL, 0, NULL, NULL);
1414 VariantClear(&v);
1416 else
1417 return hr;
1419 break;
1420 case DBTYPE_DATE:
1421 case DBTYPE_DECIMAL:
1422 case DBTYPE_EMPTY:
1423 case DBTYPE_I1:
1424 case DBTYPE_I2:
1425 case DBTYPE_UI2:
1426 case DBTYPE_I4:
1427 case DBTYPE_UI4:
1428 case DBTYPE_I8:
1429 case DBTYPE_UI8:
1430 case DBTYPE_R4:
1431 case DBTYPE_DBDATE:
1432 case DBTYPE_DBTIMESTAMP:
1433 case DBTYPE_DBTIME:
1434 break;
1435 default:
1436 FIXME("unimplemented for %04x -> DBTYPE_STR\n", src_type);
1437 return E_NOTIMPL;
1439 break;
1440 case DBTYPE_WSTR:
1441 switch (src_type)
1443 case DBTYPE_VARIANT:
1445 VARIANT v;
1447 VariantInit(&v);
1448 if ((hr = VariantChangeType(&v, (VARIANT*)src, 0, VT_BSTR)) == S_OK)
1450 *dst_len = (SysStringLen(V_BSTR(&v))+1) * sizeof(WCHAR);
1451 VariantClear(&v);
1454 break;
1455 case DBTYPE_STR:
1456 if(src_len)
1457 *dst_len = (*src_len + 1) * sizeof(WCHAR);
1458 else
1459 *dst_len = (strlen(src) + 1) * sizeof(WCHAR);
1460 break;
1461 case DBTYPE_WSTR:
1462 if(src_len)
1463 *dst_len = (*src_len) + sizeof(WCHAR);
1464 else
1465 *dst_len = (lstrlenW(src) + 1) * sizeof(WCHAR);
1466 break;
1467 case DBTYPE_DATE:
1468 case DBTYPE_DECIMAL:
1469 case DBTYPE_EMPTY:
1470 case DBTYPE_I1:
1471 case DBTYPE_I2:
1472 case DBTYPE_UI2:
1473 case DBTYPE_I4:
1474 case DBTYPE_UI4:
1475 case DBTYPE_I8:
1476 case DBTYPE_UI8:
1477 case DBTYPE_R4:
1478 case DBTYPE_DBDATE:
1479 case DBTYPE_DBTIMESTAMP:
1480 case DBTYPE_DBTIME:
1481 break;
1482 default:
1483 FIXME("unimplemented for %04x -> DBTYPE_WSTR\n", src_type);
1484 return E_NOTIMPL;
1486 break;
1487 case DBTYPE_BYTES:
1488 switch (src_type)
1490 case DBTYPE_VARIANT:
1491 if(V_VT((VARIANT*)src) == VT_BSTR)
1492 *dst_len = (SysStringLen(V_BSTR((VARIANT*)src))) / sizeof(WCHAR);
1493 else
1495 switch(V_VT((VARIANT*)src))
1497 case VT_UI1 | VT_ARRAY:
1499 LONG l;
1501 hr = SafeArrayGetUBound(V_ARRAY((VARIANT*)src), 1, &l);
1502 if(FAILED(hr))
1503 return hr;
1504 *dst_len = l+1;
1506 break;
1508 default:
1509 WARN("DBTYPE_VARIANT(%d)->DBTYPE_BYTES unimplemented\n", V_VT((VARIANT*)src));
1512 break;
1513 default:
1514 FIXME("unimplemented for %04x -> DBTYPE_BYTES\n", src_type);
1515 return E_NOTIMPL;
1517 break;
1518 default:
1519 FIXME("unimplemented for conversion %d->%d\n", src_type, dst_type);
1520 return E_NOTIMPL;
1523 return S_OK;
1526 static const struct IDataConvertVtbl convert_vtbl =
1528 convert_QueryInterface,
1529 convert_AddRef,
1530 convert_Release,
1531 convert_DataConvert,
1532 convert_CanConvert,
1533 convert_GetConversionSize
1536 static HRESULT WINAPI dcinfo_QueryInterface(IDCInfo* iface, REFIID riid, void **obj)
1538 convert *This = impl_from_IDCInfo(iface);
1540 return IDataConvert_QueryInterface(&This->IDataConvert_iface, riid, obj);
1543 static ULONG WINAPI dcinfo_AddRef(IDCInfo* iface)
1545 convert *This = impl_from_IDCInfo(iface);
1547 return IDataConvert_AddRef(&This->IDataConvert_iface);
1550 static ULONG WINAPI dcinfo_Release(IDCInfo* iface)
1552 convert *This = impl_from_IDCInfo(iface);
1554 return IDataConvert_Release(&This->IDataConvert_iface);
1557 static HRESULT WINAPI dcinfo_GetInfo(IDCInfo *iface, ULONG num, DCINFOTYPE types[], DCINFO **info_ptr)
1559 convert *This = impl_from_IDCInfo(iface);
1560 ULONG i;
1561 DCINFO *infos;
1563 TRACE("(%p)->(%d, %p, %p)\n", This, num, types, info_ptr);
1565 *info_ptr = infos = CoTaskMemAlloc(num * sizeof(*infos));
1566 if(!infos) return E_OUTOFMEMORY;
1568 for(i = 0; i < num; i++)
1570 infos[i].eInfoType = types[i];
1571 VariantInit(&infos[i].vData);
1573 switch(types[i])
1575 case DCINFOTYPE_VERSION:
1576 V_VT(&infos[i].vData) = VT_UI4;
1577 V_UI4(&infos[i].vData) = This->version;
1578 break;
1582 return S_OK;
1585 static HRESULT WINAPI dcinfo_SetInfo(IDCInfo* iface, ULONG num, DCINFO info[])
1587 convert *This = impl_from_IDCInfo(iface);
1588 ULONG i;
1589 HRESULT hr = S_OK;
1591 TRACE("(%p)->(%d, %p)\n", This, num, info);
1593 for(i = 0; i < num; i++)
1595 switch(info[i].eInfoType)
1597 case DCINFOTYPE_VERSION:
1598 if(V_VT(&info[i].vData) != VT_UI4)
1600 FIXME("VERSION with vt %x\n", V_VT(&info[i].vData));
1601 hr = DB_S_ERRORSOCCURRED;
1602 break;
1604 This->version = V_UI4(&info[i].vData);
1605 break;
1607 default:
1608 FIXME("Unhandled info type %d (vt %x)\n", info[i].eInfoType, V_VT(&info[i].vData));
1611 return hr;
1614 static const struct IDCInfoVtbl dcinfo_vtbl =
1616 dcinfo_QueryInterface,
1617 dcinfo_AddRef,
1618 dcinfo_Release,
1619 dcinfo_GetInfo,
1620 dcinfo_SetInfo
1623 HRESULT create_oledb_convert(IUnknown *outer, void **obj)
1625 convert *This;
1627 TRACE("(%p, %p)\n", outer, obj);
1629 *obj = NULL;
1631 if(outer) return CLASS_E_NOAGGREGATION;
1633 This = heap_alloc(sizeof(*This));
1634 if(!This) return E_OUTOFMEMORY;
1636 This->IDataConvert_iface.lpVtbl = &convert_vtbl;
1637 This->IDCInfo_iface.lpVtbl = &dcinfo_vtbl;
1638 This->ref = 1;
1639 This->version = 0x110;
1641 *obj = &This->IDataConvert_iface;
1643 return S_OK;