~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/oledb32/convert.c

Version: ~ [ wine-1.5.31 ] ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /* OLE DB Conversion library
  2  *
  3  * Copyright 2009 Huw Davies
  4  *
  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.
  9  *
 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.
 14  *
 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
 18  */
 19 
 20 #include <stdarg.h>
 21 
 22 #define COBJMACROS
 23 #define NONAMELESSUNION
 24 #define NONAMELESSSTRUCT
 25 
 26 #include "windef.h"
 27 #include "winbase.h"
 28 #include "winnls.h"
 29 #include "ole2.h"
 30 #include "msdadc.h"
 31 #include "oledberr.h"
 32 
 33 #include "oledb_private.h"
 34 
 35 #include "wine/debug.h"
 36 
 37 WINE_DEFAULT_DEBUG_CHANNEL(oledb);
 38 
 39 typedef struct
 40 {
 41     const struct IDataConvertVtbl *lpVtbl;
 42     const struct IDCInfoVtbl *lpDCInfoVtbl;
 43 
 44     LONG ref;
 45 
 46     UINT version; /* Set by IDCInfo_SetInfo */
 47 } convert;
 48 
 49 static inline convert *impl_from_IDataConvert(IDataConvert *iface)
 50 {
 51     return (convert *)((char*)iface - FIELD_OFFSET(convert, lpVtbl));
 52 }
 53 
 54 static inline convert *impl_from_IDCInfo(IDCInfo *iface)
 55 {
 56     return (convert *)((char*)iface - FIELD_OFFSET(convert, lpDCInfoVtbl));
 57 }
 58 
 59 static HRESULT WINAPI convert_QueryInterface(IDataConvert* iface,
 60                                              REFIID riid,
 61                                              void **obj)
 62 {
 63     convert *This = impl_from_IDataConvert(iface);
 64     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
 65 
 66     *obj = NULL;
 67 
 68     if(IsEqualIID(riid, &IID_IUnknown) ||
 69        IsEqualIID(riid, &IID_IDataConvert))
 70     {
 71         *obj = iface;
 72     }
 73     else if(IsEqualIID(riid, &IID_IDCInfo))
 74     {
 75         *obj = &This->lpDCInfoVtbl;
 76     }
 77     else
 78     {
 79         FIXME("interface %s not implemented\n", debugstr_guid(riid));
 80         return E_NOINTERFACE;
 81     }
 82 
 83     IDataConvert_AddRef(iface);
 84     return S_OK;
 85 }
 86 
 87 
 88 static ULONG WINAPI convert_AddRef(IDataConvert* iface)
 89 {
 90     convert *This = impl_from_IDataConvert(iface);
 91     TRACE("(%p)\n", This);
 92 
 93     return InterlockedIncrement(&This->ref);
 94 }
 95 
 96 
 97 static ULONG WINAPI convert_Release(IDataConvert* iface)
 98 {
 99     convert *This = impl_from_IDataConvert(iface);
100     LONG ref;
101 
102     TRACE("(%p)\n", This);
103 
104     ref = InterlockedDecrement(&This->ref);
105     if(ref == 0)
106     {
107         HeapFree(GetProcessHeap(), 0, This);
108     }
109 
110     return ref;
111 }
112 
113 static int get_length(DBTYPE type)
114 {
115     switch(type)
116     {
117     case DBTYPE_I1:
118     case DBTYPE_UI1:
119         return 1;
120     case DBTYPE_I2:
121     case DBTYPE_UI2:
122         return 2;
123     case DBTYPE_I4:
124     case DBTYPE_UI4:
125     case DBTYPE_R4:
126         return 4;
127     case DBTYPE_I8:
128     case DBTYPE_UI8:
129         return 8;
130     case DBTYPE_CY:
131         return sizeof(CY);
132     case DBTYPE_BSTR:
133         return sizeof(BSTR);
134     case DBTYPE_FILETIME:
135         return sizeof(FILETIME);
136     case DBTYPE_GUID:
137         return sizeof(GUID);
138     case DBTYPE_WSTR:
139     case DBTYPE_STR:
140     case DBTYPE_BYREF | DBTYPE_WSTR:
141         return 0;
142     default:
143         FIXME("Unhandled type %04x\n", type);
144         return 0;
145     }
146 }
147 
148 static HRESULT WINAPI convert_DataConvert(IDataConvert* iface,
149                                           DBTYPE src_type, DBTYPE dst_type,
150                                           DBLENGTH src_len, DBLENGTH *dst_len,
151                                           void *src, void *dst,
152                                           DBLENGTH dst_max_len,
153                                           DBSTATUS src_status, DBSTATUS *dst_status,
154                                           BYTE precision, BYTE scale,
155                                           DBDATACONVERT flags)
156 {
157     convert *This = impl_from_IDataConvert(iface);
158     HRESULT hr;
159 
160     TRACE("(%p)->(%d, %d, %d, %p, %p, %p, %d, %d, %p, %d, %d, %x)\n", This,
161           src_type, dst_type, src_len, dst_len, src, dst, dst_max_len,
162           src_status, dst_status, precision, scale, flags);
163 
164     *dst_len = get_length(dst_type);
165     *dst_status = DBSTATUS_E_BADACCESSOR;
166 
167     if(IDataConvert_CanConvert(iface, src_type, dst_type) != S_OK)
168     {
169         return DB_E_UNSUPPORTEDCONVERSION;
170     }
171 
172     if(src_type == DBTYPE_STR)
173     {
174         BSTR b;
175         DWORD len;
176 
177         if(flags & DBDATACONVERT_LENGTHFROMNTS)
178             len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0) - 1;
179         else
180             len = MultiByteToWideChar(CP_ACP, 0, src, src_len, NULL, 0);
181         b = SysAllocStringLen(NULL, len);
182         if(!b) return E_OUTOFMEMORY;
183         if(flags & DBDATACONVERT_LENGTHFROMNTS)
184             MultiByteToWideChar(CP_ACP, 0, src, -1, b, len + 1);
185         else
186             MultiByteToWideChar(CP_ACP, 0, src, src_len, b, len);
187 
188         hr = IDataConvert_DataConvert(iface, DBTYPE_BSTR, dst_type, 0, dst_len,
189                                       &b, dst, dst_max_len, src_status, dst_status,
190                                       precision, scale, flags);
191 
192         SysFreeString(b);
193         return hr;
194     }
195 
196     if(src_type == DBTYPE_WSTR)
197     {
198         BSTR b;
199 
200         if(flags & DBDATACONVERT_LENGTHFROMNTS)
201             b = SysAllocString(src);
202         else
203             b = SysAllocStringLen(src, src_len / 2);
204         if(!b) return E_OUTOFMEMORY;
205         hr = IDataConvert_DataConvert(iface, DBTYPE_BSTR, dst_type, 0, dst_len,
206                                       &b, dst, dst_max_len, src_status, dst_status,
207                                       precision, scale, flags);
208         SysFreeString(b);
209         return hr;
210     }
211 
212     switch(dst_type)
213     {
214     case DBTYPE_I2:
215     {
216         signed short *d = dst;
217         switch(src_type)
218         {
219         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
220         case DBTYPE_I2:          *d = *(signed short*)src; hr = S_OK;            break;
221         case DBTYPE_I4:          hr = VarI2FromI4(*(signed int*)src, d);         break;
222         case DBTYPE_R4:          hr = VarI2FromR4(*(FLOAT*)src, d);              break;
223         case DBTYPE_R8:          hr = VarI2FromR8(*(double*)src, d);             break;
224         case DBTYPE_CY:          hr = VarI2FromCy(*(CY*)src, d);                 break;
225         case DBTYPE_DATE:        hr = VarI2FromDate(*(DATE*)src, d);             break;
226         case DBTYPE_BSTR:        hr = VarI2FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
227         case DBTYPE_BOOL:        hr = VarI2FromBool(*(VARIANT_BOOL*)src, d);     break;
228         case DBTYPE_DECIMAL:     hr = VarI2FromDec((DECIMAL*)src, d);            break;
229         case DBTYPE_I1:          hr = VarI2FromI1(*(signed char*)src, d);        break;
230         case DBTYPE_UI1:         hr = VarI2FromUI1(*(BYTE*)src, d);              break;
231         case DBTYPE_UI2:         hr = VarI2FromUI2(*(WORD*)src, d);              break;
232         case DBTYPE_UI4:         hr = VarI2FromUI4(*(DWORD*)src, d);             break;
233         case DBTYPE_I8:          hr = VarI2FromI8(*(LONGLONG*)src, d);           break;
234         case DBTYPE_UI8:         hr = VarI2FromUI8(*(ULONGLONG*)src, d);         break;
235         default: FIXME("Unimplemented conversion %04x -> I2\n", src_type); return E_NOTIMPL;
236         }
237         break;
238     }
239 
240     case DBTYPE_I4:
241     {
242         signed int *d = dst;
243         switch(src_type)
244         {
245         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
246         case DBTYPE_I2:          hr = VarI4FromI2(*(signed short*)src, d);       break;
247         case DBTYPE_I4:          *d = *(signed int*)src; hr = S_OK;              break;
248         case DBTYPE_R4:          hr = VarI4FromR4(*(FLOAT*)src, d);              break;
249         case DBTYPE_R8:          hr = VarI4FromR8(*(double*)src, d);             break;
250         case DBTYPE_CY:          hr = VarI4FromCy(*(CY*)src, d);                 break;
251         case DBTYPE_DATE:        hr = VarI4FromDate(*(DATE*)src, d);             break;
252         case DBTYPE_BSTR:        hr = VarI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
253         case DBTYPE_BOOL:        hr = VarI4FromBool(*(VARIANT_BOOL*)src, d);     break;
254         case DBTYPE_DECIMAL:     hr = VarI4FromDec((DECIMAL*)src, d);            break;
255         case DBTYPE_I1:          hr = VarI4FromI1(*(signed char*)src, d);        break;
256         case DBTYPE_UI1:         hr = VarI4FromUI1(*(BYTE*)src, d);              break;
257         case DBTYPE_UI2:         hr = VarI4FromUI2(*(WORD*)src, d);              break;
258         case DBTYPE_UI4:         hr = VarI4FromUI4(*(DWORD*)src, d);             break;
259         case DBTYPE_I8:          hr = VarI4FromI8(*(LONGLONG*)src, d);           break;
260         case DBTYPE_UI8:         hr = VarI4FromUI8(*(ULONGLONG*)src, d);         break;
261         default: FIXME("Unimplemented conversion %04x -> I4\n", src_type); return E_NOTIMPL;
262         }
263         break;
264     }
265 
266     case DBTYPE_R4:
267     {
268         FLOAT *d = dst;
269         switch(src_type)
270         {
271         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
272         case DBTYPE_I2:          hr = VarR4FromI2(*(signed short*)src, d);       break;
273         case DBTYPE_I4:          hr = VarR4FromI4(*(signed int*)src, d);         break;
274         case DBTYPE_R4:          *d = *(FLOAT*)src; hr = S_OK;                   break;
275         case DBTYPE_R8:          hr = VarR4FromR8(*(double*)src, d);             break;
276         case DBTYPE_CY:          hr = VarR4FromCy(*(CY*)src, d);                 break;
277         case DBTYPE_DATE:        hr = VarR4FromDate(*(DATE*)src, d);             break;
278         case DBTYPE_BSTR:        hr = VarR4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
279         case DBTYPE_BOOL:        hr = VarR4FromBool(*(VARIANT_BOOL*)src, d);     break;
280         case DBTYPE_DECIMAL:     hr = VarR4FromDec((DECIMAL*)src, d);            break;
281         case DBTYPE_I1:          hr = VarR4FromI1(*(signed char*)src, d);        break;
282         case DBTYPE_UI1:         hr = VarR4FromUI1(*(BYTE*)src, d);              break;
283         case DBTYPE_UI2:         hr = VarR4FromUI2(*(WORD*)src, d);              break;
284         case DBTYPE_UI4:         hr = VarR4FromUI4(*(DWORD*)src, d);             break;
285         case DBTYPE_I8:          hr = VarR4FromI8(*(LONGLONG*)src, d);           break;
286         case DBTYPE_UI8:         hr = VarR4FromUI8(*(ULONGLONG*)src, d);         break;
287         default: FIXME("Unimplemented conversion %04x -> R4\n", src_type); return E_NOTIMPL;
288         }
289         break;
290     }
291 
292     case DBTYPE_CY:
293     {
294         CY *d = dst;
295         switch(src_type)
296         {
297         case DBTYPE_EMPTY:       d->int64 = 0; hr = S_OK;                              break;
298         case DBTYPE_I2:          hr = VarCyFromI2(*(signed short*)src, d);       break;
299         case DBTYPE_I4:          hr = VarCyFromI4(*(signed int*)src, d);         break;
300         case DBTYPE_R4:          hr = VarCyFromR4(*(FLOAT*)src, d);              break;
301         case DBTYPE_R8:          hr = VarCyFromR8(*(double*)src, d);             break;
302         case DBTYPE_CY:          *d = *(CY*)src; hr = S_OK;                      break;
303         case DBTYPE_DATE:        hr = VarCyFromDate(*(DATE*)src, d);             break;
304         case DBTYPE_BSTR:        hr = VarCyFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
305         case DBTYPE_BOOL:        hr = VarCyFromBool(*(VARIANT_BOOL*)src, d);     break;
306         case DBTYPE_DECIMAL:     hr = VarCyFromDec((DECIMAL*)src, d);            break;
307         case DBTYPE_I1:          hr = VarCyFromI1(*(signed char*)src, d);        break;
308         case DBTYPE_UI1:         hr = VarCyFromUI1(*(BYTE*)src, d);              break;
309         case DBTYPE_UI2:         hr = VarCyFromUI2(*(WORD*)src, d);              break;
310         case DBTYPE_UI4:         hr = VarCyFromUI4(*(DWORD*)src, d);             break;
311         case DBTYPE_I8:          hr = VarCyFromI8(*(LONGLONG*)src, d);           break;
312         case DBTYPE_UI8:         hr = VarCyFromUI8(*(ULONGLONG*)src, d);         break;
313         default: FIXME("Unimplemented conversion %04x -> CY\n", src_type); return E_NOTIMPL;
314         }
315         break;
316     }
317 
318     case DBTYPE_BSTR:
319     {
320         BSTR *d = dst;
321         switch(src_type)
322         {
323         case DBTYPE_EMPTY:       *d = SysAllocStringLen(NULL, 0); hr = *d ? S_OK : E_OUTOFMEMORY;      break;
324         case DBTYPE_I2:          hr = VarBstrFromI2(*(signed short*)src, LOCALE_USER_DEFAULT, 0, d);   break;
325         case DBTYPE_I4:          hr = VarBstrFromI4(*(signed int*)src, LOCALE_USER_DEFAULT, 0, d);     break;
326         case DBTYPE_R4:          hr = VarBstrFromR4(*(FLOAT*)src, LOCALE_USER_DEFAULT, 0, d);          break;
327         case DBTYPE_R8:          hr = VarBstrFromR8(*(double*)src, LOCALE_USER_DEFAULT, 0, d);         break;
328         case DBTYPE_CY:          hr = VarBstrFromCy(*(CY*)src, LOCALE_USER_DEFAULT, 0, d);             break;
329         case DBTYPE_DATE:        hr = VarBstrFromDate(*(DATE*)src, LOCALE_USER_DEFAULT, 0, d);         break;
330         case DBTYPE_BSTR:        *d = SysAllocStringLen(*(BSTR*)src, SysStringLen(*(BSTR*)src)); hr = *d ? S_OK : E_OUTOFMEMORY;     break;
331         case DBTYPE_BOOL:        hr = VarBstrFromBool(*(VARIANT_BOOL*)src, LOCALE_USER_DEFAULT, 0, d); break;
332         case DBTYPE_DECIMAL:     hr = VarBstrFromDec((DECIMAL*)src, LOCALE_USER_DEFAULT, 0, d);        break;
333         case DBTYPE_I1:          hr = VarBstrFromI1(*(signed char*)src, LOCALE_USER_DEFAULT, 0, d);    break;
334         case DBTYPE_UI1:         hr = VarBstrFromUI1(*(BYTE*)src, LOCALE_USER_DEFAULT, 0, d);          break;
335         case DBTYPE_UI2:         hr = VarBstrFromUI2(*(WORD*)src, LOCALE_USER_DEFAULT, 0, d);          break;
336         case DBTYPE_UI4:         hr = VarBstrFromUI4(*(DWORD*)src, LOCALE_USER_DEFAULT, 0, d);         break;
337         case DBTYPE_I8:          hr = VarBstrFromI8(*(LONGLONG*)src, LOCALE_USER_DEFAULT, 0, d);       break;
338         case DBTYPE_UI8:         hr = VarBstrFromUI8(*(ULONGLONG*)src, LOCALE_USER_DEFAULT, 0, d);     break;
339         case DBTYPE_GUID:
340         {
341             WCHAR szBuff[39];
342             const GUID *id = (const GUID *)src;
343             WCHAR format[] = {
344                 '{','%','','8','X','-','%','','4','X','-','%','','4','X','-',
345                 '%','','2','X','%','','2','X','-',
346                 '%','','2','X','%','','2','X','%','','2','X','%','','2','X','%','','2','X','%','','2','X','}',0};
347             wsprintfW(szBuff, format,
348                 id->Data1, id->Data2, id->Data3,
349                 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
350                 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
351             *d = SysAllocString(szBuff);
352             hr = *d ? S_OK : E_OUTOFMEMORY;
353         }
354         break;
355         case DBTYPE_BYTES:
356         {
357             *d = SysAllocStringLen(NULL, 2 * src_len);
358             if (*d == NULL)
359                 hr = E_OUTOFMEMORY;
360             else
361             {
362                 const char hexchars[] = "0123456789ABCDEF";
363                 WCHAR *s = *d;
364                 unsigned char *p = src;
365                 while (src_len > 0)
366                 {
367                     *s++ = hexchars[(*p >> 4) & 0x0F];
368                     *s++ = hexchars[(*p)      & 0x0F];
369                     src_len--; p++;
370                 }
371                 hr = S_OK;
372             }
373         }
374         break;
375         default: FIXME("Unimplemented conversion %04x -> BSTR\n", src_type); return E_NOTIMPL;
376         }
377         break;
378     }
379 
380     case DBTYPE_UI1:
381     {
382         BYTE *d = dst;
383         switch(src_type)
384         {
385         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
386         case DBTYPE_I2:          hr = VarUI1FromI2(*(signed short*)src, d);      break;
387         case DBTYPE_I4:          hr = VarUI1FromI4(*(signed int*)src, d);        break;
388         case DBTYPE_R4:          hr = VarUI1FromR4(*(FLOAT*)src, d);             break;
389         case DBTYPE_R8:          hr = VarUI1FromR8(*(double*)src, d);            break;
390         case DBTYPE_CY:          hr = VarUI1FromCy(*(CY*)src, d);                break;
391         case DBTYPE_DATE:        hr = VarUI1FromDate(*(DATE*)src, d);            break;
392         case DBTYPE_BSTR:        hr = VarUI1FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
393         case DBTYPE_BOOL:        hr = VarUI1FromBool(*(VARIANT_BOOL*)src, d);    break;
394         case DBTYPE_DECIMAL:     hr = VarUI1FromDec((DECIMAL*)src, d);           break;
395         case DBTYPE_I1:          hr = VarUI1FromI1(*(signed char*)src, d);       break;
396         case DBTYPE_UI1:         *d = *(BYTE*)src; hr = S_OK;                    break;
397         case DBTYPE_UI2:         hr = VarUI1FromUI2(*(WORD*)src, d);             break;
398         case DBTYPE_UI4:         hr = VarUI1FromUI4(*(DWORD*)src, d);            break;
399         case DBTYPE_I8:          hr = VarUI1FromI8(*(LONGLONG*)src, d);          break;
400         case DBTYPE_UI8:         hr = VarUI1FromUI8(*(ULONGLONG*)src, d);        break;
401         default: FIXME("Unimplemented conversion %04x -> UI1\n", src_type); return E_NOTIMPL;
402         }
403         break;
404     }
405 
406     case DBTYPE_UI4:
407     {
408         DWORD *d = dst;
409         switch(src_type)
410         {
411         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
412         case DBTYPE_I2:          hr = VarUI4FromI2(*(signed short*)src, d);      break;
413         case DBTYPE_I4:          hr = VarUI4FromI4(*(signed int*)src, d);        break;
414         case DBTYPE_R4:          hr = VarUI4FromR4(*(FLOAT*)src, d);             break;
415         case DBTYPE_R8:          hr = VarUI4FromR8(*(double*)src, d);            break;
416         case DBTYPE_CY:          hr = VarUI4FromCy(*(CY*)src, d);                break;
417         case DBTYPE_DATE:        hr = VarUI4FromDate(*(DATE*)src, d);            break;
418         case DBTYPE_BSTR:        hr = VarUI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
419         case DBTYPE_BOOL:        hr = VarUI4FromBool(*(VARIANT_BOOL*)src, d);    break;
420         case DBTYPE_DECIMAL:     hr = VarUI4FromDec((DECIMAL*)src, d);           break;
421         case DBTYPE_I1:          hr = VarUI4FromI1(*(signed char*)src, d);       break;
422         case DBTYPE_UI1:         hr = VarUI4FromUI1(*(BYTE*)src, d);             break;
423         case DBTYPE_UI2:         hr = VarUI4FromUI2(*(WORD*)src, d);             break;
424         case DBTYPE_UI4:         *d = *(DWORD*)src; hr = S_OK;                   break;
425         case DBTYPE_I8:          hr = VarUI4FromI8(*(LONGLONG*)src, d);          break;
426         case DBTYPE_UI8:         hr = VarUI4FromUI8(*(ULONGLONG*)src, d);        break;
427         default: FIXME("Unimplemented conversion %04x -> UI4\n", src_type); return E_NOTIMPL;
428         }
429         break;
430     }
431 
432     case DBTYPE_UI8:
433     {
434         ULONGLONG *d = dst;
435         switch(src_type)
436         {
437         case DBTYPE_EMPTY:       *d = 0; hr = S_OK;                              break;
438         case DBTYPE_I2:          hr = VarUI8FromI2(*(signed short*)src, d);      break;
439         case DBTYPE_I4:          {LONGLONG s = *(signed int*)src; hr = VarUI8FromI8(s, d);        break;}
440         case DBTYPE_R4:          hr = VarUI8FromR4(*(FLOAT*)src, d);             break;
441         case DBTYPE_R8:          hr = VarUI8FromR8(*(double*)src, d);            break;
442         case DBTYPE_CY:          hr = VarUI8FromCy(*(CY*)src, d);                break;
443         case DBTYPE_DATE:        hr = VarUI8FromDate(*(DATE*)src, d);            break;
444         case DBTYPE_BSTR:        hr = VarUI8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break;
445         case DBTYPE_BOOL:        hr = VarUI8FromBool(*(VARIANT_BOOL*)src, d);    break;
446         case DBTYPE_DECIMAL:     hr = VarUI8FromDec((DECIMAL*)src, d);           break;
447         case DBTYPE_I1:          hr = VarUI8FromI1(*(signed char*)src, d);       break;
448         case DBTYPE_UI1:         hr = VarUI8FromUI1(*(BYTE*)src, d);             break;
449         case DBTYPE_UI2:         hr = VarUI8FromUI2(*(WORD*)src, d);             break;
450         case DBTYPE_UI4:         hr = VarUI8FromUI4(*(DWORD*)src, d);            break;
451         case DBTYPE_I8:          hr = VarUI8FromI8(*(LONGLONG*)src, d);          break;
452         case DBTYPE_UI8:         *d = *(ULONGLONG*)src; hr = S_OK;               break;
453         default: FIXME("Unimplemented conversion %04x -> UI8\n", src_type); return E_NOTIMPL;
454         }
455         break;
456     }
457 
458     case DBTYPE_FILETIME:
459     {
460         FILETIME *d = dst;
461         switch(src_type)
462         {
463         case DBTYPE_EMPTY:       d->dwLowDateTime = d->dwHighDateTime = 0; hr = S_OK;    break;
464         case DBTYPE_FILETIME:    *d = *(FILETIME*)src; hr = S_OK;                        break;
465         default: FIXME("Unimplemented conversion %04x -> FILETIME\n", src_type); return E_NOTIMPL;
466         }
467         break;
468     }
469 
470     case DBTYPE_GUID:
471     {
472         GUID *d = dst;
473         switch(src_type)
474         {
475         case DBTYPE_EMPTY:       *d = GUID_NULL; hr = S_OK; break;
476         case DBTYPE_GUID:        *d = *(GUID*)src; hr = S_OK; break;
477         default: FIXME("Unimplemented conversion %04x -> GUID\n", src_type); return E_NOTIMPL;
478         }
479         break;
480     }
481 
482     case DBTYPE_WSTR:
483     {
484         BSTR b;
485         DBLENGTH bstr_len;
486         INT bytes_to_copy;
487         hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
488                                       src, &b, sizeof(BSTR), src_status, dst_status,
489                                       precision, scale, flags);
490         if(hr != S_OK) return hr;
491         bstr_len = SysStringLen(b);
492         *dst_len = bstr_len * sizeof(WCHAR); /* Doesn't include size for '\0' */
493         *dst_status = DBSTATUS_S_OK;
494         bytes_to_copy = min(*dst_len + sizeof(WCHAR), dst_max_len);
495         if(dst)
496         {
497             if(bytes_to_copy >= sizeof(WCHAR))
498             {
499                 memcpy(dst, b, bytes_to_copy - sizeof(WCHAR));
500                 *((WCHAR*)dst + bytes_to_copy / sizeof(WCHAR) - 1) = 0;
501                 if(bytes_to_copy < *dst_len + sizeof(WCHAR))
502                     *dst_status = DBSTATUS_S_TRUNCATED;
503             }
504             else
505             {
506                 *dst_status = DBSTATUS_E_DATAOVERFLOW;
507                 hr = DB_E_ERRORSOCCURRED;
508             }
509         }
510         SysFreeString(b);
511         return hr;
512     }
513     case DBTYPE_STR:
514     {
515         BSTR b;
516         DBLENGTH bstr_len;
517         INT bytes_to_copy;
518         hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
519                                       src, &b, sizeof(BSTR), src_status, dst_status,
520                                       precision, scale, flags);
521         if(hr != S_OK) return hr;
522         bstr_len = SysStringLen(b);
523         *dst_len = bstr_len * sizeof(char); /* Doesn't include size for '\0' */
524         *dst_status = DBSTATUS_S_OK;
525         bytes_to_copy = min(*dst_len + sizeof(char), dst_max_len);
526         if(dst)
527         {
528             if(bytes_to_copy >= sizeof(char))
529             {
530                 WideCharToMultiByte(CP_ACP, 0, b, bytes_to_copy - sizeof(char), dst, dst_max_len, NULL, NULL);
531                 *((char *)dst + bytes_to_copy / sizeof(char) - 1) = 0;
532                 if(bytes_to_copy < *dst_len + sizeof(char))
533                     *dst_status = DBSTATUS_S_TRUNCATED;
534             }
535             else
536             {
537                 *dst_status = DBSTATUS_E_DATAOVERFLOW;
538                 hr = DB_E_ERRORSOCCURRED;
539             }
540         }
541         SysFreeString(b);
542         return hr;
543     }
544 
545     case DBTYPE_BYREF | DBTYPE_WSTR:
546     {
547         BSTR b;
548         WCHAR **d = dst;
549         DBLENGTH bstr_len;
550         hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len,
551                                       src, &b, sizeof(BSTR), src_status, dst_status,
552                                       precision, scale, flags);
553         if(hr != S_OK) return hr;
554 
555         bstr_len = SysStringLen(b) * sizeof(WCHAR);
556         *dst_len = bstr_len; /* Doesn't include size for '\0' */
557 
558         *d = CoTaskMemAlloc(bstr_len + sizeof(WCHAR));
559         if(*d) memcpy(*d, b, bstr_len + sizeof(WCHAR));
560         else hr = E_OUTOFMEMORY;
561         SysFreeString(b);
562         return hr;
563     }
564 
565     default:
566         FIXME("Unimplemented conversion %04x -> %04x\n", src_type, dst_type);
567         return E_NOTIMPL;
568 
569     }
570 
571     if(hr == DISP_E_OVERFLOW)
572     {
573         *dst_status = DBSTATUS_E_DATAOVERFLOW;
574         hr = DB_E_ERRORSOCCURRED;
575     }
576     else if(hr == S_OK)
577         *dst_status = DBSTATUS_S_OK;
578 
579     return hr;
580 }
581 
582 static inline WORD get_dbtype_class(DBTYPE type)
583 {
584     switch(type)
585     {
586     case DBTYPE_I2:
587     case DBTYPE_R4:
588     case DBTYPE_R8:
589     case DBTYPE_I1:
590     case DBTYPE_UI1:
591     case DBTYPE_UI2:
592         return DBTYPE_I2;
593 
594     case DBTYPE_I4:
595     case DBTYPE_UI4:
596         return DBTYPE_I4;
597 
598     case DBTYPE_I8:
599     case DBTYPE_UI8:
600         return DBTYPE_I8;
601 
602     case DBTYPE_BSTR:
603     case DBTYPE_STR:
604     case DBTYPE_WSTR:
605         return DBTYPE_BSTR;
606 
607     case DBTYPE_DBDATE:
608     case DBTYPE_DBTIME:
609     case DBTYPE_DBTIMESTAMP:
610         return DBTYPE_DBDATE;
611     }
612     return type;
613 }
614 
615 /* Many src types will convert to this group of dst types */
616 static inline BOOL common_class(WORD dst_class)
617 {
618     switch(dst_class)
619     {
620     case DBTYPE_EMPTY:
621     case DBTYPE_NULL:
622     case DBTYPE_I2:
623     case DBTYPE_I4:
624     case DBTYPE_BSTR:
625     case DBTYPE_BOOL:
626     case DBTYPE_VARIANT:
627     case DBTYPE_I8:
628     case DBTYPE_CY:
629     case DBTYPE_DECIMAL:
630     case DBTYPE_NUMERIC:
631         return TRUE;
632     }
633     return FALSE;
634 }
635 
636 static inline BOOL array_type(DBTYPE type)
637 {
638     return (type >= DBTYPE_I2 && type <= DBTYPE_UI4);
639 }
640 
641 static HRESULT WINAPI convert_CanConvert(IDataConvert* iface,
642                                          DBTYPE src_type, DBTYPE dst_type)
643 {
644     convert *This = impl_from_IDataConvert(iface);
645     DBTYPE src_base_type = src_type & 0x1ff;
646     DBTYPE dst_base_type = dst_type & 0x1ff;
647     WORD dst_class = get_dbtype_class(dst_base_type);
648 
649     TRACE("(%p)->(%d, %d)\n", This, src_type, dst_type);
650 
651     if(src_type & DBTYPE_VECTOR || dst_type & DBTYPE_VECTOR) return S_FALSE;
652 
653     if(src_type & DBTYPE_ARRAY)
654     {
655         if(!array_type(src_base_type)) return S_FALSE;
656         if(dst_type & DBTYPE_ARRAY)
657         {
658             if(src_type == dst_type) return S_OK;
659             return S_FALSE;
660         }
661         if(dst_type == DBTYPE_VARIANT) return S_OK;
662         return S_FALSE;
663     }
664 
665     if(dst_type & DBTYPE_ARRAY)
666     {
667         if(!array_type(dst_base_type)) return S_FALSE;
668         if(src_type == DBTYPE_IDISPATCH || src_type == DBTYPE_VARIANT) return S_OK;
669         return S_FALSE;
670     }
671 
672     if(dst_type & DBTYPE_BYREF)
673         if(dst_base_type != DBTYPE_BYTES && dst_base_type != DBTYPE_STR && dst_base_type != DBTYPE_WSTR)
674             return S_FALSE;
675 
676     switch(get_dbtype_class(src_base_type))
677     {
678     case DBTYPE_EMPTY:
679         if(common_class(dst_class)) return S_OK;
680         switch(dst_class)
681         {
682         case DBTYPE_DATE:
683         case DBTYPE_GUID:
684         case DBTYPE_FILETIME:
685             return S_OK;
686         default:
687             if(dst_base_type == DBTYPE_DBTIMESTAMP) return S_OK;
688             return S_FALSE;
689         }
690 
691     case DBTYPE_NULL:
692         switch(dst_base_type)
693         {
694         case DBTYPE_NULL:
695         case DBTYPE_VARIANT:
696         case DBTYPE_FILETIME: return S_OK;
697         default: return S_FALSE;
698         }
699 
700     case DBTYPE_I4:
701         if(dst_base_type == DBTYPE_BYTES) return S_OK;
702         /* fall through */
703     case DBTYPE_I2:
704         if(dst_base_type == DBTYPE_DATE) return S_OK;
705         /* fall through */
706     case DBTYPE_DECIMAL:
707         if(common_class(dst_class)) return S_OK;
708         if(dst_class == DBTYPE_DBDATE) return S_OK;
709         return S_FALSE;
710 
711     case DBTYPE_BOOL:
712         if(dst_base_type == DBTYPE_DATE) return S_OK;
713     case DBTYPE_NUMERIC:
714     case DBTYPE_CY:
715         if(common_class(dst_class)) return S_OK;
716         return S_FALSE;
717 
718     case DBTYPE_I8:
719         if(common_class(dst_class)) return S_OK;
720         switch(dst_base_type)
721         {
722         case DBTYPE_BYTES:
723         case DBTYPE_FILETIME: return S_OK;
724         default: return S_FALSE;
725         }
726 
727     case DBTYPE_DATE:
728         switch(dst_class)
729         {
730         case DBTYPE_EMPTY:
731         case DBTYPE_NULL:
732         case DBTYPE_I2:
733         case DBTYPE_I4:
734         case DBTYPE_BSTR:
735         case DBTYPE_BOOL:
736         case DBTYPE_VARIANT:
737         case DBTYPE_I8:
738         case DBTYPE_DATE:
739         case DBTYPE_DBDATE:
740         case DBTYPE_FILETIME:
741             return S_OK;
742         default: return S_FALSE;
743         }
744 
745     case DBTYPE_IDISPATCH:
746     case DBTYPE_VARIANT:
747         switch(dst_base_type)
748         {
749         case DBTYPE_IDISPATCH:
750         case DBTYPE_ERROR:
751         case DBTYPE_IUNKNOWN:
752             return S_OK;
753         }
754         /* fall through */
755     case DBTYPE_BSTR:
756         if(common_class(dst_class)) return S_OK;
757         switch(dst_class)
758         {
759         case DBTYPE_DATE:
760         case DBTYPE_GUID:
761         case DBTYPE_BYTES:
762         case DBTYPE_DBDATE:
763         case DBTYPE_FILETIME:
764             return S_OK;
765         default: return S_FALSE;
766         }
767 
768     case DBTYPE_ERROR:
769         switch(dst_base_type)
770         {
771         case DBTYPE_BSTR:
772         case DBTYPE_ERROR:
773         case DBTYPE_VARIANT:
774         case DBTYPE_WSTR:
775             return S_OK;
776         default: return S_FALSE;
777         }
778 
779     case DBTYPE_IUNKNOWN:
780         switch(dst_base_type)
781         {
782         case DBTYPE_EMPTY:
783         case DBTYPE_NULL:
784         case DBTYPE_IDISPATCH:
785         case DBTYPE_VARIANT:
786         case DBTYPE_IUNKNOWN:
787             return S_OK;
788         default: return S_FALSE;
789         }
790 
791     case DBTYPE_BYTES:
792         if(dst_class == DBTYPE_I4 || dst_class == DBTYPE_I8) return S_OK;
793         /* fall through */
794     case DBTYPE_GUID:
795         switch(dst_class)
796         {
797         case DBTYPE_EMPTY:
798         case DBTYPE_NULL:
799         case DBTYPE_BSTR:
800         case DBTYPE_VARIANT:
801         case DBTYPE_GUID:
802         case DBTYPE_BYTES:
803             return S_OK;
804         default: return S_FALSE;
805         }
806 
807     case DBTYPE_FILETIME:
808         if(dst_class == DBTYPE_I8) return S_OK;
809         /* fall through */
810     case DBTYPE_DBDATE:
811         switch(dst_class)
812         {
813         case DBTYPE_EMPTY:
814         case DBTYPE_NULL:
815         case DBTYPE_DATE:
816         case DBTYPE_BSTR:
817         case DBTYPE_VARIANT:
818         case DBTYPE_DBDATE:
819         case DBTYPE_FILETIME:
820             return S_OK;
821         default: return S_FALSE;
822         }
823 
824     }
825     return S_FALSE;
826 }
827 
828 static HRESULT WINAPI convert_GetConversionSize(IDataConvert* iface,
829                                                 DBTYPE wSrcType, DBTYPE wDstType,
830                                                 DBLENGTH *pcbSrcLength, DBLENGTH *pcbDstLength,
831                                                 void *pSrc)
832 {
833     convert *This = impl_from_IDataConvert(iface);
834     FIXME("(%p)->(%d, %d, %p, %p, %p): stub\n", This, wSrcType, wDstType, pcbSrcLength, pcbDstLength, pSrc);
835 
836     return E_NOTIMPL;
837 }
838 
839 static const struct IDataConvertVtbl convert_vtbl =
840 {
841     convert_QueryInterface,
842     convert_AddRef,
843     convert_Release,
844     convert_DataConvert,
845     convert_CanConvert,
846     convert_GetConversionSize
847 };
848 
849 static HRESULT WINAPI dcinfo_QueryInterface(IDCInfo* iface, REFIID riid, void **obj)
850 {
851     convert *This = impl_from_IDCInfo(iface);
852 
853     return IDataConvert_QueryInterface((IDataConvert *)This, riid, obj);
854 }
855 
856 static ULONG WINAPI dcinfo_AddRef(IDCInfo* iface)
857 {
858     convert *This = impl_from_IDCInfo(iface);
859 
860     return IDataConvert_AddRef((IDataConvert *)This);
861 }
862 
863 static ULONG WINAPI dcinfo_Release(IDCInfo* iface)
864 {
865     convert *This = impl_from_IDCInfo(iface);
866 
867     return IDataConvert_Release((IDataConvert *)This);
868 }
869 
870 static HRESULT WINAPI dcinfo_GetInfo(IDCInfo *iface, ULONG num, DCINFOTYPE types[], DCINFO **info_ptr)
871 {
872     convert *This = impl_from_IDCInfo(iface);
873     ULONG i;
874     DCINFO *infos;
875 
876     TRACE("(%p)->(%d, %p, %p)\n", This, num, types, info_ptr);
877 
878     *info_ptr = infos = CoTaskMemAlloc(num * sizeof(*infos));
879     if(!infos) return E_OUTOFMEMORY;
880 
881     for(i = 0; i < num; i++)
882     {
883         infos[i].eInfoType = types[i];
884         VariantInit(&infos[i].vData);
885 
886         switch(types[i])
887         {
888         case DCINFOTYPE_VERSION:
889             V_VT(&infos[i].vData) = VT_UI4;
890             V_UI4(&infos[i].vData) = This->version;
891             break;
892         }
893     }
894 
895     return S_OK;
896 }
897 
898 static HRESULT WINAPI dcinfo_SetInfo(IDCInfo* iface, ULONG num, DCINFO info[])
899 {
900     convert *This = impl_from_IDCInfo(iface);
901     ULONG i;
902     HRESULT hr = S_OK;
903 
904     TRACE("(%p)->(%d, %p)\n", This, num, info);
905 
906     for(i = 0; i < num; i++)
907     {
908         switch(info[i].eInfoType)
909         {
910         case DCINFOTYPE_VERSION:
911             if(V_VT(&info[i].vData) != VT_UI4)
912             {
913                 FIXME("VERSION with vt %x\n", V_VT(&info[i].vData));
914                 hr = DB_S_ERRORSOCCURRED;
915                 break;
916             }
917             This->version = V_UI4(&info[i].vData);
918             break;
919 
920         default:
921             FIXME("Unhandled info type %d (vt %x)\n", info[i].eInfoType, V_VT(&info[i].vData));
922         }
923     }
924     return hr;
925 }
926 
927 static const struct IDCInfoVtbl dcinfo_vtbl =
928 {
929     dcinfo_QueryInterface,
930     dcinfo_AddRef,
931     dcinfo_Release,
932     dcinfo_GetInfo,
933     dcinfo_SetInfo
934 };
935 
936 HRESULT create_oledb_convert(IUnknown *outer, void **obj)
937 {
938     convert *This;
939 
940     TRACE("(%p, %p)\n", outer, obj);
941 
942     *obj = NULL;
943 
944     if(outer) return CLASS_E_NOAGGREGATION;
945 
946     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
947     if(!This) return E_OUTOFMEMORY;
948 
949     This->lpVtbl = &convert_vtbl;
950     This->lpDCInfoVtbl = &dcinfo_vtbl;
951     This->ref = 1;
952     This->version = 0x110;
953 
954     *obj = &This->lpVtbl;
955 
956     return S_OK;
957 }
958 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.