1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _CONNECTIVITY_ADO_AOLEWRAP_HXX_
24 #define _CONNECTIVITY_ADO_AOLEWRAP_HXX_
25 
26 #include <osl/diagnose.h>
27 #include <osl/thread.h>
28 #include <map>
29 #include <vector>
30 #include "connectivity/StdTypeDefs.hxx"
31 
32 namespace rtl
33 {
34 	class OUString;
35 }
36 namespace connectivity
37 {
38 	namespace ado
39 	{
40 		class OLEVariant;
41 		class WpBase
42 		{
43 		protected:
44 			IDispatch* pIUnknown;
45 
46 			void setIDispatch(IDispatch* _pIUnknown);
47 		public:
48 			WpBase();
49 			WpBase(IDispatch* pInt);
50 			//inline
51 			WpBase& operator=(const WpBase& rhs);
52 			WpBase& operator=(IDispatch* rhs);
53 			WpBase(const WpBase& aWrapper);
54 			virtual ~WpBase();
55 			void clear();
56 
57 
58 			sal_Bool IsValid() const;
59 			operator IDispatch*();
60 
61 		};
62 		//////////////////////////////////////////////////////////////////////////
63 		//
64 		// Template-Klasse WpOLEBase<class T>
65 		// ==================================
66 		//
67         // Objekte dieser Klasse haelt einen Zeiger auf ein Interface vom Typ T.
68 		// Es gibt Konstruktoren und Zuweisungsoperator die sicherstellen, dass
69 		// AddRef() und Release() entsprechend den COM-Konventionen gerufen werden.
70 		// Ein Objekt kann auch keinen Zeiger halten (Nullzeiger), dann ergibt
71 		// der Aufruf von IsValid() FALSE.
72 		//
73 		// Um effizientes pass-by-value machen zu koennen, ist diese (ebenso wie die
74 		// abgeleiteten Klassen) eine ganz schmale Wrapper-Klasse unter Vermeidung
75 		// virtueller Methoden und mit Inlining.
76 
77 		//------------------------------------------------------------------------
78 		template<class T> class WpOLEBase : public WpBase
79 		{
80 		protected:
81 			T* pInterface;
82 
83 		public:
WpOLEBase(T * pInt=NULL)84 			WpOLEBase(T* pInt = NULL) : WpBase(pInt),pInterface(pInt){}
85 
86 
87 			//inline
operator =(const WpOLEBase<T> & rhs)88 			WpOLEBase<T>& operator=(const WpOLEBase<T>& rhs)
89 			{
90 				WpBase::operator=(rhs);
91 				pInterface = rhs.pInterface;
92 				return *this;
93 			};
94 
operator =(T * rhs)95 			WpOLEBase<T>& operator=(T* rhs)
96 			{
97 				WpBase::operator=(rhs);
98 				pInterface = rhs.pInterface;
99 				return *this;
100 			}
101 
WpOLEBase(const WpOLEBase<T> & aWrapper)102 			WpOLEBase(const WpOLEBase<T>& aWrapper)
103 			{
104 				operator=(aWrapper);
105 			}
106 
~WpOLEBase()107 			virtual ~WpOLEBase()
108 			{
109 			}
110 
operator T*() const111 			operator T*() const { return static_cast<T*>(pInterface); }
setWithOutAddRef(T * _pInterface)112 			void setWithOutAddRef(T* _pInterface)
113 			{
114 				pInterface = _pInterface;
115 				WpBase::setIDispatch(_pInterface);
116 			}
117 		};
118 
119 
120 		//////////////////////////////////////////////////////////////////////////
121 		//
122 		// Template-Klasse WpOLECollection<class Ts, class T, class WrapT>
123 		// ===============================================================
124 		//
125 		// Diese Klasse, welche sich von WpOLEBase<Ts> ableitet, abstrahiert die
126 		// den DAO-Collections gemeinsamen Eigenschaften:
127 		//
128         // Sie werden ueber ein Interface Ts (etwa: DAOFields) angesprochen
129 		// und koennen ueber get_Item (hier:GetItem) Items des Typs T (genauer:
130 		// mit Interface T, etwa DAOField) herausgeben.
131 		//
132 		// Diese Wrapperklasse gibt aber nicht ein Interface T heraus,
133         // sondern ein Objekt der Klasse WrapT. Dieses muss eine Konstruktion
134 		// durch T zulassen, vorzugsweise ist es von WpOLEBase<T> abgeleitet.
135 		//
136 
137 		//------------------------------------------------------------------------
138 		template<class Ts, class T, class WrapT> class WpOLECollection : public WpOLEBase<Ts>
139 		{
140 		public:
141 			using WpOLEBase<Ts>::pInterface;
142 			using WpOLEBase<Ts>::IsValid;
143 			// Konstruktoren, operator=
144 			// diese rufen nur die Oberklasse
WpOLECollection(Ts * pInt=NULL)145 			WpOLECollection(Ts* pInt=NULL):WpOLEBase<Ts>(pInt){}
WpOLECollection(const WpOLECollection & rhs)146 			WpOLECollection(const WpOLECollection& rhs){operator=(rhs);}
operator =(const WpOLECollection & rhs)147 			inline WpOLECollection& operator=(const WpOLECollection& rhs)
148 				{WpOLEBase<Ts>::operator=(rhs); return *this;};
149 
150 			//////////////////////////////////////////////////////////////////////
151 
Refresh()152 			inline void Refresh(){pInterface->Refresh();}
153 
GetItemCount() const154 			inline sal_Int32 GetItemCount()	const
155 			{
156 				sal_Int32 nCount = 0;
157 				return pInterface ? (SUCCEEDED(pInterface->get_Count(&nCount)) ? nCount : sal_Int32(0)) : sal_Int32(0);
158 			}
159 
GetItem(sal_Int32 index) const160 			inline WrapT GetItem(sal_Int32 index) const
161 			{
162 				OSL_ENSURE(index >= 0 && index<GetItemCount(),"Wrong index for field!");
163 				T* pT = NULL;
164 				WrapT aRet(NULL);
165 				if(SUCCEEDED(pInterface->get_Item(OLEVariant(index), &pT)))
166 					aRet.setWithOutAddRef(pT);
167 				return aRet;
168 			}
169 
GetItem(const OLEVariant & index) const170 			inline WrapT GetItem(const OLEVariant& index) const
171 			{
172 				T* pT = NULL;
173 				WrapT aRet(NULL);
174 				if(SUCCEEDED(pInterface->get_Item(index, &pT)))
175 					aRet.setWithOutAddRef(pT);
176 				return aRet;
177 			}
178 
GetItem(const::rtl::OUString & sStr) const179 			inline WrapT GetItem(const ::rtl::OUString& sStr) const
180 			{
181 				WrapT aRet(NULL);
182 				T* pT = NULL;
183 				if (FAILED(pInterface->get_Item(OLEVariant(sStr), &pT)))
184 				{
185 #if OSL_DEBUG_LEVEL > 0
186 					::rtl::OString sTemp("Unknown Item: ");
187 					sTemp += ::rtl::OString(sStr.getStr(),sStr.getLength(),osl_getThreadTextEncoding());
188 					OSL_ENSURE(0,sTemp);
189 #endif
190 				}
191 				else
192 					aRet.setWithOutAddRef(pT);
193 				return aRet;
194 			}
fillElementNames(TStringVector & _rVector)195 			inline void fillElementNames(TStringVector& _rVector)
196 			{
197 				if(IsValid())
198 				{
199 					Refresh();
200 					sal_Int32 nCount = GetItemCount();
201 					_rVector.reserve(nCount);
202 					for(sal_Int32 i=0;i< nCount;++i)
203 					{
204 						WrapT aElement = GetItem(i);
205 						if(aElement.IsValid())
206 							_rVector.push_back(aElement.get_Name());
207 					}
208 				}
209 			}
210 		};
211 
212 		template<class Ts, class T, class WrapT> class WpOLEAppendCollection:
213 				public WpOLECollection<Ts,T,WrapT>
214 		{
215 
216 		public:
217 			// Konstruktoren, operator=
218 			// diese rufen nur die Oberklasse
219 			using WpOLEBase<Ts>::pInterface;
WpOLEAppendCollection(Ts * pInt=NULL)220 			WpOLEAppendCollection(Ts* pInt=NULL):WpOLECollection<Ts,T,WrapT>(pInt){}
WpOLEAppendCollection(const WpOLEAppendCollection & rhs)221 			WpOLEAppendCollection(const WpOLEAppendCollection& rhs){ operator=(rhs); }
operator =(const WpOLEAppendCollection & rhs)222 			inline WpOLEAppendCollection& operator=(const WpOLEAppendCollection& rhs)
223 				{WpOLEBase<Ts>::operator=(rhs); return *this;};
224 			//////////////////////////////////////////////////////////////////////
225 
Append(const WrapT & aWrapT)226 			inline sal_Bool Append(const WrapT& aWrapT)
227 			{
228 				return SUCCEEDED(pInterface->Append(OLEVariant((T*)aWrapT)));
229 			};
230 
Delete(const::rtl::OUString & sName)231 			inline sal_Bool Delete(const ::rtl::OUString& sName)
232 			{
233 				return SUCCEEDED(pInterface->Delete(OLEVariant(sName)));
234 			};
235 
236 
237 		};
238 	}
239 }
240 #endif // _CONNECTIVITY_ADO_AOLEWRAP_HXX_
241 
242