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/stream.hxx>
21 : : #include <basic/sbx.hxx>
22 : : #include "runtime.hxx"
23 : : #include <vector>
24 : : using namespace std;
25 : :
26 : : struct SbxDim { // an array-dimension:
27 : : SbxDim* pNext; // Link
28 : : sal_Int32 nLbound, nUbound; // Limitations
29 : : sal_Int32 nSize; // Number of elements
30 : : };
31 : :
32 : : class SbxVarEntry : public SbxVariableRef {
33 : : public:
34 : : XubString* pAlias;
35 : 48640 : SbxVarEntry() : SbxVariableRef(), pAlias( NULL ) {}
36 [ + + ][ + - ]: 36386 : ~SbxVarEntry() { delete pAlias; }
37 : : };
38 : :
39 : : typedef SbxVarEntry* SbxVarEntryPtr;
40 : : typedef vector< SbxVarEntryPtr > SbxVarEntryPtrVector;
41 : 29050 : class SbxVarRefs : public SbxVarEntryPtrVector
42 : : {
43 : : public:
44 : 30554 : SbxVarRefs( void ) {}
45 : : };
46 : :
47 : :
48 [ - + ][ - + ]: 140 : TYPEINIT1(SbxArray,SbxBase)
49 [ + + ][ - + ]: 8112 : TYPEINIT1(SbxDimArray,SbxArray)
50 : :
51 : : // SbxArray
52 : :
53 [ + - ][ + - ]: 30554 : SbxArray::SbxArray( SbxDataType t ) : SbxBase()
54 : : {
55 [ + - ][ + - ]: 30554 : pData = new SbxVarRefs;
[ + - ][ + - ]
56 : 30554 : eType = t;
57 [ + + ][ + + ]: 30554 : if( t != SbxVARIANT )
58 : 7907 : SetFlag( SBX_FIXED );
59 : 30554 : }
60 : :
61 : 0 : SbxArray::SbxArray( const SbxArray& rArray ) :
62 [ # # ][ # # ]: 0 : SvRefBase( rArray ), SbxBase()
63 : : {
64 [ # # ][ # # ]: 0 : pData = new SbxVarRefs;
[ # # ][ # # ]
65 [ # # ][ # # ]: 0 : if( rArray.eType != SbxVARIANT )
66 : 0 : SetFlag( SBX_FIXED );
67 [ # # ][ # # ]: 0 : *this = rArray;
68 : 0 : }
69 : :
70 : 0 : SbxArray& SbxArray::operator=( const SbxArray& rArray )
71 : : {
72 [ # # ]: 0 : if( &rArray != this )
73 : : {
74 : 0 : eType = rArray.eType;
75 : 0 : Clear();
76 : 0 : SbxVarRefs* pSrc = rArray.pData;
77 [ # # ]: 0 : for( sal_uInt32 i = 0; i < pSrc->size(); i++ )
78 : : {
79 : 0 : SbxVarEntryPtr pSrcRef = (*pSrc)[i];
80 : 0 : const SbxVariable* pSrc_ = *pSrcRef;
81 [ # # ]: 0 : if( !pSrc_ )
82 : 0 : continue;
83 [ # # ][ # # ]: 0 : SbxVarEntryPtr pDstRef = new SbxVarEntry;
84 [ # # ]: 0 : *((SbxVariableRef*) pDstRef) = *((SbxVariableRef*) pSrcRef);
85 [ # # ]: 0 : if( pSrcRef->pAlias )
86 [ # # ][ # # ]: 0 : pDstRef->pAlias = new XubString( *pSrcRef->pAlias );
87 [ # # ]: 0 : if( eType != SbxVARIANT )
88 : : // Convert no objects
89 [ # # ][ # # ]: 0 : if( eType != SbxOBJECT || pSrc_->GetClass() != SbxCLASS_OBJECT )
[ # # ][ # # ]
90 [ # # ]: 0 : ((SbxVariable*) pSrc_)->Convert( eType );
91 [ # # ]: 0 : pData->push_back( pDstRef );
92 : : }
93 : : }
94 : 0 : return *this;
95 : : }
96 : :
97 [ + - ][ + - ]: 57986 : SbxArray::~SbxArray()
98 : : {
99 [ + - ][ + - ]: 29050 : Clear();
100 [ + - ][ + - ]: 29050 : delete pData;
101 [ + - ][ - + ]: 86922 : }
[ # # ][ - + ]
[ - + ][ # # ]
102 : :
103 : 970 : SbxDataType SbxArray::GetType() const
104 : : {
105 : 970 : return (SbxDataType) ( eType | SbxARRAY );
106 : : }
107 : :
108 : 0 : SbxClassType SbxArray::GetClass() const
109 : : {
110 : 0 : return SbxCLASS_ARRAY;
111 : : }
112 : :
113 : 38808 : void SbxArray::Clear()
114 : : {
115 : 38808 : sal_uInt32 nSize = pData->size();
116 [ + + ]: 75194 : for( sal_uInt32 i = 0 ; i < nSize ; i++ )
117 : : {
118 : 36386 : SbxVarEntry* pEntry = (*pData)[i];
119 [ + - ]: 36386 : delete pEntry;
120 : : }
121 : 38808 : pData->clear();
122 : 38808 : }
123 : :
124 : 0 : sal_uInt32 SbxArray::Count32() const
125 : : {
126 : 0 : return pData->size();
127 : : }
128 : :
129 : 235507 : sal_uInt16 SbxArray::Count() const
130 : : {
131 : 235507 : sal_uInt32 nCount = pData->size();
132 : : DBG_ASSERT( nCount <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
133 : 235507 : return (sal_uInt16)nCount;
134 : : }
135 : :
136 : 1492 : SbxVariableRef& SbxArray::GetRef32( sal_uInt32 nIdx )
137 : : {
138 : : // If necessary extend the array
139 : : DBG_ASSERT( nIdx <= SBX_MAXINDEX32, "SBX: Array-Index > SBX_MAXINDEX32" );
140 : : // Very Hot Fix
141 [ - + ]: 1492 : if( nIdx > SBX_MAXINDEX32 )
142 : : {
143 : 0 : SetError( SbxERR_BOUNDS );
144 : 0 : nIdx = 0;
145 : : }
146 [ + + ]: 1966 : while( pData->size() <= nIdx )
147 : : {
148 [ + - ][ + - ]: 474 : const SbxVarEntryPtr p = new SbxVarEntry;
149 [ + - ]: 474 : pData->push_back( p );
150 : : }
151 : 1492 : return *((*pData)[nIdx]);
152 : : }
153 : :
154 : 219474 : SbxVariableRef& SbxArray::GetRef( sal_uInt16 nIdx )
155 : : {
156 : : // If necessary extend the array
157 : : DBG_ASSERT( nIdx <= SBX_MAXINDEX, "SBX: Array-Index > SBX_MAXINDEX" );
158 : : // Very Hot Fix
159 [ - + ]: 219474 : if( nIdx > SBX_MAXINDEX )
160 : : {
161 : 0 : SetError( SbxERR_BOUNDS );
162 : 0 : nIdx = 0;
163 : : }
164 [ + + ]: 267469 : while( pData->size() <= nIdx )
165 : : {
166 [ + - ][ + - ]: 47995 : const SbxVarEntryPtr p = new SbxVarEntry;
167 [ + - ]: 47995 : pData->push_back( p );
168 : : }
169 : 219474 : return *((*pData)[nIdx]);
170 : : }
171 : :
172 : 960 : SbxVariable* SbxArray::Get32( sal_uInt32 nIdx )
173 : : {
174 [ - + ]: 960 : if( !CanRead() )
175 : : {
176 : 0 : SetError( SbxERR_PROP_WRITEONLY );
177 : 0 : return NULL;
178 : : }
179 : 960 : SbxVariableRef& rRef = GetRef32( nIdx );
180 : :
181 [ + + ]: 960 : if ( !rRef.Is() )
182 [ + - ]: 462 : rRef = new SbxVariable( eType );
183 : : #ifdef DBG_UTIL
184 : : else
185 : : DBG_CHKOBJ( rRef, SbxBase, 0 );
186 : : #endif
187 : :
188 : 960 : return rRef;
189 : : }
190 : :
191 : 94057 : SbxVariable* SbxArray::Get( sal_uInt16 nIdx )
192 : : {
193 [ - + ]: 94057 : if( !CanRead() )
194 : : {
195 : 0 : SetError( SbxERR_PROP_WRITEONLY );
196 : 0 : return NULL;
197 : : }
198 : 94057 : SbxVariableRef& rRef = GetRef( nIdx );
199 : :
200 [ + + ]: 94057 : if ( !rRef.Is() )
201 [ + - ]: 100 : rRef = new SbxVariable( eType );
202 : : #ifdef DBG_UTIL
203 : : else
204 : : DBG_CHKOBJ( rRef, SbxBase, 0 );
205 : : #endif
206 : :
207 : 94057 : return rRef;
208 : : }
209 : :
210 : 8 : void SbxArray::Put32( SbxVariable* pVar, sal_uInt32 nIdx )
211 : : {
212 [ - + ]: 8 : if( !CanWrite() )
213 : 0 : SetError( SbxERR_PROP_READONLY );
214 : : else
215 : : {
216 [ + - ]: 8 : if( pVar )
217 [ + - ]: 8 : if( eType != SbxVARIANT )
218 : : // Convert no objects
219 [ + + ][ - + ]: 8 : if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
[ + + ]
220 : 4 : pVar->Convert( eType );
221 : 8 : SbxVariableRef& rRef = GetRef32( nIdx );
222 [ + - ]: 8 : if( (SbxVariable*) rRef != pVar )
223 : : {
224 : 8 : rRef = pVar;
225 : 8 : SetFlag( SBX_MODIFIED );
226 : : }
227 : : }
228 : 8 : }
229 : :
230 : 61600 : void SbxArray::Put( SbxVariable* pVar, sal_uInt16 nIdx )
231 : : {
232 [ - + ]: 61600 : if( !CanWrite() )
233 : 0 : SetError( SbxERR_PROP_READONLY );
234 : : else
235 : : {
236 [ + + ]: 61600 : if( pVar )
237 [ + + ]: 60688 : if( eType != SbxVARIANT )
238 : : // Convert no objects
239 [ + - ][ - + ]: 5432 : if( eType != SbxOBJECT || pVar->GetClass() != SbxCLASS_OBJECT )
[ - + ]
240 : 0 : pVar->Convert( eType );
241 : 61600 : SbxVariableRef& rRef = GetRef( nIdx );
242 [ + + ]: 61600 : if( (SbxVariable*) rRef != pVar )
243 : : {
244 : 61444 : rRef = pVar;
245 : 61444 : SetFlag( SBX_MODIFIED );
246 : : }
247 : : }
248 : 61600 : }
249 : :
250 : 4338 : const XubString& SbxArray::GetAlias( sal_uInt16 nIdx )
251 : : {
252 [ - + ]: 4338 : if( !CanRead() )
253 : : {
254 : 0 : SetError( SbxERR_PROP_WRITEONLY );
255 : 0 : return String::EmptyString();
256 : : }
257 : 4338 : SbxVarEntry& rRef = (SbxVarEntry&) GetRef( nIdx );
258 : :
259 [ + + ]: 4338 : if ( !rRef.pAlias )
260 : 4260 : return String::EmptyString();
261 : : #ifdef DBG_UTIL
262 : : else
263 : : DBG_CHKOBJ( rRef, SbxBase, 0 );
264 : : #endif
265 : :
266 : 4338 : return *rRef.pAlias;
267 : : }
268 : :
269 : 1570 : void SbxArray::PutAlias( const XubString& rAlias, sal_uInt16 nIdx )
270 : : {
271 [ - + ]: 1570 : if( !CanWrite() )
272 : 0 : SetError( SbxERR_PROP_READONLY );
273 : : else
274 : : {
275 : 1570 : SbxVarEntry& rRef = (SbxVarEntry&) GetRef( nIdx );
276 [ + - ]: 1570 : if( !rRef.pAlias )
277 [ + - ]: 1570 : rRef.pAlias = new XubString( rAlias );
278 : : else
279 : 0 : *rRef.pAlias = rAlias;
280 : : }
281 : 1570 : }
282 : :
283 : 171 : void SbxArray::Insert32( SbxVariable* pVar, sal_uInt32 nIdx )
284 : : {
285 : : DBG_ASSERT( pData->size() <= SBX_MAXINDEX32, "SBX: Array wird zu gross" );
286 [ + - ]: 171 : if( pData->size() > SBX_MAXINDEX32 )
287 : 171 : return;
288 [ + - ][ + - ]: 171 : SbxVarEntryPtr p = new SbxVarEntry;
289 [ + - ]: 171 : *((SbxVariableRef*) p) = pVar;
290 : 171 : SbxVarEntryPtrVector::size_type nSize = pData->size();
291 [ - + ]: 171 : if( nIdx > nSize )
292 : 0 : nIdx = nSize;
293 [ - + ][ # # ]: 171 : if( eType != SbxVARIANT && pVar )
294 [ # # ]: 0 : (*p)->Convert( eType );
295 [ + - ]: 171 : if( nIdx == nSize )
296 : : {
297 [ + - ]: 171 : pData->push_back( p );
298 : : }
299 : : else
300 : : {
301 [ # # ][ # # ]: 0 : pData->insert( pData->begin() + nIdx, p );
302 : : }
303 : 171 : SetFlag( SBX_MODIFIED );
304 : : }
305 : :
306 : 171 : void SbxArray::Insert( SbxVariable* pVar, sal_uInt16 nIdx )
307 : : {
308 : : DBG_ASSERT( pData->size() <= 0x3FF0, "SBX: Array wird zu gross" );
309 [ - + ]: 171 : if( pData->size() > 0x3FF0 )
310 : 171 : return;
311 : 171 : Insert32( pVar, nIdx );
312 : : }
313 : :
314 : 0 : void SbxArray::Remove32( sal_uInt32 nIdx )
315 : : {
316 [ # # ]: 0 : if( nIdx < pData->size() )
317 : : {
318 : 0 : SbxVariableRef* pRef = (*pData)[nIdx];
319 [ # # ][ # # ]: 0 : pData->erase( pData->begin() + nIdx );
320 [ # # ]: 0 : delete pRef;
321 : 0 : SetFlag( SBX_MODIFIED );
322 : : }
323 : 0 : }
324 : :
325 : 11252 : void SbxArray::Remove( sal_uInt16 nIdx )
326 : : {
327 [ + - ]: 11252 : if( nIdx < pData->size() )
328 : : {
329 : 11252 : SbxVariableRef* pRef = (*pData)[nIdx];
330 [ + - ][ + - ]: 11252 : pData->erase( pData->begin() + nIdx );
331 [ + - ]: 11252 : delete pRef;
332 : 11252 : SetFlag( SBX_MODIFIED );
333 : : }
334 : 11252 : }
335 : :
336 : 0 : void SbxArray::Remove( SbxVariable* pVar )
337 : : {
338 [ # # ]: 0 : if( pVar )
339 : : {
340 [ # # ]: 0 : for( sal_uInt32 i = 0; i < pData->size(); i++ )
341 : : {
342 : 0 : SbxVariableRef* pRef = (*pData)[i];
343 [ # # ]: 0 : if( *pRef == pVar )
344 : : {
345 : 0 : Remove32( i ); break;
346 : : }
347 : : }
348 : : }
349 : 0 : }
350 : :
351 : : // Taking over of the data from the passed array, at which
352 : : // the variable of the same name will be overwritten.
353 : :
354 : 0 : void SbxArray::Merge( SbxArray* p )
355 : : {
356 [ # # ]: 0 : if( p )
357 : : {
358 : 0 : sal_uInt32 nSize = p->Count();
359 [ # # ]: 0 : for( sal_uInt32 i = 0; i < nSize; i++ )
360 : : {
361 : 0 : SbxVarEntryPtr pRef1 = (*(p->pData))[i];
362 : : // Is the element by name already inside?
363 : : // Then overwrite!
364 : 0 : SbxVariable* pVar = *pRef1;
365 [ # # ]: 0 : if( pVar )
366 : : {
367 [ # # ][ # # ]: 0 : XubString aName = pVar->GetName();
368 : 0 : sal_uInt16 nHash = pVar->GetHashCode();
369 [ # # ]: 0 : for( sal_uInt32 j = 0; j < pData->size(); j++ )
370 : : {
371 : 0 : SbxVariableRef* pRef2 = (*pData)[j];
372 [ # # ][ # # ]: 0 : if( (*pRef2)->GetHashCode() == nHash
[ # # ]
373 [ # # ][ # # ]: 0 : && (*pRef2)->GetName().EqualsIgnoreCaseAscii( aName ) )
374 : : {
375 [ # # ]: 0 : *pRef2 = pVar; pRef1 = NULL;
376 : 0 : break;
377 : : }
378 : : }
379 [ # # ]: 0 : if( pRef1 )
380 : : {
381 [ # # ][ # # ]: 0 : SbxVarEntryPtr pRef = new SbxVarEntry;
382 : 0 : const SbxVarEntryPtr pTemp = pRef;
383 [ # # ]: 0 : pData->push_back( pTemp );
384 [ # # ]: 0 : *((SbxVariableRef*) pRef) = *((SbxVariableRef*) pRef1);
385 [ # # ]: 0 : if( pRef1->pAlias )
386 [ # # ][ # # ]: 0 : pRef->pAlias = new XubString( *pRef1->pAlias );
387 [ # # ]: 0 : }
388 : : }
389 : : }
390 : : }
391 : 0 : }
392 : :
393 : : // Search of an element via the user data. If the element is
394 : : // object, it will also be scanned.
395 : :
396 : 0 : SbxVariable* SbxArray::FindUserData( sal_uInt32 nData )
397 : : {
398 : 0 : SbxVariable* p = NULL;
399 [ # # ]: 0 : for( sal_uInt32 i = 0; i < pData->size(); i++ )
400 : : {
401 : 0 : SbxVariableRef* pRef = (*pData)[i];
402 : 0 : SbxVariable* pVar = *pRef;
403 [ # # ]: 0 : if( pVar )
404 : : {
405 [ # # ][ # # ]: 0 : if( pVar->IsVisible() && pVar->GetUserData() == nData )
[ # # ]
406 : : {
407 : 0 : p = pVar;
408 : 0 : p->ResetFlag( SBX_EXTFOUND );
409 : 0 : break; // JSM 1995-10-06
410 : : }
411 : : // Did we have an array/object with extended search?
412 [ # # ]: 0 : else if( pVar->IsSet( SBX_EXTSEARCH ) )
413 : : {
414 [ # # # ]: 0 : switch( pVar->GetClass() )
415 : : {
416 : : case SbxCLASS_OBJECT:
417 : : {
418 : : // Objects are not allowed to scan their parent.
419 : 0 : sal_uInt16 nOld = pVar->GetFlags();
420 : 0 : pVar->ResetFlag( SBX_GBLSEARCH );
421 : 0 : p = ((SbxObject*) pVar)->FindUserData( nData );
422 : 0 : pVar->SetFlags( nOld );
423 : 0 : break;
424 : : }
425 : : case SbxCLASS_ARRAY:
426 : 0 : p = ((SbxArray*) pVar)->FindUserData( nData );
427 : 0 : break;
428 : 0 : default: break;
429 : : }
430 [ # # ]: 0 : if( p )
431 : : {
432 : 0 : p->SetFlag( SBX_EXTFOUND );
433 : 0 : break;
434 : : }
435 : : }
436 : : }
437 : : }
438 : 0 : return p;
439 : : }
440 : :
441 : : // Search of an element by his name and type. If an element is an object,
442 : : // it will also be scanned..
443 : :
444 : 332954 : SbxVariable* SbxArray::Find( const rtl::OUString& rName, SbxClassType t )
445 : : {
446 : 332954 : SbxVariable* p = NULL;
447 : 332954 : sal_uInt32 nCount = pData->size();
448 [ + + ]: 332954 : if( !nCount )
449 : 133906 : return NULL;
450 : 199048 : sal_Bool bExtSearch = IsSet( SBX_EXTSEARCH );
451 [ + - ]: 199048 : sal_uInt16 nHash = SbxVariable::MakeHashCode( rName );
452 [ + + ]: 1539123 : for( sal_uInt32 i = 0; i < nCount; i++ )
453 : : {
454 : 1383153 : SbxVariableRef* pRef = (*pData)[i];
455 : 1383153 : SbxVariable* pVar = *pRef;
456 [ + - ][ + - ]: 1383153 : if( pVar && pVar->IsVisible() )
[ + - ]
457 : : {
458 : : // The very secure search works as well, if there is no hashcode!
459 : 1383153 : sal_uInt16 nVarHash = pVar->GetHashCode();
460 [ + + ][ + + ]: 2856323 : if( ( !nVarHash || nVarHash == nHash )
[ + - ][ + + ]
[ + + ][ + - ]
461 [ + - ]: 42616 : && ( t == SbxCLASS_DONTCARE || pVar->GetClass() == t )
462 [ + - ][ + - ]: 1430554 : && ( pVar->GetName().EqualsIgnoreCaseAscii( rName ) ) )
[ + - ][ + + ]
[ # # ]
463 : : {
464 : 43078 : p = pVar;
465 : 43078 : p->ResetFlag( SBX_EXTFOUND );
466 : 43078 : break;
467 : : }
468 : : // Did we have an array/object with extended search?
469 [ + + ][ + + ]: 1340075 : else if( bExtSearch && pVar->IsSet( SBX_EXTSEARCH ) )
[ + + ]
470 : : {
471 [ + - - ]: 28919 : switch( pVar->GetClass() )
472 : : {
473 : : case SbxCLASS_OBJECT:
474 : : {
475 : : // Objects are not allowed to scan their parent.
476 : 28919 : sal_uInt16 nOld = pVar->GetFlags();
477 : 28919 : pVar->ResetFlag( SBX_GBLSEARCH );
478 : 28919 : p = ((SbxObject*) pVar)->Find( rName, t );
479 : 28919 : pVar->SetFlags( nOld );
480 : 28919 : break;
481 : : }
482 : : case SbxCLASS_ARRAY:
483 : 0 : p = ((SbxArray*) pVar)->Find( rName, t );
484 : 0 : break;
485 : 0 : default: break;
486 : : }
487 [ - + ]: 28919 : if( p )
488 : : {
489 : 0 : p->SetFlag( SBX_EXTFOUND );
490 : 0 : break;
491 : : }
492 : : }
493 : : }
494 : : }
495 : 332954 : return p;
496 : : }
497 : :
498 : 0 : sal_Bool SbxArray::LoadData( SvStream& rStrm, sal_uInt16 nVer )
499 : : {
500 : : sal_uInt16 nElem;
501 [ # # ]: 0 : Clear();
502 : 0 : sal_Bool bRes = sal_True;
503 : 0 : sal_uInt16 f = nFlags;
504 : 0 : nFlags |= SBX_WRITE;
505 [ # # ]: 0 : rStrm >> nElem;
506 : 0 : nElem &= 0x7FFF;
507 [ # # ]: 0 : for( sal_uInt32 n = 0; n < nElem; n++ )
508 : : {
509 : : sal_uInt16 nIdx;
510 [ # # ]: 0 : rStrm >> nIdx;
511 [ # # ]: 0 : SbxVariable* pVar = (SbxVariable*) Load( rStrm );
512 [ # # ]: 0 : if( pVar )
513 : : {
514 [ # # ]: 0 : SbxVariableRef& rRef = GetRef( nIdx );
515 [ # # ]: 0 : rRef = pVar;
516 : : }
517 : : else
518 : : {
519 : 0 : bRes = sal_False; break;
520 : : }
521 : : }
522 [ # # ]: 0 : if( bRes )
523 [ # # ]: 0 : bRes = LoadPrivateData( rStrm, nVer );
524 : 0 : nFlags = f;
525 : 0 : return bRes;
526 : : }
527 : :
528 : 0 : sal_Bool SbxArray::StoreData( SvStream& rStrm ) const
529 : : {
530 : 0 : sal_uInt32 nElem = 0;
531 : : sal_uInt32 n;
532 : : // Which elements are even defined?
533 [ # # ]: 0 : for( n = 0; n < pData->size(); n++ )
534 : : {
535 : 0 : SbxVariableRef* pRef = (*pData)[n];
536 : 0 : SbxVariable* p = *pRef;
537 [ # # ][ # # ]: 0 : if( p && !( p->GetFlags() & SBX_DONTSTORE ) )
[ # # ]
538 : 0 : nElem++;
539 : : }
540 : 0 : rStrm << (sal_uInt16) nElem;
541 [ # # ]: 0 : for( n = 0; n < pData->size(); n++ )
542 : : {
543 : 0 : SbxVariableRef* pRef = (*pData)[n];
544 : 0 : SbxVariable* p = *pRef;
545 [ # # ][ # # ]: 0 : if( p && !( p->GetFlags() & SBX_DONTSTORE ) )
[ # # ]
546 : : {
547 : 0 : rStrm << (sal_uInt16) n;
548 [ # # ]: 0 : if( !p->Store( rStrm ) )
549 : 0 : return sal_False;
550 : : }
551 : : }
552 : 0 : return StorePrivateData( rStrm );
553 : : }
554 : :
555 : : // #100883 Method to set method directly to parameter array
556 : 524 : void SbxArray::PutDirect( SbxVariable* pVar, sal_uInt32 nIdx )
557 : : {
558 : 524 : SbxVariableRef& rRef = GetRef32( nIdx );
559 : 524 : rRef = pVar;
560 : 524 : }
561 : :
562 : :
563 : : // SbxArray
564 : :
565 [ + - ][ # # ]: 114 : SbxDimArray::SbxDimArray( SbxDataType t ) : SbxArray( t ), mbHasFixedSize( false )
566 : : {
567 : 114 : pFirst = pLast = NULL;
568 : 114 : nDim = 0;
569 : 114 : }
570 : :
571 : 0 : SbxDimArray::SbxDimArray( const SbxDimArray& rArray )
572 [ # # ][ # # ]: 0 : : SvRefBase( rArray ), SbxArray( rArray.eType )
573 : : {
574 : 0 : pFirst = pLast = NULL;
575 : 0 : nDim = 0;
576 [ # # ][ # # ]: 0 : *this = rArray;
577 : 0 : }
578 : :
579 : 0 : SbxDimArray& SbxDimArray::operator=( const SbxDimArray& rArray )
580 : : {
581 [ # # ]: 0 : if( &rArray != this )
582 : : {
583 : 0 : SbxArray::operator=( (const SbxArray&) rArray );
584 : 0 : SbxDim* p = rArray.pFirst;
585 [ # # ]: 0 : while( p )
586 : : {
587 : 0 : AddDim32( p->nLbound, p->nUbound );
588 : 0 : p = p->pNext;
589 : : }
590 : 0 : this->mbHasFixedSize = rArray.mbHasFixedSize;
591 : : }
592 : 0 : return *this;
593 : : }
594 : :
595 [ + - ][ # # ]: 228 : SbxDimArray::~SbxDimArray()
596 : : {
597 [ + - ][ # # ]: 114 : Clear();
598 [ + - ][ - + ]: 342 : }
[ # # ][ # # ]
[ # # ][ # # ]
599 : :
600 : 114 : void SbxDimArray::Clear()
601 : : {
602 : 114 : SbxDim* p = pFirst;
603 [ + + ]: 232 : while( p )
604 : : {
605 : 118 : SbxDim* q = p->pNext;
606 : 118 : delete p;
607 : 118 : p = q;
608 : : }
609 : 114 : pFirst = pLast = NULL;
610 : 114 : nDim = 0;
611 : 114 : }
612 : :
613 : : // Add a dimension
614 : :
615 : 118 : void SbxDimArray::AddDimImpl32( sal_Int32 lb, sal_Int32 ub, sal_Bool bAllowSize0 )
616 : : {
617 : 118 : SbxError eRes = SbxERR_OK;
618 [ + + ][ - + ]: 118 : if( ub < lb && !bAllowSize0 )
619 : : {
620 : 0 : eRes = SbxERR_BOUNDS;
621 : 0 : ub = lb;
622 : : }
623 : 118 : SbxDim* p = new SbxDim;
624 : 118 : p->nLbound = lb;
625 : 118 : p->nUbound = ub;
626 : 118 : p->nSize = ub - lb + 1;
627 : 118 : p->pNext = NULL;
628 [ + + ]: 118 : if( !pFirst )
629 : 114 : pFirst = pLast = p;
630 : : else
631 : 4 : pLast->pNext = p, pLast = p;
632 : 118 : nDim++;
633 [ - + ]: 118 : if( eRes )
634 : 0 : SetError( eRes );
635 : 118 : }
636 : :
637 : 82 : short SbxDimArray::GetDims() const
638 : : {
639 : 82 : return nDim;
640 : : }
641 : :
642 : 0 : void SbxDimArray::AddDim( short lb, short ub )
643 : : {
644 : 0 : AddDimImpl32( lb, ub, sal_False );
645 : 0 : }
646 : :
647 : 44 : void SbxDimArray::unoAddDim( short lb, short ub )
648 : : {
649 : 44 : AddDimImpl32( lb, ub, sal_True );
650 : 44 : }
651 : :
652 : 72 : void SbxDimArray::AddDim32( sal_Int32 lb, sal_Int32 ub )
653 : : {
654 : 72 : AddDimImpl32( lb, ub, sal_False );
655 : 72 : }
656 : :
657 : 2 : void SbxDimArray::unoAddDim32( sal_Int32 lb, sal_Int32 ub )
658 : : {
659 : 2 : AddDimImpl32( lb, ub, sal_True );
660 : 2 : }
661 : :
662 : :
663 : : // Readout dimension data
664 : :
665 : 82 : sal_Bool SbxDimArray::GetDim32( sal_Int32 n, sal_Int32& rlb, sal_Int32& rub ) const
666 : : {
667 [ + - ][ - + ]: 82 : if( n < 1 || n > nDim )
668 : : {
669 : 0 : SetError( SbxERR_BOUNDS ); rub = rlb = 0; return sal_False;
670 : : }
671 : 82 : SbxDim* p = pFirst;
672 [ - + ]: 82 : while( --n )
673 : 0 : p = p->pNext;
674 : 82 : rub = p->nUbound;
675 : 82 : rlb = p->nLbound;
676 : 82 : return sal_True;
677 : : }
678 : :
679 : 0 : sal_Bool SbxDimArray::GetDim( short n, short& rlb, short& rub ) const
680 : : {
681 : : sal_Int32 rlb32, rub32;
682 [ # # ]: 0 : sal_Bool bRet = GetDim32( n, rlb32, rub32 );
683 [ # # ]: 0 : if( bRet )
684 : : {
685 [ # # ][ # # ]: 0 : if( rlb32 < -SBX_MAXINDEX || rub32 > SBX_MAXINDEX )
686 : : {
687 [ # # ]: 0 : SetError( SbxERR_BOUNDS );
688 : 0 : return sal_False;
689 : : }
690 : 0 : rub = (short)rub32;
691 : 0 : rlb = (short)rlb32;
692 : : }
693 : 0 : return bRet;
694 : : }
695 : :
696 : : // Element-Ptr with the help of an index list
697 : :
698 : 64 : sal_uInt32 SbxDimArray::Offset32( const sal_Int32* pIdx )
699 : : {
700 : 64 : sal_uInt32 nPos = 0;
701 [ + + ]: 128 : for( SbxDim* p = pFirst; p; p = p->pNext )
702 : : {
703 : 64 : sal_Int32 nIdx = *pIdx++;
704 [ + - ][ - + ]: 64 : if( nIdx < p->nLbound || nIdx > p->nUbound )
705 : : {
706 : 0 : nPos = (sal_uInt32)SBX_MAXINDEX32 + 1; break;
707 : : }
708 : 64 : nPos = nPos * p->nSize + nIdx - p->nLbound;
709 : : }
710 [ + - ][ - + ]: 64 : if( nDim == 0 || nPos > SBX_MAXINDEX32 )
711 : : {
712 : 0 : SetError( SbxERR_BOUNDS ); nPos = 0;
713 : : }
714 : 64 : return nPos;
715 : : }
716 : :
717 : 0 : sal_uInt16 SbxDimArray::Offset( const short* pIdx )
718 : : {
719 : 0 : long nPos = 0;
720 [ # # ]: 0 : for( SbxDim* p = pFirst; p; p = p->pNext )
721 : : {
722 : 0 : short nIdx = *pIdx++;
723 [ # # ][ # # ]: 0 : if( nIdx < p->nLbound || nIdx > p->nUbound )
724 : : {
725 : 0 : nPos = SBX_MAXINDEX + 1; break;
726 : : }
727 : 0 : nPos = nPos * p->nSize + nIdx - p->nLbound;
728 : : }
729 [ # # ][ # # ]: 0 : if( nDim == 0 || nPos > SBX_MAXINDEX )
730 : : {
731 : 0 : SetError( SbxERR_BOUNDS ); nPos = 0;
732 : : }
733 : 0 : return (sal_uInt16) nPos;
734 : : }
735 : :
736 : 0 : SbxVariable* SbxDimArray::Get( const short* pIdx )
737 : : {
738 : 0 : return SbxArray::Get( Offset( pIdx ) );
739 : : }
740 : :
741 : 0 : void SbxDimArray::Put( SbxVariable* p, const short* pIdx )
742 : : {
743 : 0 : SbxArray::Put( p, Offset( pIdx ) );
744 : 0 : }
745 : :
746 : 60 : SbxVariable* SbxDimArray::Get32( const sal_Int32* pIdx )
747 : : {
748 : 60 : return SbxArray::Get32( Offset32( pIdx ) );
749 : : }
750 : :
751 : 4 : void SbxDimArray::Put32( SbxVariable* p, const sal_Int32* pIdx )
752 : : {
753 : 4 : SbxArray::Put32( p, Offset32( pIdx ) );
754 : 4 : }
755 : :
756 : :
757 : : // Element-Number with the help of Parameter-Array
758 : :
759 : 900 : sal_uInt32 SbxDimArray::Offset32( SbxArray* pPar )
760 : : {
761 : : #ifndef DISABLE_SCRIPTING
762 [ + - ][ + - ]: 900 : if( nDim == 0 || !pPar || ( ( nDim != ( pPar->Count() - 1 ) ) && SbiRuntime::isVBAEnabled() ) )
[ - + ][ # # ]
[ - + ]
763 : : {
764 : 0 : SetError( SbxERR_BOUNDS ); return 0;
765 : : }
766 : : #endif
767 : 900 : sal_uInt32 nPos = 0;
768 : 900 : sal_uInt16 nOff = 1; // Non element 0!
769 [ + + ][ + - ]: 2480 : for( SbxDim* p = pFirst; p && !IsError(); p = p->pNext )
[ + + ]
770 : : {
771 : 1580 : sal_Int32 nIdx = pPar->Get( nOff++ )->GetLong();
772 [ - + ][ + - ]: 1580 : if( nIdx < p->nLbound || nIdx > p->nUbound )
773 : : {
774 : 0 : nPos = (sal_uInt32) SBX_MAXINDEX32+1; break;
775 : : }
776 : 1580 : nPos = nPos * p->nSize + nIdx - p->nLbound;
777 : : }
778 [ - + ]: 900 : if( nPos > (sal_uInt32) SBX_MAXINDEX32 )
779 : : {
780 : 0 : SetError( SbxERR_BOUNDS ); nPos = 0;
781 : : }
782 : 900 : return nPos;
783 : : }
784 : :
785 : 900 : SbxVariable* SbxDimArray::Get( SbxArray* pPar )
786 : : {
787 : 900 : return SbxArray::Get32( Offset32( pPar ) );
788 : : }
789 : :
790 : 0 : sal_Bool SbxDimArray::LoadData( SvStream& rStrm, sal_uInt16 nVer )
791 : : {
792 : : short nDimension;
793 [ # # ]: 0 : rStrm >> nDimension;
794 [ # # ][ # # ]: 0 : for( short i = 0; i < nDimension && rStrm.GetError() == SVSTREAM_OK; i++ )
[ # # ]
795 : : {
796 : : sal_Int16 lb, ub;
797 [ # # ][ # # ]: 0 : rStrm >> lb >> ub;
798 [ # # ]: 0 : AddDim( lb, ub );
799 : : }
800 [ # # ]: 0 : return SbxArray::LoadData( rStrm, nVer );
801 : : }
802 : :
803 : 0 : sal_Bool SbxDimArray::StoreData( SvStream& rStrm ) const
804 : : {
805 : 0 : rStrm << (sal_Int16) nDim;
806 [ # # ]: 0 : for( short i = 0; i < nDim; i++ )
807 : : {
808 : : short lb, ub;
809 [ # # ]: 0 : GetDim( i, lb, ub );
810 [ # # ][ # # ]: 0 : rStrm << (sal_Int16) lb << (sal_Int16) ub;
811 : : }
812 : 0 : return SbxArray::StoreData( rStrm );
813 : : }
814 : :
815 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|