bump product version to 6.3.0.0.beta1
[LibreOffice.git] / connectivity / source / drivers / ado / Aolevariant.cxx
blob7f740e81d7c213b91a1dac699e7005175838bedb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <ado/Aolevariant.hxx>
21 #include <connectivity/dbconversion.hxx>
22 #include <osl/diagnose.h>
23 #include <o3tl/char16_t2wchar_t.hxx>
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>
28 #include <resource/sharedresources.hxx>
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>
35 using namespace com::sun::star::beans;
36 using namespace com::sun::star::uno;
37 using namespace com::sun::star::bridge::oleautomation;
38 using namespace connectivity::ado;
40 OLEString::OLEString()
41 :m_sStr(nullptr)
44 OLEString::OLEString(const BSTR& _sBStr)
45 :m_sStr(_sBStr)
48 OLEString::OLEString(const OUString& _sBStr)
50 m_sStr = ::SysAllocString(o3tl::toW(_sBStr.getStr()));
52 OLEString::~OLEString()
54 if(m_sStr)
55 ::SysFreeString(m_sStr);
57 OLEString& OLEString::operator=(const OUString& _rSrc)
59 if(m_sStr)
60 ::SysFreeString(m_sStr);
61 m_sStr = ::SysAllocString(o3tl::toW(_rSrc.getStr()));
62 return *this;
64 OLEString& OLEString::operator=(const OLEString& _rSrc)
66 if(this != &_rSrc)
68 if(m_sStr)
69 ::SysFreeString(m_sStr);
70 m_sStr = ::SysAllocString(_rSrc.m_sStr);
72 return *this;
74 OLEString& OLEString::operator=(const BSTR& _rSrc)
76 if(m_sStr)
77 ::SysFreeString(m_sStr);
78 m_sStr = _rSrc;
79 return *this;
81 OUString OLEString::asOUString() const
83 return (m_sStr != nullptr) ? OUString(o3tl::toU(LPCOLESTR(m_sStr)),::SysStringLen(m_sStr)) : OUString();
85 BSTR OLEString::asBSTR() const
87 return m_sStr;
89 BSTR* OLEString::getAddress()
91 return &m_sStr;
93 sal_Int32 OLEString::length() const
95 return (m_sStr != nullptr) ? ::SysStringLen(m_sStr) : 0;
98 OLEVariant::OLEVariant()
100 VariantInit(this);
102 OLEVariant::OLEVariant(const VARIANT& varSrc)
104 ::VariantInit(this);
105 HRESULT eRet = ::VariantCopy(this, &varSrc);
106 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
108 OLEVariant::OLEVariant(const OLEVariant& varSrc)
110 ::VariantInit(this);
111 HRESULT eRet = ::VariantCopy(this, static_cast<const VARIANT*>(&varSrc));
112 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
115 OLEVariant::OLEVariant(bool x) { VariantInit(this); vt = VT_BOOL; boolVal = (x ? VARIANT_TRUE : VARIANT_FALSE);}
116 OLEVariant::OLEVariant(sal_Int8 n) { VariantInit(this); vt = VT_I1; bVal = n;}
117 OLEVariant::OLEVariant(sal_Int16 n) { VariantInit(this); vt = VT_I2; intVal = n;}
118 OLEVariant::OLEVariant(sal_Int32 n) { VariantInit(this); vt = VT_I4; lVal = n;}
119 OLEVariant::OLEVariant(sal_Int64 x) { VariantInit(this); vt = VT_I4; lVal = static_cast<LONG>(x);}
121 OLEVariant::OLEVariant(const OUString& us)
123 ::VariantInit(this);
124 vt = VT_BSTR;
125 bstrVal = SysAllocString(o3tl::toW(us.getStr()));
127 OLEVariant::~OLEVariant()
129 HRESULT eRet = ::VariantClear(this);
130 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
131 } // clears all the memory that was allocated before
133 OLEVariant::OLEVariant(const css::util::Date& x )
135 VariantInit(this);
136 vt = VT_DATE;
137 dblVal = ::dbtools::DBTypeConversion::toDouble(x,css::util::Date(30,12,1899));
139 OLEVariant::OLEVariant(const css::util::Time& x )
141 VariantInit(this);
142 vt = VT_DATE;
143 dblVal = ::dbtools::DBTypeConversion::toDouble(x);
145 OLEVariant::OLEVariant(const css::util::DateTime& x )
147 VariantInit(this);
148 vt = VT_DATE;
149 dblVal = ::dbtools::DBTypeConversion::toDouble(x,css::util::Date(30,12,1899));
151 OLEVariant::OLEVariant(float x)
153 VariantInit(this);
154 vt = VT_R4;
155 fltVal = x;
157 OLEVariant::OLEVariant(const double &x)
159 VariantInit(this);
160 vt = VT_R8;
161 dblVal = x;
165 OLEVariant::OLEVariant(IDispatch* pDispInterface)
167 VariantInit(this);
168 setIDispatch( pDispInterface );
171 OLEVariant::OLEVariant(const css::uno::Sequence< sal_Int8 >& x)
173 VariantInit(this);
175 vt = VT_ARRAY|VT_UI1;
177 parray = SafeArrayCreateVector(VT_UI1, 0, x.getLength());
178 const sal_Int8* pBegin = x.getConstArray();
179 const sal_Int8* pEnd = pBegin + x.getLength();
181 for(sal_Int32 i=0;pBegin != pEnd;++i,++pBegin)
183 sal_Int32 nData = *pBegin;
184 HRESULT rs = SafeArrayPutElement(parray,&i,&nData);
185 OSL_ENSURE(S_OK == rs,"Error while copy byte data");
189 OLEVariant& OLEVariant::operator=(const OLEVariant& varSrc)
191 HRESULT eRet = ::VariantCopy(this, static_cast<const VARIANT*>(&varSrc));
192 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
193 return *this;
195 // Assign a const VARIANT& (::VariantCopy handles everything)
197 OLEVariant& OLEVariant::operator=(const tagVARIANT& varSrc)
199 HRESULT eRet = ::VariantCopy(this, &varSrc);
200 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
202 return *this;
205 // Assign a const VARIANT* (::VariantCopy handles everything)
207 OLEVariant& OLEVariant::operator=(const VARIANT* pSrc)
209 HRESULT eRet = ::VariantCopy(this, pSrc);
210 OSL_ENSURE(eRet == S_OK,"Error while copying an ado variant!");
212 return *this;
215 void OLEVariant::setByte(sal_uInt8 n)
217 HRESULT eRet = VariantClear(this);
218 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
219 vt = VT_UI1;
220 bVal = n;
222 void OLEVariant::setInt16(sal_Int16 n)
224 HRESULT eRet = VariantClear(this);
225 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
226 vt = VT_I2;
227 iVal = n;
229 void OLEVariant::setInt32(sal_Int32 n)
231 HRESULT eRet = VariantClear(this);
232 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
233 vt = VT_I4;
234 lVal = n;
236 void OLEVariant::setFloat(float f)
237 { HRESULT eRet = VariantClear(this);
238 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
239 vt = VT_R4;
240 fltVal = f;
242 void OLEVariant::setDouble(double d)
244 HRESULT eRet = VariantClear(this);
245 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
246 vt = VT_R8;
247 dblVal = d;
249 void OLEVariant::setDate(DATE d)
250 { HRESULT eRet = VariantClear(this);
251 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
252 vt = VT_DATE;
253 date = d;
255 void OLEVariant::setChar(unsigned char a)
257 HRESULT eRet = VariantClear(this);
258 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
259 vt = VT_UI1;
260 bVal = a;
262 void OLEVariant::setCurrency(double aCur)
264 HRESULT eRet = VariantClear(this);
265 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
266 vt = VT_CY;
267 set(aCur*10000);
269 void OLEVariant::setBool(bool b)
271 HRESULT eRet = VariantClear(this);
272 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
273 vt = VT_BOOL;
274 boolVal = b ? VARIANT_TRUE : VARIANT_FALSE;
276 void OLEVariant::setString(const OUString& us)
278 HRESULT eRet = VariantClear(this);
279 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
280 vt = VT_BSTR;
281 bstrVal = ::SysAllocString(o3tl::toW(us.getStr()));
283 void OLEVariant::setNoArg()
285 HRESULT eRet = VariantClear(this);
286 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
287 vt = VT_ERROR;
288 scode = DISP_E_PARAMNOTFOUND;
291 void OLEVariant::setNull()
293 HRESULT eRet = VariantClear(this);
294 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
295 vt = VT_NULL;
297 void OLEVariant::setEmpty()
299 HRESULT eRet = VariantClear(this);
300 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
301 vt = VT_EMPTY;
304 void OLEVariant::setUI1SAFEARRAYPtr(SAFEARRAY* pSafeAr)
306 HRESULT eRet = VariantClear(this);
307 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
308 vt = VT_ARRAY|VT_UI1; parray = pSafeAr;
311 void OLEVariant::setArray(SAFEARRAY* pSafeArray, VARTYPE vtType)
313 HRESULT eRet = VariantClear(this);
314 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
315 vt = static_cast<VARTYPE>(VT_ARRAY|vtType);
316 parray = pSafeArray;
319 void OLEVariant::setIDispatch(IDispatch* pDispInterface)
321 HRESULT eRet = VariantClear(this);
322 OSL_ENSURE(eRet == S_OK,"Error while clearing an ado variant!");
324 vt = VT_DISPATCH;
325 pdispVal = pDispInterface;
327 if ( pDispInterface )
328 pDispInterface->AddRef();
332 bool OLEVariant::isNull() const { return (vt == VT_NULL); }
333 bool OLEVariant::isEmpty() const { return (vt == VT_EMPTY); }
335 VARTYPE OLEVariant::getType() const { return vt; }
337 css::util::Date OLEVariant::getDate() const
339 return isNull() ? css::util::Date(30,12,1899) : ::dbtools::DBTypeConversion::toDate(getDateAsDouble(),css::util::Date(30,12,1899));
341 css::util::Time OLEVariant::getTime() const
343 return isNull() ? css::util::Time() : ::dbtools::DBTypeConversion::toTime(getDateAsDouble());
345 css::util::DateTime OLEVariant::getDateTime() const
347 return isNull() ? css::util::DateTime() : ::dbtools::DBTypeConversion::toDateTime(getDateAsDouble(),css::util::Date(30,12,1899));
350 VARIANT_BOOL OLEVariant::VariantBool(bool bEinBoolean)
352 return (bEinBoolean ? VARIANT_TRUE : VARIANT_FALSE);
355 void OLEVariant::CHS()
357 cyVal.Lo ^= sal_uInt32(-1);
358 cyVal.Hi ^= -1;
359 cyVal.Lo++;
360 if( !cyVal.Lo )
361 cyVal.Hi++;
364 void OLEVariant::set(double n)
366 if( n >= 0 )
368 cyVal.Hi = static_cast<sal_Int32>(n / 4294967296.0);
369 cyVal.Lo = static_cast<sal_uInt32>(n - (static_cast<double>(cyVal.Hi) * 4294967296.0));
371 else {
372 cyVal.Hi = static_cast<sal_Int32>(-n / 4294967296.0);
373 cyVal.Lo = static_cast<sal_uInt32>(-n - (static_cast<double>(cyVal.Hi) * 4294967296.0));
374 CHS();
378 OUString OLEVariant::getString() const
380 if (V_VT(this) == VT_BSTR)
381 return o3tl::toU(LPCOLESTR(V_BSTR(this)));
383 if(isNull())
384 return OUString();
386 OLEVariant varDest;
388 varDest.ChangeType(VT_BSTR, this);
390 return o3tl::toU(LPCOLESTR(V_BSTR(&varDest)));
394 void OLEVariant::ChangeType(VARTYPE vartype, const OLEVariant* pSrc)
397 // If pDest is NULL, convert type in place
399 if (pSrc == nullptr)
400 pSrc = this;
402 if ( ( this != pSrc )
403 || ( vartype != V_VT( this ) )
406 if ( FAILED( ::VariantChangeType( static_cast< VARIANT* >( this ),
407 static_cast< const VARIANT* >( pSrc ),
409 vartype ) ) )
411 ::connectivity::SharedResources aResources;
412 const OUString sError( aResources.getResourceString(STR_TYPE_NOT_CONVERT));
413 throw css::sdbc::SQLException(
414 sError,
415 nullptr,
416 "S1000",
417 1000,
418 css::uno::Any()
425 css::uno::Sequence< sal_Int8 > OLEVariant::getByteSequence() const
427 css::uno::Sequence< sal_Int8 > aRet;
428 if(V_VT(this) == VT_BSTR)
430 OLEString sStr(V_BSTR(this));
431 aRet = css::uno::Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(sStr.asBSTR()),sizeof(sal_Unicode)*sStr.length());
433 else if(!isNull())
435 SAFEARRAY* pArray = getUI1SAFEARRAYPtr();
437 if(pArray)
439 HRESULT hresult1,hresult2;
440 long lBound,uBound;
441 // Verify that the SafeArray is the proper shape.
442 hresult1 = ::SafeArrayGetLBound(pArray, 1, &lBound);
443 hresult2 = ::SafeArrayGetUBound(pArray, 1, &uBound);
444 if ( SUCCEEDED(hresult1) && SUCCEEDED(hresult2) )
446 long nCount = uBound-lBound+1;
447 aRet.realloc(nCount);
448 sal_Int8* pData = aRet.getArray();
449 for(long i=0; SUCCEEDED(hresult1) && lBound <= uBound ;++i,++lBound)
451 sal_Int32 nData = 0;
452 hresult1 = ::SafeArrayGetElement(pArray,&lBound,&nData);
453 if ( SUCCEEDED(hresult1) )
455 *pData = static_cast<sal_Int8>(nData);
456 ++pData;
463 return aRet;
466 bool OLEVariant::getBool() const
468 if (V_VT(this) == VT_BOOL)
469 return V_BOOL(this) == VARIANT_TRUE;
470 if(isNull())
471 return false;
473 OLEVariant varDest;
475 varDest.ChangeType(VT_BOOL, this);
477 return V_BOOL(&varDest) == VARIANT_TRUE;
480 IUnknown* OLEVariant::getIUnknown() const
482 if (V_VT(this) == VT_UNKNOWN)
484 return V_UNKNOWN(this);
486 if(isNull())
487 return nullptr;
489 OLEVariant varDest;
491 varDest.ChangeType(VT_UNKNOWN, this);
493 V_UNKNOWN(&varDest)->AddRef();
494 return V_UNKNOWN(&varDest);
497 IDispatch* OLEVariant::getIDispatch() const
499 if (V_VT(this) == VT_DISPATCH)
501 return V_DISPATCH(this);
504 if(isNull())
505 return nullptr;
507 OLEVariant varDest;
509 varDest.ChangeType(VT_DISPATCH, this);
511 V_DISPATCH(&varDest)->AddRef();
512 return V_DISPATCH(&varDest);
515 sal_uInt8 OLEVariant::getByte() const
517 if (V_VT(this) == VT_UI1)
518 return V_UI1(this);
520 if(isNull())
521 return sal_Int8(0);
522 OLEVariant varDest;
524 varDest.ChangeType(VT_UI1, this);
526 return V_UI1(&varDest);
529 sal_Int16 OLEVariant::getInt16() const
531 if (V_VT(this) == VT_I2)
532 return V_I2(this);
534 if(isNull())
535 return sal_Int16(0);
536 OLEVariant varDest;
538 varDest.ChangeType(VT_I2, this);
540 return V_I2(&varDest);
543 sal_Int8 OLEVariant::getInt8() const
545 if (V_VT(this) == VT_I1)
546 return V_I1(this);
548 if(isNull())
549 return sal_Int8(0);
551 OLEVariant varDest;
553 varDest.ChangeType(VT_I1, this);
555 return V_I1(&varDest);
558 sal_Int32 OLEVariant::getInt32() const
560 if (V_VT(this) == VT_I4)
561 return V_I4(this);
563 if(isNull())
564 return sal_Int32(0);
566 OLEVariant varDest;
568 varDest.ChangeType(VT_I4, this);
570 return V_I4(&varDest);
573 sal_uInt32 OLEVariant::getUInt32() const
575 if (V_VT(this) == VT_UI4)
576 return V_UI4(this);
578 if(isNull())
579 return sal_uInt32(0);
581 OLEVariant varDest;
583 varDest.ChangeType(VT_UI4, this);
585 return V_UI4(&varDest);
588 float OLEVariant::getFloat() const
590 if (V_VT(this) == VT_R4)
591 return V_R4(this);
593 if(isNull())
594 return float(0);
595 OLEVariant varDest;
597 varDest.ChangeType(VT_R4, this);
599 return V_R4(&varDest);
602 double OLEVariant::getDouble() const
604 if (V_VT(this) == VT_R8)
605 return V_R8(this);
607 if(isNull())
608 return double(0);
609 OLEVariant varDest;
611 varDest.ChangeType(VT_R8, this);
613 return V_R8(&varDest);
616 double OLEVariant::getDateAsDouble() const
618 if (V_VT(this) == VT_DATE)
619 return V_DATE(this);
621 if(isNull())
622 return double(0);
623 OLEVariant varDest;
625 varDest.ChangeType(VT_DATE, this);
627 return V_DATE(&varDest);
630 CY OLEVariant::getCurrency() const
632 if (V_VT(this) == VT_CY)
633 return V_CY(this);
635 if(isNull())
637 CY aVar;
638 aVar.int64 = sal_Int64(0);
639 return aVar;
641 OLEVariant varDest;
643 varDest.ChangeType(VT_CY, this);
645 return V_CY(&varDest);
648 SAFEARRAY* OLEVariant::getUI1SAFEARRAYPtr() const
650 if (V_VT(this) == (VT_ARRAY|VT_UI1))
651 return V_ARRAY(this);
653 if(isNull())
654 return nullptr;
655 OLEVariant varDest;
657 varDest.ChangeType((VT_ARRAY|VT_UI1), this);
659 return V_ARRAY(&varDest);
662 css::uno::Any OLEVariant::makeAny() const
664 css::uno::Any aValue;
665 switch (V_VT(this))
667 case VT_EMPTY:
668 case VT_NULL:
669 aValue.setValue(nullptr, Type());
670 break;
671 case VT_I2:
672 aValue.setValue( & iVal, cppu::UnoType<sal_Int16>::get());
673 break;
674 case VT_I4:
675 aValue.setValue( & lVal, cppu::UnoType<sal_Int32>::get());
676 break;
677 case VT_R4:
678 aValue.setValue( & fltVal, cppu::UnoType<float>::get());
679 break;
680 case VT_R8:
681 aValue.setValue(& dblVal, cppu::UnoType<double>::get());
682 break;
683 case VT_CY:
685 Currency cy(cyVal.int64);
686 aValue <<= cy;
687 break;
689 case VT_DATE:
691 aValue <<= getDate();
692 break;
694 case VT_BSTR:
696 OUString b(o3tl::toU(bstrVal));
697 aValue.setValue( &b, cppu::UnoType<decltype(b)>::get());
698 break;
700 case VT_BOOL:
702 aValue <<= (boolVal == VARIANT_TRUE);
703 break;
705 case VT_I1:
706 aValue.setValue( & cVal, cppu::UnoType<sal_Int8>::get());
707 break;
708 case VT_UI1: // there is no unsigned char in UNO
709 aValue <<= sal_Int8(bVal);
710 break;
711 case VT_UI2:
712 aValue.setValue( & uiVal, cppu::UnoType<cppu::UnoUnsignedShortType>::get());
713 break;
714 case VT_UI4:
715 aValue.setValue( & ulVal, cppu::UnoType<sal_uInt32>::get());
716 break;
717 case VT_INT:
718 aValue.setValue( & intVal, cppu::UnoType<sal_Int32>::get());
719 break;
720 case VT_UINT:
721 aValue.setValue( & uintVal, cppu::UnoType<sal_uInt32>::get());
722 break;
723 case VT_VOID:
724 aValue.setValue( nullptr, Type());
725 break;
726 case VT_DECIMAL:
728 Decimal dec;
729 dec.Scale = decVal.scale;
730 dec.Sign = decVal.sign;
731 dec.LowValue = decVal.Lo32;
732 dec.MiddleValue = decVal.Mid32;
733 dec.HighValue = decVal.Hi32;
734 aValue <<= dec;
735 break;
738 default:
739 break;
741 return aValue;
745 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */