LibreOffice Module sc (master)  1
callform.cxx
Go to the documentation of this file.
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 #include <sal/config.h>
21 
22 #include <vcl/svapp.hxx>
23 #include <vcl/settings.hxx>
24 #include <osl/module.hxx>
25 #include <osl/file.hxx>
27 #include <memory>
28 
29 #include <callform.hxx>
30 #include <global.hxx>
31 #include <adiasync.hxx>
32 
33 extern "C" {
34 
35 typedef void (CALLTYPE* ExFuncPtr1)(void*);
36 typedef void (CALLTYPE* ExFuncPtr2)(void*, void*);
37 typedef void (CALLTYPE* ExFuncPtr3)(void*, void*, void*);
38 typedef void (CALLTYPE* ExFuncPtr4)(void*, void*, void*, void*);
39 typedef void (CALLTYPE* ExFuncPtr5)(void*, void*, void*, void*, void*);
40 typedef void (CALLTYPE* ExFuncPtr6)(void*, void*, void*, void*, void*, void*);
41 typedef void (CALLTYPE* ExFuncPtr7)(void*, void*, void*, void*, void*, void*, void*);
42 typedef void (CALLTYPE* ExFuncPtr8)(void*, void*, void*, void*, void*, void*, void*, void*);
43 typedef void (CALLTYPE* ExFuncPtr9)(void*, void*, void*, void*, void*, void*, void*, void*, void*);
44 typedef void (CALLTYPE* ExFuncPtr10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
45 typedef void (CALLTYPE* ExFuncPtr11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
46 typedef void (CALLTYPE* ExFuncPtr12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
47 typedef void (CALLTYPE* ExFuncPtr13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
48 typedef void (CALLTYPE* ExFuncPtr14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
49 typedef void (CALLTYPE* ExFuncPtr15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
50 typedef void (CALLTYPE* ExFuncPtr16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
51 
52 typedef void (CALLTYPE* GetFuncCountPtr)(sal_uInt16& nCount);
53 typedef void (CALLTYPE* GetFuncDataPtr)
54  (sal_uInt16& nNo, char* pFuncName, sal_uInt16& nParamCount, ParamType* peType, char* pInternalName);
55 
56 typedef void (CALLTYPE* SetLanguagePtr)( sal_uInt16& nLanguage );
57 typedef void (CALLTYPE* GetParamDesc)
58  (sal_uInt16& nNo, sal_uInt16& nParam, char* pName, char* pDesc );
59 
60 typedef void (CALLTYPE* IsAsync) ( sal_uInt16& nNo,
61  ParamType* peType );
62 typedef void (CALLTYPE* Advice) ( sal_uInt16& nNo,
64 typedef void (CALLTYPE* Unadvice)( double& nHandle );
65 
66 }
67 
68 #ifndef DISABLE_DYNLOADING
69 #define GETFUNCTIONCOUNT "GetFunctionCount"
70 #define GETFUNCTIONDATA "GetFunctionData"
71 #define SETLANGUAGE "SetLanguage"
72 #define GETPARAMDESC "GetParameterDescription"
73 #define ISASYNC "IsAsync"
74 #define ADVICE "Advice"
75 #define UNADVICE "Unadvice"
76 #endif
77 
79 {
80 friend class ModuleCollection;
81  OUString aName;
82  std::unique_ptr<osl::Module> pInstance;
83 public:
84  ModuleData(const ModuleData&) = delete;
85  const ModuleData& operator=(const ModuleData&) = delete;
86 
87  ModuleData(const OUString& rStr, std::unique_ptr<osl::Module> pInst) : aName(rStr), pInstance(std::move(pInst)) {}
88 
89  const OUString& GetName() const { return aName; }
90  osl::Module* GetInstance() const { return pInstance.get(); }
91 };
92 
94  const OUString& rIName,
95  const OUString& rFName,
96  sal_uInt16 nNo,
97  sal_uInt16 nCount,
98  const ParamType* peType,
99  ParamType eType) :
100  pModuleData (pModule),
101  aInternalName (rIName),
102  aFuncName (rFName),
103  nNumber (nNo),
104  nParamCount (nCount),
105  eAsyncType (eType)
106 {
107  for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++)
108  eParamType[i] = peType[i];
109 }
110 
112  pModuleData (rData.pModuleData),
113  aInternalName (rData.aInternalName),
114  aFuncName (rData.aFuncName),
115  nNumber (rData.nNumber),
116  nParamCount (rData.nParamCount),
117  eAsyncType (rData.eAsyncType)
118 {
119  for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++)
120  eParamType[i] = rData.eParamType[i];
121 }
122 
123 namespace {
124 
125 class ModuleCollection
126 {
127  typedef std::map<OUString, std::unique_ptr<ModuleData>> MapType;
128  MapType m_Data;
129 public:
130  ModuleCollection() {}
131 
132  const ModuleData* findByName(const OUString& rName) const;
133  void insert(ModuleData* pNew);
134  void clear();
135 };
136 
137 const ModuleData* ModuleCollection::findByName(const OUString& rName) const
138 {
139  MapType::const_iterator it = m_Data.find(rName);
140  return it == m_Data.end() ? nullptr : it->second.get();
141 }
142 
143 void ModuleCollection::insert(ModuleData* pNew)
144 {
145  if (!pNew)
146  return;
147 
148  OUString aName = pNew->GetName();
149  m_Data.insert(std::make_pair(aName, std::unique_ptr<ModuleData>(pNew)));
150 }
151 
152 void ModuleCollection::clear()
153 {
154  m_Data.clear();
155 }
156 
157 ModuleCollection aModuleCollection;
158 
159 }
160 
161 bool InitExternalFunc(const OUString& rModuleName)
162 {
163 #ifdef DISABLE_DYNLOADING
164  (void) rModuleName;
165  return false;
166 #else
167  // Module already loaded?
168  const ModuleData* pTemp = aModuleCollection.findByName(rModuleName);
169  if (pTemp)
170  return false;
171 
172  OUString aNP = rModuleName;
173 
174  std::unique_ptr<osl::Module> pLib(new osl::Module( aNP ));
175  if (!pLib->is())
176  return false;
177 
178  oslGenericFunction fpGetCount = pLib->getFunctionSymbol(GETFUNCTIONCOUNT);
179  oslGenericFunction fpGetData = pLib->getFunctionSymbol(GETFUNCTIONDATA);
180  if ((fpGetCount == nullptr) || (fpGetData == nullptr))
181  return false;
182 
183  oslGenericFunction fpIsAsync = pLib->getFunctionSymbol(ISASYNC);
184  oslGenericFunction fpAdvice = pLib->getFunctionSymbol(ADVICE);
185  oslGenericFunction fpSetLanguage = pLib->getFunctionSymbol(SETLANGUAGE);
186  if ( fpSetLanguage )
187  {
189  sal_uInt16 nLanguage = static_cast<sal_uInt16>(eLanguage);
190  (*reinterpret_cast<SetLanguagePtr>(fpSetLanguage))( nLanguage );
191  }
192 
193  // include module into the collection
194  ModuleData* pModuleData = new ModuleData(rModuleName, std::move(pLib));
195  aModuleCollection.insert(pModuleData);
196 
197  // initialize interface
198  AdvData pfCallBack = &ScAddInAsyncCallBack;
200  sal_uInt16 nCount;
201  (*reinterpret_cast<GetFuncCountPtr>(fpGetCount))(nCount);
202  for (sal_uInt16 i=0; i < nCount; i++)
203  {
204  char cFuncName[256];
205  char cInternalName[256];
206  sal_uInt16 nParamCount;
207  ParamType eParamType[MAXFUNCPARAM];
208  ParamType eAsyncType = ParamType::NONE;
209  // initialize all, in case the AddIn behaves bad
210  cFuncName[0] = 0;
211  cInternalName[0] = 0;
212  nParamCount = 0;
213  for (ParamType & rParamType : eParamType)
214  {
215  rParamType = ParamType::NONE;
216  }
217  (*reinterpret_cast<GetFuncDataPtr>(fpGetData))(i, cFuncName, nParamCount,
218  eParamType, cInternalName);
219  if( fpIsAsync )
220  {
221  (*reinterpret_cast<IsAsync>(fpIsAsync))(i, &eAsyncType);
222  if ( fpAdvice && eAsyncType != ParamType::NONE )
223  (*reinterpret_cast<Advice>(fpAdvice))( i, pfCallBack );
224  }
225  OUString aInternalName( cInternalName, strlen(cInternalName), osl_getThreadTextEncoding() );
226  OUString aFuncName( cFuncName, strlen(cFuncName), osl_getThreadTextEncoding() );
227  LegacyFuncData* pLegacyFuncData = new LegacyFuncData( pModuleData,
228  aInternalName,
229  aFuncName,
230  i,
231  nParamCount,
232  eParamType,
233  eAsyncType );
234  pLegacyFuncCol->insert(pLegacyFuncData);
235  }
236  return true;
237 #endif
238 }
239 
241 {
242  aModuleCollection.clear();
243 }
244 
245 void LegacyFuncData::Call(void** ppParam) const
246 {
247 #ifdef DISABLE_DYNLOADING
248  (void) ppParam;
249 #else
250  osl::Module* pLib = pModuleData->GetInstance();
251  oslGenericFunction fProc = pLib->getFunctionSymbol(aFuncName);
252  if (fProc == nullptr)
253  return;
254 
255  switch (nParamCount)
256  {
257  case 1 :
258  (*reinterpret_cast<ExFuncPtr1>(fProc))(ppParam[0]);
259  break;
260  case 2 :
261  (*reinterpret_cast<ExFuncPtr2>(fProc))(ppParam[0], ppParam[1]);
262  break;
263  case 3 :
264  (*reinterpret_cast<ExFuncPtr3>(fProc))(ppParam[0], ppParam[1], ppParam[2]);
265  break;
266  case 4 :
267  (*reinterpret_cast<ExFuncPtr4>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3]);
268  break;
269  case 5 :
270  (*reinterpret_cast<ExFuncPtr5>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4]);
271  break;
272  case 6 :
273  (*reinterpret_cast<ExFuncPtr6>(fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5]);
274  break;
275  case 7 :
276  (*reinterpret_cast<ExFuncPtr7>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
277  ppParam[6]);
278  break;
279  case 8 :
280  (*reinterpret_cast<ExFuncPtr8>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
281  ppParam[6], ppParam[7]);
282  break;
283  case 9 :
284  (*reinterpret_cast<ExFuncPtr9>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
285  ppParam[6], ppParam[7], ppParam[8]);
286  break;
287  case 10 :
288  (*reinterpret_cast<ExFuncPtr10>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
289  ppParam[6], ppParam[7], ppParam[8], ppParam[9]);
290  break;
291  case 11 :
292  (*reinterpret_cast<ExFuncPtr11>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
293  ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10]);
294  break;
295  case 12:
296  (*reinterpret_cast<ExFuncPtr12>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
297  ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11]);
298  break;
299  case 13:
300  (*reinterpret_cast<ExFuncPtr13>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
301  ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
302  ppParam[12]);
303  break;
304  case 14 :
305  (*reinterpret_cast<ExFuncPtr14>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
306  ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
307  ppParam[12], ppParam[13]);
308  break;
309  case 15 :
310  (*reinterpret_cast<ExFuncPtr15>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
311  ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
312  ppParam[12], ppParam[13], ppParam[14]);
313  break;
314  case 16 :
315  (*reinterpret_cast<ExFuncPtr16>(fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
316  ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
317  ppParam[12], ppParam[13], ppParam[14], ppParam[15]);
318  break;
319  default : break;
320  }
321 #endif
322 }
323 
324 void LegacyFuncData::Unadvice( double nHandle )
325 {
326 #ifdef DISABLE_DYNLOADING
327  (void) nHandle;
328 #else
329  osl::Module* pLib = pModuleData->GetInstance();
330  oslGenericFunction fProc = pLib->getFunctionSymbol(UNADVICE);
331  if (fProc != nullptr)
332  {
333  reinterpret_cast< ::Unadvice>(fProc)(nHandle);
334  }
335 #endif
336 }
337 
338 const OUString& LegacyFuncData::GetModuleName() const
339 {
340  return pModuleData->GetName();
341 }
342 
343 void LegacyFuncData::getParamDesc( OUString& aName, OUString& aDesc, sal_uInt16 nParam ) const
344 {
345 #ifdef DISABLE_DYNLOADING
346  (void) aName;
347  (void) aDesc;
348  (void) nParam;
349 #else
350  bool bRet = false;
351  if ( nParam <= nParamCount )
352  {
353  osl::Module* pLib = pModuleData->GetInstance();
354  oslGenericFunction fProc = pLib->getFunctionSymbol(GETPARAMDESC);
355  if ( fProc != nullptr )
356  {
357  char pcName[256];
358  char pcDesc[256];
359  *pcName = *pcDesc = 0;
360  sal_uInt16 nFuncNo = nNumber; // don't let it mess up via reference...
361  reinterpret_cast< ::GetParamDesc>(fProc)( nFuncNo, nParam, pcName, pcDesc );
362  aName = OUString( pcName, 256, osl_getThreadTextEncoding() );
363  aDesc = OUString( pcDesc, 256, osl_getThreadTextEncoding() );
364  bRet = true;
365  }
366  }
367  if ( !bRet )
368  {
369  aName.clear();
370  aDesc.clear();
371  }
372 #endif
373 }
374 
377 {
378  for (auto const& it : r.m_Data)
379  {
380  m_Data.insert(std::make_pair(it.first, std::make_unique<LegacyFuncData>(*it.second)));
381  }
382 }
383 
384 const LegacyFuncData* LegacyFuncCollection::findByName(const OUString& rName) const
385 {
386  MapType::const_iterator it = m_Data.find(rName);
387  return it == m_Data.end() ? nullptr : it->second.get();
388 }
389 
391 {
392  MapType::iterator it = m_Data.find(rName);
393  return it == m_Data.end() ? nullptr : it->second.get();
394 }
395 
397 {
398  OUString aName = pNew->GetInternalName();
399  m_Data.insert(std::make_pair(aName, std::unique_ptr<LegacyFuncData>(pNew)));
400 }
401 
403 {
404  return m_Data.begin();
405 }
406 
408 {
409  return m_Data.end();
410 }
411 
412 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void(CALLTYPE * AdvData)(double &nHandle, void *pData)
Definition: callform.hxx:38
MapType::const_iterator const_iterator
Definition: callform.hxx:94
bool InitExternalFunc(const OUString &rModuleName)
Definition: callform.cxx:161
void(CALLTYPE * ExFuncPtr13)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:47
void(CALLTYPE * ExFuncPtr11)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:45
sal_uInt16 nNumber
Definition: callform.hxx:60
const_iterator end() const
Definition: callform.cxx:407
const ModuleData & operator=(const ModuleData &)=delete
const LanguageTag & GetUILanguageTag() const
AdvData & pfCallback
Definition: callform.cxx:63
void(CALLTYPE * ExFuncPtr9)(void *, void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:43
LanguageType getLanguageType(bool bResolveSystem=true) const
sal_uInt16 char char * pDesc
Definition: callform.cxx:58
OUString aFuncName
Definition: callform.hxx:59
static const AllSettings & GetSettings()
const_iterator begin() const
Definition: callform.cxx:402
#define MAXFUNCPARAM
Definition: callform.hxx:28
void(CALLTYPE * ExFuncPtr10)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:44
void(CALLTYPE * ExFuncPtr1)(void *)
Definition: callform.cxx:35
void(CALLTYPE * GetFuncCountPtr)(sal_uInt16 &nCount)
Definition: callform.cxx:52
void ExitExternalFunc()
Definition: callform.cxx:240
void(CALLTYPE * ExFuncPtr8)(void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:42
void(CALLTYPE * ExFuncPtr12)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:46
#define ISASYNC
Definition: callform.cxx:73
std::unique_ptr< osl::Module > pInstance
Definition: callform.cxx:82
void(CALLTYPE * ExFuncPtr3)(void *, void *, void *)
Definition: callform.cxx:37
const LegacyFuncData * findByName(const OUString &rName) const
Definition: callform.cxx:384
char sal_uInt16 & nParamCount
Definition: callform.cxx:54
const OUString & GetName() const
Definition: callform.cxx:89
friend class ModuleCollection
Definition: callform.cxx:80
#define SETLANGUAGE
Definition: callform.cxx:71
int nCount
LegacyFuncData(const ModuleData *pModule, const OUString &rIName, const OUString &rFName, sal_uInt16 nNo, sal_uInt16 nCount, const ParamType *peType, ParamType eType)
Definition: callform.cxx:93
#define GETPARAMDESC
Definition: callform.cxx:72
#define UNADVICE
Definition: callform.cxx:75
sal_Int32 nHandle
void(CALLTYPE * SetLanguagePtr)(sal_uInt16 &nLanguage)
Definition: callform.cxx:56
char sal_uInt16 ParamType * peType
Definition: callform.cxx:54
void insert(LegacyFuncData *pNew)
Definition: callform.cxx:396
void(CALLTYPE * ExFuncPtr2)(void *, void *)
Definition: callform.cxx:36
sal_uInt16 char * pName
Definition: callform.cxx:58
ModuleData(const ModuleData &)=delete
int i
#define ADVICE
Definition: callform.cxx:74
OUString aName
Definition: callform.cxx:81
void(CALLTYPE * ExFuncPtr5)(void *, void *, void *, void *, void *)
Definition: callform.cxx:39
void getParamDesc(OUString &aName, OUString &aDesc, sal_uInt16 nParam) const
name and description of parameter nParam.
Definition: callform.cxx:343
sal_uInt16 & nParam
Definition: callform.cxx:58
const OUString & GetInternalName() const
Definition: callform.hxx:75
void CALLTYPE ScAddInAsyncCallBack(double &nHandle, void *pData)
Definition: adiasync.cxx:37
ParamType
Definition: callform.hxx:41
#define GETFUNCTIONCOUNT
Definition: callform.cxx:69
void(CALLTYPE * ExFuncPtr6)(void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:40
const ModuleData * pModuleData
Definition: callform.hxx:57
void(CALLTYPE * ExFuncPtr15)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:49
void(CALLTYPE * ExFuncPtr14)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:48
static LegacyFuncCollection * GetLegacyFuncCollection()
Definition: global.cxx:267
void Unadvice(double nHandle)
Definition: callform.cxx:324
void Call(void **ppParam) const
Definition: callform.cxx:245
OUString aName
#define CALLTYPE
Definition: callform.hxx:32
char sal_uInt16 ParamType char * pInternalName
Definition: callform.cxx:54
void(CALLTYPE * Unadvice)(double &nHandle)
Definition: callform.cxx:64
ParamType eParamType[MAXFUNCPARAM]
Definition: callform.hxx:63
char * pFuncName
Definition: callform.cxx:54
ModuleData(const OUString &rStr, std::unique_ptr< osl::Module > pInst)
Definition: callform.cxx:87
void(CALLTYPE * ExFuncPtr4)(void *, void *, void *, void *)
Definition: callform.cxx:38
const OUString & GetModuleName() const
Definition: callform.cxx:338
void(CALLTYPE * ExFuncPtr16)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:50
void(CALLTYPE * ExFuncPtr7)(void *, void *, void *, void *, void *, void *, void *)
Definition: callform.cxx:41
osl::Module * GetInstance() const
Definition: callform.cxx:90
#define GETFUNCTIONDATA
Definition: callform.cxx:70
const char * pLib
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo