LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/data - markarr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 179 190 94.2 %
Date: 2013-07-09 Functions: 14 14 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             : //------------------------------------------------------------------------
      27             : 
      28      999424 : ScMarkArray::ScMarkArray() :
      29             :     nCount( 0 ),
      30             :     nLimit( 0 ),
      31      999424 :     pData( NULL )
      32             : {
      33             :     // special case "no marks" with pData = NULL
      34      999424 : }
      35             : 
      36             : //------------------------------------------------------------------------
      37             : 
      38      998400 : ScMarkArray::~ScMarkArray()
      39             : {
      40      998400 :     delete[] pData;
      41      998400 : }
      42             : 
      43             : //------------------------------------------------------------------------
      44             : 
      45       24302 : void ScMarkArray::Reset( sal_Bool bMarked )
      46             : {
      47             :     // always create pData here
      48             :     // (or have separate method to ensure pData)
      49             : 
      50       24302 :     delete[] pData;
      51             : 
      52       24302 :     nCount = nLimit = 1;
      53       24302 :     pData = new ScMarkEntry[1];
      54       24302 :     pData[0].nRow = MAXROW;
      55       24302 :     pData[0].bMarked = bMarked;
      56       24302 : }
      57             : 
      58             : //------------------------------------------------------------------------
      59             : 
      60       20874 : sal_Bool ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
      61             : {
      62       20874 :     long    nHi         = static_cast<long>(nCount) - 1;
      63       20874 :     long    i           = 0;
      64       20874 :     sal_Bool    bFound      = (nCount == 1);
      65       20874 :     if (pData)
      66             :     {
      67       20362 :         long    nLo         = 0;
      68       20362 :         long    nStartRow   = 0;
      69       48959 :         while ( !bFound && nLo <= nHi )
      70             :         {
      71        8235 :             i = (nLo + nHi) / 2;
      72        8235 :             if (i > 0)
      73        5780 :                 nStartRow = (long) pData[i - 1].nRow;
      74             :             else
      75        2455 :                 nStartRow = -1;
      76        8235 :             long nEndRow = (long) pData[i].nRow;
      77        8235 :             if (nEndRow < (long) nRow)
      78        2596 :                 nLo = ++i;
      79             :             else
      80        5639 :                 if (nStartRow >= (long) nRow)
      81         441 :                     nHi = --i;
      82             :                 else
      83        5198 :                     bFound = sal_True;
      84             :         }
      85             :     }
      86             :     else
      87         512 :         bFound = false;
      88             : 
      89       20874 :     if (bFound)
      90       20362 :         nIndex=(SCSIZE)i;
      91             :     else
      92         512 :         nIndex=0;
      93       20874 :     return bFound;
      94             : }
      95             : 
      96        2791 : sal_Bool ScMarkArray::GetMark( SCROW nRow ) const
      97             : {
      98             :     SCSIZE i;
      99        2791 :     if (Search( nRow, i ))
     100        2595 :         return pData[i].bMarked;
     101             :     else
     102         196 :         return false;
     103             : 
     104             : }
     105             : 
     106             : //------------------------------------------------------------------------
     107             : 
     108       29434 : void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, sal_Bool bMarked )
     109             : {
     110       29434 :     if (ValidRow(nStartRow) && ValidRow(nEndRow))
     111             :     {
     112       29434 :         if ((nStartRow == 0) && (nEndRow == MAXROW))
     113             :         {
     114        9464 :             Reset(bMarked);
     115             :         }
     116             :         else
     117             :         {
     118       19970 :             if (!pData)
     119       14836 :                 Reset(false);   // create pData for further processing - could use special case handling!
     120             : 
     121       19970 :             SCSIZE nNeeded = nCount + 2;
     122       19970 :             if ( nLimit < nNeeded )
     123             :             {
     124       15094 :                 nLimit += SC_MARKARRAY_DELTA;
     125       15094 :                 if ( nLimit < nNeeded )
     126           0 :                     nLimit = nNeeded;
     127       15094 :                 ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
     128       15094 :                 memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
     129       15094 :                 delete[] pData;
     130       15094 :                 pData = pNewData;
     131             :             }
     132             : 
     133             :             SCSIZE ni;          // number of entries in beginning
     134             :             SCSIZE nInsert;     // insert position (MAXROW+1 := no insert)
     135       19970 :             sal_Bool bCombined = false;
     136       19970 :             sal_Bool bSplit = false;
     137       19970 :             if ( nStartRow > 0 )
     138             :             {
     139             :                 // skip beginning
     140             :                 SCSIZE nIndex;
     141       17494 :                 Search( nStartRow, nIndex );
     142       17494 :                 ni = nIndex;
     143             : 
     144       17494 :                 nInsert = MAXROWCOUNT;
     145       17494 :                 if ( pData[ni].bMarked != bMarked )
     146             :                 {
     147        2816 :                     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        1032 :                         if ( pData[ni].nRow > nEndRow )
     151         980 :                             bSplit = sal_True;
     152        1032 :                         ni++;
     153        1032 :                         nInsert = ni;
     154             :                     }
     155        1784 :                     else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
     156        1784 :                         nInsert = ni;
     157             :                 }
     158       17494 :                 if ( ni > 0 && pData[ni-1].bMarked == bMarked )
     159             :                 {   // combine
     160        1784 :                     pData[ni-1].nRow = nEndRow;
     161        1784 :                     nInsert = MAXROWCOUNT;
     162        1784 :                     bCombined = sal_True;
     163             :                 }
     164             :             }
     165             :             else
     166             :         {
     167        2476 :                 nInsert = 0;
     168        2476 :                 ni = 0;
     169             :         }
     170             : 
     171       19970 :             SCSIZE nj = ni;     // stop position of range to replace
     172       40874 :             while ( nj < nCount && pData[nj].nRow <= nEndRow )
     173         934 :                 nj++;
     174       19970 :             if ( !bSplit )
     175             :             {
     176       18990 :                 if ( nj < nCount && pData[nj].bMarked == bMarked )
     177             :                 {   // combine
     178       15393 :                     if ( ni > 0 )
     179             :                     {
     180          82 :                         if ( pData[ni-1].bMarked == bMarked )
     181             :                         {   // adjacent entries
     182          40 :                             pData[ni-1].nRow = pData[nj].nRow;
     183          40 :                             nj++;
     184             :                         }
     185          42 :                         else if ( ni == nInsert )
     186           8 :                             pData[ni-1].nRow = nStartRow - 1;   // shrink
     187             :                     }
     188       15393 :                     nInsert = MAXROWCOUNT;
     189       15393 :                     bCombined = sal_True;
     190             :                 }
     191        3597 :                 else if ( ni > 0 && ni == nInsert )
     192          44 :                     pData[ni-1].nRow = nStartRow - 1;   // shrink
     193             :             }
     194       19970 :             if ( ni < nj )
     195             :             {   // remove middle entries
     196         934 :                 if ( !bCombined )
     197             :                 {   // replace one entry
     198         818 :                     pData[ni].nRow = nEndRow;
     199         818 :                     pData[ni].bMarked = bMarked;
     200         818 :                     ni++;
     201         818 :                     nInsert = MAXROWCOUNT;
     202             :                 }
     203         934 :                 if ( ni < nj )
     204             :                 {   // remove entries
     205         116 :                     memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
     206         116 :                     nCount -= nj - ni;
     207             :                 }
     208             :             }
     209             : 
     210       19970 :             if ( nInsert < sal::static_int_cast<SCSIZE>(MAXROWCOUNT) )
     211             :             {   // insert or append new entry
     212        2015 :                 if ( nInsert <= nCount )
     213             :                 {
     214        2015 :                     if ( !bSplit )
     215        1035 :                         memmove( pData + nInsert + 1, pData + nInsert,
     216        2070 :                             (nCount - nInsert) * sizeof(ScMarkEntry) );
     217             :                     else
     218             :                     {
     219         980 :                         memmove( pData + nInsert + 2, pData + nInsert,
     220        1960 :                             (nCount - nInsert) * sizeof(ScMarkEntry) );
     221         980 :                         pData[nInsert+1] = pData[nInsert-1];
     222         980 :                         nCount++;
     223             :                     }
     224             :                 }
     225        2015 :                 if ( nInsert )
     226        1024 :                     pData[nInsert-1].nRow = nStartRow - 1;
     227        2015 :                 pData[nInsert].nRow = nEndRow;
     228        2015 :                 pData[nInsert].bMarked = bMarked;
     229        2015 :                 nCount++;
     230             :             }
     231             :         }
     232             :     }
     233       29434 : }
     234             : 
     235          36 : sal_Bool ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
     236             : {
     237             :     SCSIZE nStartIndex;
     238             :     SCSIZE nEndIndex;
     239             : 
     240          36 :     if (Search( nStartRow, nStartIndex ))
     241          36 :         if (pData[nStartIndex].bMarked)
     242          36 :             if (Search( nEndRow, nEndIndex ))
     243          36 :                 if (nEndIndex==nStartIndex)
     244          36 :                     return sal_True;
     245             : 
     246           0 :     return false;
     247             : }
     248             : 
     249         705 : sal_Bool ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
     250             : {
     251         705 :     sal_Bool bRet = false;
     252         705 :     if ( nCount == 1 )
     253             :     {
     254          26 :         if ( pData[0].bMarked )
     255             :         {
     256          26 :             rStartRow = 0;
     257          26 :             rEndRow = MAXROW;
     258          26 :             bRet = sal_True;
     259             :         }
     260             :     }
     261         679 :     else if ( nCount == 2 )
     262             :     {
     263         589 :         if ( pData[0].bMarked )
     264             :         {
     265         589 :             rStartRow = 0;
     266         589 :             rEndRow = pData[0].nRow;
     267             :         }
     268             :         else
     269             :         {
     270           0 :             rStartRow = pData[0].nRow + 1;
     271           0 :             rEndRow = MAXROW;
     272             :         }
     273         589 :         bRet = sal_True;
     274             :     }
     275          90 :     else if ( nCount == 3 )
     276             :     {
     277          77 :         if ( pData[1].bMarked )
     278             :         {
     279          77 :             rStartRow = pData[0].nRow + 1;
     280          77 :             rEndRow = pData[1].nRow;
     281          77 :             bRet = sal_True;
     282             :         }
     283             :     }
     284         705 :     return bRet;
     285             : }
     286             : 
     287      334848 : void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
     288             : {
     289      334848 :     delete[] rDestMarkArray.pData;
     290             : 
     291      334848 :     if (pData)
     292             :     {
     293        1684 :         rDestMarkArray.pData = new ScMarkEntry[nCount];
     294        1684 :         memcpy( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
     295             :     }
     296             :     else
     297      333164 :         rDestMarkArray.pData = NULL;
     298             : 
     299      334848 :     rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
     300      334848 : }
     301             : 
     302           4 : SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, sal_Bool bUp ) const
     303             : {
     304           4 :     if (!pData)
     305           2 :         const_cast<ScMarkArray*>(this)->Reset(false);   // create pData for further processing
     306             : 
     307           4 :     SCsROW nRet = nRow;
     308           4 :     if (ValidRow(nRow))
     309             :     {
     310             :         SCSIZE nIndex;
     311           4 :         Search(nRow, nIndex);
     312           4 :         if (!pData[nIndex].bMarked)
     313             :         {
     314           2 :             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           2 :                 nRet = pData[nIndex].nRow + 1;
     323             :         }
     324             :     }
     325           4 :     return nRet;
     326             : }
     327             : 
     328           2 : SCROW ScMarkArray::GetMarkEnd( SCROW nRow, sal_Bool bUp ) const
     329             : {
     330           2 :     if (!pData)
     331           0 :         const_cast<ScMarkArray*>(this)->Reset(false);   // create pData for further processing
     332             : 
     333             :     SCROW nRet;
     334             :     SCSIZE nIndex;
     335           2 :     Search(nRow, nIndex);
     336             :     OSL_ENSURE( pData[nIndex].bMarked, "GetMarkEnd without bMarked" );
     337           2 :     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           2 :         nRet = pData[nIndex].nRow;
     346             : 
     347           2 :     return nRet;
     348             : }
     349             : 
     350             : //
     351             : //  -------------- Iterator ----------------------------------------------
     352             : //
     353             : 
     354      787783 : ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
     355             :     pArray( pNewArray ),
     356      787783 :     nPos( 0 )
     357             : {
     358      787783 : }
     359             : 
     360      787783 : ScMarkArrayIter::~ScMarkArrayIter()
     361             : {
     362      787783 : }
     363             : 
     364     1311905 : sal_Bool ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
     365             : {
     366     1311905 :     if ( nPos >= pArray->nCount )
     367      276448 :         return false;
     368     2431572 :     while (!pArray->pData[nPos].bMarked)
     369             :     {
     370      871993 :         ++nPos;
     371      871993 :         if ( nPos >= pArray->nCount )
     372      511335 :             return false;
     373             :     }
     374      524122 :     rBottom = pArray->pData[nPos].nRow;
     375      524122 :     if (nPos==0)
     376      163464 :         rTop = 0;
     377             :     else
     378      360658 :         rTop = pArray->pData[nPos-1].nRow + 1;
     379      524122 :     ++nPos;
     380      524122 :     return sal_True;
     381             : }
     382             : 
     383             : 
     384             : 
     385             : 
     386             : 
     387             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10