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 <com/sun/star/sdbc/SQLException.hpp>
23 #include <com/sun/star/util/Time.hpp>
24 #include <com/sun/star/util/Date.hpp>
25 #include <com/sun/star/util/DateTime.hpp>
26 #include "diagnose_ex.h"
27 #include "resource/sharedresources.hxx"
28 #include "resource/ado_res.hrc"
29 #include "com/sun/star/bridge/oleautomation/Date.hpp"
30 #include "com/sun/star/bridge/oleautomation/Currency.hpp"
31 #include "com/sun/star/bridge/oleautomation/SCode.hpp"
32 #include "com/sun/star/bridge/oleautomation/Decimal.hpp"
34 using namespace com::sun::star::beans
;
35 using namespace com::sun::star::uno
;
36 using namespace com::sun::star::bridge::oleautomation
;
37 using namespace connectivity::ado
;
39 OLEString::OLEString()
43 OLEString::OLEString(const BSTR
& _sBStr
)
47 OLEString::OLEString(const OUString
& _sBStr
)
49 m_sStr
= ::SysAllocString(reinterpret_cast<LPCOLESTR
>(_sBStr
.getStr()));
51 OLEString::~OLEString()
54 ::SysFreeString(m_sStr
);
56 OLEString
& OLEString::operator=(const OUString
& _rSrc
)
59 ::SysFreeString(m_sStr
);
60 m_sStr
= ::SysAllocString(reinterpret_cast<LPCOLESTR
>(_rSrc
.getStr()));
63 OLEString
& OLEString::operator=(const OLEString
& _rSrc
)
68 ::SysFreeString(m_sStr
);
69 m_sStr
= ::SysAllocString(_rSrc
.m_sStr
);
73 OLEString
& OLEString::operator=(const BSTR
& _rSrc
)
76 ::SysFreeString(m_sStr
);
80 OLEString::operator OUString() const
82 return (m_sStr
!= NULL
) ? OUString(reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(m_sStr
)),::SysStringLen(m_sStr
)) : OUString();
84 OLEString::operator BSTR() const
88 BSTR
* OLEString::operator &()
92 sal_Int32
OLEString::length() const
94 return (m_sStr
!= NULL
) ? ::SysStringLen(m_sStr
) : 0;
97 OLEVariant::OLEVariant()
101 OLEVariant::OLEVariant(const VARIANT
& varSrc
)
104 HRESULT eRet
= ::VariantCopy(this, const_cast<VARIANT
*>(&varSrc
));
105 OSL_ENSURE(eRet
== S_OK
,"Error while copying an ado variant!");
108 OLEVariant::OLEVariant(const OLEVariant
& varSrc
)
111 HRESULT eRet
= ::VariantCopy(this, const_cast<VARIANT
*>(static_cast<const VARIANT
*>(&varSrc
)));
112 OSL_ENSURE(eRet
== S_OK
,"Error while copying an ado variant!");
116 OLEVariant::OLEVariant(bool x
) { VariantInit(this); vt
= VT_BOOL
; boolVal
= (x
? VARIANT_TRUE
: VARIANT_FALSE
);}
117 OLEVariant::OLEVariant(sal_Int8 n
) { VariantInit(this); vt
= VT_I1
; bVal
= n
;}
118 OLEVariant::OLEVariant(sal_Int16 n
) { VariantInit(this); vt
= VT_I2
; intVal
= n
;}
119 OLEVariant::OLEVariant(sal_Int32 n
) { VariantInit(this); vt
= VT_I4
; lVal
= n
;}
120 OLEVariant::OLEVariant(sal_Int64 x
) { VariantInit(this); vt
= VT_I4
; lVal
= (LONG
)x
;}
122 OLEVariant::OLEVariant(const OUString
& us
)
126 bstrVal
= SysAllocString(reinterpret_cast<LPCOLESTR
>(us
.getStr()));
128 OLEVariant::~OLEVariant()
130 HRESULT eRet
= ::VariantClear(this);
131 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
133 } // clears all the memory that was allocated before
135 OLEVariant::OLEVariant(const ::com::sun::star::util::Date
& x
)
139 dblVal
= ::dbtools::DBTypeConversion::toDouble(x
,::com::sun::star::util::Date(30,12,1899));
141 OLEVariant::OLEVariant(const ::com::sun::star::util::Time
& x
)
145 dblVal
= ::dbtools::DBTypeConversion::toDouble(x
);
147 OLEVariant::OLEVariant(const ::com::sun::star::util::DateTime
& x
)
151 dblVal
= ::dbtools::DBTypeConversion::toDouble(x
,::com::sun::star::util::Date(30,12,1899));
153 OLEVariant::OLEVariant(const float &x
)
159 OLEVariant::OLEVariant(const double &x
)
167 OLEVariant::OLEVariant(IDispatch
* pDispInterface
)
170 setIDispatch( pDispInterface
);
173 OLEVariant::OLEVariant(const ::com::sun::star::uno::Sequence
< sal_Int8
>& x
)
177 vt
= VT_ARRAY
|VT_UI1
;
179 parray
= SafeArrayCreateVector(VT_UI1
, 0, x
.getLength());
180 const sal_Int8
* pBegin
= x
.getConstArray();
181 const sal_Int8
* pEnd
= pBegin
+ x
.getLength();
183 for(sal_Int32 i
=0;pBegin
!= pEnd
;++i
,++pBegin
)
185 sal_Int32 nData
= *pBegin
;
186 HRESULT rs
= SafeArrayPutElement(parray
,&i
,&nData
);
187 OSL_ENSURE(S_OK
== rs
,"Error while copy byte data");
192 OLEVariant
& OLEVariant::operator=(const OLEVariant
& varSrc
)
194 HRESULT eRet
= ::VariantCopy(this, const_cast<VARIANT
*>(static_cast<const VARIANT
*>(&varSrc
)));
195 OSL_ENSURE(eRet
== S_OK
,"Error while copying an ado variant!");
199 // Assign a const VARIANT& (::VariantCopy handles everything)
201 OLEVariant
& OLEVariant::operator=(const tagVARIANT
& varSrc
)
203 HRESULT eRet
= ::VariantCopy(this, const_cast<VARIANT
*>(&varSrc
));
204 OSL_ENSURE(eRet
== S_OK
,"Error while copying an ado variant!");
210 // Assign a const VARIANT* (::VariantCopy handles everything)
212 OLEVariant
& OLEVariant::operator=(const VARIANT
* pSrc
)
214 HRESULT eRet
= ::VariantCopy(this, const_cast<VARIANT
*>(pSrc
));
215 OSL_ENSURE(eRet
== S_OK
,"Error while copying an ado variant!");
221 void OLEVariant::setByte(sal_uInt8 n
)
223 HRESULT eRet
= VariantClear(this);
224 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
229 void OLEVariant::setInt16(sal_Int16 n
)
231 HRESULT eRet
= VariantClear(this);
232 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
237 void OLEVariant::setInt32(sal_Int32 n
)
239 HRESULT eRet
= VariantClear(this);
240 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
245 void OLEVariant::setFloat(float f
)
246 { HRESULT eRet
= VariantClear(this);
247 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
252 void OLEVariant::setDouble(double d
)
254 HRESULT eRet
= VariantClear(this);
255 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
260 void OLEVariant::setDate(DATE d
)
261 { HRESULT eRet
= VariantClear(this);
262 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
267 void OLEVariant::setChar(unsigned char a
)
269 HRESULT eRet
= VariantClear(this);
270 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
275 void OLEVariant::setCurrency(double aCur
)
277 HRESULT eRet
= VariantClear(this);
278 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
283 void OLEVariant::setBool(sal_Bool b
)
285 HRESULT eRet
= VariantClear(this);
286 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
289 boolVal
= b
? VARIANT_TRUE
: VARIANT_FALSE
;
291 void OLEVariant::setString(const OUString
& us
)
293 HRESULT eRet
= VariantClear(this);
294 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
297 bstrVal
= ::SysAllocString(reinterpret_cast<LPCOLESTR
>(us
.getStr()));
299 void OLEVariant::setNoArg()
301 HRESULT eRet
= VariantClear(this);
302 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
305 scode
= DISP_E_PARAMNOTFOUND
;
308 void OLEVariant::setNull()
310 HRESULT eRet
= VariantClear(this);
311 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
315 void OLEVariant::setEmpty()
317 HRESULT eRet
= VariantClear(this);
318 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
323 void OLEVariant::setUI1SAFEARRAYPtr(SAFEARRAY
* pSafeAr
)
325 HRESULT eRet
= VariantClear(this);
326 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
328 vt
= VT_ARRAY
|VT_UI1
; parray
= pSafeAr
;
331 void OLEVariant::setArray(SAFEARRAY
* pSafeArray
, VARTYPE vtType
)
333 HRESULT eRet
= VariantClear(this);
334 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
336 vt
= (VARTYPE
)(VT_ARRAY
|vtType
);
340 void OLEVariant::setIDispatch(IDispatch
* pDispInterface
)
342 HRESULT eRet
= VariantClear(this);
343 OSL_ENSURE(eRet
== S_OK
,"Error while clearing an ado variant!");
347 pdispVal
= pDispInterface
;
349 if ( pDispInterface
)
350 pDispInterface
->AddRef();
354 sal_Bool
OLEVariant::isNull() const { return (vt
== VT_NULL
); }
355 sal_Bool
OLEVariant::isEmpty() const { return (vt
== VT_EMPTY
); }
357 VARTYPE
OLEVariant::getType() const { return vt
; }
359 OLEVariant::operator ::com::sun::star::util::Date() const
361 return isNull() ? ::com::sun::star::util::Date(30,12,1899) : ::dbtools::DBTypeConversion::toDate(getDate(),::com::sun::star::util::Date(30,12,1899));
363 OLEVariant::operator ::com::sun::star::util::Time() const
365 return isNull() ? ::com::sun::star::util::Time() : ::dbtools::DBTypeConversion::toTime(getDate());
367 OLEVariant::operator ::com::sun::star::util::DateTime()const
369 return isNull() ? ::com::sun::star::util::DateTime() : ::dbtools::DBTypeConversion::toDateTime(getDate(),::com::sun::star::util::Date(30,12,1899));
372 VARIANT_BOOL
OLEVariant::VariantBool(sal_Bool bEinBoolean
)
374 return (bEinBoolean
? VARIANT_TRUE
: VARIANT_FALSE
);
377 void OLEVariant::CHS()
379 cyVal
.Lo
^= (sal_uInt32
)-1;
386 void OLEVariant::set(double n
)
390 cyVal
.Hi
= (sal_Int32
)(n
/ (double)4294967296.0);
391 cyVal
.Lo
= (sal_uInt32
)(n
- ((double)cyVal
.Hi
* (double)4294967296.0));
394 cyVal
.Hi
= (sal_Int32
)(-n
/ (double)4294967296.0);
395 cyVal
.Lo
= (sal_uInt32
)(-n
- ((double)cyVal
.Hi
* (double)4294967296.0));
400 OLEVariant::operator OUString() const
402 if (V_VT(this) == VT_BSTR
)
403 return reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(V_BSTR(this)));
410 varDest
.ChangeType(VT_BSTR
, this);
412 return reinterpret_cast<const sal_Unicode
*>(LPCOLESTR(V_BSTR(&varDest
)));
416 void OLEVariant::ChangeType(VARTYPE vartype
, const OLEVariant
* pSrc
)
419 // If pDest is NULL, convert type in place
424 if ( ( this != pSrc
)
425 || ( vartype
!= V_VT( this ) )
428 if ( FAILED( ::VariantChangeType( static_cast< VARIANT
* >( this ),
429 const_cast< VARIANT
* >( static_cast< const VARIANT
* >( pSrc
) ),
433 ::connectivity::SharedResources aResources
;
434 const OUString
sError( aResources
.getResourceString(STR_TYPE_NOT_CONVERT
));
435 throw ::com::sun::star::sdbc::SQLException(
440 ::com::sun::star::uno::Any()
447 OLEVariant::operator ::com::sun::star::uno::Sequence
< sal_Int8
>() const
449 ::com::sun::star::uno::Sequence
< sal_Int8
> aRet
;
450 if(V_VT(this) == VT_BSTR
)
452 OLEString
sStr(V_BSTR(this));
453 aRet
= ::com::sun::star::uno::Sequence
<sal_Int8
>(reinterpret_cast<const sal_Int8
*>((const wchar_t*)sStr
),sizeof(sal_Unicode
)*sStr
.length());
457 SAFEARRAY
* pArray
= getUI1SAFEARRAYPtr();
461 HRESULT hresult1
,hresult2
;
463 // Verify that the SafeArray is the proper shape.
464 hresult1
= ::SafeArrayGetLBound(pArray
, 1, &lBound
);
465 hresult2
= ::SafeArrayGetUBound(pArray
, 1, &uBound
);
466 if ( SUCCEEDED(hresult1
) && SUCCEEDED(hresult2
) )
468 long nCount
= uBound
-lBound
+1;
469 aRet
.realloc(nCount
);
470 sal_Int8
* pData
= aRet
.getArray();
471 for(long i
=0; SUCCEEDED(hresult1
) && lBound
<= uBound
;++i
,++lBound
)
474 hresult1
= ::SafeArrayGetElement(pArray
,&lBound
,&nData
);
475 if ( SUCCEEDED(hresult1
) )
477 *pData
= static_cast<sal_Int8
>(nData
);
488 OUString
OLEVariant::getString() const
496 sal_Bool
OLEVariant::getBool() const
498 if (V_VT(this) == VT_BOOL
)
499 return V_BOOL(this) == VARIANT_TRUE
? sal_True
: sal_False
;
505 varDest
.ChangeType(VT_BOOL
, this);
507 return V_BOOL(&varDest
) == VARIANT_TRUE
? sal_True
: sal_False
;
510 IUnknown
* OLEVariant::getIUnknown() const
512 if (V_VT(this) == VT_UNKNOWN
)
514 return V_UNKNOWN(this);
521 varDest
.ChangeType(VT_UNKNOWN
, this);
523 V_UNKNOWN(&varDest
)->AddRef();
524 return V_UNKNOWN(&varDest
);
527 IDispatch
* OLEVariant::getIDispatch() const
529 if (V_VT(this) == VT_DISPATCH
)
531 return V_DISPATCH(this);
539 varDest
.ChangeType(VT_DISPATCH
, this);
541 V_DISPATCH(&varDest
)->AddRef();
542 return V_DISPATCH(&varDest
);
545 sal_uInt8
OLEVariant::getByte() const
547 if (V_VT(this) == VT_UI1
)
554 varDest
.ChangeType(VT_UI1
, this);
556 return V_UI1(&varDest
);
559 sal_Int16
OLEVariant::getInt16() const
561 if (V_VT(this) == VT_I2
)
568 varDest
.ChangeType(VT_I2
, this);
570 return V_I2(&varDest
);
573 sal_Int8
OLEVariant::getInt8() const
575 if (V_VT(this) == VT_I1
)
583 varDest
.ChangeType(VT_I1
, this);
585 return V_I1(&varDest
);
588 sal_Int32
OLEVariant::getInt32() const
590 if (V_VT(this) == VT_I4
)
598 varDest
.ChangeType(VT_I4
, this);
600 return V_I4(&varDest
);
603 sal_uInt32
OLEVariant::getUInt32() const
605 if (V_VT(this) == VT_UI4
)
609 return sal_uInt32(0);
613 varDest
.ChangeType(VT_UI4
, this);
615 return V_UI4(&varDest
);
618 float OLEVariant::getFloat() const
620 if (V_VT(this) == VT_R4
)
627 varDest
.ChangeType(VT_R4
, this);
629 return V_R4(&varDest
);
632 double OLEVariant::getDouble() const
634 if (V_VT(this) == VT_R8
)
641 varDest
.ChangeType(VT_R8
, this);
643 return V_R8(&varDest
);
646 double OLEVariant::getDate() const
648 if (V_VT(this) == VT_DATE
)
655 varDest
.ChangeType(VT_DATE
, this);
657 return V_DATE(&varDest
);
660 CY
OLEVariant::getCurrency() const
662 if (V_VT(this) == VT_CY
)
668 aVar
.int64
= sal_Int64(0);
673 varDest
.ChangeType(VT_CY
, this);
675 return V_CY(&varDest
);
678 SAFEARRAY
* OLEVariant::getUI1SAFEARRAYPtr() const
680 if (V_VT(this) == (VT_ARRAY
|VT_UI1
))
681 return V_ARRAY(this);
687 varDest
.ChangeType((VT_ARRAY
|VT_UI1
), this);
689 return V_ARRAY(&varDest
);
692 ::com::sun::star::uno::Any
OLEVariant::makeAny() const
694 ::com::sun::star::uno::Any aValue
;
699 aValue
.setValue(NULL
, Type());
702 aValue
.setValue( & iVal
, cppu::UnoType
<sal_Int16
>::get());
705 aValue
.setValue( & lVal
, cppu::UnoType
<sal_Int32
>::get());
708 aValue
.setValue( & fltVal
, cppu::UnoType
<float>::get());
711 aValue
.setValue(& dblVal
, cppu::UnoType
<double>::get());
715 Currency
cy(cyVal
.int64
);
721 aValue
<<= (::com::sun::star::util::Date
)*this;
726 OUString
b(reinterpret_cast<const sal_Unicode
*>(bstrVal
));
727 aValue
.setValue( &b
, getCppuType( &b
));
732 sal_Bool b
= boolVal
== VARIANT_TRUE
;
733 aValue
.setValue( &b
, getCppuType( &b
));
737 aValue
.setValue( & cVal
, getCppuType((sal_Int8
*)0));
739 case VT_UI1
: // there is no unsigned char in UNO
740 aValue
.setValue( & bVal
, getCppuType( (sal_Int8
*)0));
743 aValue
.setValue( & uiVal
, getCppuType( (sal_uInt16
*)0));
746 aValue
.setValue( & ulVal
, getCppuType( (sal_uInt32
*)0));
749 aValue
.setValue( & intVal
, cppu::UnoType
<sal_Int32
>::get());
752 aValue
.setValue( & uintVal
, getCppuType( (sal_uInt32
*)0));
755 aValue
.setValue( NULL
, Type());
760 dec
.Scale
= decVal
.scale
;
761 dec
.Sign
= decVal
.sign
;
762 dec
.LowValue
= decVal
.Lo32
;
763 dec
.MiddleValue
= decVal
.Mid32
;
764 dec
.HighValue
= decVal
.Hi32
;
778 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */