1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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()
44 OLEString::OLEString(const BSTR
& _sBStr
)
48 OLEString::OLEString(const OUString
& _sBStr
)
50 m_sStr
= ::SysAllocString(o3tl::toW(_sBStr
.getStr()));
52 OLEString::~OLEString()
55 ::SysFreeString(m_sStr
);
57 OLEString
& OLEString::operator=(const OUString
& _rSrc
)
60 ::SysFreeString(m_sStr
);
61 m_sStr
= ::SysAllocString(o3tl::toW(_rSrc
.getStr()));
64 OLEString
& OLEString::operator=(const OLEString
& _rSrc
)
69 ::SysFreeString(m_sStr
);
70 m_sStr
= ::SysAllocString(_rSrc
.m_sStr
);
74 OLEString
& OLEString::operator=(const BSTR
& _rSrc
)
77 ::SysFreeString(m_sStr
);
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
89 BSTR
* OLEString::getAddress()
93 sal_Int32
OLEString::length() const
95 return (m_sStr
!= nullptr) ? ::SysStringLen(m_sStr
) : 0;
98 OLEVariant::OLEVariant()
102 OLEVariant::OLEVariant(const VARIANT
& varSrc
)
105 HRESULT eRet
= ::VariantCopy(this, &varSrc
);
106 OSL_ENSURE(eRet
== S_OK
,"Error while copying an ado variant!");
108 OLEVariant::OLEVariant(const OLEVariant
& varSrc
)
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
)
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
)
137 dblVal
= ::dbtools::DBTypeConversion::toDouble(x
,css::util::Date(30,12,1899));
139 OLEVariant::OLEVariant(const css::util::Time
& x
)
143 dblVal
= ::dbtools::DBTypeConversion::toDouble(x
);
145 OLEVariant::OLEVariant(const css::util::DateTime
& x
)
149 dblVal
= ::dbtools::DBTypeConversion::toDouble(x
,css::util::Date(30,12,1899));
151 OLEVariant::OLEVariant(float x
)
157 OLEVariant::OLEVariant(const double &x
)
165 OLEVariant::OLEVariant(IDispatch
* pDispInterface
)
168 setIDispatch( pDispInterface
);
171 OLEVariant::OLEVariant(const css::uno::Sequence
< sal_Int8
>& x
)
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!");
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!");
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!");
215 void OLEVariant::setByte(sal_uInt8 n
)
217 HRESULT eRet
= VariantClear(this);
218 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
222 void OLEVariant::setInt16(sal_Int16 n
)
224 HRESULT eRet
= VariantClear(this);
225 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
229 void OLEVariant::setInt32(sal_Int32 n
)
231 HRESULT eRet
= VariantClear(this);
232 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
236 void OLEVariant::setFloat(float f
)
237 { HRESULT eRet
= VariantClear(this);
238 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
242 void OLEVariant::setDouble(double d
)
244 HRESULT eRet
= VariantClear(this);
245 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
249 void OLEVariant::setDate(DATE d
)
250 { HRESULT eRet
= VariantClear(this);
251 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
255 void OLEVariant::setChar(unsigned char a
)
257 HRESULT eRet
= VariantClear(this);
258 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
262 void OLEVariant::setCurrency(double aCur
)
264 HRESULT eRet
= VariantClear(this);
265 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
269 void OLEVariant::setBool(bool b
)
271 HRESULT eRet
= VariantClear(this);
272 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
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!");
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!");
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!");
297 void OLEVariant::setEmpty()
299 HRESULT eRet
= VariantClear(this);
300 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
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
);
319 void OLEVariant::setIDispatch(IDispatch
* pDispInterface
)
321 HRESULT eRet
= VariantClear(this);
322 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
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);
364 void OLEVariant::set(double n
)
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));
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));
378 OUString
OLEVariant::getString() const
380 if (V_VT(this) == VT_BSTR
)
381 return o3tl::toU(LPCOLESTR(V_BSTR(this)));
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
402 if ( ( this != pSrc
)
403 || ( vartype
!= V_VT( this ) )
406 if ( FAILED( ::VariantChangeType( static_cast< VARIANT
* >( this ),
407 static_cast< const VARIANT
* >( pSrc
),
411 ::connectivity::SharedResources aResources
;
412 const OUString
sError( aResources
.getResourceString(STR_TYPE_NOT_CONVERT
));
413 throw css::sdbc::SQLException(
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());
435 SAFEARRAY
* pArray
= getUI1SAFEARRAYPtr();
439 HRESULT hresult1
,hresult2
;
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
)
452 hresult1
= ::SafeArrayGetElement(pArray
,&lBound
,&nData
);
453 if ( SUCCEEDED(hresult1
) )
455 *pData
= static_cast<sal_Int8
>(nData
);
466 bool OLEVariant::getBool() const
468 if (V_VT(this) == VT_BOOL
)
469 return V_BOOL(this) == VARIANT_TRUE
;
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);
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);
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
)
524 varDest
.ChangeType(VT_UI1
, this);
526 return V_UI1(&varDest
);
529 sal_Int16
OLEVariant::getInt16() const
531 if (V_VT(this) == VT_I2
)
538 varDest
.ChangeType(VT_I2
, this);
540 return V_I2(&varDest
);
543 sal_Int8
OLEVariant::getInt8() const
545 if (V_VT(this) == VT_I1
)
553 varDest
.ChangeType(VT_I1
, this);
555 return V_I1(&varDest
);
558 sal_Int32
OLEVariant::getInt32() const
560 if (V_VT(this) == VT_I4
)
568 varDest
.ChangeType(VT_I4
, this);
570 return V_I4(&varDest
);
573 sal_uInt32
OLEVariant::getUInt32() const
575 if (V_VT(this) == VT_UI4
)
579 return sal_uInt32(0);
583 varDest
.ChangeType(VT_UI4
, this);
585 return V_UI4(&varDest
);
588 float OLEVariant::getFloat() const
590 if (V_VT(this) == VT_R4
)
597 varDest
.ChangeType(VT_R4
, this);
599 return V_R4(&varDest
);
602 double OLEVariant::getDouble() const
604 if (V_VT(this) == VT_R8
)
611 varDest
.ChangeType(VT_R8
, this);
613 return V_R8(&varDest
);
616 double OLEVariant::getDateAsDouble() const
618 if (V_VT(this) == VT_DATE
)
625 varDest
.ChangeType(VT_DATE
, this);
627 return V_DATE(&varDest
);
630 CY
OLEVariant::getCurrency() const
632 if (V_VT(this) == VT_CY
)
638 aVar
.int64
= sal_Int64(0);
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);
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
;
669 aValue
.setValue(nullptr, Type());
672 aValue
.setValue( & iVal
, cppu::UnoType
<sal_Int16
>::get());
675 aValue
.setValue( & lVal
, cppu::UnoType
<sal_Int32
>::get());
678 aValue
.setValue( & fltVal
, cppu::UnoType
<float>::get());
681 aValue
.setValue(& dblVal
, cppu::UnoType
<double>::get());
685 Currency
cy(cyVal
.int64
);
691 aValue
<<= getDate();
696 OUString
b(o3tl::toU(bstrVal
));
697 aValue
.setValue( &b
, cppu::UnoType
<decltype(b
)>::get());
702 aValue
<<= (boolVal
== VARIANT_TRUE
);
706 aValue
.setValue( & cVal
, cppu::UnoType
<sal_Int8
>::get());
708 case VT_UI1
: // there is no unsigned char in UNO
709 aValue
<<= sal_Int8(bVal
);
712 aValue
.setValue( & uiVal
, cppu::UnoType
<cppu::UnoUnsignedShortType
>::get());
715 aValue
.setValue( & ulVal
, cppu::UnoType
<sal_uInt32
>::get());
718 aValue
.setValue( & intVal
, cppu::UnoType
<sal_Int32
>::get());
721 aValue
.setValue( & uintVal
, cppu::UnoType
<sal_uInt32
>::get());
724 aValue
.setValue( nullptr, Type());
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
;
745 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */