Branch data Line data Source code
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 <tools/shl.hxx>
21 : : #include <tools/stream.hxx>
22 : :
23 : : #include <basic/sbx.hxx>
24 : : #include <basic/sbxfac.hxx>
25 : : #include <basic/sbxbase.hxx>
26 : :
27 : : #include <rtl/instance.hxx>
28 : : #include <rtl/oustringostreaminserter.hxx>
29 : : #include <sal/log.hxx>
30 : : #include <boost/foreach.hpp>
31 : :
32 : : // AppData-Structure for SBX:
33 : :
34 [ - + ]: 159350 : TYPEINIT0(SbxBase)
35 : :
36 : : namespace
37 : : {
38 : : class theSbxAppData : public rtl::Static<SbxAppData, theSbxAppData> {};
39 : : }
40 : :
41 : 207790 : SbxAppData& GetSbxData_Impl()
42 : : {
43 : 207790 : return theSbxAppData::get();
44 : : }
45 : :
46 : 156 : SbxAppData::~SbxAppData()
47 : : {
48 [ - + ][ # # ]: 156 : delete pBasicFormater;
49 : 156 : }
50 : :
51 : :
52 : : //////////////////////////////// SbxBase /////////////////////////////////
53 : :
54 : : DBG_NAME(SbxBase);
55 : :
56 : 0 : SbxBase::SbxBase()
57 : : {
58 : : DBG_CTOR( SbxBase, 0 );
59 : 73993 : nFlags = SBX_READWRITE;
60 : 73993 : }
61 : :
62 : 6261 : SbxBase::SbxBase( const SbxBase& r )
63 : 0 : : SvRefBase( r )
64 : : {
65 : : DBG_CTOR( SbxBase, 0 );
66 : 6261 : nFlags = r.nFlags;
67 : 6261 : }
68 : :
69 : 0 : SbxBase::~SbxBase()
70 : : {
71 : : DBG_DTOR(SbxBase,0);
72 [ # # ][ # # ]: 76513 : }
[ - + ][ - + ]
73 : :
74 : 0 : SbxBase& SbxBase::operator=( const SbxBase& r )
75 : : {
76 : : DBG_CHKTHIS( SbxBase, 0 );
77 : 0 : nFlags = r.nFlags;
78 : 0 : return *this;
79 : : }
80 : :
81 : 0 : SbxDataType SbxBase::GetType() const
82 : : {
83 : : DBG_CHKTHIS( SbxBase, 0 );
84 : 0 : return SbxEMPTY;
85 : : }
86 : :
87 : 0 : SbxClassType SbxBase::GetClass() const
88 : : {
89 : : DBG_CHKTHIS( SbxBase, 0 );
90 : 0 : return SbxCLASS_DONTCARE;
91 : : }
92 : :
93 : 0 : void SbxBase::Clear()
94 : : {
95 : : DBG_CHKTHIS( SbxBase, 0 );
96 : 0 : }
97 : :
98 : 0 : sal_Bool SbxBase::IsFixed() const
99 : : {
100 : : DBG_CHKTHIS( SbxBase, 0 );
101 : 0 : return IsSet( SBX_FIXED );
102 : : }
103 : :
104 : 75630 : void SbxBase::SetModified( sal_Bool b )
105 : : {
106 : : DBG_CHKTHIS( SbxBase, 0 );
107 [ + + ]: 75630 : if( IsSet( SBX_NO_MODIFY ) )
108 : 75630 : return;
109 [ + + ]: 73041 : if( b )
110 : 61284 : SetFlag( SBX_MODIFIED );
111 : : else
112 : 11757 : ResetFlag( SBX_MODIFIED );
113 : : }
114 : :
115 : 125427 : SbxError SbxBase::GetError()
116 : : {
117 : 125427 : return GetSbxData_Impl().eSbxError;
118 : : }
119 : :
120 : 0 : void SbxBase::SetError( SbxError e )
121 : : {
122 : 0 : SbxAppData& r = GetSbxData_Impl();
123 [ # # ][ # # ]: 0 : if( e && r.eSbxError == SbxERR_OK )
124 : 0 : r.eSbxError = e;
125 : 0 : }
126 : :
127 : 78936 : sal_Bool SbxBase::IsError()
128 : : {
129 : 78936 : return sal_Bool( GetSbxData_Impl().eSbxError != SbxERR_OK );
130 : : }
131 : :
132 : 200 : void SbxBase::ResetError()
133 : : {
134 : 200 : GetSbxData_Impl().eSbxError = SbxERR_OK;
135 : 200 : }
136 : :
137 : 1892 : void SbxBase::AddFactory( SbxFactory* pFac )
138 : : {
139 : 1892 : SbxAppData& r = GetSbxData_Impl();
140 : :
141 : : // From 1996-03-06: take the HandleLast-Flag into account
142 : 1892 : sal_uInt16 nPos = r.aFacs.size(); // Insert position
143 [ + - ]: 1892 : if( !pFac->IsHandleLast() ) // Only if not self HandleLast
144 : : {
145 : : // Rank new factory in front of factories with HandleLast
146 [ + + - + ]: 3608 : while( nPos > 0 &&
[ - + ]
147 : 1716 : r.aFacs[ nPos-1 ].IsHandleLast() )
148 : 0 : nPos--;
149 : : }
150 : 1892 : r.aFacs.insert( r.aFacs.begin() + nPos, pFac );
151 : 1892 : }
152 : :
153 : 1299 : void SbxBase::RemoveFactory( SbxFactory* pFac )
154 : : {
155 : 1299 : SbxAppData& r = GetSbxData_Impl();
156 [ + - ][ + - ]: 6052 : for(SbxFacs::iterator it = r.aFacs.begin(); it != r.aFacs.end(); ++it)
[ + - ][ + - ]
[ + - ]
157 : : {
158 [ + - ][ + + ]: 6052 : if( &(*it) == pFac )
159 : : {
160 [ + - ][ + - ]: 1299 : r.aFacs.release( it ).release(); break;
[ + - ]
161 : : }
162 : : }
163 : 1299 : }
164 : :
165 : :
166 : 0 : SbxBase* SbxBase::Create( sal_uInt16 nSbxId, sal_uInt32 nCreator )
167 : : {
168 : : // #91626: Hack to skip old Basic dialogs
169 : : // Problem: There does not exist a factory any more,
170 : : // so we have to create a dummy SbxVariable instead
171 [ # # ]: 0 : if( nSbxId == 0x65 ) // Dialog Id
172 [ # # ][ # # ]: 0 : return new SbxVariable;
173 : :
174 : 0 : rtl::OUString aEmptyStr;
175 [ # # ]: 0 : if( nCreator == SBXCR_SBX )
176 [ # # # # : 0 : switch( nSbxId )
# # # # #
# ]
177 : : {
178 [ # # ][ # # ]: 0 : case SBXID_VALUE: return new SbxValue;
179 [ # # ][ # # ]: 0 : case SBXID_VARIABLE: return new SbxVariable;
180 [ # # ][ # # ]: 0 : case SBXID_ARRAY: return new SbxArray;
181 [ # # ][ # # ]: 0 : case SBXID_DIMARRAY: return new SbxDimArray;
182 [ # # ][ # # ]: 0 : case SBXID_OBJECT: return new SbxObject( aEmptyStr );
[ # # ][ # # ]
183 [ # # ][ # # ]: 0 : case SBXID_COLLECTION: return new SbxCollection( aEmptyStr );
[ # # ][ # # ]
184 : : case SBXID_FIXCOLLECTION:
185 [ # # ][ # # ]: 0 : return new SbxStdCollection( aEmptyStr, aEmptyStr );
[ # # ][ # # ]
[ # # ][ # # ]
186 [ # # ][ # # ]: 0 : case SBXID_METHOD: return new SbxMethod( aEmptyStr, SbxEMPTY );
[ # # ][ # # ]
187 [ # # ][ # # ]: 0 : case SBXID_PROPERTY: return new SbxProperty( aEmptyStr, SbxEMPTY );
[ # # ][ # # ]
188 : : }
189 : : // Unknown type: go over the factories!
190 [ # # ]: 0 : SbxAppData& r = GetSbxData_Impl();
191 : 0 : SbxBase* pNew = NULL;
192 [ # # ][ # # ]: 0 : BOOST_FOREACH(SbxFactory& rFac, r.aFacs)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
193 : : {
194 [ # # ]: 0 : pNew = rFac.Create( nSbxId, nCreator );
195 [ # # ]: 0 : if( pNew )
196 : 0 : break;
197 : : }
198 : : SAL_WARN_IF(!pNew, "basic", "No factory for SBX ID " << nSbxId);
199 : 0 : return pNew;
200 : : }
201 : :
202 : 36 : SbxObject* SbxBase::CreateObject( const rtl::OUString& rClass )
203 : : {
204 : 36 : SbxAppData& r = GetSbxData_Impl();
205 : 36 : SbxObject* pNew = NULL;
206 [ + - ][ + - ]: 432 : BOOST_FOREACH(SbxFactory& rFac, r.aFacs)
[ + - ][ + - ]
[ + + ][ + + ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ][ + - ]
207 : : {
208 [ + - ]: 216 : pNew = rFac.CreateObject( rClass );
209 [ + + ]: 216 : if( pNew )
210 : 36 : break;
211 : : }
212 : : SAL_WARN_IF(!pNew, "basic", "No factory for object class " << rClass);
213 : 36 : return pNew;
214 : : }
215 : :
216 : 0 : SbxBase* SbxBase::Load( SvStream& rStrm )
217 : : {
218 : : sal_uInt16 nSbxId, nFlags, nVer;
219 : : sal_uInt32 nCreator, nSize;
220 [ # # ][ # # ]: 0 : rStrm >> nCreator >> nSbxId >> nFlags >> nVer;
[ # # ][ # # ]
221 : :
222 : : // Correcting a foolishness of mine:
223 [ # # ]: 0 : if( nFlags & SBX_RESERVED )
224 : 0 : nFlags = ( nFlags & ~SBX_RESERVED ) | SBX_GBLSEARCH;
225 : :
226 : 0 : sal_uIntPtr nOldPos = rStrm.Tell();
227 [ # # ]: 0 : rStrm >> nSize;
228 [ # # ]: 0 : SbxBase* p = Create( nSbxId, nCreator );
229 [ # # ]: 0 : if( p )
230 : : {
231 : 0 : p->nFlags = nFlags;
232 [ # # ][ # # ]: 0 : if( p->LoadData( rStrm, nVer ) )
233 : : {
234 : 0 : sal_uIntPtr nNewPos = rStrm.Tell();
235 : 0 : nOldPos += nSize;
236 : : DBG_ASSERT( nOldPos >= nNewPos, "SBX: Zu viele Daten eingelesen" );
237 [ # # ]: 0 : if( nOldPos != nNewPos )
238 [ # # ]: 0 : rStrm.Seek( nOldPos );
239 [ # # ][ # # ]: 0 : if( !p->LoadCompleted() )
240 : : {
241 : : // Deleting of the object
242 : 0 : SbxBaseRef aRef( p );
243 [ # # ]: 0 : p = NULL;
244 : : }
245 : : }
246 : : else
247 : : {
248 [ # # ]: 0 : rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR );
249 : : // Deleting of the object
250 : 0 : SbxBaseRef aRef( p );
251 [ # # ]: 0 : p = NULL;
252 : : }
253 : : }
254 : : else
255 [ # # ]: 0 : rStrm.SetError( SVSTREAM_FILEFORMAT_ERROR );
256 : 0 : return p;
257 : : }
258 : :
259 : : // Skip the Sbx-Object inside the stream
260 : 0 : void SbxBase::Skip( SvStream& rStrm )
261 : : {
262 : : sal_uInt16 nSbxId, nFlags, nVer;
263 : : sal_uInt32 nCreator, nSize;
264 [ # # ][ # # ]: 0 : rStrm >> nCreator >> nSbxId >> nFlags >> nVer;
[ # # ][ # # ]
265 : :
266 : 0 : sal_uIntPtr nStartPos = rStrm.Tell();
267 [ # # ]: 0 : rStrm >> nSize;
268 : :
269 [ # # ]: 0 : rStrm.Seek( nStartPos + nSize );
270 : 0 : }
271 : :
272 : 0 : sal_Bool SbxBase::Store( SvStream& rStrm )
273 : : {
274 : : DBG_CHKTHIS( SbxBase, 0 );
275 [ # # ]: 0 : if( !( nFlags & SBX_DONTSTORE ) )
276 : : {
277 : 0 : rStrm << (sal_uInt32) GetCreator()
278 : 0 : << (sal_uInt16) GetSbxId()
279 : 0 : << (sal_uInt16) GetFlags()
280 : 0 : << (sal_uInt16) GetVersion();
281 : 0 : sal_uIntPtr nOldPos = rStrm.Tell();
282 : 0 : rStrm << (sal_uInt32) 0L;
283 : 0 : sal_Bool bRes = StoreData( rStrm );
284 : 0 : sal_uIntPtr nNewPos = rStrm.Tell();
285 : 0 : rStrm.Seek( nOldPos );
286 : 0 : rStrm << (sal_uInt32) ( nNewPos - nOldPos );
287 : 0 : rStrm.Seek( nNewPos );
288 [ # # ]: 0 : if( rStrm.GetError() != SVSTREAM_OK )
289 : 0 : bRes = sal_False;
290 [ # # ]: 0 : if( bRes )
291 : 0 : bRes = StoreCompleted();
292 : 0 : return bRes;
293 : : }
294 : : else
295 : 0 : return sal_True;
296 : : }
297 : :
298 : 0 : sal_Bool SbxBase::LoadData( SvStream&, sal_uInt16 )
299 : : {
300 : : DBG_CHKTHIS( SbxBase, 0 );
301 : 0 : return sal_False;
302 : : }
303 : :
304 : 0 : sal_Bool SbxBase::StoreData( SvStream& ) const
305 : : {
306 : : DBG_CHKTHIS( SbxBase, 0 );
307 : 0 : return sal_False;
308 : : }
309 : :
310 : 0 : sal_Bool SbxBase::LoadPrivateData( SvStream&, sal_uInt16 )
311 : : {
312 : : DBG_CHKTHIS( SbxBase, 0 );
313 : 0 : return sal_True;
314 : : }
315 : :
316 : 0 : sal_Bool SbxBase::StorePrivateData( SvStream& ) const
317 : : {
318 : : DBG_CHKTHIS( SbxBase, 0 );
319 : 0 : return sal_True;
320 : : }
321 : :
322 : 0 : sal_Bool SbxBase::LoadCompleted()
323 : : {
324 : : DBG_CHKTHIS( SbxBase, 0 );
325 : 0 : return sal_True;
326 : : }
327 : :
328 : 0 : sal_Bool SbxBase::StoreCompleted()
329 : : {
330 : : DBG_CHKTHIS( SbxBase, 0 );
331 : 0 : return sal_True;
332 : : }
333 : :
334 : : //////////////////////////////// SbxFactory ////////////////////////////////
335 : :
336 : 1892 : SbxFactory::~SbxFactory()
337 : : {
338 [ - + ]: 1892 : }
339 : :
340 : 0 : SbxBase* SbxFactory::Create( sal_uInt16, sal_uInt32 )
341 : : {
342 : 0 : return NULL;
343 : : }
344 : :
345 : 0 : SbxObject* SbxFactory::CreateObject( const rtl::OUString& )
346 : : {
347 : 0 : return NULL;
348 : : }
349 : :
350 : : ///////////////////////////////// SbxInfo //////////////////////////////////
351 : :
352 [ + - ][ + - ]: 237 : SbxInfo::~SbxInfo()
[ + - ]
353 [ - + ]: 474 : {}
354 : :
355 : 302 : void SbxInfo::AddParam(const rtl::OUString& rName, SbxDataType eType, sal_uInt16 nFlags)
356 : : {
357 [ + - ][ + - ]: 302 : aParams.push_back(new SbxParamInfo(rName, eType, nFlags));
[ + - ]
358 : 302 : }
359 : :
360 : 2663 : const SbxParamInfo* SbxInfo::GetParam( sal_uInt16 n ) const
361 : : {
362 [ + - ][ + + ]: 2663 : if( n < 1 || n > aParams.size() )
[ + + ]
363 : 1011 : return NULL;
364 : : else
365 : 2663 : return &(aParams[n - 1]);
366 : : }
367 : :
368 : 0 : sal_Bool SbxInfo::LoadData( SvStream& rStrm, sal_uInt16 nVer )
369 : : {
370 [ # # ]: 0 : aParams.clear();
371 : : sal_uInt16 nParam;
372 : : aComment = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rStrm,
373 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_ASCII_US);
374 : : aHelpFile = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rStrm,
375 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_ASCII_US);
376 [ # # ][ # # ]: 0 : rStrm >> nHelpId >> nParam;
377 [ # # ]: 0 : while( nParam-- )
378 : : {
379 : : sal_uInt16 nType, nFlags;
380 : 0 : sal_uInt32 nUserData = 0;
381 : : rtl::OUString aName = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rStrm,
382 [ # # ]: 0 : RTL_TEXTENCODING_ASCII_US);
383 [ # # ][ # # ]: 0 : rStrm >> nType >> nFlags;
384 [ # # ]: 0 : if( nVer > 1 )
385 [ # # ]: 0 : rStrm >> nUserData;
386 [ # # ]: 0 : AddParam( aName, (SbxDataType) nType, nFlags );
387 [ # # ]: 0 : SbxParamInfo& p(aParams.back());
388 : 0 : p.nUserData = nUserData;
389 : 0 : }
390 : 0 : return sal_True;
391 : : }
392 : :
393 : 0 : sal_Bool SbxInfo::StoreData( SvStream& rStrm ) const
394 : : {
395 : : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rStrm, aComment,
396 [ # # ]: 0 : RTL_TEXTENCODING_ASCII_US );
397 : : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rStrm, aHelpFile,
398 [ # # ]: 0 : RTL_TEXTENCODING_ASCII_US);
399 : 0 : rStrm << nHelpId << static_cast<sal_uInt16>(aParams.size());
400 [ # # ][ # # ]: 0 : for(SbxParams::const_iterator i = aParams.begin(); i != aParams.end(); ++i)
[ # # ][ # # ]
[ # # ]
401 : : {
402 [ # # ]: 0 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rStrm, i->aName,
403 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_ASCII_US);
404 [ # # ][ # # ]: 0 : rStrm << (sal_uInt16) i->eType
405 [ # # ][ # # ]: 0 : << (sal_uInt16) i->nFlags
406 [ # # ][ # # ]: 0 : << (sal_uInt32) i->nUserData;
407 : : }
408 : 0 : return sal_True;
409 : : }
410 : :
411 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|