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

Generated by: LCOV version 1.10