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 _SMARTARRAY_H
24 #define _SMARTARRAY_H
25 
26 
27 template< class sourceType>
28 class SmartArray
29 {
30 	SAFEARRAY *m_array;
31 public:
32 
SmartArray(sourceType * parParams,int count,VARTYPE destVartype)33 	SmartArray( sourceType * parParams, int count, VARTYPE destVartype): m_array(NULL)
34 	{
35 		HRESULT hr= S_OK;
36 		SAFEARRAYBOUND rgsabound[1];
37 		rgsabound[0].cElements= count;
38 		rgsabound[0].lLbound= 0;
39 		m_array= SafeArrayCreate( destVartype, 1, rgsabound);
40 		SafeArrayLock( m_array);
41 
42 		void* pData;
43 		if( m_array && (SUCCEEDED( SafeArrayAccessData( m_array, (void**)&pData)) ) )
44 		{
45 
46 			for( int i=0; i< count; i++)
47 			{
48 				CComVariant varSource( parParams[i]);
49 				switch (destVartype)
50 				{
51 				case VT_I1:
52 					{
53 						char* p= (char*) pData;
54 						if( SUCCEEDED( hr= varSource.ChangeType( destVartype)))
55 							p[i]= V_I1( &varSource);
56 						break;
57 					}
58 				case VT_I2:
59 					{
60 						short* p= (short*) pData;
61 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
62 							p[i]= V_I2( &varSource);
63 						break;
64 					}
65 				case VT_UI2:
66 					{
67 						unsigned short* p= (unsigned short*) pData;
68 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
69 							p[i]= V_UI2( &varSource);
70 						break;
71 					}
72 				case VT_I4:
73 					{
74 						long* p= (long*)pData;
75 					if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
76 						p[i]= V_I4( &varSource);
77 					break;
78 					}
79 				case VT_UI4:
80 					{
81 						unsigned long* p= (unsigned long*)pData;
82 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
83 						p[i]= V_UI4( &varSource);
84 						break;
85 					}
86 				case VT_R4:
87 					{
88 						float* p= (float*)pData;
89 					if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
90 						p[i]= V_R4( &varSource);
91 						break;
92 					}
93 				case VT_R8:
94 					{
95 						double* p= (double*)pData;
96 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
97 						p[i]= V_R8( &varSource);
98 						break;
99 					}
100 				case VT_BOOL:
101 					{
102 						VARIANT_BOOL* p= (VARIANT_BOOL*)pData;
103 						if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
104 						p[i]= V_BOOL( &varSource);
105 						break;
106 					}
107 				case VT_BSTR:
108 					{
109 					BSTR* pBstr= ( BSTR*)pData;
110 					if( SUCCEEDED( hr=varSource.ChangeType( destVartype)))
111 						pBstr[i]= SysAllocString(V_BSTR( &varSource));
112 					break;
113 					}
114 				case VT_VARIANT:
115 					{
116 						VARIANT *pVariant= (VARIANT*)pData;
117 						hr= VariantCopy( &pVariant[i], &varSource); break;
118 					}
119 //				case VT_UNKNOWN:
120 //					{
121 //						long* pUnk= (long*)pData;
122 //						pUnk[i]= reinterpret_cast<long>(parParams[i]);
123 //						((IUnknown*)pUnk[i])->AddRef(); break;
124 //					}
125 //				case VT_DISPATCH:
126 //					{
127 //						long* pDisp= (long*)pData;
128 //						pDisp[i]= (long)parParams[i];
129 //						((IDispatch*)pDisp[i])->AddRef(); break;
130 //					}
131 				default:
132 					hr= E_FAIL;
133 				}
134 			}
135 			if( FAILED( hr))
136 			{
137 				SafeArrayDestroy( m_array);
138 				m_array= NULL;
139 			}
140 		}
141 		SafeArrayUnaccessData( m_array);
142 	}
~SmartArray()143 	~SmartArray(){
144 		SafeArrayUnlock( m_array);
145 		SafeArrayDestroy( m_array );
146 	}
147 
148 	operator bool (){ return m_array == NULL ?  false : true; }
149 
operator SAFEARRAY*()150 	operator SAFEARRAY* (){ return m_array;}
151 
152 };
153 
154 template<>
155 class SmartArray<IUnknown*>
156 {
157 	SAFEARRAY *m_array;
158 public:
159 
160 	SmartArray( sourceType * parParams, int count, VARTYPE destVartype);
161 //	{
162 //		ATLTRACE("SmartArray<IUnknown>");
163 //		HRESULT hr= S_OK;
164 //		SAFEARRAYBOUND rgsabound[1];
165 //		rgsabound[0].cElements= count;
166 //		rgsabound[0].lLbound= 0;
167 //		m_array= SafeArrayCreateVector( VT_UNKNOWN, 0, count);
168 //		SafeArrayLock( m_array);
169 //
170 //		IUnknown* *pData;
171 //		if( m_array && (SUCCEEDED( SafeArrayAccessData( m_array, (void**)&pData)) ) )
172 //		{
173 //
174 //			for( int i=0; i< count; i++)
175 //			{
176 //				CComVariant varSource( parParams[i]);
177 //				switch (destVartype)
178 //				{
179 //
180 //				case VT_UNKNOWN:
181 //					{
182 //						pData[i]= parParams[i];
183 //						pData[i]->AddRef();
184 //					}
185 //				default:
186 //					hr= E_FAIL;
187 //				}
188 //			}
189 //			if( FAILED( hr))
190 //			{
191 //				SafeArrayDestroy( m_array);
192 //				m_array= NULL;
193 //			}
194 //		}
195 //		SafeArrayUnaccessData( m_array);
196 //	}
~SmartArray()197 	~SmartArray(){
198 		SafeArrayUnlock( m_array);
199 		SafeArrayDestroy( m_array );
200 	}
201 
202 	operator bool (){ return m_array == NULL ?  false : true; }
203 
operator SAFEARRAY*()204 	operator SAFEARRAY* (){ return m_array;}
205 
206 };
207 
SmartArray(sourceType * parParams,int count,VARTYPE destVartype)208 template <> SmartArray <IUnknown*>::SmartArray(sourceType * parParams, int count, VARTYPE destVartype):m_array(NULL)
209 {
210 	ATLTRACE("SmartArray<IUnknown>");
211 	HRESULT hr= S_OK;
212 	SAFEARRAYBOUND rgsabound[1];
213 	rgsabound[0].cElements= count;
214 	rgsabound[0].lLbound= 0;
215 	m_array= SafeArrayCreateVector( VT_UNKNOWN, 0, count);
216 	SafeArrayLock( m_array);
217 
218 	IUnknown* *pData;
219 	if( m_array && (SUCCEEDED( SafeArrayAccessData( m_array, (void**)&pData)) ) )
220 	{
221 		for( int i=0; i< count; i++)
222 		{
223 			pData[i]= parParams[i];
224 			pData[i]->AddRef();
225 		}
226 	}
227 	SafeArrayUnaccessData( m_array);
228 };
229 #endif
230