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

Generated by: LCOV version 1.10