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