File: | home/maarten/src/libreoffice/core/include/tools/ref.hxx |
Warning: | line 87, column 19 Potential leak of memory pointed to by field 'pObj' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <vcl/errinf.hxx> | |||
21 | #include <tools/stream.hxx> | |||
22 | #include <sot/storage.hxx> | |||
23 | #include <tools/urlobj.hxx> | |||
24 | #include <svl/hint.hxx> | |||
25 | #include <basic/sbx.hxx> | |||
26 | #include <basic/sbmeth.hxx> | |||
27 | #include <sot/storinfo.hxx> | |||
28 | #include <unotools/pathoptions.hxx> | |||
29 | #include <tools/debug.hxx> | |||
30 | #include <tools/diagnose_ex.h> | |||
31 | #include <basic/sbmod.hxx> | |||
32 | #include <unotools/transliterationwrapper.hxx> | |||
33 | #include <sal/log.hxx> | |||
34 | ||||
35 | #include <basic/sberrors.hxx> | |||
36 | #include <basic/sbuno.hxx> | |||
37 | #include <basic/basmgr.hxx> | |||
38 | #include <global.hxx> | |||
39 | #include <com/sun/star/script/XLibraryContainer.hpp> | |||
40 | #include <com/sun/star/script/XPersistentLibraryContainer.hpp> | |||
41 | ||||
42 | #include <memory> | |||
43 | #include <vector> | |||
44 | ||||
45 | #define LIB_SEP0x01 0x01 | |||
46 | #define LIBINFO_SEP0x02 0x02 | |||
47 | #define LIBINFO_ID0x1491 0x1491 | |||
48 | #define PASSWORD_MARKER0x31452134 0x31452134 | |||
49 | ||||
50 | ||||
51 | // Library API, implemented for XML import/export | |||
52 | ||||
53 | #include <com/sun/star/container/XNameContainer.hpp> | |||
54 | #include <com/sun/star/container/XContainer.hpp> | |||
55 | #include <com/sun/star/script/XStarBasicAccess.hpp> | |||
56 | #include <com/sun/star/script/XStarBasicModuleInfo.hpp> | |||
57 | #include <com/sun/star/script/XStarBasicDialogInfo.hpp> | |||
58 | #include <com/sun/star/script/XStarBasicLibraryInfo.hpp> | |||
59 | #include <com/sun/star/script/XLibraryContainerPassword.hpp> | |||
60 | #include <com/sun/star/script/ModuleInfo.hpp> | |||
61 | #include <com/sun/star/script/vba/XVBACompatibility.hpp> | |||
62 | #include <com/sun/star/script/vba/XVBAModuleInfo.hpp> | |||
63 | #include <com/sun/star/ucb/ContentCreationException.hpp> | |||
64 | ||||
65 | #include <cppuhelper/implbase.hxx> | |||
66 | ||||
67 | using com::sun::star::uno::Reference; | |||
68 | using namespace com::sun::star; | |||
69 | using namespace com::sun::star::script; | |||
70 | using namespace cppu; | |||
71 | ||||
72 | typedef WeakImplHelper< container::XNameContainer > NameContainerHelper; | |||
73 | typedef WeakImplHelper< script::XStarBasicModuleInfo > ModuleInfoHelper; | |||
74 | typedef WeakImplHelper< script::XStarBasicAccess > StarBasicAccessHelper; | |||
75 | ||||
76 | // Version 1 | |||
77 | // sal_uInt32 nEndPos | |||
78 | // sal_uInt16 nId | |||
79 | // sal_uInt16 nVer | |||
80 | // bool bDoLoad | |||
81 | // String LibName | |||
82 | // String AbsStorageName | |||
83 | // String RelStorageName | |||
84 | // Version 2 | |||
85 | // + bool bReference | |||
86 | ||||
87 | const char szStdLibName[] = "Standard"; | |||
88 | const char szBasicStorage[] = "StarBASIC"; | |||
89 | const char szOldManagerStream[] = "BasicManager"; | |||
90 | const char szManagerStream[] = "BasicManager2"; | |||
91 | const char szImbedded[] = "LIBIMBEDDED"; | |||
92 | const char szCryptingKey[] = "CryptedBasic"; | |||
93 | ||||
94 | ||||
95 | const StreamMode eStreamReadMode = StreamMode::READ | StreamMode::NOCREATE | StreamMode::SHARE_DENYALL; | |||
96 | const StreamMode eStorageReadMode = StreamMode::READ | StreamMode::SHARE_DENYWRITE; | |||
97 | ||||
98 | ||||
99 | // BasicManager impl data | |||
100 | struct BasicManagerImpl | |||
101 | { | |||
102 | LibraryContainerInfo maContainerInfo; | |||
103 | ||||
104 | std::vector<std::unique_ptr<BasicLibInfo>> aLibs; | |||
105 | OUString aBasicLibPath; | |||
106 | ||||
107 | BasicManagerImpl() | |||
108 | {} | |||
109 | }; | |||
110 | ||||
111 | // BasMgrContainerListenerImpl | |||
112 | ||||
113 | ||||
114 | typedef ::cppu::WeakImplHelper< container::XContainerListener > ContainerListenerHelper; | |||
115 | ||||
116 | class BasMgrContainerListenerImpl: public ContainerListenerHelper | |||
117 | { | |||
118 | BasicManager* mpMgr; | |||
119 | OUString maLibName; // empty -> no lib, but lib container | |||
120 | ||||
121 | public: | |||
122 | BasMgrContainerListenerImpl( BasicManager* pMgr, const OUString& aLibName ) | |||
123 | : mpMgr( pMgr ) | |||
124 | , maLibName( aLibName ) {} | |||
125 | ||||
126 | static void insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont, BasicManager* pMgr, | |||
127 | const uno::Any& aLibAny, const OUString& aLibName ); | |||
128 | static void addLibraryModulesImpl( BasicManager const * pMgr, const uno::Reference< container::XNameAccess >& xLibNameAccess, | |||
129 | const OUString& aLibName ); | |||
130 | ||||
131 | ||||
132 | // XEventListener | |||
133 | virtual void SAL_CALL disposing( const lang::EventObject& Source ) override; | |||
134 | ||||
135 | // XContainerListener | |||
136 | virtual void SAL_CALL elementInserted( const container::ContainerEvent& Event ) override; | |||
137 | virtual void SAL_CALL elementReplaced( const container::ContainerEvent& Event ) override; | |||
138 | virtual void SAL_CALL elementRemoved( const container::ContainerEvent& Event ) override; | |||
139 | }; | |||
140 | ||||
141 | ||||
142 | // BasMgrContainerListenerImpl | |||
143 | ||||
144 | ||||
145 | void BasMgrContainerListenerImpl::insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont, | |||
146 | BasicManager* pMgr, const uno::Any& aLibAny, const OUString& aLibName ) | |||
147 | { | |||
148 | Reference< container::XNameAccess > xLibNameAccess; | |||
149 | aLibAny >>= xLibNameAccess; | |||
150 | ||||
151 | if( !pMgr->GetLib( aLibName ) ) | |||
152 | { | |||
153 | StarBASIC* pLib = | |||
154 | pMgr->CreateLibForLibContainer( aLibName, xScriptCont ); | |||
155 | DBG_ASSERT( pLib, "XML Import: Basic library could not be created")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "155" ": "), "%s", "XML Import: Basic library could not be created" ); } } while (false); | |||
156 | } | |||
157 | ||||
158 | uno::Reference< container::XContainer> xLibContainer( xLibNameAccess, uno::UNO_QUERY ); | |||
159 | if( xLibContainer.is() ) | |||
160 | { | |||
161 | // Register listener for library | |||
162 | Reference< container::XContainerListener > xLibraryListener | |||
163 | = new BasMgrContainerListenerImpl( pMgr, aLibName ); | |||
164 | xLibContainer->addContainerListener( xLibraryListener ); | |||
165 | } | |||
166 | ||||
167 | if( xScriptCont->isLibraryLoaded( aLibName ) ) | |||
168 | { | |||
169 | addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName ); | |||
170 | } | |||
171 | } | |||
172 | ||||
173 | ||||
174 | void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager const * pMgr, | |||
175 | const uno::Reference< container::XNameAccess >& xLibNameAccess, const OUString& aLibName ) | |||
176 | { | |||
177 | uno::Sequence< OUString > aModuleNames = xLibNameAccess->getElementNames(); | |||
178 | sal_Int32 nModuleCount = aModuleNames.getLength(); | |||
179 | ||||
180 | StarBASIC* pLib = pMgr->GetLib( aLibName ); | |||
181 | DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "181" ": "), "%s", "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!" ); } } while (false); | |||
182 | if( !pLib ) | |||
183 | return; | |||
184 | ||||
185 | const OUString* pNames = aModuleNames.getConstArray(); | |||
186 | for( sal_Int32 j = 0 ; j < nModuleCount ; j++ ) | |||
187 | { | |||
188 | OUString aModuleName = pNames[ j ]; | |||
189 | uno::Any aElement = xLibNameAccess->getByName( aModuleName ); | |||
190 | OUString aMod; | |||
191 | aElement >>= aMod; | |||
192 | uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, uno::UNO_QUERY ); | |||
193 | if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) ) | |||
194 | { | |||
195 | ModuleInfo aInfo = xVBAModuleInfo->getModuleInfo( aModuleName ); | |||
196 | pLib->MakeModule( aModuleName, aInfo, aMod ); | |||
197 | } | |||
198 | else | |||
199 | pLib->MakeModule( aModuleName, aMod ); | |||
200 | } | |||
201 | ||||
202 | pLib->SetModified( false ); | |||
203 | } | |||
204 | ||||
205 | ||||
206 | // XEventListener | |||
207 | ||||
208 | ||||
209 | void SAL_CALL BasMgrContainerListenerImpl::disposing( const lang::EventObject& ) {} | |||
210 | ||||
211 | // XContainerListener | |||
212 | ||||
213 | ||||
214 | void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const container::ContainerEvent& Event ) | |||
215 | { | |||
216 | bool bLibContainer = maLibName.isEmpty(); | |||
217 | OUString aName; | |||
218 | Event.Accessor >>= aName; | |||
219 | ||||
220 | if( bLibContainer ) | |||
221 | { | |||
222 | uno::Reference< script::XLibraryContainer > xScriptCont( Event.Source, uno::UNO_QUERY ); | |||
223 | if (xScriptCont.is()) | |||
224 | insertLibraryImpl(xScriptCont, mpMgr, Event.Element, aName); | |||
225 | StarBASIC* pLib = mpMgr->GetLib( aName ); | |||
226 | if ( pLib ) | |||
227 | { | |||
228 | uno::Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, uno::UNO_QUERY ); | |||
229 | if ( xVBACompat.is() ) | |||
230 | pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() ); | |||
231 | } | |||
232 | } | |||
233 | else | |||
234 | { | |||
235 | ||||
236 | StarBASIC* pLib = mpMgr->GetLib( maLibName ); | |||
237 | DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "237" ": "), "%s", "BasMgrContainerListenerImpl::elementInserted: Unknown lib!" ); } } while (false); | |||
238 | if( pLib ) | |||
239 | { | |||
240 | SbModule* pMod = pLib->FindModule( aName ); | |||
241 | if( !pMod ) | |||
242 | { | |||
243 | OUString aMod; | |||
244 | Event.Element >>= aMod; | |||
245 | uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, uno::UNO_QUERY ); | |||
246 | if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) ) | |||
247 | { | |||
248 | ModuleInfo aInfo = xVBAModuleInfo->getModuleInfo( aName ); | |||
249 | pLib->MakeModule( aName, aInfo, aMod ); | |||
250 | } | |||
251 | else | |||
252 | pLib->MakeModule( aName, aMod ); | |||
253 | pLib->SetModified( false ); | |||
254 | } | |||
255 | } | |||
256 | } | |||
257 | } | |||
258 | ||||
259 | ||||
260 | void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const container::ContainerEvent& Event ) | |||
261 | { | |||
262 | OUString aName; | |||
263 | Event.Accessor >>= aName; | |||
264 | ||||
265 | // Replace not possible for library container | |||
266 | DBG_ASSERT( !maLibName.isEmpty(), "library container fired elementReplaced()")do { if (true && (!(!maLibName.isEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "266" ": "), "%s", "library container fired elementReplaced()" ); } } while (false); | |||
267 | ||||
268 | StarBASIC* pLib = mpMgr->GetLib( maLibName ); | |||
269 | if( !pLib ) | |||
270 | return; | |||
271 | ||||
272 | SbModule* pMod = pLib->FindModule( aName ); | |||
273 | OUString aMod; | |||
274 | Event.Element >>= aMod; | |||
275 | ||||
276 | if( pMod ) | |||
277 | pMod->SetSource32( aMod ); | |||
278 | else | |||
279 | pLib->MakeModule( aName, aMod ); | |||
280 | ||||
281 | pLib->SetModified( false ); | |||
282 | } | |||
283 | ||||
284 | ||||
285 | void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const container::ContainerEvent& Event ) | |||
286 | { | |||
287 | OUString aName; | |||
288 | Event.Accessor >>= aName; | |||
289 | ||||
290 | bool bLibContainer = maLibName.isEmpty(); | |||
291 | if( bLibContainer ) | |||
292 | { | |||
293 | StarBASIC* pLib = mpMgr->GetLib( aName ); | |||
294 | if( pLib ) | |||
295 | { | |||
296 | sal_uInt16 nLibId = mpMgr->GetLibId( aName ); | |||
297 | mpMgr->RemoveLib( nLibId, false ); | |||
298 | } | |||
299 | } | |||
300 | else | |||
301 | { | |||
302 | StarBASIC* pLib = mpMgr->GetLib( maLibName ); | |||
303 | SbModule* pMod = pLib ? pLib->FindModule( aName ) : nullptr; | |||
304 | if( pMod ) | |||
305 | { | |||
306 | pLib->Remove( pMod ); | |||
307 | pLib->SetModified( false ); | |||
308 | } | |||
309 | } | |||
310 | } | |||
311 | ||||
312 | BasicError::BasicError( ErrCode nId, BasicErrorReason nR ) | |||
313 | { | |||
314 | nErrorId = nId; | |||
315 | nReason = nR; | |||
316 | } | |||
317 | ||||
318 | BasicError::BasicError( const BasicError& rErr ) | |||
319 | { | |||
320 | nErrorId = rErr.nErrorId; | |||
321 | nReason = rErr.nReason; | |||
322 | } | |||
323 | ||||
324 | ||||
325 | class BasicLibInfo | |||
326 | { | |||
327 | private: | |||
328 | StarBASICRef xLib; | |||
329 | OUString aLibName; | |||
330 | OUString aStorageName; // string is sufficient, unique at runtime | |||
331 | OUString aRelStorageName; | |||
332 | OUString aPassword; | |||
333 | ||||
334 | bool bDoLoad; | |||
335 | bool bReference; | |||
336 | ||||
337 | // Lib represents library in new UNO library container | |||
338 | uno::Reference< script::XLibraryContainer > mxScriptCont; | |||
339 | ||||
340 | public: | |||
341 | BasicLibInfo(); | |||
342 | ||||
343 | bool IsReference() const { return bReference; } | |||
344 | void SetReference(bool b) { bReference = b; } | |||
345 | ||||
346 | bool IsExtern() const { return aStorageName != szImbedded; } | |||
347 | ||||
348 | void SetStorageName( const OUString& rName ) { aStorageName = rName; } | |||
349 | const OUString& GetStorageName() const { return aStorageName; } | |||
350 | ||||
351 | void SetRelStorageName( const OUString& rN ) { aRelStorageName = rN; } | |||
352 | const OUString& GetRelStorageName() const { return aRelStorageName; } | |||
353 | ||||
354 | StarBASICRef GetLib() const | |||
355 | { | |||
356 | if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) && | |||
357 | !mxScriptCont->isLibraryLoaded( aLibName ) ) | |||
358 | return StarBASICRef(); | |||
359 | return xLib; | |||
360 | } | |||
361 | StarBASICRef& GetLibRef() { return xLib; } | |||
362 | void SetLib( StarBASIC* pBasic ) { xLib = pBasic; } | |||
363 | ||||
364 | const OUString& GetLibName() const { return aLibName; } | |||
365 | void SetLibName( const OUString& rName ) { aLibName = rName; } | |||
366 | ||||
367 | // Only temporary for Load/Save | |||
368 | bool DoLoad() { return bDoLoad; } | |||
369 | ||||
370 | bool HasPassword() const { return !aPassword.isEmpty(); } | |||
371 | const OUString& GetPassword() const { return aPassword; } | |||
372 | void SetPassword( const OUString& rNewPassword ) | |||
373 | { aPassword = rNewPassword; } | |||
374 | ||||
375 | static BasicLibInfo* Create( SotStorageStream& rSStream ); | |||
376 | ||||
377 | const uno::Reference< script::XLibraryContainer >& GetLibraryContainer() const | |||
378 | { return mxScriptCont; } | |||
379 | void SetLibraryContainer( const uno::Reference< script::XLibraryContainer >& xScriptCont ) | |||
380 | { mxScriptCont = xScriptCont; } | |||
381 | }; | |||
382 | ||||
383 | ||||
384 | BasicLibInfo::BasicLibInfo() | |||
385 | : aStorageName(szImbedded) | |||
386 | , aRelStorageName(szImbedded) | |||
387 | , bDoLoad(false) | |||
388 | , bReference(false) | |||
389 | { | |||
390 | } | |||
391 | ||||
392 | BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream ) | |||
393 | { | |||
394 | BasicLibInfo* pInfo = new BasicLibInfo; | |||
395 | ||||
396 | sal_uInt32 nEndPos; | |||
397 | sal_uInt16 nId; | |||
398 | sal_uInt16 nVer; | |||
399 | ||||
400 | rSStream.ReadUInt32( nEndPos ); | |||
401 | rSStream.ReadUInt16( nId ); | |||
402 | rSStream.ReadUInt16( nVer ); | |||
403 | ||||
404 | DBG_ASSERT( nId == LIBINFO_ID, "No BasicLibInfo?!" )do { if (true && (!(nId == 0x1491))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "404" ": "), "%s", "No BasicLibInfo?!"); } } while (false ); | |||
405 | if( nId == LIBINFO_ID0x1491 ) | |||
406 | { | |||
407 | // Reload? | |||
408 | bool bDoLoad; | |||
409 | rSStream.ReadCharAsBool( bDoLoad ); | |||
410 | pInfo->bDoLoad = bDoLoad; | |||
411 | ||||
412 | // The name of the lib... | |||
413 | OUString aName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet()); | |||
414 | pInfo->SetLibName( aName ); | |||
415 | ||||
416 | // Absolute path... | |||
417 | OUString aStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet()); | |||
418 | pInfo->SetStorageName( aStorageName ); | |||
419 | ||||
420 | // Relative path... | |||
421 | OUString aRelStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet()); | |||
422 | pInfo->SetRelStorageName( aRelStorageName ); | |||
423 | ||||
424 | if ( nVer >= 2 ) | |||
425 | { | |||
426 | bool bReferenz; | |||
427 | rSStream.ReadCharAsBool( bReferenz ); | |||
428 | pInfo->SetReference(bReferenz); | |||
429 | } | |||
430 | ||||
431 | rSStream.Seek( nEndPos ); | |||
432 | } | |||
433 | return pInfo; | |||
434 | } | |||
435 | ||||
436 | BasicManager::BasicManager( SotStorage& rStorage, const OUString& rBaseURL, StarBASIC* pParentFromStdLib, OUString const * pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr ) | |||
437 | { | |||
438 | Init(); | |||
439 | ||||
440 | if( pLibPath ) | |||
| ||||
441 | { | |||
442 | mpImpl->aBasicLibPath = *pLibPath; | |||
443 | } | |||
444 | OUString aStorName( rStorage.GetName() ); | |||
445 | maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE ); | |||
446 | ||||
447 | ||||
448 | // If there is no Manager Stream, no further actions are necessary | |||
449 | if ( rStorage.IsStream( szManagerStream ) ) | |||
450 | { | |||
451 | LoadBasicManager( rStorage, rBaseURL ); | |||
452 | // StdLib contains Parent: | |||
453 | StarBASIC* pStdLib = GetStdLib(); | |||
454 | DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" )do { if (true && (!(pStdLib))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "454" ": "), "%s", "Standard-Lib not loaded?"); } } while (false); | |||
455 | if ( !pStdLib ) | |||
456 | { | |||
457 | // Should never happen, but if it happens we won't crash... | |||
458 | pStdLib = new StarBASIC( nullptr, mbDocMgr ); | |||
459 | ||||
460 | if (mpImpl->aLibs.empty()) | |||
461 | CreateLibInfo(); | |||
462 | ||||
463 | BasicLibInfo& rStdLibInfo = *mpImpl->aLibs.front(); | |||
464 | ||||
465 | rStdLibInfo.SetLib( pStdLib ); | |||
466 | StarBASICRef xStdLib = rStdLibInfo.GetLib(); | |||
467 | xStdLib->SetName( szStdLibName ); | |||
468 | rStdLibInfo.SetLibName( szStdLibName ); | |||
469 | xStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch ); | |||
470 | xStdLib->SetModified( false ); | |||
471 | } | |||
472 | else | |||
473 | { | |||
474 | pStdLib->SetParent( pParentFromStdLib ); | |||
475 | // The other get StdLib as parent: | |||
476 | ||||
477 | for ( sal_uInt16 nBasic = 1; nBasic < GetLibCount(); nBasic++ ) | |||
478 | { | |||
479 | StarBASIC* pBasic = GetLib( nBasic ); | |||
480 | if ( pBasic ) | |||
481 | { | |||
482 | pStdLib->Insert( pBasic ); | |||
483 | pBasic->SetFlag( SbxFlagBits::ExtSearch ); | |||
484 | } | |||
485 | } | |||
486 | // Modified through insert | |||
487 | pStdLib->SetModified( false ); | |||
488 | } | |||
489 | } | |||
490 | else | |||
491 | { | |||
492 | ImpCreateStdLib( pParentFromStdLib ); | |||
493 | if ( rStorage.IsStream( szOldManagerStream ) ) | |||
494 | LoadOldBasicManager( rStorage ); | |||
495 | } | |||
496 | } | |||
497 | ||||
498 | static void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo ) | |||
499 | { | |||
500 | uno::Reference< script::XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() ); | |||
501 | if ( !xScriptCont.is() ) | |||
502 | return; | |||
503 | ||||
504 | OUString aLibName = pBasic->GetName(); | |||
505 | if( !xScriptCont->hasByName( aLibName ) ) | |||
506 | xScriptCont->createLibrary( aLibName ); | |||
507 | ||||
508 | uno::Any aLibAny = xScriptCont->getByName( aLibName ); | |||
509 | uno::Reference< container::XNameContainer > xLib; | |||
510 | aLibAny >>= xLib; | |||
511 | if ( !xLib.is() ) | |||
512 | return; | |||
513 | ||||
514 | for ( const auto& pModule: pBasic->GetModules() ) | |||
515 | { | |||
516 | OUString aModName = pModule->GetName(); | |||
517 | if( !xLib->hasByName( aModName ) ) | |||
518 | { | |||
519 | OUString aSource = pModule->GetSource32(); | |||
520 | uno::Any aSourceAny; | |||
521 | aSourceAny <<= aSource; | |||
522 | xLib->insertByName( aModName, aSourceAny ); | |||
523 | } | |||
524 | } | |||
525 | } | |||
526 | ||||
527 | const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const | |||
528 | { | |||
529 | return mpImpl->maContainerInfo.mxDialogCont; | |||
530 | } | |||
531 | ||||
532 | const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const | |||
533 | { | |||
534 | return mpImpl->maContainerInfo.mxScriptCont; | |||
535 | } | |||
536 | ||||
537 | void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo ) | |||
538 | { | |||
539 | mpImpl->maContainerInfo = rInfo; | |||
540 | ||||
541 | uno::Reference< script::XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() ); | |||
542 | if( xScriptCont.is() ) | |||
543 | { | |||
544 | // Register listener for lib container | |||
545 | uno::Reference< container::XContainerListener > xLibContainerListener | |||
546 | = new BasMgrContainerListenerImpl( this, "" ); | |||
547 | ||||
548 | uno::Reference< container::XContainer> xLibContainer( xScriptCont, uno::UNO_QUERY ); | |||
549 | xLibContainer->addContainerListener( xLibContainerListener ); | |||
550 | ||||
551 | const uno::Sequence< OUString > aScriptLibNames = xScriptCont->getElementNames(); | |||
552 | ||||
553 | if( aScriptLibNames.hasElements() ) | |||
554 | { | |||
555 | for(const auto& rScriptLibName : aScriptLibNames) | |||
556 | { | |||
557 | uno::Any aLibAny = xScriptCont->getByName( rScriptLibName ); | |||
558 | ||||
559 | if ( rScriptLibName == "Standard" || rScriptLibName == "VBAProject") | |||
560 | xScriptCont->loadLibrary( rScriptLibName ); | |||
561 | ||||
562 | BasMgrContainerListenerImpl::insertLibraryImpl | |||
563 | ( xScriptCont, this, aLibAny, rScriptLibName ); | |||
564 | } | |||
565 | } | |||
566 | else | |||
567 | { | |||
568 | // No libs? Maybe an 5.2 document already loaded | |||
569 | for (auto const& rpBasLibInfo : mpImpl->aLibs) | |||
570 | { | |||
571 | StarBASIC* pLib = rpBasLibInfo->GetLib().get(); | |||
572 | if( !pLib ) | |||
573 | { | |||
574 | bool bLoaded = ImpLoadLibrary( rpBasLibInfo.get(), nullptr ); | |||
575 | if( bLoaded ) | |||
576 | pLib = rpBasLibInfo->GetLib().get(); | |||
577 | } | |||
578 | if( pLib ) | |||
579 | { | |||
580 | copyToLibraryContainer( pLib, mpImpl->maContainerInfo ); | |||
581 | if (rpBasLibInfo->HasPassword()) | |||
582 | { | |||
583 | OldBasicPassword* pOldBasicPassword = | |||
584 | mpImpl->maContainerInfo.mpOldBasicPassword; | |||
585 | if( pOldBasicPassword ) | |||
586 | { | |||
587 | pOldBasicPassword->setLibraryPassword( | |||
588 | pLib->GetName(), rpBasLibInfo->GetPassword() ); | |||
589 | } | |||
590 | } | |||
591 | } | |||
592 | } | |||
593 | } | |||
594 | } | |||
595 | ||||
596 | SetGlobalUNOConstant( "BasicLibraries", uno::Any( mpImpl->maContainerInfo.mxScriptCont ) ); | |||
597 | SetGlobalUNOConstant( "DialogLibraries", uno::Any( mpImpl->maContainerInfo.mxDialogCont ) ); | |||
598 | } | |||
599 | ||||
600 | BasicManager::BasicManager( StarBASIC* pSLib, OUString const * pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr ) | |||
601 | { | |||
602 | Init(); | |||
603 | DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" )do { if (true && (!(pSLib))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "603" ": "), "%s", "BasicManager cannot be created with a NULL-Pointer!" ); } } while (false); | |||
604 | ||||
605 | if( pLibPath ) | |||
606 | { | |||
607 | mpImpl->aBasicLibPath = *pLibPath; | |||
608 | } | |||
609 | BasicLibInfo* pStdLibInfo = CreateLibInfo(); | |||
610 | pStdLibInfo->SetLib( pSLib ); | |||
611 | StarBASICRef xStdLib = pStdLibInfo->GetLib(); | |||
612 | xStdLib->SetName(szStdLibName); | |||
613 | pStdLibInfo->SetLibName(szStdLibName ); | |||
614 | pSLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch ); | |||
615 | ||||
616 | // Save is only necessary if basic has changed | |||
617 | xStdLib->SetModified( false ); | |||
618 | } | |||
619 | ||||
620 | void BasicManager::ImpMgrNotLoaded( const OUString& rStorageName ) | |||
621 | { | |||
622 | // pErrInf is only destroyed if the error os processed by an | |||
623 | // ErrorHandler | |||
624 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), rStorageName, DialogMask::ButtonsOk ); | |||
625 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENMGRSTREAM); | |||
626 | ||||
627 | // Create a stdlib otherwise we crash! | |||
628 | BasicLibInfo* pStdLibInfo = CreateLibInfo(); | |||
629 | pStdLibInfo->SetLib( new StarBASIC( nullptr, mbDocMgr ) ); | |||
630 | StarBASICRef xStdLib = pStdLibInfo->GetLib(); | |||
631 | xStdLib->SetName( szStdLibName ); | |||
632 | pStdLibInfo->SetLibName( szStdLibName ); | |||
633 | xStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch ); | |||
634 | xStdLib->SetModified( false ); | |||
635 | } | |||
636 | ||||
637 | ||||
638 | void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib ) | |||
639 | { | |||
640 | BasicLibInfo* pStdLibInfo = CreateLibInfo(); | |||
641 | StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr ); | |||
642 | pStdLibInfo->SetLib( pStdLib ); | |||
643 | pStdLib->SetName( szStdLibName ); | |||
644 | pStdLibInfo->SetLibName( szStdLibName ); | |||
645 | pStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch ); | |||
646 | } | |||
647 | ||||
648 | void BasicManager::LoadBasicManager( SotStorage& rStorage, const OUString& rBaseURL ) | |||
649 | { | |||
650 | tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( szManagerStream, eStreamReadMode ); | |||
651 | ||||
652 | OUString aStorName( rStorage.GetName() ); | |||
653 | // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); | |||
654 | ||||
655 | if ( !xManagerStream.is() || xManagerStream->GetError() || ( xManagerStream->TellEnd() == 0 ) ) | |||
656 | { | |||
657 | ImpMgrNotLoaded( aStorName ); | |||
658 | return; | |||
659 | } | |||
660 | ||||
661 | maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE ); | |||
662 | // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name"); | |||
663 | ||||
664 | OUString aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL | |||
665 | ||||
666 | if ( !rBaseURL.isEmpty() ) | |||
667 | { | |||
668 | INetURLObject aObj( rBaseURL ); | |||
669 | if ( aObj.GetProtocol() == INetProtocol::File ) | |||
670 | { | |||
671 | aRealStorageName = aObj.PathToFileName(); | |||
672 | } | |||
673 | } | |||
674 | ||||
675 | xManagerStream->SetBufferSize( 1024 ); | |||
676 | xManagerStream->Seek( STREAM_SEEK_TO_BEGIN0L ); | |||
677 | ||||
678 | sal_uInt32 nEndPos; | |||
679 | xManagerStream->ReadUInt32( nEndPos ); | |||
680 | ||||
681 | sal_uInt16 nLibs; | |||
682 | xManagerStream->ReadUInt16( nLibs ); | |||
683 | // Plausibility! | |||
684 | if( nLibs & 0xF000 ) | |||
685 | { | |||
686 | SAL_WARN( "basic", "BasicManager-Stream defect!" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager-Stream defect!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "686" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "BasicManager-Stream defect!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager-Stream defect!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "686" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager-Stream defect!") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "686" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "BasicManager-Stream defect!"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager-Stream defect!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "686" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
687 | return; | |||
688 | } | |||
689 | const size_t nMinBasicLibSize(8); | |||
690 | const size_t nMaxPossibleLibs = xManagerStream->remainingSize() / nMinBasicLibSize; | |||
691 | if (nLibs > nMaxPossibleLibs) | |||
692 | { | |||
693 | SAL_WARN("basic", "Parsing error: " << nMaxPossibleLibs <<do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
694 | " max possible entries, but " << nLibs << " claimed, truncating")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs << " max possible entries, but " << nLibs << " claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "694" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
695 | nLibs = nMaxPossibleLibs; | |||
696 | } | |||
697 | for (sal_uInt16 nL = 0; nL < nLibs; ++nL) | |||
698 | { | |||
699 | BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream ); | |||
700 | ||||
701 | // Correct absolute pathname if relative is existing. | |||
702 | // Always try relative first if there are two stands on disk | |||
703 | if ( !pInfo->GetRelStorageName().isEmpty() && pInfo->GetRelStorageName() != szImbedded ) | |||
704 | { | |||
705 | INetURLObject aObj( aRealStorageName, INetProtocol::File ); | |||
706 | aObj.removeSegment(); | |||
707 | bool bWasAbsolute = false; | |||
708 | aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute ); | |||
709 | ||||
710 | //*** TODO: Replace if still necessary | |||
711 | //*** TODO-End | |||
712 | if ( ! mpImpl->aBasicLibPath.isEmpty() ) | |||
713 | { | |||
714 | // Search lib in path | |||
715 | OUString aSearchFile = pInfo->GetRelStorageName(); | |||
716 | OUString aSearchFileOldFormat(aSearchFile); | |||
717 | SvtPathOptions aPathCFG; | |||
718 | if( aPathCFG.SearchFile( aSearchFileOldFormat, SvtPathOptions::PATH_BASIC ) ) | |||
719 | { | |||
720 | pInfo->SetStorageName( aSearchFile ); | |||
721 | } | |||
722 | } | |||
723 | } | |||
724 | ||||
725 | mpImpl->aLibs.push_back(std::unique_ptr<BasicLibInfo>(pInfo)); | |||
726 | // Libs from external files should be loaded only when necessary. | |||
727 | // But references are loaded at once, otherwise some big customers get into trouble | |||
728 | if ( pInfo->DoLoad() && | |||
729 | ( !pInfo->IsExtern() || pInfo->IsReference())) | |||
730 | { | |||
731 | ImpLoadLibrary( pInfo, &rStorage ); | |||
732 | } | |||
733 | } | |||
734 | ||||
735 | xManagerStream->Seek( nEndPos ); | |||
736 | xManagerStream->SetBufferSize( 0 ); | |||
737 | xManagerStream.clear(); | |||
738 | } | |||
739 | ||||
740 | void BasicManager::LoadOldBasicManager( SotStorage& rStorage ) | |||
741 | { | |||
742 | tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( szOldManagerStream, eStreamReadMode ); | |||
743 | ||||
744 | OUString aStorName( rStorage.GetName() ); | |||
745 | DBG_ASSERT( aStorName.getLength(), "No Storage Name!" )do { if (true && (!(aStorName.getLength()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "745" ": "), "%s", "No Storage Name!"); } } while (false ); | |||
746 | ||||
747 | if ( !xManagerStream.is() || xManagerStream->GetError() || ( xManagerStream->TellEnd() == 0 ) ) | |||
748 | { | |||
749 | ImpMgrNotLoaded( aStorName ); | |||
750 | return; | |||
751 | } | |||
752 | ||||
753 | xManagerStream->SetBufferSize( 1024 ); | |||
754 | xManagerStream->Seek( STREAM_SEEK_TO_BEGIN0L ); | |||
755 | sal_uInt32 nBasicStartOff, nBasicEndOff; | |||
756 | xManagerStream->ReadUInt32( nBasicStartOff ); | |||
757 | xManagerStream->ReadUInt32( nBasicEndOff ); | |||
758 | ||||
759 | DBG_ASSERT( !xManagerStream->GetError(), "Invalid Manager-Stream!" )do { if (true && (!(!xManagerStream->GetError()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "759" ": "), "%s", "Invalid Manager-Stream!"); } } while (false); | |||
760 | ||||
761 | xManagerStream->Seek( nBasicStartOff ); | |||
762 | if (!ImplLoadBasic( *xManagerStream, mpImpl->aLibs.front()->GetLibRef() )) | |||
763 | { | |||
764 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), aStorName, DialogMask::ButtonsOk ); | |||
765 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENMGRSTREAM); | |||
766 | // and it proceeds ... | |||
767 | } | |||
768 | xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator | |||
769 | OUString aLibs = xManagerStream->ReadUniOrByteString(xManagerStream->GetStreamCharSet()); | |||
770 | xManagerStream->SetBufferSize( 0 ); | |||
771 | xManagerStream.clear(); // Close stream | |||
772 | ||||
773 | if ( aLibs.isEmpty() ) | |||
774 | return; | |||
775 | ||||
776 | INetURLObject aCurStorage( aStorName, INetProtocol::File ); | |||
777 | sal_Int32 nLibPos {0}; | |||
778 | do { | |||
779 | const OUString aLibInfo(aLibs.getToken(0, LIB_SEP0x01, nLibPos)); | |||
780 | sal_Int32 nInfoPos {0}; | |||
781 | const OUString aLibName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) ); | |||
782 | DBG_ASSERT( nInfoPos >= 0, "Invalid Lib-Info!" )do { if (true && (!(nInfoPos >= 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "782" ": "), "%s", "Invalid Lib-Info!"); } } while (false ); | |||
783 | const OUString aLibAbsStorageName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) ); | |||
784 | // TODO: fail also here if there are no more tokens? | |||
785 | const OUString aLibRelStorageName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) ); | |||
786 | DBG_ASSERT( nInfoPos < 0, "Invalid Lib-Info!" )do { if (true && (!(nInfoPos < 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "786" ": "), "%s", "Invalid Lib-Info!"); } } while (false ); | |||
787 | INetURLObject aLibAbsStorage( aLibAbsStorageName, INetProtocol::File ); | |||
788 | ||||
789 | INetURLObject aLibRelStorage( aStorName ); | |||
790 | aLibRelStorage.removeSegment(); | |||
791 | bool bWasAbsolute = false; | |||
792 | aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute); | |||
793 | DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" )do { if (true && (!(!bWasAbsolute))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "793" ": "), "%s", "RelStorageName was absolute!"); } } while (false); | |||
794 | ||||
795 | tools::SvRef<SotStorage> xStorageRef; | |||
796 | if ( aLibAbsStorage == aCurStorage || aLibRelStorageName == szImbedded ) | |||
797 | { | |||
798 | xStorageRef = &rStorage; | |||
799 | } | |||
800 | else | |||
801 | { | |||
802 | xStorageRef = new SotStorage( false, aLibAbsStorage.GetMainURL | |||
803 | ( INetURLObject::DecodeMechanism::NONE ), eStorageReadMode ); | |||
804 | if ( xStorageRef->GetError() != ERRCODE_NONEErrCode(0) ) | |||
805 | xStorageRef = new SotStorage( false, aLibRelStorage. | |||
806 | GetMainURL( INetURLObject::DecodeMechanism::NONE ), eStorageReadMode ); | |||
807 | } | |||
808 | if ( xStorageRef.is() ) | |||
809 | { | |||
810 | AddLib( *xStorageRef, aLibName, false ); | |||
811 | } | |||
812 | else | |||
813 | { | |||
814 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), aStorName, DialogMask::ButtonsOk ); | |||
815 | aErrors.emplace_back(*pErrInf, BasicErrorReason::STORAGENOTFOUND); | |||
816 | } | |||
817 | } while (nLibPos>=0); | |||
818 | } | |||
819 | ||||
820 | BasicManager::~BasicManager() | |||
821 | { | |||
822 | // Notify listener if something needs to be saved | |||
823 | Broadcast( SfxHint( SfxHintId::Dying) ); | |||
824 | } | |||
825 | ||||
826 | bool BasicManager::HasExeCode( const OUString& sLib ) | |||
827 | { | |||
828 | StarBASIC* pLib = GetLib(sLib); | |||
829 | if ( pLib ) | |||
830 | { | |||
831 | for (const auto& pModule: pLib->GetModules()) | |||
832 | { | |||
833 | if (pModule->HasExeCode()) | |||
834 | return true; | |||
835 | } | |||
836 | } | |||
837 | return false; | |||
838 | } | |||
839 | ||||
840 | void BasicManager::Init() | |||
841 | { | |||
842 | mpImpl.reset( new BasicManagerImpl ); | |||
843 | } | |||
844 | ||||
845 | BasicLibInfo* BasicManager::CreateLibInfo() | |||
846 | { | |||
847 | BasicLibInfo* pInf(new BasicLibInfo); | |||
848 | mpImpl->aLibs.push_back(std::unique_ptr<BasicLibInfo>(pInf)); | |||
849 | return pInf; | |||
850 | } | |||
851 | ||||
852 | bool BasicManager::ImpLoadLibrary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage ) | |||
853 | { | |||
854 | try { | |||
855 | DBG_ASSERT( pLibInfo, "LibInfo!?" )do { if (true && (!(pLibInfo))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "855" ": "), "%s", "LibInfo!?"); } } while (false); | |||
856 | ||||
857 | OUString aStorageName( pLibInfo->GetStorageName() ); | |||
858 | if ( aStorageName.isEmpty() || aStorageName == szImbedded ) | |||
859 | { | |||
860 | aStorageName = GetStorageName(); | |||
861 | } | |||
862 | tools::SvRef<SotStorage> xStorage; | |||
863 | // The current must not be opened again... | |||
864 | if ( pCurStorage ) | |||
865 | { | |||
866 | OUString aStorName( pCurStorage->GetName() ); | |||
867 | // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" ); | |||
868 | ||||
869 | INetURLObject aCurStorageEntry(aStorName, INetProtocol::File); | |||
870 | // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::DecodeMechanism::NONE ).Len() != 0, "Bad storage name"); | |||
871 | ||||
872 | INetURLObject aStorageEntry(aStorageName, INetProtocol::File); | |||
873 | // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::DecodeMechanism::NONE ).Len() != 0, "Bad storage name"); | |||
874 | ||||
875 | if ( aCurStorageEntry == aStorageEntry ) | |||
876 | { | |||
877 | xStorage = pCurStorage; | |||
878 | } | |||
879 | } | |||
880 | ||||
881 | if ( !xStorage.is() ) | |||
882 | { | |||
883 | xStorage = new SotStorage( false, aStorageName, eStorageReadMode ); | |||
884 | } | |||
885 | tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage( szBasicStorage, eStorageReadMode, false ); | |||
886 | ||||
887 | if ( !xBasicStorage.is() || xBasicStorage->GetError() ) | |||
888 | { | |||
889 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), xStorage->GetName(), DialogMask::ButtonsOk ); | |||
890 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTORAGE); | |||
891 | } | |||
892 | else | |||
893 | { | |||
894 | // In the Basic-Storage every lib is in a Stream... | |||
895 | tools::SvRef<SotStorageStream> xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode ); | |||
896 | if ( !xBasicStream.is() || xBasicStream->GetError() ) | |||
897 | { | |||
898 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124) , pLibInfo->GetLibName(), DialogMask::ButtonsOk ); | |||
899 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTREAM); | |||
900 | } | |||
901 | else | |||
902 | { | |||
903 | bool bLoaded = false; | |||
904 | if ( xBasicStream->TellEnd() != 0 ) | |||
905 | { | |||
906 | if ( !pLibInfo->GetLib().is() ) | |||
907 | { | |||
908 | pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) ); | |||
909 | } | |||
910 | xBasicStream->SetBufferSize( 1024 ); | |||
911 | xBasicStream->Seek( STREAM_SEEK_TO_BEGIN0L ); | |||
912 | bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() ); | |||
913 | xBasicStream->SetBufferSize( 0 ); | |||
914 | StarBASICRef xStdLib = pLibInfo->GetLib(); | |||
915 | xStdLib->SetName( pLibInfo->GetLibName() ); | |||
916 | xStdLib->SetModified( false ); | |||
917 | xStdLib->SetFlag( SbxFlagBits::DontStore ); | |||
918 | } | |||
919 | if ( !bLoaded ) | |||
920 | { | |||
921 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), pLibInfo->GetLibName(), DialogMask::ButtonsOk ); | |||
922 | aErrors.emplace_back(*pErrInf, BasicErrorReason::BASICLOADERROR); | |||
923 | } | |||
924 | else | |||
925 | { | |||
926 | // Perhaps there are additional information in the stream... | |||
927 | xBasicStream->SetCryptMaskKey(szCryptingKey); | |||
928 | xBasicStream->RefreshBuffer(); | |||
929 | sal_uInt32 nPasswordMarker = 0; | |||
930 | xBasicStream->ReadUInt32( nPasswordMarker ); | |||
931 | if ( ( nPasswordMarker == PASSWORD_MARKER0x31452134 ) && !xBasicStream->eof() ) | |||
932 | { | |||
933 | OUString aPassword = xBasicStream->ReadUniOrByteString( | |||
934 | xBasicStream->GetStreamCharSet()); | |||
935 | pLibInfo->SetPassword( aPassword ); | |||
936 | } | |||
937 | xBasicStream->SetCryptMaskKey(OString()); | |||
938 | CheckModules( pLibInfo->GetLib().get(), pLibInfo->IsReference() ); | |||
939 | } | |||
940 | return bLoaded; | |||
941 | } | |||
942 | } | |||
943 | } | |||
944 | catch (const css::ucb::ContentCreationException&) | |||
945 | { | |||
946 | } | |||
947 | return false; | |||
948 | } | |||
949 | ||||
950 | bool BasicManager::ImplEncryptStream( SvStream& rStrm ) | |||
951 | { | |||
952 | sal_uInt64 const nPos = rStrm.Tell(); | |||
953 | sal_uInt32 nCreator; | |||
954 | rStrm.ReadUInt32( nCreator ); | |||
955 | rStrm.Seek( nPos ); | |||
956 | bool bProtected = false; | |||
957 | if ( nCreator != SBXCR_SBX ) | |||
958 | { | |||
959 | // Should only be the case for encrypted Streams | |||
960 | bProtected = true; | |||
961 | rStrm.SetCryptMaskKey(szCryptingKey); | |||
962 | rStrm.RefreshBuffer(); | |||
963 | } | |||
964 | return bProtected; | |||
965 | } | |||
966 | ||||
967 | // This code is necessary to load the BASIC of Beta 1 | |||
968 | // TODO: Which Beta 1? | |||
969 | bool BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const | |||
970 | { | |||
971 | bool bProtected = ImplEncryptStream( rStrm ); | |||
972 | SbxBaseRef xNew = SbxBase::Load( rStrm ); | |||
973 | bool bLoaded = false; | |||
974 | if( xNew.is() ) | |||
975 | { | |||
976 | if( auto pNew = dynamic_cast<StarBASIC*>( xNew.get() ) ) | |||
977 | { | |||
978 | // Use the Parent of the old BASICs | |||
979 | if( rOldBasic.is() ) | |||
980 | { | |||
981 | pNew->SetParent( rOldBasic->GetParent() ); | |||
982 | if( pNew->GetParent() ) | |||
983 | { | |||
984 | pNew->GetParent()->Insert( pNew ); | |||
985 | } | |||
986 | pNew->SetFlag( SbxFlagBits::ExtSearch ); | |||
987 | } | |||
988 | rOldBasic = pNew; | |||
989 | ||||
990 | // Fill new library container (5.2 -> 6.0) | |||
991 | copyToLibraryContainer( pNew, mpImpl->maContainerInfo ); | |||
992 | ||||
993 | pNew->SetModified( false ); | |||
994 | bLoaded = true; | |||
995 | } | |||
996 | } | |||
997 | if ( bProtected ) | |||
998 | { | |||
999 | rStrm.SetCryptMaskKey(OString()); | |||
1000 | } | |||
1001 | return bLoaded; | |||
1002 | } | |||
1003 | ||||
1004 | void BasicManager::CheckModules( StarBASIC* pLib, bool bReference ) | |||
1005 | { | |||
1006 | if ( !pLib ) | |||
1007 | { | |||
1008 | return; | |||
1009 | } | |||
1010 | bool bModified = pLib->IsModified(); | |||
1011 | ||||
1012 | for ( const auto& pModule: pLib->GetModules() ) | |||
1013 | { | |||
1014 | DBG_ASSERT(pModule, "Module not received!")do { if (true && (!(pModule))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1014" ": "), "%s", "Module not received!"); } } while ( false); | |||
1015 | if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() ) | |||
1016 | { | |||
1017 | pModule->Compile(); | |||
1018 | } | |||
1019 | } | |||
1020 | ||||
1021 | // #67477, AB 8.12.99 On demand compile in referenced libs should not | |||
1022 | // cause modified | |||
1023 | if( !bModified && bReference ) | |||
1024 | { | |||
1025 | OSL_FAIL( "Referenced basic library is not compiled!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1025" ": "), "%s", "Referenced basic library is not compiled!" ); } } while (false); | |||
1026 | pLib->SetModified( false ); | |||
1027 | } | |||
1028 | } | |||
1029 | ||||
1030 | StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const OUString& rLibName, bool bReference ) | |||
1031 | { | |||
1032 | OUString aStorName( rStorage.GetName() ); | |||
1033 | DBG_ASSERT( !aStorName.isEmpty(), "No Storage Name!" )do { if (true && (!(!aStorName.isEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1033" ": "), "%s", "No Storage Name!"); } } while (false ); | |||
1034 | ||||
1035 | OUString aStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE ); | |||
1036 | DBG_ASSERT(!aStorageName.isEmpty(), "Bad storage name")do { if (true && (!(!aStorageName.isEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1036" ": "), "%s", "Bad storage name"); } } while (false ); | |||
1037 | ||||
1038 | OUString aNewLibName( rLibName ); | |||
1039 | while ( HasLib( aNewLibName ) ) | |||
1040 | { | |||
1041 | aNewLibName += "_"; | |||
1042 | } | |||
1043 | BasicLibInfo* pLibInfo = CreateLibInfo(); | |||
1044 | // Use original name otherwise ImpLoadLibrary fails... | |||
1045 | pLibInfo->SetLibName( rLibName ); | |||
1046 | // but doesn't work this way if name exists twice | |||
1047 | sal_uInt16 nLibId = static_cast<sal_uInt16>(mpImpl->aLibs.size()) - 1; | |||
1048 | ||||
1049 | // Set StorageName before load because it is compared with pCurStorage | |||
1050 | pLibInfo->SetStorageName( aStorageName ); | |||
1051 | bool bLoaded = ImpLoadLibrary( pLibInfo, &rStorage ); | |||
1052 | ||||
1053 | if ( bLoaded ) | |||
1054 | { | |||
1055 | if ( aNewLibName != rLibName ) | |||
1056 | { | |||
1057 | pLibInfo->SetLibName(aNewLibName); | |||
1058 | } | |||
1059 | if ( bReference ) | |||
1060 | { | |||
1061 | pLibInfo->GetLib()->SetModified( false ); // Don't save in this case | |||
1062 | pLibInfo->SetRelStorageName( OUString() ); | |||
1063 | pLibInfo->SetReference(true); | |||
1064 | } | |||
1065 | else | |||
1066 | { | |||
1067 | pLibInfo->GetLib()->SetModified( true ); // Must be saved after Add! | |||
1068 | pLibInfo->SetStorageName( szImbedded ); // Save in BasicManager-Storage | |||
1069 | } | |||
1070 | } | |||
1071 | else | |||
1072 | { | |||
1073 | RemoveLib( nLibId, false ); | |||
1074 | pLibInfo = nullptr; | |||
1075 | } | |||
1076 | ||||
1077 | return pLibInfo ? &*pLibInfo->GetLib() : nullptr; | |||
1078 | ||||
1079 | } | |||
1080 | ||||
1081 | bool BasicManager::IsReference( sal_uInt16 nLib ) | |||
1082 | { | |||
1083 | DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" )do { if (true && (!(nLib < mpImpl->aLibs.size() ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1083" ": "), "%s", "Lib does not exist!"); } } while (false ); | |||
1084 | if ( nLib < mpImpl->aLibs.size() ) | |||
1085 | { | |||
1086 | return mpImpl->aLibs[nLib]->IsReference(); | |||
1087 | } | |||
1088 | return false; | |||
1089 | } | |||
1090 | ||||
1091 | void BasicManager::RemoveLib( sal_uInt16 nLib ) | |||
1092 | { | |||
1093 | // Only physical deletion if no reference | |||
1094 | RemoveLib( nLib, !IsReference( nLib ) ); | |||
1095 | } | |||
1096 | ||||
1097 | bool BasicManager::RemoveLib( sal_uInt16 nLib, bool bDelBasicFromStorage ) | |||
1098 | { | |||
1099 | DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" )do { if (true && (!(nLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1099" ": "), "%s", "Standard-Lib cannot be removed!"); } } while (false); | |||
1100 | ||||
1101 | DBG_ASSERT( !nLib || nLib < mpImpl->aLibs.size(), "Lib not found!" )do { if (true && (!(!nLib || nLib < mpImpl->aLibs .size()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN) , ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1101" ": "), "%s", "Lib not found!"); } } while (false); | |||
1102 | ||||
1103 | if( !nLib || nLib < mpImpl->aLibs.size() ) | |||
1104 | { | |||
1105 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIBErrCode( ErrCodeArea::Sbx, 130), OUString(), DialogMask::ButtonsOk ); | |||
1106 | aErrors.emplace_back(*pErrInf, BasicErrorReason::STDLIB); | |||
1107 | return false; | |||
1108 | } | |||
1109 | ||||
1110 | auto const itLibInfo = mpImpl->aLibs.begin() + nLib; | |||
1111 | ||||
1112 | // If one of the streams cannot be opened, this is not an error, | |||
1113 | // because BASIC was never written before... | |||
1114 | if (bDelBasicFromStorage && !(*itLibInfo)->IsReference() && | |||
1115 | (!(*itLibInfo)->IsExtern() || SotStorage::IsStorageFile((*itLibInfo)->GetStorageName()))) | |||
1116 | { | |||
1117 | tools::SvRef<SotStorage> xStorage; | |||
1118 | try | |||
1119 | { | |||
1120 | if (!(*itLibInfo)->IsExtern()) | |||
1121 | { | |||
1122 | xStorage = new SotStorage(false, GetStorageName()); | |||
1123 | } | |||
1124 | else | |||
1125 | { | |||
1126 | xStorage = new SotStorage(false, (*itLibInfo)->GetStorageName()); | |||
1127 | } | |||
1128 | } | |||
1129 | catch (const css::ucb::ContentCreationException&) | |||
1130 | { | |||
1131 | TOOLS_WARN_EXCEPTION("basic", "BasicManager::RemoveLib:")do { css::uno::Any tools_warn_exception( DbgGetCaughtException () ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1131" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "BasicManager::RemoveLib:" << " " << exceptionToString(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1131" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1131" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "BasicManager::RemoveLib:" << " " << exceptionToString(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1131" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); } while (false); | |||
1132 | } | |||
1133 | ||||
1134 | if (xStorage.is() && xStorage->IsStorage(szBasicStorage)) | |||
1135 | { | |||
1136 | tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage | |||
1137 | ( szBasicStorage, StreamMode::STD_READWRITE, false ); | |||
1138 | ||||
1139 | if ( !xBasicStorage.is() || xBasicStorage->GetError() ) | |||
1140 | { | |||
1141 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIBErrCode( ErrCodeArea::Sbx, 130), OUString(), DialogMask::ButtonsOk ); | |||
1142 | aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTORAGE); | |||
1143 | } | |||
1144 | else if (xBasicStorage->IsStream((*itLibInfo)->GetLibName())) | |||
1145 | { | |||
1146 | xBasicStorage->Remove((*itLibInfo)->GetLibName()); | |||
1147 | xBasicStorage->Commit(); | |||
1148 | ||||
1149 | // If no further stream available, | |||
1150 | // delete the SubStorage. | |||
1151 | SvStorageInfoList aInfoList; | |||
1152 | xBasicStorage->FillInfoList( &aInfoList ); | |||
1153 | if ( aInfoList.empty() ) | |||
1154 | { | |||
1155 | xBasicStorage.clear(); | |||
1156 | xStorage->Remove( szBasicStorage ); | |||
1157 | xStorage->Commit(); | |||
1158 | // If no further Streams or SubStorages available, | |||
1159 | // delete the Storage, too. | |||
1160 | aInfoList.clear(); | |||
1161 | xStorage->FillInfoList( &aInfoList ); | |||
1162 | if ( aInfoList.empty() ) | |||
1163 | { | |||
1164 | //OUString aName_( xStorage->GetName() ); | |||
1165 | xStorage.clear(); | |||
1166 | //*** TODO: Replace if still necessary | |||
1167 | //SfxContentHelper::Kill( aName ); | |||
1168 | //*** TODO-End | |||
1169 | } | |||
1170 | } | |||
1171 | } | |||
1172 | } | |||
1173 | } | |||
1174 | if ((*itLibInfo)->GetLib().is()) | |||
1175 | { | |||
1176 | GetStdLib()->Remove( (*itLibInfo)->GetLib().get() ); | |||
1177 | } | |||
1178 | mpImpl->aLibs.erase(itLibInfo); | |||
1179 | return true; // Remove was successful, del unimportant | |||
1180 | } | |||
1181 | ||||
1182 | sal_uInt16 BasicManager::GetLibCount() const | |||
1183 | { | |||
1184 | return static_cast<sal_uInt16>(mpImpl->aLibs.size()); | |||
1185 | } | |||
1186 | ||||
1187 | StarBASIC* BasicManager::GetLib( sal_uInt16 nLib ) const | |||
1188 | { | |||
1189 | DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" )do { if (true && (!(nLib < mpImpl->aLibs.size() ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1189" ": "), "%s", "Lib does not exist!"); } } while (false ); | |||
1190 | if ( nLib < mpImpl->aLibs.size() ) | |||
1191 | { | |||
1192 | return mpImpl->aLibs[nLib]->GetLib().get(); | |||
1193 | } | |||
1194 | return nullptr; | |||
1195 | } | |||
1196 | ||||
1197 | StarBASIC* BasicManager::GetStdLib() const | |||
1198 | { | |||
1199 | StarBASIC* pLib = GetLib( 0 ); | |||
1200 | return pLib; | |||
1201 | } | |||
1202 | ||||
1203 | StarBASIC* BasicManager::GetLib( const OUString& rName ) const | |||
1204 | { | |||
1205 | for (auto const& rpLib : mpImpl->aLibs) | |||
1206 | { | |||
1207 | if (rpLib->GetLibName().equalsIgnoreAsciiCase(rName)) // Check if available... | |||
1208 | { | |||
1209 | return rpLib->GetLib().get(); | |||
1210 | } | |||
1211 | } | |||
1212 | return nullptr; | |||
1213 | } | |||
1214 | ||||
1215 | sal_uInt16 BasicManager::GetLibId( const OUString& rName ) const | |||
1216 | { | |||
1217 | for (size_t i = 0; i < mpImpl->aLibs.size(); i++) | |||
1218 | { | |||
1219 | if (mpImpl->aLibs[i]->GetLibName().equalsIgnoreAsciiCase( rName )) | |||
1220 | { | |||
1221 | return static_cast<sal_uInt16>(i); | |||
1222 | } | |||
1223 | } | |||
1224 | return LIB_NOTFOUND0xFFFF; | |||
1225 | } | |||
1226 | ||||
1227 | bool BasicManager::HasLib( const OUString& rName ) const | |||
1228 | { | |||
1229 | for (const auto& rpLib : mpImpl->aLibs) | |||
1230 | { | |||
1231 | if (rpLib->GetLibName().equalsIgnoreAsciiCase(rName)) // Check if available... | |||
1232 | { | |||
1233 | return true; | |||
1234 | } | |||
1235 | } | |||
1236 | return false; | |||
1237 | } | |||
1238 | ||||
1239 | OUString BasicManager::GetLibName( sal_uInt16 nLib ) | |||
1240 | { | |||
1241 | DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib?!" )do { if (true && (!(nLib < mpImpl->aLibs.size() ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1241" ": "), "%s", "Lib?!"); } } while (false); | |||
1242 | if ( nLib < mpImpl->aLibs.size() ) | |||
1243 | { | |||
1244 | return mpImpl->aLibs[nLib]->GetLibName(); | |||
1245 | } | |||
1246 | return OUString(); | |||
1247 | } | |||
1248 | ||||
1249 | bool BasicManager::LoadLib( sal_uInt16 nLib ) | |||
1250 | { | |||
1251 | bool bDone = false; | |||
1252 | DBG_ASSERT( nLib < mpImpl->aLibs.size() , "Lib?!" )do { if (true && (!(nLib < mpImpl->aLibs.size() ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1252" ": "), "%s", "Lib?!"); } } while (false); | |||
1253 | if ( nLib < mpImpl->aLibs.size() ) | |||
1254 | { | |||
1255 | BasicLibInfo& rLibInfo = *mpImpl->aLibs[nLib]; | |||
1256 | uno::Reference< script::XLibraryContainer > xLibContainer = rLibInfo.GetLibraryContainer(); | |||
1257 | if( xLibContainer.is() ) | |||
1258 | { | |||
1259 | OUString aLibName = rLibInfo.GetLibName(); | |||
1260 | xLibContainer->loadLibrary( aLibName ); | |||
1261 | bDone = xLibContainer->isLibraryLoaded( aLibName ); | |||
1262 | } | |||
1263 | else | |||
1264 | { | |||
1265 | bDone = ImpLoadLibrary( &rLibInfo, nullptr ); | |||
1266 | StarBASIC* pLib = GetLib( nLib ); | |||
1267 | if ( pLib ) | |||
1268 | { | |||
1269 | GetStdLib()->Insert( pLib ); | |||
1270 | pLib->SetFlag( SbxFlagBits::ExtSearch ); | |||
1271 | } | |||
1272 | } | |||
1273 | } | |||
1274 | else | |||
1275 | { | |||
1276 | StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), OUString(), DialogMask::ButtonsOk ); | |||
1277 | aErrors.emplace_back(*pErrInf, BasicErrorReason::LIBNOTFOUND); | |||
1278 | } | |||
1279 | return bDone; | |||
1280 | } | |||
1281 | ||||
1282 | StarBASIC* BasicManager::CreateLib( const OUString& rLibName ) | |||
1283 | { | |||
1284 | if ( GetLib( rLibName ) ) | |||
1285 | { | |||
1286 | return nullptr; | |||
1287 | } | |||
1288 | BasicLibInfo* pLibInfo = CreateLibInfo(); | |||
1289 | StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr ); | |||
1290 | GetStdLib()->Insert( pNew ); | |||
1291 | pNew->SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::DontStore ); | |||
1292 | pLibInfo->SetLib( pNew ); | |||
1293 | pLibInfo->SetLibName( rLibName ); | |||
1294 | pLibInfo->GetLib()->SetName( rLibName ); | |||
1295 | return pLibInfo->GetLib().get(); | |||
1296 | } | |||
1297 | ||||
1298 | // For XML import/export: | |||
1299 | StarBASIC* BasicManager::CreateLib( const OUString& rLibName, const OUString& Password, | |||
1300 | const OUString& LinkTargetURL ) | |||
1301 | { | |||
1302 | // Ask if lib exists because standard lib is always there | |||
1303 | StarBASIC* pLib = GetLib( rLibName ); | |||
1304 | if( !pLib ) | |||
1305 | { | |||
1306 | if( !LinkTargetURL.isEmpty()) | |||
1307 | { | |||
1308 | try | |||
1309 | { | |||
1310 | tools::SvRef<SotStorage> xStorage = new SotStorage(false, LinkTargetURL, StreamMode::READ | StreamMode::SHARE_DENYWRITE); | |||
1311 | if (!xStorage->GetError()) | |||
1312 | { | |||
1313 | pLib = AddLib(*xStorage, rLibName, true); | |||
1314 | } | |||
1315 | } | |||
1316 | catch (const css::ucb::ContentCreationException&) | |||
1317 | { | |||
1318 | TOOLS_WARN_EXCEPTION("basic", "BasicManager::RemoveLib:")do { css::uno::Any tools_warn_exception( DbgGetCaughtException () ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1318" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "BasicManager::RemoveLib:" << " " << exceptionToString(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1318" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1318" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "BasicManager::RemoveLib:" << " " << exceptionToString(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "BasicManager::RemoveLib:" << " " << exceptionToString (tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1318" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); } while (false); | |||
1319 | } | |||
1320 | DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1320" ": "), "%s", "XML Import: Linked basic library could not be loaded" ); } } while (false); | |||
1321 | } | |||
1322 | else | |||
1323 | { | |||
1324 | pLib = CreateLib( rLibName ); | |||
1325 | if( Password.isEmpty()) | |||
1326 | { | |||
1327 | BasicLibInfo* pLibInfo = FindLibInfo( pLib ); | |||
1328 | pLibInfo ->SetPassword( Password ); | |||
1329 | } | |||
1330 | } | |||
1331 | //ExternalSourceURL ? | |||
1332 | } | |||
1333 | return pLib; | |||
1334 | } | |||
1335 | ||||
1336 | StarBASIC* BasicManager::CreateLibForLibContainer( const OUString& rLibName, | |||
1337 | const uno::Reference< script::XLibraryContainer >& xScriptCont ) | |||
1338 | { | |||
1339 | if ( GetLib( rLibName ) ) | |||
1340 | { | |||
1341 | return nullptr; | |||
1342 | } | |||
1343 | BasicLibInfo* pLibInfo = CreateLibInfo(); | |||
1344 | StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr ); | |||
1345 | GetStdLib()->Insert( pNew ); | |||
1346 | pNew->SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::DontStore ); | |||
1347 | pLibInfo->SetLib( pNew ); | |||
1348 | pLibInfo->SetLibName( rLibName ); | |||
1349 | pLibInfo->GetLib()->SetName( rLibName ); | |||
1350 | pLibInfo->SetLibraryContainer( xScriptCont ); | |||
1351 | return pNew; | |||
1352 | } | |||
1353 | ||||
1354 | ||||
1355 | BasicLibInfo* BasicManager::FindLibInfo( StarBASIC const * pBasic ) | |||
1356 | { | |||
1357 | for (auto const& rpLib : mpImpl->aLibs) | |||
1358 | { | |||
1359 | if (rpLib->GetLib().get() == pBasic) | |||
1360 | { | |||
1361 | return rpLib.get(); | |||
1362 | } | |||
1363 | } | |||
1364 | return nullptr; | |||
1365 | } | |||
1366 | ||||
1367 | ||||
1368 | bool BasicManager::IsBasicModified() const | |||
1369 | { | |||
1370 | for (auto const& rpLib : mpImpl->aLibs) | |||
1371 | { | |||
1372 | if (rpLib->GetLib().is() && rpLib->GetLib()->IsModified()) | |||
1373 | { | |||
1374 | return true; | |||
1375 | } | |||
1376 | } | |||
1377 | return false; | |||
1378 | } | |||
1379 | ||||
1380 | ||||
1381 | bool BasicManager::GetGlobalUNOConstant( const OUString& rName, uno::Any& aOut ) | |||
1382 | { | |||
1383 | bool bRes = false; | |||
1384 | StarBASIC* pStandardLib = GetStdLib(); | |||
1385 | OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" )do { if (true && (!(pStandardLib))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1385" ": "), "%s", "BasicManager::GetGlobalUNOConstant: no lib to read from!" ); } } while (false); | |||
1386 | if ( pStandardLib ) | |||
1387 | bRes = pStandardLib->GetUNOConstant( rName, aOut ); | |||
1388 | return bRes; | |||
1389 | } | |||
1390 | ||||
1391 | uno::Any BasicManager::SetGlobalUNOConstant( const OUString& rName, const uno::Any& _rValue ) | |||
1392 | { | |||
1393 | uno::Any aOldValue; | |||
1394 | ||||
1395 | StarBASIC* pStandardLib = GetStdLib(); | |||
1396 | OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" )do { if (true && (!(pStandardLib))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1396" ": "), "%s", "BasicManager::SetGlobalUNOConstant: no lib to insert into!" ); } } while (false); | |||
1397 | if ( !pStandardLib ) | |||
1398 | return aOldValue; | |||
1399 | ||||
1400 | // obtain the old value | |||
1401 | SbxVariable* pVariable = pStandardLib->Find( rName, SbxClassType::Object ); | |||
1402 | if ( pVariable ) | |||
1403 | aOldValue = sbxToUnoValue( pVariable ); | |||
1404 | SbxObjectRef xUnoObj = GetSbUnoObject( _rValue.getValueType ().getTypeName () , _rValue ); | |||
1405 | xUnoObj->SetName(rName); | |||
1406 | xUnoObj->SetFlag( SbxFlagBits::DontStore ); | |||
1407 | pStandardLib->Insert( xUnoObj.get() ); | |||
1408 | ||||
1409 | return aOldValue; | |||
1410 | } | |||
1411 | ||||
1412 | bool BasicManager::LegacyPsswdBinaryLimitExceeded( std::vector< OUString >& _out_rModuleNames ) | |||
1413 | { | |||
1414 | try | |||
1415 | { | |||
1416 | uno::Reference< container::XNameAccess > xScripts( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW ); | |||
1417 | uno::Reference< script::XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW ); | |||
1418 | ||||
1419 | const uno::Sequence< OUString > aNames( xScripts->getElementNames() ); | |||
1420 | for ( auto const & scriptElementName : aNames ) | |||
1421 | { | |||
1422 | if( !xPassword->isLibraryPasswordProtected( scriptElementName ) ) | |||
1423 | continue; | |||
1424 | ||||
1425 | StarBASIC* pBasicLib = GetLib( scriptElementName ); | |||
1426 | if ( !pBasicLib ) | |||
1427 | continue; | |||
1428 | ||||
1429 | uno::Reference< container::XNameAccess > xScriptLibrary( xScripts->getByName( scriptElementName ), uno::UNO_QUERY_THROW ); | |||
1430 | const uno::Sequence< OUString > aElementNames( xScriptLibrary->getElementNames() ); | |||
1431 | sal_Int32 nLen = aElementNames.getLength(); | |||
1432 | ||||
1433 | std::vector< OUString > aBigModules( nLen ); | |||
1434 | sal_Int32 nBigModules = 0; | |||
1435 | ||||
1436 | for ( auto const & libraryElementName : aElementNames ) | |||
1437 | { | |||
1438 | SbModule* pMod = pBasicLib->FindModule( libraryElementName ); | |||
1439 | if ( pMod && pMod->ExceedsLegacyModuleSize() ) | |||
1440 | aBigModules[ nBigModules++ ] = libraryElementName; | |||
1441 | } | |||
1442 | ||||
1443 | if ( nBigModules ) | |||
1444 | { | |||
1445 | _out_rModuleNames.swap(aBigModules); | |||
1446 | return true; | |||
1447 | } | |||
1448 | } | |||
1449 | } | |||
1450 | catch( const uno::Exception& ) | |||
1451 | { | |||
1452 | DBG_UNHANDLED_EXCEPTION("basic")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "1452" ": ", "basic" );; | |||
1453 | } | |||
1454 | return false; | |||
1455 | } | |||
1456 | ||||
1457 | ||||
1458 | namespace | |||
1459 | { | |||
1460 | SbMethod* lcl_queryMacro( BasicManager* i_manager, OUString const& i_fullyQualifiedName ) | |||
1461 | { | |||
1462 | sal_Int32 nLast = 0; | |||
1463 | const OUString sLibName {i_fullyQualifiedName.getToken( 0, '.', nLast )}; | |||
1464 | const OUString sModule {i_fullyQualifiedName.getToken( 0, '.', nLast )}; | |||
1465 | OUString sMacro; | |||
1466 | if(nLast >= 0) | |||
1467 | { | |||
1468 | sMacro = i_fullyQualifiedName.copy(nLast); | |||
1469 | } | |||
1470 | else | |||
1471 | { | |||
1472 | sMacro = i_fullyQualifiedName; | |||
1473 | } | |||
1474 | ||||
1475 | utl::TransliterationWrapper& rTransliteration = SbGlobal::GetTransliteration(); | |||
1476 | sal_uInt16 nLibCount = i_manager->GetLibCount(); | |||
1477 | for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib ) | |||
1478 | { | |||
1479 | if ( rTransliteration.isEqual( i_manager->GetLibName( nLib ), sLibName ) ) | |||
1480 | { | |||
1481 | StarBASIC* pLib = i_manager->GetLib( nLib ); | |||
1482 | if( !pLib ) | |||
1483 | { | |||
1484 | bool const bLoaded = i_manager->LoadLib( nLib ); | |||
1485 | if (bLoaded) | |||
1486 | { | |||
1487 | pLib = i_manager->GetLib( nLib ); | |||
1488 | } | |||
1489 | } | |||
1490 | ||||
1491 | if( pLib ) | |||
1492 | { | |||
1493 | for ( const auto& pMod: pLib->GetModules() ) | |||
1494 | { | |||
1495 | if ( rTransliteration.isEqual( pMod->GetName(), sModule ) ) | |||
1496 | { | |||
1497 | SbMethod* pMethod = static_cast<SbMethod*>(pMod->Find( sMacro, SbxClassType::Method )); | |||
1498 | if( pMethod ) | |||
1499 | { | |||
1500 | return pMethod; | |||
1501 | } | |||
1502 | } | |||
1503 | } | |||
1504 | } | |||
1505 | } | |||
1506 | } | |||
1507 | return nullptr; | |||
1508 | } | |||
1509 | } | |||
1510 | ||||
1511 | bool BasicManager::HasMacro( OUString const& i_fullyQualifiedName ) const | |||
1512 | { | |||
1513 | return ( lcl_queryMacro( const_cast< BasicManager* >( this ), i_fullyQualifiedName ) != nullptr ); | |||
1514 | } | |||
1515 | ||||
1516 | ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, SbxArray* i_arguments, SbxValue* i_retValue ) | |||
1517 | { | |||
1518 | SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName ); | |||
1519 | ErrCode nError = ERRCODE_NONEErrCode(0); | |||
1520 | if ( pMethod ) | |||
1521 | { | |||
1522 | if ( i_arguments ) | |||
1523 | pMethod->SetParameters( i_arguments ); | |||
1524 | nError = pMethod->Call( i_retValue ); | |||
1525 | } | |||
1526 | else | |||
1527 | nError = ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8); | |||
1528 | return nError; | |||
1529 | } | |||
1530 | ||||
1531 | ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, OUString const& i_commaSeparatedArgs, SbxValue* i_retValue ) | |||
1532 | { | |||
1533 | SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName ); | |||
1534 | if ( !pMethod ) | |||
1535 | { | |||
1536 | return ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8); | |||
1537 | } | |||
1538 | // arguments must be quoted | |||
1539 | OUString sQuotedArgs; | |||
1540 | OUStringBuffer sArgs( i_commaSeparatedArgs ); | |||
1541 | if ( sArgs.getLength()<2 || sArgs[1] == '\"') | |||
1542 | { | |||
1543 | // no args or already quoted args | |||
1544 | sQuotedArgs = sArgs.makeStringAndClear(); | |||
1545 | } | |||
1546 | else | |||
1547 | { | |||
1548 | // quote parameters | |||
1549 | sArgs.remove( 0, 1 ); | |||
1550 | sArgs.remove( sArgs.getLength() - 1, 1 ); | |||
1551 | ||||
1552 | OUStringBuffer aBuff; | |||
1553 | OUString sArgs2 = sArgs.makeStringAndClear(); | |||
1554 | ||||
1555 | aBuff.append("("); | |||
1556 | if (!sArgs2.isEmpty()) | |||
1557 | { | |||
1558 | ||||
1559 | sal_Int32 nPos {0}; | |||
1560 | for (;;) | |||
1561 | { | |||
1562 | aBuff.append( "\"" ); | |||
1563 | aBuff.append( sArgs2.getToken(0, ',', nPos) ); | |||
1564 | aBuff.append( "\"" ); | |||
1565 | if (nPos<0) | |||
1566 | break; | |||
1567 | aBuff.append( "," ); | |||
1568 | } | |||
1569 | } | |||
1570 | aBuff.append( ")" ); | |||
1571 | ||||
1572 | sQuotedArgs = aBuff.makeStringAndClear(); | |||
1573 | } | |||
1574 | ||||
1575 | // add quoted arguments and do the call | |||
1576 | OUString sCall = "[" | |||
1577 | + pMethod->GetName() | |||
1578 | + sQuotedArgs | |||
1579 | + "]"; | |||
1580 | ||||
1581 | SbxVariable* pRet = pMethod->GetParent()->Execute( sCall ); | |||
1582 | if ( pRet && ( pRet != pMethod ) ) | |||
1583 | { | |||
1584 | *i_retValue = *pRet; | |||
1585 | } | |||
1586 | return SbxBase::GetError(); | |||
1587 | } | |||
1588 | ||||
1589 | namespace { | |||
1590 | ||||
1591 | class ModuleInfo_Impl : public ModuleInfoHelper | |||
1592 | { | |||
1593 | OUString maName; | |||
1594 | OUString maLanguage; | |||
1595 | OUString maSource; | |||
1596 | ||||
1597 | public: | |||
1598 | ModuleInfo_Impl( const OUString& aName, const OUString& aLanguage, const OUString& aSource ) | |||
1599 | : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {} | |||
1600 | ||||
1601 | // Methods XStarBasicModuleInfo | |||
1602 | virtual OUString SAL_CALL getName() override | |||
1603 | { return maName; } | |||
1604 | virtual OUString SAL_CALL getLanguage() override | |||
1605 | { return maLanguage; } | |||
1606 | virtual OUString SAL_CALL getSource() override | |||
1607 | { return maSource; } | |||
1608 | }; | |||
1609 | ||||
1610 | ||||
1611 | class DialogInfo_Impl : public WeakImplHelper< script::XStarBasicDialogInfo > | |||
1612 | { | |||
1613 | OUString maName; | |||
1614 | uno::Sequence< sal_Int8 > mData; | |||
1615 | ||||
1616 | public: | |||
1617 | DialogInfo_Impl( const OUString& aName, const uno::Sequence< sal_Int8 >& Data ) | |||
1618 | : maName( aName ), mData( Data ) {} | |||
1619 | ||||
1620 | // Methods XStarBasicDialogInfo | |||
1621 | virtual OUString SAL_CALL getName() override | |||
1622 | { return maName; } | |||
1623 | virtual uno::Sequence< sal_Int8 > SAL_CALL getData() override | |||
1624 | { return mData; } | |||
1625 | }; | |||
1626 | ||||
1627 | ||||
1628 | class LibraryInfo_Impl : public WeakImplHelper< script::XStarBasicLibraryInfo > | |||
1629 | { | |||
1630 | OUString maName; | |||
1631 | uno::Reference< container::XNameContainer > mxModuleContainer; | |||
1632 | uno::Reference< container::XNameContainer > mxDialogContainer; | |||
1633 | OUString maPassword; | |||
1634 | OUString maExternaleSourceURL; | |||
1635 | OUString maLinkTargetURL; | |||
1636 | ||||
1637 | public: | |||
1638 | LibraryInfo_Impl | |||
1639 | ( | |||
1640 | const OUString& aName, | |||
1641 | uno::Reference< container::XNameContainer > const & xModuleContainer, | |||
1642 | uno::Reference< container::XNameContainer > const & xDialogContainer, | |||
1643 | const OUString& aPassword, | |||
1644 | const OUString& aExternaleSourceURL, | |||
1645 | const OUString& aLinkTargetURL | |||
1646 | ) | |||
1647 | : maName( aName ) | |||
1648 | , mxModuleContainer( xModuleContainer ) | |||
1649 | , mxDialogContainer( xDialogContainer ) | |||
1650 | , maPassword( aPassword ) | |||
1651 | , maExternaleSourceURL( aExternaleSourceURL ) | |||
1652 | , maLinkTargetURL( aLinkTargetURL ) | |||
1653 | {} | |||
1654 | ||||
1655 | // Methods XStarBasicLibraryInfo | |||
1656 | virtual OUString SAL_CALL getName() override | |||
1657 | { return maName; } | |||
1658 | virtual uno::Reference< container::XNameContainer > SAL_CALL getModuleContainer() override | |||
1659 | { return mxModuleContainer; } | |||
1660 | virtual uno::Reference< container::XNameContainer > SAL_CALL getDialogContainer() override | |||
1661 | { return mxDialogContainer; } | |||
1662 | virtual OUString SAL_CALL getPassword() override | |||
1663 | { return maPassword; } | |||
1664 | virtual OUString SAL_CALL getExternalSourceURL() override | |||
1665 | { return maExternaleSourceURL; } | |||
1666 | virtual OUString SAL_CALL getLinkTargetURL() override | |||
1667 | { return maLinkTargetURL; } | |||
1668 | }; | |||
1669 | ||||
1670 | ||||
1671 | class ModuleContainer_Impl : public NameContainerHelper | |||
1672 | { | |||
1673 | StarBASIC* mpLib; | |||
1674 | ||||
1675 | public: | |||
1676 | explicit ModuleContainer_Impl( StarBASIC* pLib ) | |||
1677 | :mpLib( pLib ) {} | |||
1678 | ||||
1679 | // Methods XElementAccess | |||
1680 | virtual uno::Type SAL_CALL getElementType() override; | |||
1681 | virtual sal_Bool SAL_CALL hasElements() override; | |||
1682 | ||||
1683 | // Methods XNameAccess | |||
1684 | virtual uno::Any SAL_CALL getByName( const OUString& aName ) override; | |||
1685 | virtual uno::Sequence< OUString > SAL_CALL getElementNames() override; | |||
1686 | virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; | |||
1687 | ||||
1688 | // Methods XNameReplace | |||
1689 | virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override; | |||
1690 | ||||
1691 | // Methods XNameContainer | |||
1692 | virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override; | |||
1693 | virtual void SAL_CALL removeByName( const OUString& Name ) override; | |||
1694 | }; | |||
1695 | ||||
1696 | } | |||
1697 | ||||
1698 | // Methods XElementAccess | |||
1699 | uno::Type ModuleContainer_Impl::getElementType() | |||
1700 | { | |||
1701 | uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get(); | |||
1702 | return aModuleType; | |||
1703 | } | |||
1704 | ||||
1705 | sal_Bool ModuleContainer_Impl::hasElements() | |||
1706 | { | |||
1707 | return mpLib && !mpLib->GetModules().empty(); | |||
1708 | } | |||
1709 | ||||
1710 | // Methods XNameAccess | |||
1711 | uno::Any ModuleContainer_Impl::getByName( const OUString& aName ) | |||
1712 | { | |||
1713 | SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : nullptr; | |||
1714 | if( !pMod ) | |||
1715 | throw container::NoSuchElementException(); | |||
1716 | uno::Reference< script::XStarBasicModuleInfo > xMod = new ModuleInfo_Impl( aName, "StarBasic", pMod->GetSource32() ); | |||
1717 | uno::Any aRetAny; | |||
1718 | aRetAny <<= xMod; | |||
1719 | return aRetAny; | |||
1720 | } | |||
1721 | ||||
1722 | uno::Sequence< OUString > ModuleContainer_Impl::getElementNames() | |||
1723 | { | |||
1724 | sal_uInt16 nMods = mpLib ? mpLib->GetModules().size() : 0; | |||
1725 | uno::Sequence< OUString > aRetSeq( nMods ); | |||
1726 | OUString* pRetSeq = aRetSeq.getArray(); | |||
1727 | for( sal_uInt16 i = 0 ; i < nMods ; i++ ) | |||
1728 | { | |||
1729 | pRetSeq[i] = mpLib->GetModules()[i]->GetName(); | |||
1730 | } | |||
1731 | return aRetSeq; | |||
1732 | } | |||
1733 | ||||
1734 | sal_Bool ModuleContainer_Impl::hasByName( const OUString& aName ) | |||
1735 | { | |||
1736 | SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : nullptr; | |||
1737 | bool bRet = (pMod != nullptr); | |||
1738 | return bRet; | |||
1739 | } | |||
1740 | ||||
1741 | ||||
1742 | // Methods XNameReplace | |||
1743 | void ModuleContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement ) | |||
1744 | { | |||
1745 | removeByName( aName ); | |||
1746 | insertByName( aName, aElement ); | |||
1747 | } | |||
1748 | ||||
1749 | ||||
1750 | // Methods XNameContainer | |||
1751 | void ModuleContainer_Impl::insertByName( const OUString& aName, const uno::Any& aElement ) | |||
1752 | { | |||
1753 | uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get(); | |||
1754 | const uno::Type& aAnyType = aElement.getValueType(); | |||
1755 | if( aModuleType != aAnyType ) | |||
1756 | { | |||
1757 | throw lang::IllegalArgumentException(); | |||
1758 | } | |||
1759 | uno::Reference< script::XStarBasicModuleInfo > xMod; | |||
1760 | aElement >>= xMod; | |||
1761 | mpLib->MakeModule( aName, xMod->getSource() ); | |||
1762 | } | |||
1763 | ||||
1764 | void ModuleContainer_Impl::removeByName( const OUString& Name ) | |||
1765 | { | |||
1766 | SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : nullptr; | |||
1767 | if( !pMod ) | |||
1768 | { | |||
1769 | throw container::NoSuchElementException(); | |||
1770 | } | |||
1771 | mpLib->Remove( pMod ); | |||
1772 | } | |||
1773 | ||||
1774 | ||||
1775 | static uno::Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog ) | |||
1776 | { | |||
1777 | SvMemoryStream aMemStream; | |||
1778 | pDialog->Store( aMemStream ); | |||
1779 | sal_Int32 nLen = aMemStream.Tell(); | |||
1780 | if (nLen < 0) { abort(); } | |||
1781 | uno::Sequence< sal_Int8 > aData( nLen ); | |||
1782 | sal_Int8* pDestData = aData.getArray(); | |||
1783 | const sal_Int8* pSrcData = static_cast<const sal_Int8*>(aMemStream.GetData()); | |||
1784 | memcpy( pDestData, pSrcData, nLen ); | |||
1785 | return aData; | |||
1786 | } | |||
1787 | ||||
1788 | static SbxObject* implCreateDialog( const uno::Sequence< sal_Int8 >& aData ) | |||
1789 | { | |||
1790 | sal_Int8* pData = const_cast< uno::Sequence< sal_Int8 >& >(aData).getArray(); | |||
1791 | SvMemoryStream aMemStream( pData, aData.getLength(), StreamMode::READ ); | |||
1792 | SbxBase* pBase = SbxBase::Load( aMemStream ); | |||
1793 | return dynamic_cast<SbxObject*>(pBase); | |||
1794 | } | |||
1795 | ||||
1796 | // HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx | |||
1797 | // which we can't include here, we have to use the value directly | |||
1798 | #define SBXID_DIALOG101 101 | |||
1799 | ||||
1800 | namespace { | |||
1801 | ||||
1802 | class DialogContainer_Impl : public NameContainerHelper | |||
1803 | { | |||
1804 | StarBASIC* mpLib; | |||
1805 | ||||
1806 | public: | |||
1807 | explicit DialogContainer_Impl( StarBASIC* pLib ) | |||
1808 | :mpLib( pLib ) {} | |||
1809 | ||||
1810 | // Methods XElementAccess | |||
1811 | virtual uno::Type SAL_CALL getElementType() override; | |||
1812 | virtual sal_Bool SAL_CALL hasElements() override; | |||
1813 | ||||
1814 | // Methods XNameAccess | |||
1815 | virtual uno::Any SAL_CALL getByName( const OUString& aName ) override; | |||
1816 | virtual uno::Sequence< OUString > SAL_CALL getElementNames() override; | |||
1817 | virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; | |||
1818 | ||||
1819 | // Methods XNameReplace | |||
1820 | virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override; | |||
1821 | ||||
1822 | // Methods XNameContainer | |||
1823 | virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override; | |||
1824 | virtual void SAL_CALL removeByName( const OUString& Name ) override; | |||
1825 | }; | |||
1826 | ||||
1827 | } | |||
1828 | ||||
1829 | // Methods XElementAccess | |||
1830 | uno::Type DialogContainer_Impl::getElementType() | |||
1831 | { | |||
1832 | uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get(); | |||
1833 | return aModuleType; | |||
1834 | } | |||
1835 | ||||
1836 | sal_Bool DialogContainer_Impl::hasElements() | |||
1837 | { | |||
1838 | bool bRet = false; | |||
1839 | ||||
1840 | sal_Int32 nCount = mpLib->GetObjects()->Count32(); | |||
1841 | for( sal_Int32 nObj = 0; nObj < nCount ; nObj++ ) | |||
1842 | { | |||
1843 | SbxVariable* pVar = mpLib->GetObjects()->Get32( nObj ); | |||
1844 | SbxObject* pObj = dynamic_cast<SbxObject*>(pVar); | |||
1845 | if ( pObj && (pObj->GetSbxId() == SBXID_DIALOG101 ) ) | |||
1846 | { | |||
1847 | bRet = true; | |||
1848 | break; | |||
1849 | } | |||
1850 | } | |||
1851 | return bRet; | |||
1852 | } | |||
1853 | ||||
1854 | // Methods XNameAccess | |||
1855 | uno::Any DialogContainer_Impl::getByName( const OUString& aName ) | |||
1856 | { | |||
1857 | SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxClassType::DontCare ); | |||
1858 | SbxObject* pObj = dynamic_cast<SbxObject*>(pVar); | |||
1859 | if( !( pObj && pObj->GetSbxId() == SBXID_DIALOG101 ) ) | |||
1860 | { | |||
1861 | throw container::NoSuchElementException(); | |||
1862 | } | |||
1863 | ||||
1864 | uno::Reference< script::XStarBasicDialogInfo > xDialog = | |||
1865 | new DialogInfo_Impl(aName, implGetDialogData(pObj)); | |||
1866 | ||||
1867 | uno::Any aRetAny; | |||
1868 | aRetAny <<= xDialog; | |||
1869 | return aRetAny; | |||
1870 | } | |||
1871 | ||||
1872 | uno::Sequence< OUString > DialogContainer_Impl::getElementNames() | |||
1873 | { | |||
1874 | sal_Int32 nCount = mpLib->GetObjects()->Count32(); | |||
1875 | uno::Sequence< OUString > aRetSeq( nCount ); | |||
1876 | OUString* pRetSeq = aRetSeq.getArray(); | |||
1877 | sal_Int32 nDialogCounter = 0; | |||
1878 | ||||
1879 | for( sal_Int32 nObj = 0; nObj < nCount ; nObj++ ) | |||
1880 | { | |||
1881 | SbxVariable* pVar = mpLib->GetObjects()->Get32( nObj ); | |||
1882 | SbxObject* pObj = dynamic_cast<SbxObject*> (pVar); | |||
1883 | if ( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) ) | |||
1884 | { | |||
1885 | pRetSeq[ nDialogCounter ] = pVar->GetName(); | |||
1886 | nDialogCounter++; | |||
1887 | } | |||
1888 | } | |||
1889 | aRetSeq.realloc( nDialogCounter ); | |||
1890 | return aRetSeq; | |||
1891 | } | |||
1892 | ||||
1893 | sal_Bool DialogContainer_Impl::hasByName( const OUString& aName ) | |||
1894 | { | |||
1895 | bool bRet = false; | |||
1896 | SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxClassType::DontCare ); | |||
1897 | SbxObject* pObj = dynamic_cast<SbxObject*>(pVar); | |||
1898 | if( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) ) | |||
1899 | { | |||
1900 | bRet = true; | |||
1901 | } | |||
1902 | return bRet; | |||
1903 | } | |||
1904 | ||||
1905 | ||||
1906 | // Methods XNameReplace | |||
1907 | void DialogContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement ) | |||
1908 | { | |||
1909 | removeByName( aName ); | |||
1910 | insertByName( aName, aElement ); | |||
1911 | } | |||
1912 | ||||
1913 | ||||
1914 | // Methods XNameContainer | |||
1915 | void DialogContainer_Impl::insertByName( const OUString&, const uno::Any& aElement ) | |||
1916 | { | |||
1917 | uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get(); | |||
1918 | const uno::Type& aAnyType = aElement.getValueType(); | |||
1919 | if( aModuleType != aAnyType ) | |||
1920 | { | |||
1921 | throw lang::IllegalArgumentException(); | |||
1922 | } | |||
1923 | uno::Reference< script::XStarBasicDialogInfo > xMod; | |||
1924 | aElement >>= xMod; | |||
1925 | SbxObjectRef xDialog = implCreateDialog( xMod->getData() ); | |||
1926 | mpLib->Insert( xDialog.get() ); | |||
1927 | } | |||
1928 | ||||
1929 | void DialogContainer_Impl::removeByName( const OUString& Name ) | |||
1930 | { | |||
1931 | SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxClassType::DontCare ); | |||
1932 | SbxObject* pObj = dynamic_cast<SbxObject*>(pVar); | |||
1933 | if( !( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) ) ) | |||
1934 | { | |||
1935 | throw container::NoSuchElementException(); | |||
1936 | } | |||
1937 | mpLib->Remove( pVar ); | |||
1938 | } | |||
1939 | ||||
1940 | ||||
1941 | class LibraryContainer_Impl : public NameContainerHelper | |||
1942 | { | |||
1943 | BasicManager* mpMgr; | |||
1944 | ||||
1945 | public: | |||
1946 | explicit LibraryContainer_Impl( BasicManager* pMgr ) | |||
1947 | :mpMgr( pMgr ) {} | |||
1948 | ||||
1949 | // Methods XElementAccess | |||
1950 | virtual uno::Type SAL_CALL getElementType() override; | |||
1951 | virtual sal_Bool SAL_CALL hasElements() override; | |||
1952 | ||||
1953 | // Methods XNameAccess | |||
1954 | virtual uno::Any SAL_CALL getByName( const OUString& aName ) override; | |||
1955 | virtual uno::Sequence< OUString > SAL_CALL getElementNames() override; | |||
1956 | virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; | |||
1957 | ||||
1958 | // Methods XNameReplace | |||
1959 | virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override; | |||
1960 | ||||
1961 | // Methods XNameContainer | |||
1962 | virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override; | |||
1963 | virtual void SAL_CALL removeByName( const OUString& Name ) override; | |||
1964 | }; | |||
1965 | ||||
1966 | ||||
1967 | // Methods XElementAccess | |||
1968 | uno::Type LibraryContainer_Impl::getElementType() | |||
1969 | { | |||
1970 | uno::Type aType = cppu::UnoType<script::XStarBasicLibraryInfo>::get(); | |||
1971 | return aType; | |||
1972 | } | |||
1973 | ||||
1974 | sal_Bool LibraryContainer_Impl::hasElements() | |||
1975 | { | |||
1976 | sal_Int32 nLibs = mpMgr->GetLibCount(); | |||
1977 | bool bRet = (nLibs > 0); | |||
1978 | return bRet; | |||
1979 | } | |||
1980 | ||||
1981 | // Methods XNameAccess | |||
1982 | uno::Any LibraryContainer_Impl::getByName( const OUString& aName ) | |||
1983 | { | |||
1984 | uno::Any aRetAny; | |||
1985 | if( !mpMgr->HasLib( aName ) ) | |||
1986 | throw container::NoSuchElementException(); | |||
1987 | StarBASIC* pLib = mpMgr->GetLib( aName ); | |||
1988 | ||||
1989 | uno::Reference< container::XNameContainer > xModuleContainer = | |||
1990 | new ModuleContainer_Impl( pLib ); | |||
1991 | ||||
1992 | uno::Reference< container::XNameContainer > xDialogContainer = | |||
1993 | new DialogContainer_Impl( pLib ); | |||
1994 | ||||
1995 | BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib ); | |||
1996 | ||||
1997 | OUString aPassword = pLibInfo->GetPassword(); | |||
1998 | ||||
1999 | // TODO Only provide extern info! | |||
2000 | OUString aExternaleSourceURL; | |||
2001 | OUString aLinkTargetURL; | |||
2002 | if( pLibInfo->IsReference() ) | |||
2003 | { | |||
2004 | aLinkTargetURL = pLibInfo->GetStorageName(); | |||
2005 | } | |||
2006 | else if( pLibInfo->IsExtern() ) | |||
2007 | { | |||
2008 | aExternaleSourceURL = pLibInfo->GetStorageName(); | |||
2009 | } | |||
2010 | uno::Reference< script::XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl | |||
2011 | ( | |||
2012 | aName, | |||
2013 | xModuleContainer, | |||
2014 | xDialogContainer, | |||
2015 | aPassword, | |||
2016 | aExternaleSourceURL, | |||
2017 | aLinkTargetURL | |||
2018 | ); | |||
2019 | ||||
2020 | aRetAny <<= xLibInfo; | |||
2021 | return aRetAny; | |||
2022 | } | |||
2023 | ||||
2024 | uno::Sequence< OUString > LibraryContainer_Impl::getElementNames() | |||
2025 | { | |||
2026 | sal_uInt16 nLibs = mpMgr->GetLibCount(); | |||
2027 | uno::Sequence< OUString > aRetSeq( nLibs ); | |||
2028 | OUString* pRetSeq = aRetSeq.getArray(); | |||
2029 | for( sal_uInt16 i = 0 ; i < nLibs ; i++ ) | |||
2030 | { | |||
2031 | pRetSeq[i] = mpMgr->GetLibName( i ); | |||
2032 | } | |||
2033 | return aRetSeq; | |||
2034 | } | |||
2035 | ||||
2036 | sal_Bool LibraryContainer_Impl::hasByName( const OUString& aName ) | |||
2037 | { | |||
2038 | bool bRet = mpMgr->HasLib( aName ); | |||
2039 | return bRet; | |||
2040 | } | |||
2041 | ||||
2042 | // Methods XNameReplace | |||
2043 | void LibraryContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement ) | |||
2044 | { | |||
2045 | removeByName( aName ); | |||
2046 | insertByName( aName, aElement ); | |||
2047 | } | |||
2048 | ||||
2049 | // Methods XNameContainer | |||
2050 | void LibraryContainer_Impl::insertByName( const OUString&, const uno::Any& ) | |||
2051 | { | |||
2052 | // TODO: Insert a complete Library?! | |||
2053 | } | |||
2054 | ||||
2055 | void LibraryContainer_Impl::removeByName( const OUString& Name ) | |||
2056 | { | |||
2057 | StarBASIC* pLib = mpMgr->GetLib( Name ); | |||
2058 | if( !pLib ) | |||
2059 | { | |||
2060 | throw container::NoSuchElementException(); | |||
2061 | } | |||
2062 | sal_uInt16 nLibId = mpMgr->GetLibId( Name ); | |||
2063 | mpMgr->RemoveLib( nLibId ); | |||
2064 | } | |||
2065 | ||||
2066 | ||||
2067 | typedef WeakImplHelper< script::XStarBasicAccess > StarBasicAccessHelper; | |||
2068 | ||||
2069 | ||||
2070 | class StarBasicAccess_Impl : public StarBasicAccessHelper | |||
2071 | { | |||
2072 | BasicManager* mpMgr; | |||
2073 | uno::Reference< container::XNameContainer > mxLibContainer; | |||
2074 | ||||
2075 | public: | |||
2076 | explicit StarBasicAccess_Impl( BasicManager* pMgr ) | |||
2077 | :mpMgr( pMgr ) {} | |||
2078 | ||||
2079 | public: | |||
2080 | // Methods | |||
2081 | virtual uno::Reference< container::XNameContainer > SAL_CALL getLibraryContainer() override; | |||
2082 | virtual void SAL_CALL createLibrary( const OUString& LibName, const OUString& Password, | |||
2083 | const OUString& ExternalSourceURL, const OUString& LinkTargetURL ) override; | |||
2084 | virtual void SAL_CALL addModule( const OUString& LibraryName, const OUString& ModuleName, | |||
2085 | const OUString& Language, const OUString& Source ) override; | |||
2086 | virtual void SAL_CALL addDialog( const OUString& LibraryName, const OUString& DialogName, | |||
2087 | const uno::Sequence< sal_Int8 >& Data ) override; | |||
2088 | }; | |||
2089 | ||||
2090 | uno::Reference< container::XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer() | |||
2091 | { | |||
2092 | if( !mxLibContainer.is() ) | |||
2093 | mxLibContainer = new LibraryContainer_Impl( mpMgr ); | |||
2094 | return mxLibContainer; | |||
2095 | } | |||
2096 | ||||
2097 | void SAL_CALL StarBasicAccess_Impl::createLibrary | |||
2098 | ( | |||
2099 | const OUString& LibName, | |||
2100 | const OUString& Password, | |||
2101 | const OUString&, | |||
2102 | const OUString& LinkTargetURL | |||
2103 | ) | |||
2104 | { | |||
2105 | StarBASIC* pLib = mpMgr->CreateLib( LibName, Password, LinkTargetURL ); | |||
2106 | DBG_ASSERT( pLib, "XML Import: Basic library could not be created")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "2106" ": "), "%s", "XML Import: Basic library could not be created" ); } } while (false); | |||
2107 | } | |||
2108 | ||||
2109 | void SAL_CALL StarBasicAccess_Impl::addModule | |||
2110 | ( | |||
2111 | const OUString& LibraryName, | |||
2112 | const OUString& ModuleName, | |||
2113 | const OUString&, | |||
2114 | const OUString& Source | |||
2115 | ) | |||
2116 | { | |||
2117 | StarBASIC* pLib = mpMgr->GetLib( LibraryName ); | |||
2118 | DBG_ASSERT( pLib, "XML Import: Lib for module unknown")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx" ":" "2118" ": "), "%s", "XML Import: Lib for module unknown" ); } } while (false); | |||
2119 | if( pLib ) | |||
2120 | { | |||
2121 | pLib->MakeModule( ModuleName, Source ); | |||
2122 | } | |||
2123 | } | |||
2124 | ||||
2125 | void SAL_CALL StarBasicAccess_Impl::addDialog | |||
2126 | ( | |||
2127 | const OUString&, | |||
2128 | const OUString&, | |||
2129 | const uno::Sequence< sal_Int8 >& | |||
2130 | ) | |||
2131 | {} | |||
2132 | ||||
2133 | // Basic XML Import/Export | |||
2134 | uno::Reference< script::XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr ) | |||
2135 | { | |||
2136 | uno::Reference< script::XStarBasicAccess > xRet = | |||
2137 | new StarBasicAccess_Impl( pMgr ); | |||
2138 | return xRet; | |||
2139 | } | |||
2140 | ||||
2141 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_TOOLS_REF_HXX | |||
20 | #define INCLUDED_TOOLS_REF_HXX | |||
21 | ||||
22 | #include <sal/config.h> | |||
23 | #include <cassert> | |||
24 | #include <tools/toolsdllapi.h> | |||
25 | #include <utility> | |||
26 | ||||
27 | /** | |||
28 | This implements similar functionality to boost::intrusive_ptr | |||
29 | */ | |||
30 | ||||
31 | namespace tools { | |||
32 | ||||
33 | /** T must be a class that extends SvRefBase */ | |||
34 | template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final { | |||
35 | public: | |||
36 | SvRef(): pObj(nullptr) {} | |||
37 | ||||
38 | SvRef(SvRef&& rObj) noexcept | |||
39 | { | |||
40 | pObj = rObj.pObj; | |||
41 | rObj.pObj = nullptr; | |||
42 | } | |||
43 | ||||
44 | SvRef(SvRef const & rObj): pObj(rObj.pObj) | |||
45 | { | |||
46 | if (pObj != nullptr) pObj->AddNextRef(); | |||
47 | } | |||
48 | ||||
49 | SvRef(T * pObjP): pObj(pObjP) | |||
50 | { | |||
51 | if (pObj != nullptr) pObj->AddFirstRef(); | |||
52 | } | |||
53 | ||||
54 | ~SvRef() | |||
55 | { | |||
56 | if (pObj != nullptr) pObj->ReleaseRef(); | |||
57 | } | |||
58 | ||||
59 | void clear() | |||
60 | { | |||
61 | if (pObj != nullptr) { | |||
62 | T * pRefObj = pObj; | |||
63 | pObj = nullptr; | |||
64 | pRefObj->ReleaseRef(); | |||
65 | } | |||
66 | } | |||
67 | ||||
68 | SvRef & operator =(SvRef const & rObj) | |||
69 | { | |||
70 | if (rObj.pObj != nullptr) { | |||
71 | rObj.pObj->AddNextRef(); | |||
72 | } | |||
73 | T * pRefObj = pObj; | |||
74 | pObj = rObj.pObj; | |||
75 | if (pRefObj != nullptr) { | |||
76 | pRefObj->ReleaseRef(); | |||
77 | } | |||
78 | return *this; | |||
79 | } | |||
80 | ||||
81 | SvRef & operator =(SvRef && rObj) | |||
82 | { | |||
83 | if (pObj != nullptr) { | |||
84 | pObj->ReleaseRef(); | |||
85 | } | |||
86 | pObj = rObj.pObj; | |||
87 | rObj.pObj = nullptr; | |||
| ||||
88 | return *this; | |||
89 | } | |||
90 | ||||
91 | bool is() const { return pObj != nullptr; } | |||
92 | ||||
93 | explicit operator bool() const { return is(); } | |||
94 | ||||
95 | T * get() const { return pObj; } | |||
96 | ||||
97 | T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 97, __extension__ __PRETTY_FUNCTION__)); return pObj; } | |||
98 | ||||
99 | T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 99, __extension__ __PRETTY_FUNCTION__)); return *pObj; } | |||
100 | ||||
101 | bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; } | |||
102 | bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); } | |||
103 | ||||
104 | private: | |||
105 | T * pObj; | |||
106 | }; | |||
107 | ||||
108 | /** | |||
109 | * This implements similar functionality to std::make_shared. | |||
110 | */ | |||
111 | template<typename T, typename... Args> | |||
112 | SvRef<T> make_ref(Args&& ... args) | |||
113 | { | |||
114 | return SvRef<T>(new T(std::forward<Args>(args)...)); | |||
115 | } | |||
116 | ||||
117 | } | |||
118 | ||||
119 | /** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */ | |||
120 | class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase | |||
121 | { | |||
122 | // work around a clang 3.5 optimization bug: if the bNoDelete is *first* | |||
123 | // it mis-compiles "if (--nRefCount == 0)" and never deletes any object | |||
124 | unsigned int nRefCount : 31; | |||
125 | // the only reason this is not bool is because MSVC cannot handle mixed type bitfields | |||
126 | unsigned int bNoDelete : 1; | |||
127 | ||||
128 | protected: | |||
129 | virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE; | |||
130 | ||||
131 | public: | |||
132 | SvRefBase() : nRefCount(0), bNoDelete(1) {} | |||
133 | SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {} | |||
134 | ||||
135 | SvRefBase & operator=(const SvRefBase &) { return *this; } | |||
136 | ||||
137 | void RestoreNoDelete() | |||
138 | { bNoDelete = 1; } | |||
139 | ||||
140 | void AddNextRef() | |||
141 | { | |||
142 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 142, __extension__ __PRETTY_FUNCTION__)); | |||
143 | ++nRefCount; | |||
144 | } | |||
145 | ||||
146 | void AddFirstRef() | |||
147 | { | |||
148 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 148, __extension__ __PRETTY_FUNCTION__)); | |||
149 | if( bNoDelete ) | |||
150 | bNoDelete = 0; | |||
151 | ++nRefCount; | |||
152 | } | |||
153 | ||||
154 | void ReleaseRef() | |||
155 | { | |||
156 | assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail ("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 156, __extension__ __PRETTY_FUNCTION__)); | |||
157 | if( --nRefCount == 0 && !bNoDelete) | |||
158 | { | |||
159 | // I'm not sure about the original purpose of this line, but right now | |||
160 | // it serves the purpose that anything that attempts to do an AddRef() | |||
161 | // after an object is deleted will trip an assert. | |||
162 | nRefCount = 1 << 30; | |||
163 | delete this; | |||
164 | } | |||
165 | } | |||
166 | ||||
167 | unsigned int GetRefCount() const | |||
168 | { return nRefCount; } | |||
169 | }; | |||
170 | ||||
171 | template<typename T> | |||
172 | class SvCompatWeakBase; | |||
173 | ||||
174 | /** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T. | |||
175 | */ | |||
176 | template<typename T> | |||
177 | class SvCompatWeakHdl final : public SvRefBase | |||
178 | { | |||
179 | friend class SvCompatWeakBase<T>; | |||
180 | T* _pObj; | |||
181 | ||||
182 | SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {} | |||
183 | ||||
184 | public: | |||
185 | void ResetWeakBase( ) { _pObj = nullptr; } | |||
186 | T* GetObj() { return _pObj; } | |||
187 | }; | |||
188 | ||||
189 | /** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame. | |||
190 | Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted. | |||
191 | */ | |||
192 | template<typename T> | |||
193 | class SvCompatWeakBase | |||
194 | { | |||
195 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; | |||
196 | ||||
197 | public: | |||
198 | /** Does not use initializer due to compiler warnings, | |||
199 | because the lifetime of the _xHdl object can exceed the lifetime of this class. | |||
200 | */ | |||
201 | SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); } | |||
202 | ||||
203 | ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); } | |||
204 | ||||
205 | SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); } | |||
206 | }; | |||
207 | ||||
208 | /** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak. | |||
209 | */ | |||
210 | template<typename T> | |||
211 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef | |||
212 | { | |||
213 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; | |||
214 | public: | |||
215 | SvCompatWeakRef( ) {} | |||
216 | SvCompatWeakRef( T* pObj ) | |||
217 | { if( pObj ) _xHdl = pObj->GetHdl(); } | |||
218 | #if defined(__COVERITY__) | |||
219 | ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {} | |||
220 | #endif | |||
221 | SvCompatWeakRef& operator = ( T * pObj ) | |||
222 | { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; } | |||
223 | bool is() const | |||
224 | { return _xHdl.is() && _xHdl->GetObj(); } | |||
225 | explicit operator bool() const { return is(); } | |||
226 | T* operator -> () const | |||
227 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } | |||
228 | operator T* () const | |||
229 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } | |||
230 | }; | |||
231 | ||||
232 | #endif | |||
233 | ||||
234 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |