LCOV - code coverage report
Current view: top level - libreoffice/sc/source/core/data - markarr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 140 190 73.7 %
Date: 2012-12-17 Functions: 10 14 71.4 %
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 "markarr.hxx"
      21             : #include "global.hxx"
      22             : #include "address.hxx"
      23             : 
      24             : // STATIC DATA -----------------------------------------------------------
      25             : 
      26             : //------------------------------------------------------------------------
      27             : 
      28      204800 : ScMarkArray::ScMarkArray() :
      29             :     nCount( 0 ),
      30             :     nLimit( 0 ),
      31      204800 :     pData( NULL )
      32             : {
      33             :     // special case "no marks" with pData = NULL
      34      204800 : }
      35             : 
      36             : //------------------------------------------------------------------------
      37             : 
      38      204800 : ScMarkArray::~ScMarkArray()
      39             : {
      40      204800 :     delete[] pData;
      41      204800 : }
      42             : 
      43             : //------------------------------------------------------------------------
      44             : 
      45        1016 : void ScMarkArray::Reset( sal_Bool bMarked )
      46             : {
      47             :     // always create pData here
      48             :     // (or have separate method to ensure pData)
      49             : 
      50        1016 :     delete[] pData;
      51             : 
      52        1016 :     nCount = nLimit = 1;
      53        1016 :     pData = new ScMarkEntry[1];
      54        1016 :     pData[0].nRow = MAXROW;
      55        1016 :     pData[0].bMarked = bMarked;
      56        1016 : }
      57             : 
      58             : //------------------------------------------------------------------------
      59             : 
      60        2478 : sal_Bool ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
      61             : {
      62        2478 :     long    nHi         = static_cast<long>(nCount) - 1;
      63        2478 :     long    i           = 0;
      64        2478 :     sal_Bool    bFound      = (nCount == 1);
      65        2478 :     if (pData)
      66             :     {
      67        2478 :         long    nLo         = 0;
      68        2478 :         long    nStartRow   = 0;
      69        9646 :         while ( !bFound && nLo <= nHi )
      70             :         {
      71        4690 :             i = (nLo + nHi) / 2;
      72        4690 :             if (i > 0)
      73        3392 :                 nStartRow = (long) pData[i - 1].nRow;
      74             :             else
      75        1298 :                 nStartRow = -1;
      76        4690 :             long nEndRow = (long) pData[i].nRow;
      77        4690 :             if (nEndRow < (long) nRow)
      78        2554 :                 nLo = ++i;
      79             :             else
      80        2136 :                 if (nStartRow >= (long) nRow)
      81           0 :                     nHi = --i;
      82             :                 else
      83        2136 :                     bFound = sal_True;
      84             :         }
      85             :     }
      86             :     else
      87           0 :         bFound = false;
      88             : 
      89        2478 :     if (bFound)
      90        2478 :         nIndex=(SCSIZE)i;
      91             :     else
      92           0 :         nIndex=0;
      93        2478 :     return bFound;
      94             : }
      95             : 
      96           0 : sal_Bool ScMarkArray::GetMark( SCROW nRow ) const
      97             : {
      98             :     SCSIZE i;
      99           0 :     if (Search( nRow, i ))
     100           0 :         return pData[i].bMarked;
     101             :     else
     102           0 :         return false;
     103             : 
     104             : }
     105             : 
     106             : //------------------------------------------------------------------------
     107             : 
     108        3312 : void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, sal_Bool bMarked )
     109             : {
     110        3312 :     if (ValidRow(nStartRow) && ValidRow(nEndRow))
     111             :     {
     112        3312 :         if ((nStartRow == 0) && (nEndRow == MAXROW))
     113             :         {
     114           0 :             Reset(bMarked);
     115             :         }
     116             :         else
     117             :         {
     118        3312 :             if (!pData)
     119        1016 :                 Reset(false);   // create pData for further processing - could use special case handling!
     120             : 
     121        3312 :             SCSIZE nNeeded = nCount + 2;
     122        3312 :             if ( nLimit < nNeeded )
     123             :             {
     124        1200 :                 nLimit += SC_MARKARRAY_DELTA;
     125        1200 :                 if ( nLimit < nNeeded )
     126           0 :                     nLimit = nNeeded;
     127        1200 :                 ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
     128        1200 :                 memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
     129        1200 :                 delete[] pData;
     130        1200 :                 pData = pNewData;
     131             :             }
     132             : 
     133             :             SCSIZE ni;          // number of entries in beginning
     134             :             SCSIZE nInsert;     // insert position (MAXROW+1 := no insert)
     135        3312 :             sal_Bool bCombined = false;
     136        3312 :             sal_Bool bSplit = false;
     137        3312 :             if ( nStartRow > 0 )
     138             :             {
     139             :                 // skip beginning
     140             :                 SCSIZE nIndex;
     141        2478 :                 Search( nStartRow, nIndex );
     142        2478 :                 ni = nIndex;
     143             : 
     144        2478 :                 nInsert = MAXROWCOUNT;
     145        2478 :                 if ( pData[ni].bMarked != bMarked )
     146             :                 {
     147        2458 :                     if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
     148             :                     {   // may be a split or a simple insert or just a shrink,
     149             :                         // row adjustment is done further down
     150         734 :                         if ( pData[ni].nRow > nEndRow )
     151         728 :                             bSplit = sal_True;
     152         734 :                         ni++;
     153         734 :                         nInsert = ni;
     154             :                     }
     155        1724 :                     else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
     156        1724 :                         nInsert = ni;
     157             :                 }
     158        2478 :                 if ( ni > 0 && pData[ni-1].bMarked == bMarked )
     159             :                 {   // combine
     160        1724 :                     pData[ni-1].nRow = nEndRow;
     161        1724 :                     nInsert = MAXROWCOUNT;
     162        1724 :                     bCombined = sal_True;
     163             :                 }
     164             :             }
     165             :             else
     166             :         {
     167         834 :                 nInsert = 0;
     168         834 :                 ni = 0;
     169             :         }
     170             : 
     171        3312 :             SCSIZE nj = ni;     // stop position of range to replace
     172        6876 :             while ( nj < nCount && pData[nj].nRow <= nEndRow )
     173         252 :                 nj++;
     174        3312 :             if ( !bSplit )
     175             :             {
     176        2584 :                 if ( nj < nCount && pData[nj].bMarked == bMarked )
     177             :                 {   // combine
     178           8 :                     if ( ni > 0 )
     179             :                     {
     180           8 :                         if ( pData[ni-1].bMarked == bMarked )
     181             :                         {   // adjacent entries
     182           2 :                             pData[ni-1].nRow = pData[nj].nRow;
     183           2 :                             nj++;
     184             :                         }
     185           6 :                         else if ( ni == nInsert )
     186           0 :                             pData[ni-1].nRow = nStartRow - 1;   // shrink
     187             :                     }
     188           8 :                     nInsert = MAXROWCOUNT;
     189           8 :                     bCombined = sal_True;
     190             :                 }
     191        2576 :                 else if ( ni > 0 && ni == nInsert )
     192           6 :                     pData[ni-1].nRow = nStartRow - 1;   // shrink
     193             :             }
     194        3312 :             if ( ni < nj )
     195             :             {   // remove middle entries
     196         252 :                 if ( !bCombined )
     197             :                 {   // replace one entry
     198         174 :                     pData[ni].nRow = nEndRow;
     199         174 :                     pData[ni].bMarked = bMarked;
     200         174 :                     ni++;
     201         174 :                     nInsert = MAXROWCOUNT;
     202             :                 }
     203         252 :                 if ( ni < nj )
     204             :                 {   // remove entries
     205          78 :                     memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
     206          78 :                     nCount -= nj - ni;
     207             :                 }
     208             :             }
     209             : 
     210        3312 :             if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
     211             :             {   // insert or append new entry
     212        1408 :                 if ( nInsert <= nCount )
     213             :                 {
     214        1408 :                     if ( !bSplit )
     215         680 :                         memmove( pData + nInsert + 1, pData + nInsert,
     216        1360 :                             (nCount - nInsert) * sizeof(ScMarkEntry) );
     217             :                     else
     218             :                     {
     219         728 :                         memmove( pData + nInsert + 2, pData + nInsert,
     220        1456 :                             (nCount - nInsert) * sizeof(ScMarkEntry) );
     221         728 :                         pData[nInsert+1] = pData[nInsert-1];
     222         728 :                         nCount++;
     223             :                     }
     224             :                 }
     225        1408 :                 if ( nInsert )
     226         734 :                     pData[nInsert-1].nRow = nStartRow - 1;
     227        1408 :                 pData[nInsert].nRow = nEndRow;
     228        1408 :                 pData[nInsert].bMarked = bMarked;
     229        1408 :                 nCount++;
     230             :             }
     231             :         }
     232             :     }
     233        3312 : }
     234             : 
     235           0 : sal_Bool ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
     236             : {
     237             :     SCSIZE nStartIndex;
     238             :     SCSIZE nEndIndex;
     239             : 
     240           0 :     if (Search( nStartRow, nStartIndex ))
     241           0 :         if (pData[nStartIndex].bMarked)
     242           0 :             if (Search( nEndRow, nEndIndex ))
     243           0 :                 if (nEndIndex==nStartIndex)
     244           0 :                     return sal_True;
     245             : 
     246           0 :     return false;
     247             : }
     248             : 
     249          12 : sal_Bool ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
     250             : {
     251          12 :     sal_Bool bRet = false;
     252          12 :     if ( nCount == 1 )
     253             :     {
     254           0 :         if ( pData[0].bMarked )
     255             :         {
     256           0 :             rStartRow = 0;
     257           0 :             rEndRow = MAXROW;
     258           0 :             bRet = sal_True;
     259             :         }
     260             :     }
     261          12 :     else if ( nCount == 2 )
     262             :     {
     263           0 :         if ( pData[0].bMarked )
     264             :         {
     265           0 :             rStartRow = 0;
     266           0 :             rEndRow = pData[0].nRow;
     267             :         }
     268             :         else
     269             :         {
     270           0 :             rStartRow = pData[0].nRow + 1;
     271           0 :             rEndRow = MAXROW;
     272             :         }
     273           0 :         bRet = sal_True;
     274             :     }
     275          12 :     else if ( nCount == 3 )
     276             :     {
     277          12 :         if ( pData[1].bMarked )
     278             :         {
     279          12 :             rStartRow = pData[0].nRow + 1;
     280          12 :             rEndRow = pData[1].nRow;
     281          12 :             bRet = sal_True;
     282             :         }
     283             :     }
     284          12 :     return bRet;
     285             : }
     286             : 
     287        2048 : void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
     288             : {
     289        2048 :     delete[] rDestMarkArray.pData;
     290             : 
     291        2048 :     if (pData)
     292             :     {
     293           2 :         rDestMarkArray.pData = new ScMarkEntry[nCount];
     294           2 :         memcpy( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
     295             :     }
     296             :     else
     297        2046 :         rDestMarkArray.pData = NULL;
     298             : 
     299        2048 :     rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
     300        2048 : }
     301             : 
     302           0 : SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, sal_Bool bUp ) const
     303             : {
     304           0 :     if (!pData)
     305           0 :         const_cast<ScMarkArray*>(this)->Reset(false);   // create pData for further processing
     306             : 
     307           0 :     SCsROW nRet = nRow;
     308           0 :     if (VALIDROW(nRow))
     309             :     {
     310             :         SCSIZE nIndex;
     311           0 :         Search(nRow, nIndex);
     312           0 :         if (!pData[nIndex].bMarked)
     313             :         {
     314           0 :             if (bUp)
     315             :             {
     316           0 :                 if (nIndex>0)
     317           0 :                     nRet = pData[nIndex-1].nRow;
     318             :                 else
     319           0 :                     nRet = -1;
     320             :             }
     321             :             else
     322           0 :                 nRet = pData[nIndex].nRow + 1;
     323             :         }
     324             :     }
     325           0 :     return nRet;
     326             : }
     327             : 
     328           0 : SCROW ScMarkArray::GetMarkEnd( SCROW nRow, sal_Bool bUp ) const
     329             : {
     330           0 :     if (!pData)
     331           0 :         const_cast<ScMarkArray*>(this)->Reset(false);   // create pData for further processing
     332             : 
     333             :     SCROW nRet;
     334             :     SCSIZE nIndex;
     335           0 :     Search(nRow, nIndex);
     336             :     OSL_ENSURE( pData[nIndex].bMarked, "GetMarkEnd ohne bMarked" );
     337           0 :     if (bUp)
     338             :     {
     339           0 :         if (nIndex>0)
     340           0 :             nRet = pData[nIndex-1].nRow + 1;
     341             :         else
     342           0 :             nRet = 0;
     343             :     }
     344             :     else
     345           0 :         nRet = pData[nIndex].nRow;
     346             : 
     347           0 :     return nRet;
     348             : }
     349             : 
     350             : //
     351             : //  -------------- Iterator ----------------------------------------------
     352             : //
     353             : 
     354      225682 : ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
     355             :     pArray( pNewArray ),
     356      225682 :     nPos( 0 )
     357             : {
     358      225682 : }
     359             : 
     360      225682 : ScMarkArrayIter::~ScMarkArrayIter()
     361             : {
     362      225682 : }
     363             : 
     364      227526 : sal_Bool ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
     365             : {
     366      227526 :     if ( nPos >= pArray->nCount )
     367      224336 :         return false;
     368        7554 :     while (!pArray->pData[nPos].bMarked)
     369             :     {
     370        2386 :         ++nPos;
     371        2386 :         if ( nPos >= pArray->nCount )
     372        1212 :             return false;
     373             :     }
     374        1978 :     rBottom = pArray->pData[nPos].nRow;
     375        1978 :     if (nPos==0)
     376         804 :         rTop = 0;
     377             :     else
     378        1174 :         rTop = pArray->pData[nPos-1].nRow + 1;
     379        1978 :     ++nPos;
     380        1978 :     return sal_True;
     381             : }
     382             : 
     383             : 
     384             : 
     385             : 
     386             : 
     387             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10