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