LibreOffice Module connectivity (master) 1
Aolevariant.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <ado/Aolevariant.hxx>
22#include <osl/diagnose.h>
24#include <com/sun/star/sdbc/SQLException.hpp>
25#include <com/sun/star/util/Time.hpp>
26#include <com/sun/star/util/Date.hpp>
27#include <com/sun/star/util/DateTime.hpp>
29#include <strings.hrc>
30#include <com/sun/star/bridge/oleautomation/Date.hpp>
31#include <com/sun/star/bridge/oleautomation/Currency.hpp>
32#include <com/sun/star/bridge/oleautomation/SCode.hpp>
33#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
34
35using namespace com::sun::star::beans;
36using namespace com::sun::star::uno;
38using namespace connectivity::ado;
39
40OLEVariant::OLEVariant()
41{
42 VariantInit(this);
43}
44OLEVariant::OLEVariant(const VARIANT& varSrc)
45{
46 ::VariantInit(this);
47 HRESULT eRet = ::VariantCopy(this, &varSrc);
48 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
49}
51{
52 ::VariantInit(this);
53 HRESULT eRet = ::VariantCopy(this, static_cast<const VARIANT*>(&varSrc));
54 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
55}
56
57OLEVariant::OLEVariant(bool x) { VariantInit(this); vt = VT_BOOL; boolVal = (x ? VARIANT_TRUE : VARIANT_FALSE);}
58OLEVariant::OLEVariant(sal_Int8 n) { VariantInit(this); vt = VT_I1; bVal = n;}
59OLEVariant::OLEVariant(sal_Int16 n) { VariantInit(this); vt = VT_I2; intVal = n;}
60OLEVariant::OLEVariant(sal_Int32 n) { VariantInit(this); vt = VT_I4; lVal = n;}
61OLEVariant::OLEVariant(sal_Int64 x) { VariantInit(this); vt = VT_I4; lVal = static_cast<LONG>(x);}
62
63OLEVariant::OLEVariant(std::u16string_view us)
64{
65 ::VariantInit(this);
66 vt = VT_BSTR;
67 bstrVal = SysAllocStringLen(o3tl::toW(us.data()), us.length());
68}
70{
71 HRESULT eRet = ::VariantClear(this);
72 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
73} // clears all the memory that was allocated before
74
75OLEVariant::OLEVariant(const css::util::Date& x )
76{
77 VariantInit(this);
78 vt = VT_DATE;
79 dblVal = ::dbtools::DBTypeConversion::toDouble(x,css::util::Date(30,12,1899));
80}
81OLEVariant::OLEVariant(const css::util::Time& x )
82{
83 VariantInit(this);
84 vt = VT_DATE;
86}
87OLEVariant::OLEVariant(const css::util::DateTime& x )
88{
89 VariantInit(this);
90 vt = VT_DATE;
91 dblVal = ::dbtools::DBTypeConversion::toDouble(x,css::util::Date(30,12,1899));
92}
94{
95 VariantInit(this);
96 vt = VT_R4;
97 fltVal = x;
98}
99OLEVariant::OLEVariant(const double &x)
100{
101 VariantInit(this);
102 vt = VT_R8;
103 dblVal = x;
104}
105
106
107OLEVariant::OLEVariant(IDispatch* pDispInterface)
108{
109 VariantInit(this);
110 setIDispatch( pDispInterface );
111}
112
113OLEVariant::OLEVariant(const css::uno::Sequence< sal_Int8 >& x)
114{
115 VariantInit(this);
116
117 vt = VT_ARRAY|VT_UI1;
118
119 parray = SafeArrayCreateVector(VT_UI1, 0, x.getLength());
120 const sal_Int8* pBegin = x.getConstArray();
121 const sal_Int8* pEnd = pBegin + x.getLength();
122
123 for(sal_Int32 i=0;pBegin != pEnd;++i,++pBegin)
124 {
125 sal_Int32 nData = *pBegin;
126 HRESULT rs = SafeArrayPutElement(parray,&i,&nData);
127 OSL_ENSURE(S_OK == rs,"Error while copy byte data");
128 }
129}
130
132{
133 HRESULT eRet = ::VariantCopy(this, static_cast<const VARIANT*>(&varSrc));
134 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
135 return *this;
136}
137// Assign a const VARIANT& (::VariantCopy handles everything)
138
139OLEVariant& OLEVariant::operator=(const tagVARIANT& varSrc)
140{
141 HRESULT eRet = ::VariantCopy(this, &varSrc);
142 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
143
144 return *this;
145}
146
147// Assign a const VARIANT* (::VariantCopy handles everything)
148
150{
151 HRESULT eRet = ::VariantCopy(this, pSrc);
152 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
153
154 return *this;
155}
156
158{
159 HRESULT eRet = VariantClear(this);
160 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
161 vt = VT_UI1;
162 bVal = n;
163}
164void OLEVariant::setInt16(sal_Int16 n)
165{
166 HRESULT eRet = VariantClear(this);
167 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
168 vt = VT_I2;
169 iVal = n;
170}
171void OLEVariant::setInt32(sal_Int32 n)
172{
173 HRESULT eRet = VariantClear(this);
174 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
175 vt = VT_I4;
176 lVal = n;
177}
179{ HRESULT eRet = VariantClear(this);
180 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
181 vt = VT_R4;
182 fltVal = f;
183}
185{
186 HRESULT eRet = VariantClear(this);
187 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
188 vt = VT_R8;
189 dblVal = d;
190}
192{ HRESULT eRet = VariantClear(this);
193 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
194 vt = VT_DATE;
195 date = d;
196}
197void OLEVariant::setChar(unsigned char a)
198{
199 HRESULT eRet = VariantClear(this);
200 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
201 vt = VT_UI1;
202 bVal = a;
203}
204void OLEVariant::setCurrency(double aCur)
205{
206 HRESULT eRet = VariantClear(this);
207 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
208 vt = VT_CY;
209 set(aCur*10000);
210}
212{
213 HRESULT eRet = VariantClear(this);
214 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
215 vt = VT_BOOL;
216 boolVal = b ? VARIANT_TRUE : VARIANT_FALSE;
217}
218void OLEVariant::setString(std::u16string_view us)
219{
220 HRESULT eRet = VariantClear(this);
221 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
222 vt = VT_BSTR;
223 bstrVal = SysAllocStringLen(o3tl::toW(us.data()), us.length());
224}
226{
227 HRESULT eRet = VariantClear(this);
228 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
229 vt = VT_ERROR;
230 scode = DISP_E_PARAMNOTFOUND;
231}
232
234{
235 HRESULT eRet = VariantClear(this);
236 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
237 vt = VT_NULL;
238}
240{
241 HRESULT eRet = VariantClear(this);
242 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
243 vt = VT_EMPTY;
244}
245
246void OLEVariant::setUI1SAFEARRAYPtr(SAFEARRAY* pSafeAr)
247{
248 HRESULT eRet = VariantClear(this);
249 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
250 vt = VT_ARRAY|VT_UI1; parray = pSafeAr;
251}
252
253void OLEVariant::setArray(SAFEARRAY* pSafeArray, VARTYPE vtType)
254{
255 HRESULT eRet = VariantClear(this);
256 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
257 vt = static_cast<VARTYPE>(VT_ARRAY|vtType);
258 parray = pSafeArray;
259}
260
261void OLEVariant::setIDispatch(IDispatch* pDispInterface)
262{
263 HRESULT eRet = VariantClear(this);
264 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
265
266 vt = VT_DISPATCH;
267 pdispVal = pDispInterface;
268
269 if ( pDispInterface )
270 pDispInterface->AddRef();
271}
272
273
274bool OLEVariant::isNull() const { return (vt == VT_NULL); }
275bool OLEVariant::isEmpty() const { return (vt == VT_EMPTY); }
276
277VARTYPE OLEVariant::getType() const { return vt; }
278
279css::util::Date OLEVariant::getDate() const
280{
281 return isNull() ? css::util::Date(30,12,1899) : ::dbtools::DBTypeConversion::toDate(getDateAsDouble(),css::util::Date(30,12,1899));
282}
283css::util::Time OLEVariant::getTime() const
284{
285 return isNull() ? css::util::Time() : ::dbtools::DBTypeConversion::toTime(getDateAsDouble());
286}
287css::util::DateTime OLEVariant::getDateTime() const
288{
289 return isNull() ? css::util::DateTime() : ::dbtools::DBTypeConversion::toDateTime(getDateAsDouble(),css::util::Date(30,12,1899));
290}
291
292VARIANT_BOOL OLEVariant::VariantBool(bool bEinBoolean)
293{
294 return (bEinBoolean ? VARIANT_TRUE : VARIANT_FALSE);
295}
296
298{
299 cyVal.Lo ^= sal_uInt32(-1);
300 cyVal.Hi ^= -1;
301 cyVal.Lo++;
302 if( !cyVal.Lo )
303 cyVal.Hi++;
304}
305
306void OLEVariant::set(double n)
307{
308 if( n >= 0 )
309 {
310 cyVal.Hi = static_cast<sal_Int32>(n / 4294967296.0);
311 cyVal.Lo = static_cast<sal_uInt32>(n - (static_cast<double>(cyVal.Hi) * 4294967296.0));
312 }
313 else {
314 cyVal.Hi = static_cast<sal_Int32>(-n / 4294967296.0);
315 cyVal.Lo = static_cast<sal_uInt32>(-n - (static_cast<double>(cyVal.Hi) * 4294967296.0));
316 CHS();
317 }
318}
319
320OUString OLEVariant::getString() const
321{
322 if (V_VT(this) == VT_BSTR)
323 return OUString(o3tl::toU(V_BSTR(this)));
324
325 if(isNull())
326 return OUString();
327
328 OLEVariant varDest;
329
330 varDest.ChangeType(VT_BSTR, this);
331
332 return OUString(o3tl::toU(V_BSTR(&varDest)));
333}
334
335
336void OLEVariant::ChangeType(VARTYPE vartype, const OLEVariant* pSrc)
337{
338
339 // If pDest is NULL, convert type in place
340
341 if (pSrc == nullptr)
342 pSrc = this;
343
344 if ( ( this != pSrc )
345 || ( vartype != V_VT( this ) )
346 )
347 {
348 if ( FAILED( ::VariantChangeType( static_cast< VARIANT* >( this ),
349 static_cast< const VARIANT* >( pSrc ),
350 0,
351 vartype ) ) )
352 {
354 const OUString sError( aResources.getResourceString(STR_TYPE_NOT_CONVERT));
355 throw css::sdbc::SQLException(
356 sError,
357 nullptr,
358 "S1000",
359 1000,
360 css::uno::Any()
361 );
362 }
363 }
364}
365
366
367css::uno::Sequence< sal_Int8 > OLEVariant::getByteSequence() const
368{
369 css::uno::Sequence< sal_Int8 > aRet;
370 if(V_VT(this) == VT_BSTR)
371 {
372 aRet = css::uno::Sequence<sal_Int8>(reinterpret_cast<sal_Int8*>(V_BSTR(this)),
373 ::SysStringByteLen(V_BSTR(this)));
374 }
375 else if(!isNull())
376 {
377 SAFEARRAY* pArray = getUI1SAFEARRAYPtr();
378
379 if(pArray)
380 {
381 HRESULT hresult1,hresult2;
382 LONG lBound,uBound;
383 // Verify that the SafeArray is the proper shape.
384 hresult1 = ::SafeArrayGetLBound(pArray, 1, &lBound);
385 hresult2 = ::SafeArrayGetUBound(pArray, 1, &uBound);
386 if ( SUCCEEDED(hresult1) && SUCCEEDED(hresult2) )
387 {
388 LONG nCount = uBound-lBound+1;
389 aRet.realloc(nCount);
390 sal_Int8* pData = aRet.getArray();
391 for(; SUCCEEDED(hresult1) && lBound <= uBound ;++lBound)
392 {
393 sal_Int32 nData = 0;
394 hresult1 = ::SafeArrayGetElement(pArray,&lBound,&nData);
395 if ( SUCCEEDED(hresult1) )
396 {
397 *pData = static_cast<sal_Int8>(nData);
398 ++pData;
399 }
400 }
401 }
402 }
403 }
404
405 return aRet;
406}
407
409{
410 if (V_VT(this) == VT_BOOL)
411 return V_BOOL(this) == VARIANT_TRUE;
412 if(isNull())
413 return false;
414
415 OLEVariant varDest;
416
417 varDest.ChangeType(VT_BOOL, this);
418
419 return V_BOOL(&varDest) == VARIANT_TRUE;
420}
421
422IUnknown* OLEVariant::getIUnknown() const
423{
424 if (V_VT(this) == VT_UNKNOWN)
425 {
426 return V_UNKNOWN(this);
427 }
428 if(isNull())
429 return nullptr;
430
431 OLEVariant varDest;
432
433 varDest.ChangeType(VT_UNKNOWN, this);
434
435 V_UNKNOWN(&varDest)->AddRef();
436 return V_UNKNOWN(&varDest);
437}
438
439IDispatch* OLEVariant::getIDispatch() const
440{
441 if (V_VT(this) == VT_DISPATCH)
442 {
443 return V_DISPATCH(this);
444 }
445
446 if(isNull())
447 return nullptr;
448
449 OLEVariant varDest;
450
451 varDest.ChangeType(VT_DISPATCH, this);
452
453 V_DISPATCH(&varDest)->AddRef();
454 return V_DISPATCH(&varDest);
455}
456
458{
459 if (V_VT(this) == VT_UI1)
460 return V_UI1(this);
461
462 if(isNull())
463 return sal_Int8(0);
464 OLEVariant varDest;
465
466 varDest.ChangeType(VT_UI1, this);
467
468 return V_UI1(&varDest);
469}
470
471sal_Int16 OLEVariant::getInt16() const
472{
473 if (V_VT(this) == VT_I2)
474 return V_I2(this);
475
476 if(isNull())
477 return sal_Int16(0);
478 OLEVariant varDest;
479
480 varDest.ChangeType(VT_I2, this);
481
482 return V_I2(&varDest);
483}
484
486{
487 if (V_VT(this) == VT_I1)
488 return V_I1(this);
489
490 if(isNull())
491 return sal_Int8(0);
492
493 OLEVariant varDest;
494
495 varDest.ChangeType(VT_I1, this);
496
497 return V_I1(&varDest);
498}
499
500sal_Int32 OLEVariant::getInt32() const
501{
502 if (V_VT(this) == VT_I4)
503 return V_I4(this);
504
505 if(isNull())
506 return sal_Int32(0);
507
508 OLEVariant varDest;
509
510 varDest.ChangeType(VT_I4, this);
511
512 return V_I4(&varDest);
513}
514
515sal_uInt32 OLEVariant::getUInt32() const
516{
517 if (V_VT(this) == VT_UI4)
518 return V_UI4(this);
519
520 if(isNull())
521 return sal_uInt32(0);
522
523 OLEVariant varDest;
524
525 varDest.ChangeType(VT_UI4, this);
526
527 return V_UI4(&varDest);
528}
529
531{
532 if (V_VT(this) == VT_R4)
533 return V_R4(this);
534
535 if(isNull())
536 return float(0);
537 OLEVariant varDest;
538
539 varDest.ChangeType(VT_R4, this);
540
541 return V_R4(&varDest);
542}
543
545{
546 if (V_VT(this) == VT_R8)
547 return V_R8(this);
548
549 if(isNull())
550 return double(0);
551 OLEVariant varDest;
552
553 varDest.ChangeType(VT_R8, this);
554
555 return V_R8(&varDest);
556}
557
559{
560 if (V_VT(this) == VT_DATE)
561 return V_DATE(this);
562
563 if(isNull())
564 return double(0);
565 OLEVariant varDest;
566
567 varDest.ChangeType(VT_DATE, this);
568
569 return V_DATE(&varDest);
570}
571
573{
574 if (V_VT(this) == VT_CY)
575 return V_CY(this);
576
577 if(isNull())
578 {
579 CY aVar;
580 aVar.int64 = sal_Int64(0);
581 return aVar;
582 }
583 OLEVariant varDest;
584
585 varDest.ChangeType(VT_CY, this);
586
587 return V_CY(&varDest);
588}
589
591{
592 if (V_VT(this) == (VT_ARRAY|VT_UI1))
593 return V_ARRAY(this);
594
595 if(isNull())
596 return nullptr;
597 OLEVariant varDest;
598
599 varDest.ChangeType((VT_ARRAY|VT_UI1), this);
600
601 return V_ARRAY(&varDest);
602}
603
604css::uno::Any OLEVariant::makeAny() const
605{
606 css::uno::Any aValue;
607 switch (V_VT(this))
608 {
609 case VT_EMPTY:
610 case VT_NULL:
611 aValue.setValue(nullptr, Type());
612 break;
613 case VT_I2:
614 aValue.setValue( & iVal, cppu::UnoType<sal_Int16>::get());
615 break;
616 case VT_I4:
617 aValue.setValue( & lVal, cppu::UnoType<sal_Int32>::get());
618 break;
619 case VT_R4:
620 aValue.setValue( & fltVal, cppu::UnoType<float>::get());
621 break;
622 case VT_R8:
623 aValue.setValue(& dblVal, cppu::UnoType<double>::get());
624 break;
625 case VT_CY:
626 {
627 Currency cy(cyVal.int64);
628 aValue <<= cy;
629 break;
630 }
631 case VT_DATE:
632 {
633 aValue <<= getDate();
634 break;
635 }
636 case VT_BSTR:
637 {
638 OUString b(o3tl::toU(bstrVal));
639 aValue.setValue( &b, cppu::UnoType<decltype(b)>::get());
640 break;
641 }
642 case VT_BOOL:
643 {
644 aValue <<= (boolVal == VARIANT_TRUE);
645 break;
646 }
647 case VT_I1:
648 aValue.setValue( & cVal, cppu::UnoType<sal_Int8>::get());
649 break;
650 case VT_UI1: // there is no unsigned char in UNO
651 aValue <<= sal_Int8(bVal);
652 break;
653 case VT_UI2:
654 aValue.setValue( & uiVal, cppu::UnoType<cppu::UnoUnsignedShortType>::get());
655 break;
656 case VT_UI4:
657 aValue.setValue( & ulVal, cppu::UnoType<sal_uInt32>::get());
658 break;
659 case VT_INT:
660 aValue.setValue( & intVal, cppu::UnoType<sal_Int32>::get());
661 break;
662 case VT_UINT:
663 aValue.setValue( & uintVal, cppu::UnoType<sal_uInt32>::get());
664 break;
665 case VT_VOID:
666 aValue.setValue( nullptr, Type());
667 break;
668 case VT_DECIMAL:
669 {
670 Decimal dec;
671 dec.Scale = decVal.scale;
672 dec.Sign = decVal.sign;
673 dec.LowValue = decVal.Lo32;
674 dec.MiddleValue = decVal.Mid32;
675 dec.HighValue = decVal.Hi32;
676 aValue <<= dec;
677 break;
678 }
679
680 default:
681 break;
682 }
683 return aValue;
684}
685
686
687/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static double toDouble(std::string_view rString)
Definition: DTable.cxx:1635
double d
helper class for accessing resources shared by different libraries in the connectivity module
OUString getResourceString(TranslateId pResId) const
loads a string from the shared resource file
css::uno::Any makeAny() const
css::util::Date getDate() const
css::util::DateTime getDateTime() const
void setChar(unsigned char a)
void setCurrency(double aCur)
OLEVariant & operator=(const OLEVariant &varSrc)
void setString(std::u16string_view us)
css::util::Time getTime() const
SAFEARRAY * getUI1SAFEARRAYPtr() const
sal_uInt32 getUInt32() const
css::uno::Sequence< sal_Int8 > getByteSequence() const
void setArray(SAFEARRAY *pSafeArray, VARTYPE vtType)
static VARIANT_BOOL VariantBool(bool bEinBoolean)
void setUI1SAFEARRAYPtr(SAFEARRAY *pSafeAr)
void ChangeType(VARTYPE vartype, const OLEVariant *pSrc)
IDispatch * getIDispatch() const
IUnknown * getIUnknown() const
void setIDispatch(IDispatch *pDispInterface)
int nCount
float x
sal_Int64 n
uno_Any a
std::unique_ptr< sal_Int32[]> pData
Type
OOO_DLLPUBLIC_DBTOOLS css::util::Date toDate(double dVal, const css::util::Date &_rNullDate=getStandardDate())
OOO_DLLPUBLIC_DBTOOLS css::util::Time toTime(double dVal, short nDigits=9)
OOO_DLLPUBLIC_DBTOOLS css::util::DateTime toDateTime(double dVal, const css::util::Date &_rNullDate=getStandardDate())
int i
#define VT_UINT
#define VT_UI2
#define VT_ARRAY
#define VT_DATE
#define VT_EMPTY
#define VT_R4
#define VT_UI4
#define VT_BSTR
#define VT_R8
#define VT_INT
#define VT_ERROR
#define VT_DECIMAL
#define VT_NULL
#define VT_BOOL
#define VT_I1
#define VT_CY
#define VT_I4
#define VT_UI1
#define VT_I2
LONG
unsigned char sal_uInt8
signed char sal_Int8