1*5c66ce18SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*5c66ce18SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*5c66ce18SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*5c66ce18SAndrew Rist  * distributed with this work for additional information
6*5c66ce18SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*5c66ce18SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*5c66ce18SAndrew Rist  * "License"); you may not use this file except in compliance
9*5c66ce18SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*5c66ce18SAndrew Rist  *
11*5c66ce18SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*5c66ce18SAndrew Rist  *
13*5c66ce18SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*5c66ce18SAndrew Rist  * software distributed under the License is distributed on an
15*5c66ce18SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*5c66ce18SAndrew Rist  * KIND, either express or implied.  See the License for the
17*5c66ce18SAndrew Rist  * specific language governing permissions and limitations
18*5c66ce18SAndrew Rist  * under the License.
19*5c66ce18SAndrew Rist  *
20*5c66ce18SAndrew Rist  *************************************************************/
21*5c66ce18SAndrew Rist 
22*5c66ce18SAndrew Rist 
23cdf0e10cSrcweir #ifndef _SMARTARRAY_H
24cdf0e10cSrcweir #define _SMARTARRAY_H
25cdf0e10cSrcweir 
26cdf0e10cSrcweir 
27cdf0e10cSrcweir template< class sourceType>
28cdf0e10cSrcweir class SmartArray
29cdf0e10cSrcweir {
30cdf0e10cSrcweir 	SAFEARRAY *m_array;
31cdf0e10cSrcweir public:
32cdf0e10cSrcweir 
SmartArray(sourceType * parParams,int count,VARTYPE destVartype)33cdf0e10cSrcweir 	SmartArray( sourceType * parParams, int count, VARTYPE destVartype): m_array(NULL)
34cdf0e10cSrcweir 	{
35cdf0e10cSrcweir 		HRESULT hr= S_OK;
36cdf0e10cSrcweir 		SAFEARRAYBOUND rgsabound[1];
37cdf0e10cSrcweir 		rgsabound[0].cElements= count;
38cdf0e10cSrcweir 		rgsabound[0].lLbound= 0;
39cdf0e10cSrcweir 		m_array= SafeArrayCreate( destVartype, 1, rgsabound);
40cdf0e10cSrcweir 		SafeArrayLock( m_array);
41cdf0e10cSrcweir 
42cdf0e10cSrcweir 		void* pData;
43cdf0e10cSrcweir 		if( m_array && (SUCCEEDED( SafeArrayAccessData( m_array, (void**)&pData)) ) )
44cdf0e10cSrcweir 		{
45cdf0e10cSrcweir 
46cdf0e10cSrcweir 			for( int i=0; i< count; i++)
47cdf0e10cSrcweir 			{
48cdf0e10cSrcweir 				CComVariant varSource( parParams[i]);
49cdf0e10cSrcweir 				switch (destVartype)
50cdf0e10cSrcweir 				{
51cdf0e10cSrcweir 				case VT_I1:
52cdf0e10cSrcweir 					{
53cdf0e10cSrcweir 						char* p= (char*) pData;
54cdf0e10cSrcweir 						if( SUCCEEDED( hr= varSource.ChangeType( destVartype)))
55cdf0e10cSrcweir 							p[i]= V_I1( &varSource);
56cdf0e10cSrcweir 						break;
57cdf0e10cSrcweir 					}
58cdf0e10cSrcweir 				case VT_I2:
59cdf0e10cSrcweir 					{
60cdf0e10cSrcweir 						short* p= (short*) pData;
61cdf0e10cSrcweir 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
62cdf0e10cSrcweir 							p[i]= V_I2( &varSource);
63cdf0e10cSrcweir 						break;
64cdf0e10cSrcweir 					}
65cdf0e10cSrcweir 				case VT_UI2:
66cdf0e10cSrcweir 					{
67cdf0e10cSrcweir 						unsigned short* p= (unsigned short*) pData;
68cdf0e10cSrcweir 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
69cdf0e10cSrcweir 							p[i]= V_UI2( &varSource);
70cdf0e10cSrcweir 						break;
71cdf0e10cSrcweir 					}
72cdf0e10cSrcweir 				case VT_I4:
73cdf0e10cSrcweir 					{
74cdf0e10cSrcweir 						long* p= (long*)pData;
75cdf0e10cSrcweir 					if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
76cdf0e10cSrcweir 						p[i]= V_I4( &varSource);
77cdf0e10cSrcweir 					break;
78cdf0e10cSrcweir 					}
79cdf0e10cSrcweir 				case VT_UI4:
80cdf0e10cSrcweir 					{
81cdf0e10cSrcweir 						unsigned long* p= (unsigned long*)pData;
82cdf0e10cSrcweir 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
83cdf0e10cSrcweir 						p[i]= V_UI4( &varSource);
84cdf0e10cSrcweir 						break;
85cdf0e10cSrcweir 					}
86cdf0e10cSrcweir 				case VT_R4:
87cdf0e10cSrcweir 					{
88cdf0e10cSrcweir 						float* p= (float*)pData;
89cdf0e10cSrcweir 					if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
90cdf0e10cSrcweir 						p[i]= V_R4( &varSource);
91cdf0e10cSrcweir 						break;
92cdf0e10cSrcweir 					}
93cdf0e10cSrcweir 				case VT_R8:
94cdf0e10cSrcweir 					{
95cdf0e10cSrcweir 						double* p= (double*)pData;
96cdf0e10cSrcweir 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
97cdf0e10cSrcweir 						p[i]= V_R8( &varSource);
98cdf0e10cSrcweir 						break;
99cdf0e10cSrcweir 					}
100cdf0e10cSrcweir 				case VT_BOOL:
101cdf0e10cSrcweir 					{
102cdf0e10cSrcweir 						VARIANT_BOOL* p= (VARIANT_BOOL*)pData;
103cdf0e10cSrcweir 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
104cdf0e10cSrcweir 						p[i]= V_BOOL( &varSource);
105cdf0e10cSrcweir 						break;
106cdf0e10cSrcweir 					}
107cdf0e10cSrcweir 				case VT_BSTR:
108cdf0e10cSrcweir 					{
109cdf0e10cSrcweir 					BSTR* pBstr= ( BSTR*)pData;
110cdf0e10cSrcweir 					if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
111cdf0e10cSrcweir 						pBstr[i]= SysAllocString(V_BSTR( &varSource));
112cdf0e10cSrcweir 					break;
113cdf0e10cSrcweir 					}
114cdf0e10cSrcweir 				case VT_VARIANT:
115cdf0e10cSrcweir 					{
116cdf0e10cSrcweir 						VARIANT *pVariant= (VARIANT*)pData;
117cdf0e10cSrcweir 						hr= VariantCopy( &pVariant[i], &varSource); break;
118cdf0e10cSrcweir 					}
119cdf0e10cSrcweir //				case VT_UNKNOWN:
120cdf0e10cSrcweir //					{
121cdf0e10cSrcweir //						long* pUnk= (long*)pData;
122cdf0e10cSrcweir //						pUnk[i]= reinterpret_cast<long>(parParams[i]);
123cdf0e10cSrcweir //						((IUnknown*)pUnk[i])->AddRef(); break;
124cdf0e10cSrcweir //					}
125cdf0e10cSrcweir //				case VT_DISPATCH:
126cdf0e10cSrcweir //					{
127cdf0e10cSrcweir //						long* pDisp= (long*)pData;
128cdf0e10cSrcweir //						pDisp[i]= (long)parParams[i];
129cdf0e10cSrcweir //						((IDispatch*)pDisp[i])->AddRef(); break;
130cdf0e10cSrcweir //					}
131cdf0e10cSrcweir 				default:
132cdf0e10cSrcweir 					hr= E_FAIL;
133cdf0e10cSrcweir 				}
134cdf0e10cSrcweir 			}
135cdf0e10cSrcweir 			if( FAILED( hr))
136cdf0e10cSrcweir 			{
137cdf0e10cSrcweir 				SafeArrayDestroy( m_array);
138cdf0e10cSrcweir 				m_array= NULL;
139cdf0e10cSrcweir 			}
140cdf0e10cSrcweir 		}
141cdf0e10cSrcweir 		SafeArrayUnaccessData( m_array);
142cdf0e10cSrcweir 	}
~SmartArray()143cdf0e10cSrcweir 	~SmartArray(){
144cdf0e10cSrcweir 		SafeArrayUnlock( m_array);
145cdf0e10cSrcweir 		SafeArrayDestroy( m_array );
146cdf0e10cSrcweir 	}
147cdf0e10cSrcweir 
148cdf0e10cSrcweir 	operator bool (){ return m_array == NULL ?  false : true; }
149cdf0e10cSrcweir 
operator SAFEARRAY*()150cdf0e10cSrcweir 	operator SAFEARRAY* (){ return m_array;}
151cdf0e10cSrcweir 
152cdf0e10cSrcweir };
153cdf0e10cSrcweir 
154cdf0e10cSrcweir template<>
155cdf0e10cSrcweir class SmartArray<IUnknown*>
156cdf0e10cSrcweir {
157cdf0e10cSrcweir 	SAFEARRAY *m_array;
158cdf0e10cSrcweir public:
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 	SmartArray( sourceType * parParams, int count, VARTYPE destVartype);
161cdf0e10cSrcweir //	{
162cdf0e10cSrcweir //		ATLTRACE("SmartArray<IUnknown>");
163cdf0e10cSrcweir //		HRESULT hr= S_OK;
164cdf0e10cSrcweir //		SAFEARRAYBOUND rgsabound[1];
165cdf0e10cSrcweir //		rgsabound[0].cElements= count;
166cdf0e10cSrcweir //		rgsabound[0].lLbound= 0;
167cdf0e10cSrcweir //		m_array= SafeArrayCreateVector( VT_UNKNOWN, 0, count);
168cdf0e10cSrcweir //		SafeArrayLock( m_array);
169cdf0e10cSrcweir //
170cdf0e10cSrcweir //		IUnknown* *pData;
171cdf0e10cSrcweir //		if( m_array && (SUCCEEDED( SafeArrayAccessData( m_array, (void**)&pData)) ) )
172cdf0e10cSrcweir //		{
173cdf0e10cSrcweir //
174cdf0e10cSrcweir //			for( int i=0; i< count; i++)
175cdf0e10cSrcweir //			{
176cdf0e10cSrcweir //				CComVariant varSource( parParams[i]);
177cdf0e10cSrcweir //				switch (destVartype)
178cdf0e10cSrcweir //				{
179cdf0e10cSrcweir //
180cdf0e10cSrcweir //				case VT_UNKNOWN:
181cdf0e10cSrcweir //					{
182cdf0e10cSrcweir //						pData[i]= parParams[i];
183cdf0e10cSrcweir //						pData[i]->AddRef();
184cdf0e10cSrcweir //					}
185cdf0e10cSrcweir //				default:
186cdf0e10cSrcweir //					hr= E_FAIL;
187cdf0e10cSrcweir //				}
188cdf0e10cSrcweir //			}
189cdf0e10cSrcweir //			if( FAILED( hr))
190cdf0e10cSrcweir //			{
191cdf0e10cSrcweir //				SafeArrayDestroy( m_array);
192cdf0e10cSrcweir //				m_array= NULL;
193cdf0e10cSrcweir //			}
194cdf0e10cSrcweir //		}
195cdf0e10cSrcweir //		SafeArrayUnaccessData( m_array);
196cdf0e10cSrcweir //	}
~SmartArray()197cdf0e10cSrcweir 	~SmartArray(){
198cdf0e10cSrcweir 		SafeArrayUnlock( m_array);
199cdf0e10cSrcweir 		SafeArrayDestroy( m_array );
200cdf0e10cSrcweir 	}
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 	operator bool (){ return m_array == NULL ?  false : true; }
203cdf0e10cSrcweir 
operator SAFEARRAY*()204cdf0e10cSrcweir 	operator SAFEARRAY* (){ return m_array;}
205cdf0e10cSrcweir 
206cdf0e10cSrcweir };
207cdf0e10cSrcweir 
SmartArray(sourceType * parParams,int count,VARTYPE destVartype)208cdf0e10cSrcweir template <> SmartArray <IUnknown*>::SmartArray(sourceType * parParams, int count, VARTYPE destVartype):m_array(NULL)
209cdf0e10cSrcweir {
210cdf0e10cSrcweir 	ATLTRACE("SmartArray<IUnknown>");
211cdf0e10cSrcweir 	HRESULT hr= S_OK;
212cdf0e10cSrcweir 	SAFEARRAYBOUND rgsabound[1];
213cdf0e10cSrcweir 	rgsabound[0].cElements= count;
214cdf0e10cSrcweir 	rgsabound[0].lLbound= 0;
215cdf0e10cSrcweir 	m_array= SafeArrayCreateVector( VT_UNKNOWN, 0, count);
216cdf0e10cSrcweir 	SafeArrayLock( m_array);
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 	IUnknown* *pData;
219cdf0e10cSrcweir 	if( m_array && (SUCCEEDED( SafeArrayAccessData( m_array, (void**)&pData)) ) )
220cdf0e10cSrcweir 	{
221cdf0e10cSrcweir 		for( int i=0; i< count; i++)
222cdf0e10cSrcweir 		{
223cdf0e10cSrcweir 			pData[i]= parParams[i];
224cdf0e10cSrcweir 			pData[i]->AddRef();
225cdf0e10cSrcweir 		}
226cdf0e10cSrcweir 	}
227cdf0e10cSrcweir 	SafeArrayUnaccessData( m_array);
228cdf0e10cSrcweir };
229cdf0e10cSrcweir #endif
230