File: | home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx |
Warning: | line 580, column 21 Use of memory after it is freed |
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: */ |