1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 
31 #include <atlbase.h>
32 #include <stdio.h>
33 #include "cppuhelper/bootstrap.hxx"
34 #include "rtl/process.h"
35 #include "typelib/typedescription.hxx"
36 
37 #include "com/sun/star/bridge/ModelDependent.hpp"
38 #include "com/sun/star/bridge/XBridgeSupplier2.hpp"
39 #include "com/sun/star/uno/TypeClass.hpp"
40 #include "com/sun/star/script/XInvocation.hpp"
41 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
42 #include "com/sun/star/uno/XComponentContext.hpp"
43 #include <com/sun/star/bridge/oleautomation/NamedArgument.hpp>
44 #include "rtl/ustring.hxx"
45 
46 using namespace com::sun::star::bridge;
47 using namespace com::sun::star::bridge::ModelDependent;
48 using namespace com::sun::star::uno;
49 using namespace com::sun::star::lang;
50 using namespace com::sun::star::script;
51 using namespace com::sun::star::bridge::oleautomation;
52 using namespace rtl;
53 using namespace cppu;
54 
55 template< class T >
56 bool equalSequences(const Sequence<T>& seqIn, const Sequence<Any> & returned);
57 
58 
59 Reference< XMultiServiceFactory > objectFactory;//
60 
61 
62 Reference<XMultiServiceFactory> getMultiServiceFactory()
63 {
64 	static Reference< XMultiServiceFactory > factory;
65 	if( ! objectFactory.is() )
66 	{
67 		Reference<XComponentContext> context = defaultBootstrap_InitialComponentContext();
68 		factory = Reference<XMultiServiceFactory>( context->getServiceManager(), UNO_QUERY);
69 
70 	}
71 	return factory;
72 }
73 
74 Reference<XInvocation> getComObject( OUString progId)
75 {
76 	HRESULT hr= S_OK;
77 	Reference< XInvocation > ret;
78 //	Reference<XMultiServiceFactory> fac;
79 	if(  ! objectFactory.is())
80 	{	Reference<XMultiServiceFactory> mgr= getMultiServiceFactory();
81 		Reference<XInterface> xInt= mgr->createInstance(
82 			OUString(L"com.sun.star.bridge.oleautomation.Factory"));
83 		objectFactory= Reference<XMultiServiceFactory>::query(  xInt);
84 	}
85 
86 	if( objectFactory.is())
87 	{
88 		Reference<XInterface> xIntAx= objectFactory->createInstance( progId.getStr());
89 		if( xIntAx.is() )
90 		{
91 			Reference< XInvocation > xInv( xIntAx, UNO_QUERY);
92 			ret= xInv;
93 		}
94 	}
95 	return ret;
96 }
97 
98 Reference<XInvocation> convertComObject( IUnknown* pUnk)
99 {
100 	Reference< XMultiServiceFactory > mgr= getMultiServiceFactory();
101 	Reference< XInterface > xIntSupplier= mgr->createInstance(OUString(L"com.sun.star.bridge.OleBridgeSupplier2"));
102 	Reference< XBridgeSupplier2 > xSuppl( xIntSupplier, UNO_QUERY);
103 
104 	Any any;
105 	CComVariant var( pUnk);
106 	any <<= ( sal_uInt32)&var;
107 	sal_uInt8 arId[16];
108 	rtl_getGlobalProcessId( arId);
109 	Any target=	xSuppl->createBridge( any, Sequence<sal_Int8>( (sal_Int8*)arId, 16), OLE, UNO );
110 
111 	Reference<XInvocation> ret;
112 	target>>= ret;
113 	return ret;
114 }
115 
116 /*
117   Parameter values contains the expected return values. The value at index 0
118   correspond to parameter 0 (left - most). For parameters which are not out or
119   in/out the value must be a void any.
120 
121   The number of items in value must be the
122   same as the number of provided parameter during the  call on the  method.
123 
124   The parameter outArgs, indices correspond to the sequences which are
125   arguments to XInvocation::invoke
126  */
127 bool checkOutArgs(const Sequence<Any> & outArgs,
128                   const Sequence<sal_Int16> & indices, const Sequence<Any> & values)
129 {
130     if (values.getLength() != outArgs.getLength())
131         return false;
132     //iterate over all parameters. i represents the parameter index
133     for (int i = 0; i < values.getLength(); i++)
134     {
135         if (values[i].getValueType() == getVoidCppuType())
136             continue;
137         //out parameter
138         //Based on the parameter index find the correspondent out value
139         int indexOutSeq = -1;
140         for (int iIndices = indices.getLength() - 1; iIndices >= 0; iIndices --)
141         {
142             if (indices[iIndices] == i)
143             {
144                 indexOutSeq = iIndices;
145                 break;
146             }
147         }
148         if (indexOutSeq == -1)
149             return false;
150 
151 		Any value;
152 		Any out;
153 		values[i] >>= value;
154 		outArgs[indexOutSeq] >>=out;
155 		NamedArgument naVal;
156 		NamedArgument naOut;
157 		value >>= naVal;
158 		out >>= naOut;
159         if (values[i].getValueType() == getCppuType((NamedArgument *) 0))
160         {
161             NamedArgument inNamed;
162             values[i] >>= inNamed;
163             value <<= inNamed.Value;
164         }
165 		if (value != outArgs[indexOutSeq])
166             return false;
167     }
168     return true;
169 }
170 
171 /* The returned sequence always contains Any elements
172 */
173 bool equalSequences(const Any& orig, const Any& returned)
174 {
175 	if (orig.getValueTypeClass() != TypeClass_SEQUENCE)
176 	{
177 		OSL_ASSERT(0);
178 		return false;
179 	}
180 	TypeDescription td(orig.getValueTypeRef());
181 	typelib_IndirectTypeDescription * indirect_td = (typelib_IndirectTypeDescription *) td.get();
182 
183 	switch (indirect_td->pType->eTypeClass)
184 	{
185 		case TypeClass_CHAR:
186 			{
187 				Sequence<sal_Unicode> seq;
188 				orig >>= seq;
189 				Sequence<Any> seq2;
190 				returned >>= seq2;
191 				return equalSequences(seq, seq2);
192 			}
193 		case TypeClass_BOOLEAN:
194 			{
195 				Sequence<sal_Bool> seq;
196 				orig >>= seq;
197 				Sequence<Any> seq2;
198 				returned >>= seq2;
199 				return equalSequences(seq, seq2);
200 			}
201 		case TypeClass_BYTE:
202 			{
203 				Sequence<sal_Int8> seq;
204 				orig >>= seq;
205 				Sequence<Any> seq2;
206 				returned >>= seq2;
207 				return equalSequences(seq, seq2);
208 			}
209 		case TypeClass_SHORT:
210 			{
211 				Sequence<sal_Int16> seq;
212 				orig >>= seq;
213 				Sequence<Any> seq2;
214 				returned >>= seq2;
215 				return equalSequences(seq, seq2);
216 			}
217 		case TypeClass_LONG:
218 			{
219 				Sequence<sal_Int32> seq;
220 				orig >>= seq;
221 				Sequence<Any> seq2;
222 				returned >>= seq2;
223 				return equalSequences(seq, seq2);
224 			}
225 		case TypeClass_FLOAT:
226 			{
227 				Sequence<float> seq;
228 				orig >>= seq;
229 				Sequence<Any> seq2;
230 				returned >>= seq2;
231 				return equalSequences(seq, seq2);
232 			}
233 		case TypeClass_DOUBLE:
234 			{
235 				Sequence<double> seq;
236 				orig >>= seq;
237 				Sequence<Any> seq2;
238 				returned >>= seq2;
239 				return equalSequences(seq, seq2);
240 			}
241 		case TypeClass_STRING:
242 			{
243 				Sequence<OUString> seq;
244 				orig >>= seq;
245 				Sequence<Any> seq2;
246 				returned >>= seq2;
247 				return equalSequences(seq, seq2);
248 			}
249 		case TypeClass_ANY:
250 			{
251 				Sequence<Any> seq;
252 				orig >>= seq;
253 				Sequence<Any> seq2;
254 				returned >>= seq2;
255 				return equalSequences(seq, seq2);
256 			}
257 		case TypeClass_SEQUENCE:
258 			{
259 				//Sequence<sal_Unicode> seq;
260 				//orig >>= seq;
261 				//Sequence<Any> seq2;
262 				//returned >>= seq2;
263 				//return equalSequences(seq, seq2);
264 				break;
265 			}
266 		case TypeClass_INTERFACE:
267 			{
268 				Sequence<Reference<XInvocation> > seq;
269 				orig >>= seq;
270 				Sequence<Any> seq2;
271 				returned >>= seq2;
272 				return equalSequences(seq, seq2);
273 			}
274 		default:
275 			return false;
276 	}
277     return false;
278 }
279 
280 template< class T >
281 bool equalSequences(const Sequence<T>& seqIn, const Sequence<Any> & seqOut)
282 {
283 	if (seqIn.getLength() != seqOut.getLength())
284 		return false;
285 	int len = seqIn.getLength();
286 	for (int i = 0; i < len; i++)
287 	{
288 		Any anyIn;
289 		anyIn <<= seqIn[i];
290 		Any anyOut = seqOut[i];
291 		if (anyIn != anyOut)
292 			return false;
293 	}
294 
295 	return true;
296 }
297 
298 void printSequence( Sequence<Any>& val)
299 {
300 
301 //	typelib_TypeDescription* desc;
302 //	val.getValueTypeDescription( &desc);
303 //	typelib_typedescription_release( desc);
304 
305 	USES_CONVERSION;
306 	char buff[1024];
307 	buff[0]=0;
308 	char tmpBuf[1024];
309 	tmpBuf[0]=0;
310 	sal_Int32 i;
311 
312 	for( i=0; i< val.getLength(); i++)
313 	{
314 		Any& elem= val[i];
315 		switch ( elem.getValueTypeClass())
316 		{
317 		case TypeClass_BYTE:
318 			 sprintf( tmpBuf, "sal_Int8 %d \n", *(sal_Int8*)elem.getValue());
319 			 break;
320 		case TypeClass_SHORT:
321 			 sprintf( tmpBuf, "sal_Int16 %d \n", *(sal_Int16*)elem.getValue());
322 			 break;
323 		case TypeClass_LONG:
324 			 sprintf( tmpBuf, "sal_Int32 %d \n", *(sal_Int32*)elem.getValue());
325 			 break;
326 		case TypeClass_DOUBLE:
327 			 sprintf( tmpBuf, "double %f \n", *(double*)elem.getValue());
328 			 break;
329 		case TypeClass_FLOAT:
330 			 sprintf( tmpBuf, "float %f \n", *(float*)elem.getValue());
331 			 break;
332 		case TypeClass_STRING:
333 			 sprintf( tmpBuf, "%S \n", (*(OUString*)elem.getValue()).getStr());
334 			 break;
335 		case TypeClass_INTERFACE:
336 			{
337 			// we assume that the interface is XInvocation of a AxTestControls.Basic component.
338 			Reference<XInvocation> inv;
339 			elem>>= inv;
340 			if( inv.is())
341 			{
342 				Any prpVal= inv->getValue( OUString( L"prpString"));
343 				sprintf( tmpBuf, "Property prpString: %S \n", (*(OUString*)prpVal.getValue()).getStr());
344 			}
345 			break;
346 			}
347 		default:break;
348 		}
349 		strcat( buff, tmpBuf);
350 
351 	}
352 
353 	MessageBox( NULL, A2T(buff), _T("clientTest: printing Sequence elements"), MB_OK);
354 }
355