LCOV - code coverage report
Current view: top level - svl/source/items - nranges.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 85 249 34.1 %
Date: 2015-06-13 12:38:46 Functions: 7 13 53.8 %
Legend: Lines: hit not hit

          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 <cassert>
      21             : #include <vector>
      22             : // compiled via include from itemset.cxx only!
      23             : #include <boost/scoped_array.hpp>
      24             : 
      25             : #include <osl/diagnose.h>
      26             : 
      27             : #ifdef DBG_UTIL
      28             : 
      29             : #define DBG_CHECK_RANGES(sal_uInt16, pArr)                                 \
      30             :     for ( const sal_uInt16 *pRange = pArr; *pRange; pRange += 2 )          \
      31             :     {                                                                   \
      32             :         DBG_ASSERT( pRange[0] <= pRange[1], "ranges must be sorted" );  \
      33             :         DBG_ASSERT( !pRange[2] || ( pRange[2] - pRange[1] ) > 1,        \
      34             :                     "ranges must be sorted and discrete" );             \
      35             :     }
      36             : 
      37             : #else
      38             : 
      39             : #define DBG_CHECK_RANGES(sal_uInt16,pArr)
      40             : 
      41             : #endif
      42             : 
      43       56712 : inline void Swap_Impl(const sal_uInt16 *& rp1, const sal_uInt16 *& rp2)
      44             : {
      45       56712 :     const sal_uInt16 * pTemp = rp1;
      46       56712 :     rp1 = rp2;
      47       56712 :     rp2 = pTemp;
      48       56712 : }
      49             : 
      50             : /**
      51             :  * Creates a sal_uInt16-ranges-array in 'rpRanges' using 'nWh1' and 'nWh2' as
      52             :  * first range, 'nNull' as terminator or start of 2nd range and 'pArgs' as
      53             :  * remainder.
      54             :  *
      55             :  * It returns the number of sal_uInt16s which are contained in the described
      56             :  * set of sal_uInt16s.
      57             :  */
      58      464754 : sal_uInt16 InitializeRanges_Impl( sal_uInt16 *&rpRanges, va_list pArgs,
      59             :                                sal_uInt16 nWh1, sal_uInt16 nWh2, sal_uInt16 nNull )
      60             : {
      61      464754 :     sal_uInt16 nSize = 0, nIns = 0;
      62      464754 :     std::vector<sal_uInt16> aNumArr;
      63      464754 :     aNumArr.push_back( nWh1 );
      64      464754 :     aNumArr.push_back( nWh2 );
      65             :     DBG_ASSERT( nWh1 <= nWh2, "Invalid range" );
      66      464754 :     nSize += nWh2 - nWh1 + 1;
      67      464754 :     aNumArr.push_back( nNull );
      68      464754 :     bool bEndOfRange = false;
      69     5308664 :     while ( 0 !=
      70             :             ( nIns =
      71             :               sal::static_int_cast< sal_uInt16 >(
      72     8293558 :                   va_arg( pArgs, int ) ) ) )
      73             :     {
      74     3914402 :         bEndOfRange = !bEndOfRange;
      75     3914402 :         if ( bEndOfRange )
      76             :         {
      77     2189578 :             const sal_uInt16 nPrev(*aNumArr.rbegin());
      78             :             DBG_ASSERT( nPrev <= nIns, "Invalid range" );
      79     2189578 :             nSize += nIns - nPrev + 1;
      80             :         }
      81     3914402 :         aNumArr.push_back( nIns );
      82             :     }
      83             : 
      84             :     assert( bEndOfRange ); // odd number of WhichIds
      85             : 
      86             :     // Now all ranges are present
      87      464754 :     rpRanges = new sal_uInt16[ aNumArr.size() + 1 ];
      88      464754 :     std::copy( aNumArr.begin(), aNumArr.end(), rpRanges);
      89      464754 :     *(rpRanges + aNumArr.size()) = 0;
      90             : 
      91      464754 :     return nSize;
      92             : }
      93             : 
      94             : /**
      95             :  * Determines the number of sal_uInt16s in a 0-terminated array of pairs of
      96             :  * sal_uInt16s.
      97             :  * The terminating 0 is not included in the count.
      98             :  */
      99       75616 : sal_uInt16 Count_Impl( const sal_uInt16 *pRanges )
     100             : {
     101       75616 :     sal_uInt16 nCount = 0;
     102      378080 :     while ( *pRanges )
     103             :     {
     104      226848 :         nCount += 2;
     105      226848 :         pRanges += 2;
     106             :     }
     107       75616 :     return nCount;
     108             : }
     109             : 
     110             : /**
     111             :  * Determines the total number of sal_uInt16s described in a 0-terminated
     112             :  * array of pairs of sal_uInt16s, each representing an range of sal_uInt16s.
     113             :  */
     114       37808 : sal_uInt16 Capacity_Impl( const sal_uInt16 *pRanges )
     115             : {
     116       37808 :     sal_uInt16 nCount = 0;
     117             : 
     118       37808 :     if ( pRanges )
     119             :     {
     120      207944 :         while ( *pRanges )
     121             :         {
     122      132328 :             nCount += pRanges[1] - pRanges[0] + 1;
     123      132328 :             pRanges += 2;
     124             :         }
     125             :     }
     126       37808 :     return nCount;
     127             : }
     128             : 
     129             : /**
     130             :  * Copy ctor
     131             :  */
     132           0 : SfxUShortRanges::SfxUShortRanges( const SfxUShortRanges &rOrig )
     133             : {
     134           0 :     if ( rOrig._pRanges )
     135             :     {
     136           0 :         sal_uInt16 nCount = Count_Impl( rOrig._pRanges ) + 1;
     137           0 :         _pRanges = new sal_uInt16[nCount];
     138           0 :         memcpy( _pRanges, rOrig._pRanges, sizeof(sal_uInt16) * nCount );
     139             :     }
     140             :     else
     141           0 :         _pRanges = 0;
     142           0 : }
     143             : 
     144             : /**
     145             :  * Constructs a SfxUShortRanges instance from one range of sal_uInt16s.
     146             :  *
     147             :  * Precondition: nWhich1 <= nWhich2
     148             :  */
     149       37808 : SfxUShortRanges::SfxUShortRanges( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
     150       37808 : :   _pRanges( new sal_uInt16[3] )
     151             : {
     152       37808 :     _pRanges[0] = nWhich1;
     153       37808 :     _pRanges[1] = nWhich2;
     154       37808 :     _pRanges[2] = 0;
     155       37808 : }
     156             : 
     157             : /**
     158             :  * Constcurts an SfxUShortRanges-instance from an sorted ranges of sal_uInt16s,
     159             :  * terminates with on 0.
     160             :  *
     161             :  * Precondition: for each n >= 0 && n < (sizeof(pArr)-1)
     162             :  *     pArr[2n] <= pArr[2n+1] && ( pArr[2n+2]-pArr[2n+1] ) > 1
     163             :  */
     164       37808 : SfxUShortRanges::SfxUShortRanges( const sal_uInt16* pArr )
     165             : {
     166             :     DBG_CHECK_RANGES(sal_uInt16, pArr);
     167       37808 :     sal_uInt16 nCount = Count_Impl(pArr) + 1;
     168       37808 :     _pRanges = new sal_uInt16[ nCount ];
     169       37808 :     memcpy( _pRanges, pArr, sizeof(sal_uInt16) * nCount );
     170       37808 : }
     171             : 
     172             : 
     173           0 : bool SfxUShortRanges::operator==( const SfxUShortRanges &rOther ) const
     174             : {
     175             :     // Object pointers equal?
     176           0 :     if ( this == &rOther )
     177           0 :         return true;
     178             : 
     179             :     // Ranges pointers equal?
     180           0 :     if ( _pRanges == rOther._pRanges )
     181           0 :         return true;
     182             : 
     183             :     // Counts equal?
     184           0 :     sal_uInt16 nCount = Count();
     185           0 :     if ( nCount != rOther.Count() )
     186           0 :         return false;
     187             : 
     188             :     // Check arrays.
     189           0 :     sal_uInt16 n = 0;
     190           0 :     while( _pRanges[ n ] != 0 )
     191             :     {
     192             :         // Elements at current position equal?
     193           0 :         if ( _pRanges[ n ] != rOther._pRanges[ n ] )
     194           0 :             return false;
     195             : 
     196           0 :         ++n;
     197             :     }
     198             : 
     199           0 :     return true;
     200             : }
     201             : 
     202             : /**
     203             :  * Assigns ranges from 'rRanges' to '*this'.
     204             :  */
     205           0 : SfxUShortRanges& SfxUShortRanges::operator =
     206             : (
     207             :     const SfxUShortRanges &rRanges
     208             : )
     209             : {
     210             :     // special case: assign itself
     211           0 :     if ( &rRanges == this )
     212           0 :         return *this;
     213             : 
     214           0 :     delete[] _pRanges;
     215             : 
     216             :     // special case: 'rRanges' is empty
     217           0 :     if ( rRanges.IsEmpty() )
     218           0 :         _pRanges = 0;
     219             :     else
     220             :     {
     221             :         // copy ranges
     222           0 :         sal_uInt16 nCount = Count_Impl( rRanges._pRanges ) + 1;
     223           0 :         _pRanges = new sal_uInt16[ nCount ];
     224           0 :         memcpy( _pRanges, rRanges._pRanges, sizeof(sal_uInt16) * nCount );
     225             :     }
     226           0 :     return *this;
     227             : }
     228             : 
     229             : /**
     230             :  * Merges *this with 'rRanges'.
     231             :  *  for each sal_uInt16 n:
     232             :  *    this->Contains( n ) || rRanges.Contains( n ) => this'->Contains( n )
     233             :  *    !this->Contains( n ) && !rRanges.Contains( n ) => !this'->Contains( n )
     234             :  */
     235       37808 : SfxUShortRanges& SfxUShortRanges::operator +=
     236             : (
     237             :     const SfxUShortRanges &rRanges
     238             : )
     239             : {
     240             :     // special cases: one is empty
     241       37808 :     if ( rRanges.IsEmpty() )
     242           0 :         return *this;
     243       37808 :     if ( IsEmpty() )
     244           0 :         return *this = rRanges;
     245             : 
     246             :     // First, run through _pRanges and rRanges._pRanges and determine the size of
     247             :     // the new, merged ranges:
     248       37808 :     sal_uInt16 nCount = 0;
     249       37808 :     const sal_uInt16 * pRA = _pRanges;
     250       37808 :     const sal_uInt16 * pRB = rRanges._pRanges;
     251             : 
     252             :     for (;;)
     253             :     {
     254             :         // The first pair of pRA has a lower lower bound than the first pair
     255             :         // of pRB:
     256      132328 :         if (pRA[0] > pRB[0])
     257       28356 :             Swap_Impl(pRA, pRB);
     258             : 
     259             :         // We are done with the merging if at least pRA is exhausted:
     260      132328 :         if (!pRA[0])
     261       37808 :             break;
     262             : 
     263             :         for (;;)
     264             :         {
     265             :             // Skip those pairs in pRB that completely lie in the first pair
     266             :             // of pRA:
     267      189040 :             while (pRB[1] <= pRA[1])
     268             :             {
     269           0 :                 pRB += 2;
     270             : 
     271             :                 // Watch out for exhaustion of pRB:
     272           0 :                 if (!pRB[0])
     273             :                 {
     274           0 :                     Swap_Impl(pRA, pRB);
     275           0 :                     goto count_rest;
     276             :                 }
     277             :             }
     278             : 
     279             :             // If the next pair of pRA does not at least touch the current new
     280             :             // pair, we are done with the current new pair:
     281       94520 :             if (pRB[0] > pRA[1] + 1)
     282       94520 :                 break;
     283             : 
     284             :             // The next pair of pRB extends the current new pair; first,
     285             :             // extend the current new pair (we are done if pRB is then
     286             :             // exhausted); second, switch the roles of pRA and pRB in order to
     287             :             // merge in those following pairs of the original pRA that will
     288             :             // lie in the (now larger) current new pair or will even extend it
     289             :             // further:
     290           0 :             pRA += 2;
     291           0 :             if (!pRA[0])
     292           0 :                 goto count_rest;
     293           0 :             Swap_Impl(pRA, pRB);
     294             :         }
     295             : 
     296             :         // Done with the current new pair:
     297       94520 :         pRA += 2;
     298       94520 :         nCount += 2;
     299             :     }
     300             : 
     301             :     // Only pRB has more pairs available, pRA is already exhausted:
     302             : count_rest:
     303       75616 :     for (; pRB[0]; pRB += 2)
     304       37808 :         nCount += 2;
     305             : 
     306             :     // Now, create new ranges of the correct size and, on a second run through
     307             :     // _pRanges and rRanges._pRanges, copy the merged pairs into the new
     308             :     // ranges:
     309       37808 :     sal_uInt16 * pNew = new sal_uInt16[nCount + 1];
     310       37808 :     pRA = _pRanges;
     311       37808 :     pRB = rRanges._pRanges;
     312       37808 :     sal_uInt16 * pRN = pNew;
     313             : 
     314             :     for (;;)
     315             :     {
     316             :         // The first pair of pRA has a lower lower bound than the first pair
     317             :         // of pRB:
     318      132328 :         if (pRA[0] > pRB[0])
     319       28356 :             Swap_Impl(pRA, pRB);
     320             : 
     321             :         // We are done with the merging if at least pRA is exhausted:
     322      132328 :         if (!pRA[0])
     323       37808 :             break;
     324             : 
     325             :         // Lower bound of current new pair is already known:
     326       94520 :         *pRN++ = pRA[0];
     327             : 
     328             :         for (;;)
     329             :         {
     330             :             // Skip those pairs in pRB that completely lie in the first pair
     331             :             // of pRA:
     332      189040 :             while (pRB[1] <= pRA[1])
     333             :             {
     334           0 :                 pRB += 2;
     335             : 
     336             :                 // Watch out for exhaustion of pRB:
     337           0 :                 if (!pRB[0])
     338             :                 {
     339           0 :                     Swap_Impl(pRA, pRB);
     340           0 :                     ++pRB;
     341           0 :                     goto copy_rest;
     342             :                 }
     343             :             }
     344             : 
     345             :             // If the next pair of pRA does not at least touch the current new
     346             :             // pair, we are done with the current new pair:
     347       94520 :             if (pRB[0] > pRA[1] + 1)
     348       94520 :                 break;
     349             : 
     350             :             // The next pair of pRB extends the current new pair; first,
     351             :             // extend the current new pair (we are done if pRB is then
     352             :             // exhausted); second, switch the roles of pRA and pRB in order to
     353             :             // merge in those following pairs of the original pRA that will
     354             :             // lie in the (now larger) current new pair or will even extend it
     355             :             // further:
     356           0 :             pRA += 2;
     357           0 :             if (!pRA[0])
     358             :             {
     359           0 :                 ++pRB;
     360           0 :                 goto copy_rest;
     361             :             }
     362           0 :             Swap_Impl(pRA, pRB);
     363             :         }
     364             : 
     365             :         // Done with the current new pair, now upper bound is also known:
     366       94520 :         *pRN++ = pRA[1];
     367       94520 :         pRA += 2;
     368             :     }
     369             : 
     370             :     // Only pRB has more pairs available (which are copied to the new ranges
     371             :     // unchanged), pRA is already exhausted:
     372             : copy_rest:
     373      151232 :     for (; *pRB;)
     374       75616 :         *pRN++ = *pRB++;
     375       37808 :     *pRN = 0;
     376             : 
     377       37808 :     delete[] _pRanges;
     378       37808 :     _pRanges = pNew;
     379             : 
     380      226848 :     return *this;
     381             : }
     382             : 
     383             : /**
     384             :  * Removes 'rRanges' from '*this'.
     385             :  *  for each sal_uInt16 n:
     386             :  *    this->Contains( n ) && rRanges.Contains( n ) => !this'->Contains( n )
     387             :  *    this->Contains( n ) && !rRanges.Contains( n ) => this'->Contains( n )
     388             :  *    !this->Contains( n ) => !this'->Contains( n )
     389             :  */
     390           0 : SfxUShortRanges& SfxUShortRanges::operator -=
     391             : (
     392             :     const SfxUShortRanges &rRanges
     393             : )
     394             : {
     395             :     // special cases: one is empty
     396           0 :     if ( rRanges.IsEmpty() || IsEmpty() )
     397           0 :         return *this;
     398             : 
     399             :     // differentiate 'rRanges' in a temporary copy of '*this'
     400             :     // (size is computed for maximal possibly split-count plus terminating 0)
     401           0 :     sal_uInt16 nThisSize = Count_Impl(_pRanges);
     402           0 :     sal_uInt16 nTargetSize = 1 + (  nThisSize + Count_Impl(rRanges._pRanges) );
     403           0 :     boost::scoped_array<sal_uInt16> pTarget(new sal_uInt16[ nTargetSize ]);
     404           0 :     memset( pTarget.get(), 0, sizeof(sal_uInt16)*nTargetSize );
     405           0 :     memcpy( pTarget.get(), _pRanges, sizeof(sal_uInt16)*nThisSize );
     406             : 
     407           0 :     sal_uInt16 nPos1 = 0, nPos2 = 0, nTargetPos = 0;
     408           0 :     while( _pRanges[ nPos1 ] )
     409             :     {
     410           0 :         sal_uInt16 l1 = _pRanges[ nPos1 ];      // lower bound of interval 1
     411           0 :         sal_uInt16 u1 = _pRanges[ nPos1+1 ];    // upper bound of interval 1
     412           0 :         sal_uInt16 l2 = rRanges._pRanges[ nPos2 ];      // lower bound of interval 2
     413           0 :         sal_uInt16 u2 = rRanges._pRanges[ nPos2+1 ];    // upper bound of interval 2
     414             : 
     415             :         // boundary cases
     416             :         // * subtrahend is empty -> copy the minuend
     417           0 :         if( !l2 )
     418             :         {
     419           0 :             pTarget[ nTargetPos ] = l1;
     420           0 :             pTarget[ nTargetPos+1 ] = u1;
     421           0 :             nTargetPos += 2;
     422           0 :             nPos1 += 2;
     423           0 :             continue;
     424             :         }
     425             :         // * next subtrahend interval is completely higher -> copy the minuend
     426           0 :         if( u1 < l2 )
     427             :         {
     428           0 :             pTarget[ nTargetPos ] = l1;
     429           0 :             pTarget[ nTargetPos+1 ] = u1;
     430           0 :             nTargetPos += 2;
     431           0 :             nPos1 += 2;
     432           0 :             continue;
     433             :         }
     434             : 
     435             :         // * next subtrahend interval is completely lower -> try next
     436           0 :         if( u2 < l1 )
     437             :         {
     438           0 :             nPos2 += 2;
     439           0 :             continue;
     440             :         }
     441             : 
     442             :         // intersecting cases
     443             :         // * subtrahend cuts out from the beginning of the minuend
     444           0 :         if( l2 <= l1 && u2 <= u1 )
     445             :         {
     446             :             // reduce minuend interval, try again (minuend might be affected by other subtrahend intervals)
     447           0 :             _pRanges[ nPos1 ] = u2 + 1;
     448           0 :             nPos2 += 2; // this cannot hurt any longer
     449           0 :             continue;
     450             :         }
     451             : 
     452             :         // * subtrahend cuts out from the end of the minuend
     453           0 :         if( l1 <= l2 && u1 <= u2 )
     454             :         {
     455             :             // copy remaining part of minuend (cannot be affected by other intervals)
     456           0 :             if( l1 < l2 ) // anything left at all?
     457             :             {
     458           0 :                 pTarget[ nTargetPos ] = l1;
     459           0 :                 pTarget[ nTargetPos+1 ] = l2 - 1;
     460           0 :                 nTargetPos += 2;
     461             :                 // do not increment nPos2, might affect next minuend interval, too
     462             :             }
     463           0 :             nPos1 += 2; // nothing left at all
     464           0 :             continue;
     465             :         }
     466             : 
     467             :         // * subtrahend completely deletes minuend (larger or same at both ends)
     468           0 :         if( l1 >= l2 && u1 <= u2 )
     469             :         {
     470           0 :             nPos1 += 2; // minuend deleted
     471             :             // do not increment nPos2, might affect next minuend interval, too
     472           0 :             continue;
     473             :         }
     474             : 
     475             :         // * subtrahend divides minuend into two pieces
     476           0 :         if( l1 <= l2 && u1 >= u2 ) // >= and <= since they may be something left only at one side
     477             :         {
     478             :             // left side
     479           0 :             if( l1 < l2 ) // anything left at all
     480             :             {
     481           0 :                 pTarget[ nTargetPos ] = l1;
     482           0 :                 pTarget[ nTargetPos+1 ] = l2 - 1;
     483           0 :                 nTargetPos += 2;
     484             :             }
     485             : 
     486             :             // right side
     487           0 :             if( u1 > u2 ) // anything left at all
     488             :             {
     489             :                 // reduce minuend interval, try again (minuend might be affected by other subtrahend itnervals )
     490           0 :                 _pRanges[ nPos1 ] = u2 + 1;
     491             :             }
     492             : 
     493             :             // subtrahend is completely used
     494           0 :             nPos2 += 2;
     495           0 :             continue;
     496             :         }
     497             : 
     498             :         // we should never be here
     499             :         OSL_FAIL( "SfxUShortRanges::operator-=: internal error" );
     500             :     } // while
     501             : 
     502           0 :     pTarget[ nTargetPos ] = 0;
     503             : 
     504             :     // assign the differentiated ranges
     505           0 :     delete[] _pRanges;
     506             : 
     507           0 :     sal_uInt16 nUShorts = Count_Impl(pTarget.get()) + 1;
     508           0 :     if ( 1 != nUShorts )
     509             :     {
     510           0 :         _pRanges = new sal_uInt16[ nUShorts ];
     511           0 :         memcpy( _pRanges, pTarget.get(), nUShorts * sizeof(sal_uInt16) );
     512             :     }
     513             :     else
     514           0 :         _pRanges = 0;
     515             : 
     516           0 :     return *this;
     517             : }
     518             : 
     519             : /**
     520             :  * Determines intersection of '*this' with 'rRanges'.
     521             :  *   for each sal_uInt16 n:
     522             :  *     this->Contains( n ) && rRanges.Contains( n ) => this'->Contains( n )
     523             :  *     !this->Contains( n ) => !this'->Contains( n )
     524             :  *     !rRanges.Contains( n ) => !this'->Contains( n )
     525             :  */
     526           0 : SfxUShortRanges& SfxUShortRanges::operator /=
     527             : (
     528             :     const SfxUShortRanges &rRanges
     529             : )
     530             : {
     531             :     // boundary cases
     532             :     // * first set is empty -> nothing to be done
     533             :     // * second set is empty -> delete first set
     534           0 :     if( rRanges.IsEmpty() )
     535             :     {
     536           0 :         delete[] _pRanges;
     537             : 
     538           0 :         _pRanges = new sal_uInt16[1];
     539           0 :         _pRanges[0] = 0;
     540             : 
     541           0 :         return *this;
     542             :     }
     543             : 
     544             :     // intersect 'rRanges' in a temporary copy of '*this'
     545             :     // (size is computed for maximal possibly split-count plus terminating 0)
     546           0 :     sal_uInt16 nThisSize = Count_Impl(_pRanges);
     547           0 :     sal_uInt16 nTargetSize = 1 + (  nThisSize + Count_Impl(rRanges._pRanges) );
     548           0 :     boost::scoped_array<sal_uInt16> pTarget(new sal_uInt16[ nTargetSize ]);
     549           0 :     memset( pTarget.get(), 0, sizeof(sal_uInt16)*nTargetSize );
     550           0 :     memcpy( pTarget.get(), _pRanges, sizeof(sal_uInt16)*nThisSize );
     551             : 
     552           0 :     sal_uInt16 nPos1 = 0, nPos2 = 0, nTargetPos = 0;
     553           0 :     while( _pRanges[ nPos1 ] != 0 && rRanges._pRanges[ nPos2 ] != 0 )
     554             :     {
     555           0 :         sal_uInt16 l1 = _pRanges[ nPos1 ];      // lower bound of interval 1
     556           0 :         sal_uInt16 u1 = _pRanges[ nPos1+1 ];    // upper bound of interval 1
     557           0 :         sal_uInt16 l2 = rRanges._pRanges[ nPos2 ];      // lower bound of interval 2
     558           0 :         sal_uInt16 u2 = rRanges._pRanges[ nPos2+1 ];    // upper bound of interval 2
     559             : 
     560           0 :         if( u1 < l2 )
     561             :         {
     562             :             // current interval in s1 is completely before ci in s2
     563           0 :             nPos1 += 2;
     564           0 :             continue;
     565             :         }
     566           0 :         if( u2 < l1 )
     567             :         {
     568             :             // ci in s2 is completely before ci in s1
     569           0 :             nPos2 += 2;
     570           0 :             continue;
     571             :         }
     572             : 
     573             :         // assert: there exists an intersection between ci1 and ci2
     574             : 
     575           0 :         if( l1 <= l2 )
     576             :         {
     577             :             // c1 "is more to the left" than c2
     578             : 
     579           0 :             if( u1 <= u2 )
     580             :             {
     581           0 :                 pTarget[ nTargetPos ] = l2;
     582           0 :                 pTarget[ nTargetPos+1 ] = u1;
     583           0 :                 nTargetPos += 2;
     584           0 :                 nPos1 += 2;
     585           0 :                 continue;
     586             :             }
     587             :             else
     588             :             {
     589           0 :                 pTarget[ nTargetPos ] = l2;
     590           0 :                 pTarget[ nTargetPos+1 ] = u2;
     591           0 :                 nTargetPos += 2;
     592           0 :                 nPos2 += 2;
     593             :             }
     594             :         }
     595             :         else
     596             :         {
     597             :             // c2 "is more to the left" than c1"
     598             : 
     599           0 :             if( u1 > u2 )
     600             :             {
     601           0 :                 pTarget[ nTargetPos ] = l1;
     602           0 :                 pTarget[ nTargetPos+1 ] = u2;
     603           0 :                 nTargetPos += 2;
     604           0 :                 nPos2 += 2;
     605             :             }
     606             :             else
     607             :             {
     608           0 :                 pTarget[ nTargetPos ] = l1;
     609           0 :                 pTarget[ nTargetPos+1 ] = u1;
     610           0 :                 nTargetPos += 2;
     611           0 :                 nPos1 += 2;
     612             :             }
     613             :         }
     614             :     }; // while
     615           0 :     pTarget[ nTargetPos ] = 0;
     616             : 
     617             :     // assign the intersected ranges
     618           0 :     delete[] _pRanges;
     619             : 
     620           0 :     sal_uInt16 nUShorts = Count_Impl(pTarget.get()) + 1;
     621           0 :     if ( 1 != nUShorts )
     622             :     {
     623           0 :         _pRanges = new sal_uInt16[ nUShorts ];
     624           0 :         memcpy( _pRanges, pTarget.get(), nUShorts * sizeof(sal_uInt16) );
     625             :     }
     626             :     else
     627           0 :         _pRanges = 0;
     628             : 
     629           0 :     return *this;
     630             : }
     631             : 
     632             : /**
     633             :  * Determines the number of USHORTs in the set described by the ranges
     634             :  * of USHORTs in '*this'.
     635             :  */
     636           0 : sal_uInt16 SfxUShortRanges::Count() const
     637             : {
     638           0 :     return Capacity_Impl( _pRanges );
     639             : }
     640             : 
     641             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11