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

Generated by: LCOV version 1.10