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