LCOV - code coverage report
Current view: top level - sc/source/core/data - markarr.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 188 199 94.5 %
Date: 2014-11-03 Functions: 17 17 100.0 %
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     1900544 : ScMarkArray::ScMarkArray() :
      27             :     nCount( 0 ),
      28             :     nLimit( 0 ),
      29     1900544 :     pData( NULL )
      30             : {
      31             :     // special case "no marks" with pData = NULL
      32     1900544 : }
      33             : 
      34     1900544 : ScMarkArray::~ScMarkArray()
      35             : {
      36     1900544 :     delete[] pData;
      37     1900544 : }
      38             : 
      39       85338 : void ScMarkArray::Reset( bool bMarked )
      40             : {
      41             :     // always create pData here
      42             :     // (or have separate method to ensure pData)
      43             : 
      44       85338 :     delete[] pData;
      45             : 
      46       85338 :     nCount = nLimit = 1;
      47       85338 :     pData = new ScMarkEntry[1];
      48       85338 :     pData[0].nRow = MAXROW;
      49       85338 :     pData[0].bMarked = bMarked;
      50       85338 : }
      51             : 
      52      310637 : bool ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
      53             : {
      54      310637 :     long    nHi         = static_cast<long>(nCount) - 1;
      55      310637 :     long    i           = 0;
      56      310637 :     bool    bFound      = (nCount == 1);
      57      310637 :     if (pData)
      58             :     {
      59      309854 :         long    nLo         = 0;
      60      309854 :         long    nStartRow   = 0;
      61     1160956 :         while ( !bFound && nLo <= nHi )
      62             :         {
      63      541248 :             i = (nLo + nHi) / 2;
      64      541248 :             if (i > 0)
      65      288162 :                 nStartRow = (long) pData[i - 1].nRow;
      66             :             else
      67      253086 :                 nStartRow = -1;
      68      541248 :             long nEndRow = (long) pData[i].nRow;
      69      541248 :             if (nEndRow < (long) nRow)
      70      270002 :                 nLo = ++i;
      71             :             else
      72      271246 :                 if (nStartRow >= (long) nRow)
      73         850 :                     nHi = --i;
      74             :                 else
      75      270396 :                     bFound = true;
      76             :         }
      77             :     }
      78             :     else
      79         783 :         bFound = false;
      80             : 
      81      310637 :     if (bFound)
      82      309854 :         nIndex=(SCSIZE)i;
      83             :     else
      84         783 :         nIndex=0;
      85      310637 :     return bFound;
      86             : }
      87             : 
      88        5234 : bool ScMarkArray::GetMark( SCROW nRow ) const
      89             : {
      90             :     SCSIZE i;
      91        5234 :     if (Search( nRow, i ))
      92        4804 :         return pData[i].bMarked;
      93             :     else
      94         430 :         return false;
      95             : 
      96             : }
      97             : 
      98      351260 : void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, bool bMarked )
      99             : {
     100      351260 :     if (ValidRow(nStartRow) && ValidRow(nEndRow))
     101             :     {
     102      351260 :         if ((nStartRow == 0) && (nEndRow == MAXROW))
     103             :         {
     104       35272 :             Reset(bMarked);
     105             :         }
     106             :         else
     107             :         {
     108      315988 :             if (!pData)
     109       45598 :                 Reset(false);   // create pData for further processing - could use special case handling!
     110             : 
     111      315988 :             SCSIZE nNeeded = nCount + 2;
     112      315988 :             if ( nLimit < nNeeded )
     113             :             {
     114       47492 :                 nLimit += SC_MARKARRAY_DELTA;
     115       47492 :                 if ( nLimit < nNeeded )
     116           0 :                     nLimit = nNeeded;
     117       47492 :                 ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
     118       47492 :                 memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
     119       47492 :                 delete[] pData;
     120       47492 :                 pData = pNewData;
     121             :             }
     122             : 
     123             :             SCSIZE ni;          // number of entries in beginning
     124             :             SCSIZE nInsert;     // insert position (MAXROW+1 := no insert)
     125      315988 :             bool bCombined = false;
     126      315988 :             bool bSplit = false;
     127      315988 :             if ( nStartRow > 0 )
     128             :             {
     129             :                 // skip beginning
     130             :                 SCSIZE nIndex;
     131      300120 :                 Search( nStartRow, nIndex );
     132      300120 :                 ni = nIndex;
     133             : 
     134      300120 :                 nInsert = MAXROWCOUNT;
     135      300120 :                 if ( pData[ni].bMarked != bMarked )
     136             :                 {
     137      270686 :                     if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
     138             :                     {   // may be a split or a simple insert or just a shrink,
     139             :                         // row adjustment is done further down
     140        8728 :                         if ( pData[ni].nRow > nEndRow )
     141        8488 :                             bSplit = true;
     142        8728 :                         ni++;
     143        8728 :                         nInsert = ni;
     144             :                     }
     145      261958 :                     else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
     146      261958 :                         nInsert = ni;
     147             :                 }
     148      300120 :                 if ( ni > 0 && pData[ni-1].bMarked == bMarked )
     149             :                 {   // combine
     150      261958 :                     pData[ni-1].nRow = nEndRow;
     151      261958 :                     nInsert = MAXROWCOUNT;
     152      261958 :                     bCombined = true;
     153             :                 }
     154             :             }
     155             :             else
     156             :         {
     157       15868 :                 nInsert = 0;
     158       15868 :                 ni = 0;
     159             :         }
     160             : 
     161      315988 :             SCSIZE nj = ni;     // stop position of range to replace
     162      645852 :             while ( nj < nCount && pData[nj].nRow <= nEndRow )
     163       13876 :                 nj++;
     164      315988 :             if ( !bSplit )
     165             :             {
     166      307500 :                 if ( nj < nCount && pData[nj].bMarked == bMarked )
     167             :                 {   // combine
     168       30786 :                     if ( ni > 0 )
     169             :                     {
     170         164 :                         if ( pData[ni-1].bMarked == bMarked )
     171             :                         {   // adjacent entries
     172          80 :                             pData[ni-1].nRow = pData[nj].nRow;
     173          80 :                             nj++;
     174             :                         }
     175          84 :                         else if ( ni == nInsert )
     176          16 :                             pData[ni-1].nRow = nStartRow - 1;   // shrink
     177             :                     }
     178       30786 :                     nInsert = MAXROWCOUNT;
     179       30786 :                     bCombined = true;
     180             :                 }
     181      276714 :                 else if ( ni > 0 && ni == nInsert )
     182         224 :                     pData[ni-1].nRow = nStartRow - 1;   // shrink
     183             :             }
     184      315988 :             if ( ni < nj )
     185             :             {   // remove middle entries
     186       13876 :                 if ( !bCombined )
     187             :                 {   // replace one entry
     188        1380 :                     pData[ni].nRow = nEndRow;
     189        1380 :                     pData[ni].bMarked = bMarked;
     190        1380 :                     ni++;
     191        1380 :                     nInsert = MAXROWCOUNT;
     192             :                 }
     193       13876 :                 if ( ni < nj )
     194             :                 {   // remove entries
     195       12496 :                     memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
     196       12496 :                     nCount -= nj - ni;
     197             :                 }
     198             :             }
     199             : 
     200      315988 :             if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
     201             :             {   // insert or append new entry
     202       21944 :                 if ( nInsert <= nCount )
     203             :                 {
     204       21944 :                     if ( !bSplit )
     205       13456 :                         memmove( pData + nInsert + 1, pData + nInsert,
     206       26912 :                             (nCount - nInsert) * sizeof(ScMarkEntry) );
     207             :                     else
     208             :                     {
     209        8488 :                         memmove( pData + nInsert + 2, pData + nInsert,
     210       16976 :                             (nCount - nInsert) * sizeof(ScMarkEntry) );
     211        8488 :                         pData[nInsert+1] = pData[nInsert-1];
     212        8488 :                         nCount++;
     213             :                     }
     214             :                 }
     215       21944 :                 if ( nInsert )
     216        8712 :                     pData[nInsert-1].nRow = nStartRow - 1;
     217       21944 :                 pData[nInsert].nRow = nEndRow;
     218       21944 :                 pData[nInsert].bMarked = bMarked;
     219       21944 :                 nCount++;
     220             :             }
     221             :         }
     222             :     }
     223      351260 : }
     224             : 
     225          72 : bool ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
     226             : {
     227             :     SCSIZE nStartIndex;
     228             :     SCSIZE nEndIndex;
     229             : 
     230          72 :     if (Search( nStartRow, nStartIndex ))
     231          72 :         if (pData[nStartIndex].bMarked)
     232          72 :             if (Search( nEndRow, nEndIndex ))
     233          72 :                 if (nEndIndex==nStartIndex)
     234          72 :                     return true;
     235             : 
     236           0 :     return false;
     237             : }
     238             : 
     239         274 : bool ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
     240             : {
     241         274 :     bool bRet = false;
     242         274 :     if ( nCount == 1 )
     243             :     {
     244          52 :         if ( pData[0].bMarked )
     245             :         {
     246          52 :             rStartRow = 0;
     247          52 :             rEndRow = MAXROW;
     248          52 :             bRet = true;
     249             :         }
     250             :     }
     251         222 :     else if ( nCount == 2 )
     252             :     {
     253          38 :         if ( pData[0].bMarked )
     254             :         {
     255          38 :             rStartRow = 0;
     256          38 :             rEndRow = pData[0].nRow;
     257             :         }
     258             :         else
     259             :         {
     260           0 :             rStartRow = pData[0].nRow + 1;
     261           0 :             rEndRow = MAXROW;
     262             :         }
     263          38 :         bRet = true;
     264             :     }
     265         184 :     else if ( nCount == 3 )
     266             :     {
     267         158 :         if ( pData[1].bMarked )
     268             :         {
     269         158 :             rStartRow = pData[0].nRow + 1;
     270         158 :             rEndRow = pData[1].nRow;
     271         158 :             bRet = true;
     272             :         }
     273             :     }
     274         274 :     return bRet;
     275             : }
     276             : 
     277        9402 : bool ScMarkArray::HasEqualRowsMarked( const ScMarkArray& rOther ) const
     278             : {
     279        9402 :     if (nCount != rOther.nCount)
     280         806 :         return false;
     281             : 
     282       26250 :     for (size_t i=0; i < nCount; ++i)
     283             :     {
     284       38832 :         if (pData[i].bMarked != rOther.pData[i].bMarked ||
     285       19416 :                 pData[i].nRow != rOther.pData[i].nRow)
     286        1762 :             return false;
     287             :     }
     288             : 
     289        6834 :     return true;
     290             : }
     291             : 
     292      475136 : void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
     293             : {
     294      475136 :     delete[] rDestMarkArray.pData;
     295             : 
     296      475136 :     if (pData)
     297             :     {
     298        2312 :         rDestMarkArray.pData = new ScMarkEntry[nCount];
     299        2312 :         memcpy( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
     300             :     }
     301             :     else
     302      472824 :         rDestMarkArray.pData = NULL;
     303             : 
     304      475136 :     rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
     305      475136 : }
     306             : 
     307        4530 : SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, bool bUp ) const
     308             : {
     309        4530 :     if (!pData)
     310        4468 :         const_cast<ScMarkArray*>(this)->Reset(false);   // create pData for further processing
     311             : 
     312        4530 :     SCsROW nRet = nRow;
     313        4530 :     if (ValidRow(nRow))
     314             :     {
     315             :         SCSIZE nIndex;
     316        4530 :         Search(nRow, nIndex);
     317        4530 :         if (!pData[nIndex].bMarked)
     318             :         {
     319        4516 :             if (bUp)
     320             :             {
     321           0 :                 if (nIndex>0)
     322           0 :                     nRet = pData[nIndex-1].nRow;
     323             :                 else
     324           0 :                     nRet = -1;
     325             :             }
     326             :             else
     327        4516 :                 nRet = pData[nIndex].nRow + 1;
     328             :         }
     329             :     }
     330        4530 :     return nRet;
     331             : }
     332             : 
     333          58 : SCROW ScMarkArray::GetMarkEnd( SCROW nRow, bool bUp ) const
     334             : {
     335          58 :     if (!pData)
     336           0 :         const_cast<ScMarkArray*>(this)->Reset(false);   // create pData for further processing
     337             : 
     338             :     SCROW nRet;
     339             :     SCSIZE nIndex;
     340          58 :     Search(nRow, nIndex);
     341             :     OSL_ENSURE( pData[nIndex].bMarked, "GetMarkEnd without bMarked" );
     342          58 :     if (bUp)
     343             :     {
     344           0 :         if (nIndex>0)
     345           0 :             nRet = pData[nIndex-1].nRow + 1;
     346             :         else
     347           0 :             nRet = 0;
     348             :     }
     349             :     else
     350          58 :         nRet = pData[nIndex].nRow;
     351             : 
     352          58 :     return nRet;
     353             : }
     354             : 
     355             : //  -------------- Iterator ----------------------------------------------
     356             : 
     357     1146348 : ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
     358             :     pArray( pNewArray ),
     359     1146348 :     nPos( 0 )
     360             : {
     361     1146348 : }
     362             : 
     363     1146348 : ScMarkArrayIter::~ScMarkArrayIter()
     364             : {
     365     1146348 : }
     366             : 
     367     1295466 : bool ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
     368             : {
     369     1295466 :     if ( nPos >= pArray->nCount )
     370     1121388 :         return false;
     371      365890 :     while (!pArray->pData[nPos].bMarked)
     372             :     {
     373       42694 :         ++nPos;
     374       42694 :         if ( nPos >= pArray->nCount )
     375       24960 :             return false;
     376             :     }
     377      149118 :     rBottom = pArray->pData[nPos].nRow;
     378      149118 :     if (nPos==0)
     379      131384 :         rTop = 0;
     380             :     else
     381       17734 :         rTop = pArray->pData[nPos-1].nRow + 1;
     382      149118 :     ++nPos;
     383      149118 :     return true;
     384         228 : }
     385             : 
     386             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10