LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/filter/dif - difimp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 229 424 54.0 %
Date: 2013-07-09 Functions: 16 21 76.2 %
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             : 
      21             : #include <math.h>
      22             : 
      23             : #include <svl/zforlist.hxx>
      24             : 
      25             : #include "attrib.hxx"
      26             : #include "dif.hxx"
      27             : #include "docpool.hxx"
      28             : #include "document.hxx"
      29             : #include "filter.hxx"
      30             : #include "fprogressbar.hxx"
      31             : #include "ftools.hxx"
      32             : #include "patattr.hxx"
      33             : #include "scerrors.hxx"
      34             : #include "scitems.hxx"
      35             : #include "stringutil.hxx"
      36             : 
      37             : const sal_Unicode pKeyTABLE[]   = { 'T', 'A', 'B', 'L', 'E', 0 };
      38             : const sal_Unicode pKeyVECTORS[] = { 'V', 'E', 'C', 'T', 'O', 'R', 'S', 0 };
      39             : const sal_Unicode pKeyTUPLES[]  = { 'T', 'U', 'P', 'L', 'E', 'S', 0 };
      40             : const sal_Unicode pKeyDATA[]    = { 'D', 'A', 'T', 'A', 0 };
      41             : const sal_Unicode pKeyBOT[]     = { 'B', 'O', 'T', 0 };
      42             : const sal_Unicode pKeyEOD[]     = { 'E', 'O', 'D', 0 };
      43             : const sal_Unicode pKeyERROR[]   = { 'E', 'R', 'R', 'O', 'R', 0 };
      44             : const sal_Unicode pKeyTRUE[]    = { 'T', 'R', 'U', 'E', 0 };
      45             : const sal_Unicode pKeyFALSE[]   = { 'F', 'A', 'L', 'S', 'E', 0 };
      46             : const sal_Unicode pKeyNA[]      = { 'N', 'A', 0 };
      47             : const sal_Unicode pKeyV[]       = { 'V', 0 };
      48             : const sal_Unicode pKey1_0[]     = { '1', ',', '0', 0 };
      49             : 
      50             : 
      51           1 : FltError ScFormatFilterPluginImpl::ScImportDif( SvStream& rIn, ScDocument* pDoc, const ScAddress& rInsPos,
      52             :                         const CharSet eVon, sal_uInt32 nDifOption )
      53             : {
      54           1 :     DifParser   aDifParser( rIn, nDifOption, *pDoc, eVon );
      55             : 
      56           1 :     const bool bPlain = aDifParser.IsPlain();
      57             : 
      58           1 :     SCTAB       nBaseTab = rInsPos.Tab();
      59             : 
      60           1 :     TOPIC       eTopic = T_UNKNOWN;
      61           1 :     bool        bSyntErrWarn = false;
      62           1 :     bool        bOverflowWarn = false;
      63             : 
      64           1 :     OUString&   aData = aDifParser.aData;
      65           1 :     bool        bData = false;
      66             : 
      67           1 :     rIn.Seek( 0 );
      68             : 
      69           2 :     ScfStreamProgressBar aPrgrsBar( rIn, pDoc->GetDocumentShell() );
      70             : 
      71           6 :     while( eTopic != T_DATA && eTopic != T_END )
      72             :     {
      73           4 :         eTopic = aDifParser.GetNextTopic();
      74             : 
      75           4 :         aPrgrsBar.Progress();
      76             : 
      77           4 :         bData = !aData.isEmpty();
      78             : 
      79           4 :         switch( eTopic )
      80             :         {
      81             :             case T_TABLE:
      82             :             {
      83           1 :                 if( aDifParser.nVector != 0 || aDifParser.nVal != 1 )
      84           0 :                     bSyntErrWarn = sal_True;
      85           1 :                 if( bData )
      86           1 :                     pDoc->RenameTab( nBaseTab, aData );
      87             :             }
      88           1 :                 break;
      89             :             case T_VECTORS:
      90             :             {
      91           1 :                 if( aDifParser.nVector != 0 )
      92           0 :                     bSyntErrWarn = true;
      93             :             }
      94           1 :                 break;
      95             :             case T_TUPLES:
      96             :             {
      97           1 :                 if( aDifParser.nVector != 0 )
      98           0 :                     bSyntErrWarn = true;
      99             :             }
     100           1 :                 break;
     101             :             case T_DATA:
     102             :             {
     103           1 :                 if( aDifParser.nVector != 0 || aDifParser.nVal != 0 )
     104           0 :                     bSyntErrWarn = sal_True;
     105             :             }
     106           1 :                 break;
     107             :             case T_LABEL:
     108             :             case T_COMMENT:
     109             :             case T_SIZE:
     110             :             case T_PERIODICITY:
     111             :             case T_MAJORSTART:
     112             :             case T_MINORSTART:
     113             :             case T_TRUELENGTH:
     114             :             case T_UINITS:
     115             :             case T_DISPLAYUNITS:
     116             :             case T_END:
     117             :             case T_UNKNOWN:
     118           0 :                 break;
     119             :             default:
     120             :                 OSL_FAIL( "ScImportDif - missing enum" );
     121             :         }
     122             : 
     123             :     }
     124             : 
     125             : 
     126           1 :     if( eTopic == T_DATA )
     127             :     {   // Ab hier kommen die Daten
     128           1 :         SCCOL               nBaseCol = rInsPos.Col();
     129             : 
     130           1 :         SCCOL               nColCnt = SCCOL_MAX;
     131           1 :         SCROW               nRowCnt = rInsPos.Row();
     132           1 :         DifAttrCache        aAttrCache( bPlain );
     133             : 
     134           1 :         DATASET             eAkt = D_UNKNOWN;
     135             : 
     136           1 :         ScSetStringParam aStrParam; // used to set string value without number detection.
     137           1 :         aStrParam.setTextInput();
     138             : 
     139          39 :         while( eAkt != D_EOD )
     140             :         {
     141          37 :             eAkt = aDifParser.GetNextDataset();
     142             : 
     143          37 :             aPrgrsBar.Progress();
     144          37 :             ScAddress aPos(nColCnt, nRowCnt, nBaseTab);
     145             : 
     146          37 :             switch( eAkt )
     147             :             {
     148             :                 case D_BOT:
     149           4 :                     if( nColCnt < SCCOL_MAX )
     150           3 :                         nRowCnt++;
     151           4 :                     nColCnt = nBaseCol;
     152           4 :                     break;
     153             :                 case D_EOD:
     154           1 :                     break;
     155             :                 case D_NUMERIC:                 // Numbercell
     156           6 :                     if( nColCnt == SCCOL_MAX )
     157           0 :                         nColCnt = nBaseCol;
     158             : 
     159           6 :                     if( ValidCol(nColCnt) && ValidRow(nRowCnt) )
     160             :                     {
     161           6 :                         pDoc->EnsureTable(nBaseTab);
     162             : 
     163           6 :                         if( DifParser::IsV( aData.getStr() ) )
     164             :                         {
     165           6 :                             pDoc->SetValue(aPos, aDifParser.fVal);
     166           6 :                             if( !bPlain )
     167             :                                 aAttrCache.SetNumFormat( nColCnt, nRowCnt,
     168           6 :                                     aDifParser.nNumFormat );
     169             :                         }
     170           0 :                         else if( aData == pKeyTRUE || aData == pKeyFALSE )
     171             :                         {
     172           0 :                             pDoc->SetValue(aPos, aDifParser.fVal);
     173           0 :                             if( bPlain )
     174           0 :                                 aAttrCache.SetLogical( nColCnt, nRowCnt );
     175             :                             else
     176             :                                 aAttrCache.SetNumFormat( nColCnt, nRowCnt,
     177           0 :                                     aDifParser.nNumFormat );
     178             :                         }
     179           0 :                         else if( aData == pKeyNA || aData == pKeyERROR  )
     180             :                         {
     181           0 :                             pDoc->SetString(aPos, aData, &aStrParam);
     182             :                         }
     183             :                         else
     184             :                         {
     185           0 :                             String aTmp( RTL_CONSTASCII_USTRINGPARAM( "#IND: " ));
     186           0 :                             aTmp += aData;
     187           0 :                             aTmp += sal_Unicode('?');
     188           0 :                             pDoc->SetString(aPos, aTmp, &aStrParam);
     189             :                         }
     190             :                     }
     191             :                     else
     192           0 :                         bOverflowWarn = true;
     193             : 
     194           6 :                     nColCnt++;
     195           6 :                     break;
     196             :                 case D_STRING:                  // Textcell
     197          26 :                     if( nColCnt == SCCOL_MAX )
     198           0 :                         nColCnt = nBaseCol;
     199             : 
     200          26 :                     if( ValidCol(nColCnt) && ValidRow(nRowCnt) )
     201             :                     {
     202          26 :                         if (!aData.isEmpty())
     203             :                         {
     204           2 :                             pDoc->EnsureTable(nBaseTab);
     205           2 :                             pDoc->SetTextCell(aPos, aData);
     206             :                         }
     207             :                     }
     208             :                     else
     209           0 :                         bOverflowWarn = sal_True;
     210             : 
     211          26 :                     nColCnt++;
     212          26 :                     break;
     213             :                 case D_UNKNOWN:
     214           0 :                     break;
     215             :                 case D_SYNT_ERROR:
     216           0 :                     break;
     217             :                 default:
     218             :                     OSL_FAIL( "ScImportDif - missing enum" );
     219             :             }
     220             :         }
     221             : 
     222           1 :         aAttrCache.Apply( *pDoc, nBaseTab );
     223             :     }
     224             :     else
     225           0 :         return eERR_FORMAT;
     226             : 
     227           1 :     if( bSyntErrWarn )
     228             :         //###############################################
     229             :         // ACHTUNG: Hier fehlt noch die richtige Warnung!
     230           0 :         return eERR_RNGOVRFLW;
     231             :         //###############################################
     232           1 :     else if( bOverflowWarn )
     233           0 :         return eERR_RNGOVRFLW;
     234             :     else
     235           2 :         return eERR_OK;
     236             : }
     237             : 
     238             : 
     239           1 : DifParser::DifParser( SvStream& rNewIn, const sal_uInt32 nOption, ScDocument& rDoc, CharSet e ) :
     240           1 :     rIn( rNewIn )
     241             : {
     242           1 :     eCharSet = e;
     243           1 :     if ( rIn.GetStreamCharSet() != eCharSet )
     244             :     {
     245             :         OSL_FAIL( "CharSet passed overrides and modifies StreamCharSet" );
     246           1 :         rIn.SetStreamCharSet( eCharSet );
     247             :     }
     248           1 :     rIn.StartReadingUnicodeText( eCharSet );
     249             : 
     250           1 :     bPlain = ( nOption == SC_DIFOPT_PLAIN );
     251             : 
     252           1 :     if( bPlain )
     253           0 :         pNumFormatter = NULL;
     254             :     else
     255           1 :         pNumFormatter = rDoc.GetFormatTable();
     256           1 : }
     257             : 
     258             : 
     259           4 : TOPIC DifParser::GetNextTopic( void )
     260             : {
     261             :     enum STATE { S_VectorVal, S_Data, S_END, S_START, S_UNKNOWN, S_ERROR_L2 };
     262             : 
     263             :     static const sal_Unicode pKeyLABEL[]        = { 'L', 'A', 'B', 'E', 'L', 0 };
     264             :     static const sal_Unicode pKeyCOMMENT[]      = { 'C', 'O', 'M', 'M', 'E', 'N', 'T', 0 };
     265             :     static const sal_Unicode pKeySIZE[]         = { 'S', 'I', 'Z', 'E', 0 };
     266             :     static const sal_Unicode pKeyPERIODICITY[]  = { 'P', 'E', 'R', 'I', 'O', 'D', 'I', 'C', 'I', 'T', 'Y', 0 };
     267             :     static const sal_Unicode pKeyMAJORSTART[]   = { 'M', 'A', 'J', 'O', 'R', 'S', 'T', 'A', 'R', 'T', 0 };
     268             :     static const sal_Unicode pKeyMINORSTART[]   = { 'M', 'I', 'N', 'O', 'R', 'S', 'T', 'A', 'R', 'T', 0 };
     269             :     static const sal_Unicode pKeyTRUELENGTH[]   = { 'T', 'R', 'U', 'E', 'L', 'E', 'N', 'G', 'T', 'H', 0 };
     270             :     static const sal_Unicode pKeyUINITS[]       = { 'U', 'I', 'N', 'I', 'T', 'S', 0 };
     271             :     static const sal_Unicode pKeyDISPLAYUNITS[] = { 'D', 'I', 'S', 'P', 'L', 'A', 'Y', 'U', 'N', 'I', 'T', 'S', 0 };
     272             :     static const sal_Unicode pKeyUNKNOWN[]      = { 0 };
     273             : 
     274             :     static const sal_Unicode*   ppKeys[] =
     275             :     {
     276             :         pKeyTABLE,              // 0
     277             :         pKeyVECTORS,
     278             :         pKeyTUPLES,
     279             :         pKeyDATA,
     280             :         pKeyLABEL,
     281             :         pKeyCOMMENT,            // 5
     282             :         pKeySIZE,
     283             :         pKeyPERIODICITY,
     284             :         pKeyMAJORSTART,
     285             :         pKeyMINORSTART,
     286             :         pKeyTRUELENGTH,         // 10
     287             :         pKeyUINITS,
     288             :         pKeyDISPLAYUNITS,
     289             :         pKeyUNKNOWN             // 13
     290             :     };
     291             : 
     292             :     static const TOPIC      pTopics[] =
     293             :     {
     294             :         T_TABLE,                // 0
     295             :         T_VECTORS,
     296             :         T_TUPLES,
     297             :         T_DATA,
     298             :         T_LABEL,
     299             :         T_COMMENT,              // 5
     300             :         T_SIZE,
     301             :         T_PERIODICITY,
     302             :         T_MAJORSTART,
     303             :         T_MINORSTART,
     304             :         T_TRUELENGTH,           // 10
     305             :         T_UINITS,
     306             :         T_DISPLAYUNITS,
     307             :         T_UNKNOWN               // 13
     308             :     };
     309             : 
     310           4 :     STATE                   eS = S_START;
     311           4 :     OUString           aLine;
     312             : 
     313           4 :     nVector = 0;
     314           4 :     nVal = 0;
     315           4 :     TOPIC eRet = T_UNKNOWN;
     316             : 
     317          20 :     while( eS != S_END )
     318             :     {
     319          12 :         if( !ReadNextLine( aLine ) )
     320             :         {
     321           0 :             eS = S_END;
     322           0 :             eRet = T_END;
     323             :         }
     324             : 
     325          12 :         switch( eS )
     326             :         {
     327             :             case S_START:
     328             :             {
     329             :                 const sal_Unicode*  pRef;
     330           4 :                 sal_uInt16          nCnt = 0;
     331           4 :                 sal_Bool            bSearch = sal_True;
     332             : 
     333           4 :                 pRef = ppKeys[ nCnt ];
     334             : 
     335          18 :                 while( bSearch )
     336             :                 {
     337          10 :                     if( aLine == pRef )
     338             :                     {
     339           4 :                         eRet = pTopics[ nCnt ];
     340           4 :                         bSearch = false;
     341             :                     }
     342             :                     else
     343             :                     {
     344           6 :                         nCnt++;
     345           6 :                         pRef = ppKeys[ nCnt ];
     346           6 :                         if( !*pRef )
     347           0 :                             bSearch = false;
     348             :                     }
     349             :                 }
     350             : 
     351           4 :                 if( *pRef )
     352           4 :                     eS = S_VectorVal;
     353             :                 else
     354           0 :                     eS = S_UNKNOWN;
     355             :             }
     356           4 :                 break;
     357             :             case S_VectorVal:
     358             :             {
     359           4 :                 const sal_Unicode*      pCur = aLine.getStr();
     360             : 
     361           4 :                 pCur = ScanIntVal( pCur, nVector );
     362             : 
     363           4 :                 if( pCur && *pCur == ',' )
     364             :                 {
     365           4 :                     pCur++;
     366           4 :                     ScanIntVal( pCur, nVal );
     367           4 :                     eS = S_Data;
     368             :                 }
     369             :                 else
     370           0 :                     eS = S_ERROR_L2;
     371             :             }
     372           4 :                 break;
     373             :             case S_Data:
     374             :                 OSL_ENSURE( aLine.getLength() >= 2,
     375             :                     "+GetNextTopic(): <String> ist zu kurz!" );
     376             :                 OSL_ENSURE( aLine.getLength() - 2 <= STRING_MAXLEN, "GetNextTopic(): line doesn't fit into data");
     377           4 :                 if( aLine.getLength() > 2 )
     378           1 :                     aData = aLine.copy( 1, aLine.getLength() - 2 );
     379             :                 else
     380           3 :                     aData = OUString();
     381           4 :                 eS = S_END;
     382           4 :                 break;
     383             :             case S_END:
     384             :                 OSL_FAIL( "DifParser::GetNextTopic - unexpected state" );
     385           0 :                 break;
     386             :             case S_UNKNOWN:
     387             :                 // 2 Zeilen ueberlesen
     388           0 :                 ReadNextLine( aLine );
     389             :             case S_ERROR_L2:                // Fehler in Line 2 aufgetreten
     390             :                 // eine Zeile ueberlesen
     391           0 :                 ReadNextLine( aLine );
     392           0 :                 eS = S_END;
     393           0 :                 break;
     394             :             default:
     395             :                 OSL_FAIL( "DifParser::GetNextTopic - missing enum" );
     396             :         }
     397             :     }
     398             : 
     399           4 :     return eRet;
     400             : }
     401             : 
     402             : 
     403          26 : static void lcl_DeEscapeQuotesDif( OUString& rString )
     404             : {
     405             :     //  Special handling for DIF import: Escaped (duplicated) quotes are resolved.
     406             :     //  Single quote characters are left in place because older versions didn't
     407             :     //  escape quotes in strings (and Excel doesn't when using the clipboard).
     408             :     //  The quotes around the string are removed before this function is called.
     409             : 
     410          26 :     rString = rString.replaceAll("\"\"", "\"");
     411          26 : }
     412             : 
     413             : // Determine if passed in string is numeric data and set fVal/nNumFormat if so
     414          10 : DATASET DifParser::GetNumberDataset( const sal_Unicode* pPossibleNumericData )
     415             : {
     416          10 :     DATASET eRet = D_SYNT_ERROR;
     417          10 :     if( bPlain )
     418             :     {
     419           0 :         if( ScanFloatVal( pPossibleNumericData ) )
     420           0 :             eRet = D_NUMERIC;
     421             :         else
     422           0 :             eRet = D_SYNT_ERROR;
     423             :     }
     424             :     else
     425             :     {   // ...und zur Strafe mit'm Numberformatter...
     426             :         OSL_ENSURE( pNumFormatter, "-DifParser::GetNextDataset(): No Formatter, more fun!" );
     427          10 :         OUString aTestVal( pPossibleNumericData );
     428          10 :         sal_uInt32 nFormat = 0;
     429             :         double fTmpVal;
     430          10 :         if( pNumFormatter->IsNumberFormat( aTestVal, nFormat, fTmpVal ) )
     431             :         {
     432          10 :             fVal = fTmpVal;
     433          10 :             nNumFormat = nFormat;
     434          10 :             eRet = D_NUMERIC;
     435             :         }
     436             :         else
     437           0 :             eRet = D_SYNT_ERROR;
     438             :     }
     439          10 :     return eRet;
     440             : }
     441             : 
     442          86 : bool DifParser::ReadNextLine( OUString& rStr )
     443             : {
     444          86 :     if( aLookAheadLine.isEmpty() )
     445             :     {
     446          60 :         return rIn.ReadUniOrByteStringLine( rStr, rIn.GetStreamCharSet() );
     447             :     }
     448             :     else
     449             :     {
     450          26 :         rStr = aLookAheadLine;
     451          26 :         aLookAheadLine = OUString();
     452          26 :         return true;
     453             :     }
     454             : }
     455             : 
     456             : // Look ahead in the stream to determine if the next line is the first line of
     457             : // a valid data record structure
     458          26 : bool DifParser::LookAhead()
     459             : {
     460             :     const sal_Unicode* pAktBuffer;
     461          26 :     bool bValidStructure = false;
     462             : 
     463             :     OSL_ENSURE( aLookAheadLine.isEmpty(), "*DifParser::LookAhead(): LookAhead called twice in a row" );
     464          26 :     rIn.ReadUniOrByteStringLine( aLookAheadLine, rIn.GetStreamCharSet() );
     465             : 
     466          26 :     pAktBuffer = aLookAheadLine.getStr();
     467             : 
     468          26 :     switch( *pAktBuffer )
     469             :     {
     470             :         case '-':                   // Special Datatype
     471           4 :             pAktBuffer++;
     472             : 
     473           4 :             if( Is1_0( pAktBuffer ) )
     474             :             {
     475           4 :                 bValidStructure = true;
     476             :             }
     477           4 :             break;
     478             :         case '0':                   // Numeric Data
     479           4 :             pAktBuffer++;
     480           4 :             if( *pAktBuffer == ',' )
     481             :             {
     482           4 :                 pAktBuffer++;
     483           4 :                 bValidStructure = ( GetNumberDataset(pAktBuffer) != D_SYNT_ERROR );
     484             :             }
     485           4 :             break;
     486             :         case '1':                   // String Data
     487          18 :             if( Is1_0( aLookAheadLine.getStr() ) )
     488             :             {
     489          18 :                 bValidStructure = true;
     490             :             }
     491          18 :             break;
     492             :     }
     493          26 :     return bValidStructure;
     494             : }
     495             : 
     496          37 : DATASET DifParser::GetNextDataset( void )
     497             : {
     498          37 :     DATASET eRet = D_UNKNOWN;
     499          37 :     OUString aLine;
     500             :     const sal_Unicode* pAktBuffer;
     501             : 
     502          37 :     ReadNextLine( aLine );
     503             : 
     504          37 :     pAktBuffer = aLine.getStr();
     505             : 
     506          37 :     switch( *pAktBuffer )
     507             :     {
     508             :         case '-':                   // Special Datatype
     509           5 :             pAktBuffer++;
     510             : 
     511           5 :             if( Is1_0( pAktBuffer ) )
     512             :             {
     513           5 :                 ReadNextLine( aLine );
     514           5 :                 if( IsBOT( aLine.getStr() ) )
     515           4 :                     eRet = D_BOT;
     516           1 :                 else if( IsEOD( aLine.getStr() ) )
     517           1 :                     eRet = D_EOD;
     518             :             }
     519           5 :             break;
     520             :         case '0':                   // Numeric Data
     521           6 :             pAktBuffer++;           // Wert in fVal, 2. Zeile in aData
     522           6 :             if( *pAktBuffer == ',' )
     523             :             {
     524           6 :                 pAktBuffer++;
     525           6 :                 eRet = GetNumberDataset(pAktBuffer);
     526           6 :                 OUString aTmpLine;
     527           6 :                 ReadNextLine( aTmpLine );
     528           6 :                 if ( eRet == D_SYNT_ERROR )
     529             :                 {   // for broken records write "#ERR: data" to cell
     530           0 :                     OUStringBuffer aTmp("#ERR: ");
     531           0 :                     aTmp.append(pAktBuffer).append(" (");
     532           0 :                     aTmp.append(aTmpLine).append(')');
     533           0 :                     aData = aTmp.makeStringAndClear();
     534           0 :                     eRet = D_STRING;
     535             :                 }
     536             :                 else
     537             :                 {
     538           6 :                     aData = aTmpLine;
     539           6 :                 }
     540             :             }
     541           6 :             break;
     542             :         case '1':                   // String Data
     543          26 :             if( Is1_0( aLine.getStr() ) )
     544             :             {
     545          26 :                 ReadNextLine( aLine );
     546          26 :                 sal_Int32 nLineLength = aLine.getLength();
     547          26 :                 const sal_Unicode* pLine = aLine.getStr();
     548             : 
     549          26 :                 if( nLineLength >= 1 && *pLine == '"' )
     550             :                 {
     551             :                     // Quotes are not always escaped (duplicated), see lcl_DeEscapeQuotesDif
     552             :                     // A look ahead into the next line is needed in order to deal with
     553             :                     // multiline strings containing quotes
     554          26 :                     if( LookAhead() )
     555             :                     {
     556             :                         // Single line string
     557          26 :                         if( nLineLength >= 2 && pLine[nLineLength - 1] == '"' )
     558             :                         {
     559          26 :                             aData = aLine.copy( 1, nLineLength - 2 );
     560          26 :                             lcl_DeEscapeQuotesDif( aData );
     561          26 :                             eRet = D_STRING;
     562             :                         }
     563             :                     }
     564             :                     else
     565             :                     {
     566             :                         // Multiline string
     567           0 :                         aData = aLine.copy( 1 );
     568           0 :                         bool bContinue = true;
     569           0 :                         while ( bContinue )
     570             :                         {
     571           0 :                             aData = aData + "\n";
     572           0 :                             bContinue = !rIn.IsEof() && ReadNextLine( aLine );
     573           0 :                             if( bContinue )
     574             :                             {
     575           0 :                                 nLineLength = aLine.getLength();
     576           0 :                                 if( nLineLength >= 1 )
     577             :                                 {
     578           0 :                                     pLine = aLine.getStr();
     579           0 :                                     bContinue = !LookAhead();
     580           0 :                                     if( bContinue )
     581             :                                     {
     582           0 :                                         aData = aData + aLine;
     583             :                                     }
     584           0 :                                     else if( pLine[nLineLength - 1] == '"' )
     585             :                                     {
     586           0 :                                         aData = aData + aLine.copy(0, nLineLength -1 );
     587           0 :                                         lcl_DeEscapeQuotesDif( aData );
     588           0 :                                         eRet = D_STRING;
     589             :                                     }
     590             :                                 }
     591             :                             }
     592             :                         };
     593             :                     }
     594             :                 }
     595             :             }
     596          26 :             break;
     597             :     }
     598             : 
     599          37 :     if( eRet == D_UNKNOWN )
     600           0 :         ReadNextLine( aLine );
     601             : 
     602          37 :     if( rIn.IsEof() )
     603           0 :         eRet = D_EOD;
     604             : 
     605          37 :     return eRet;
     606             : }
     607             : 
     608             : 
     609           8 : const sal_Unicode* DifParser::ScanIntVal( const sal_Unicode* pStart, sal_uInt32& rRet )
     610             : {
     611             :     // eat leading whitespace, not specified, but seen in the wild
     612          16 :     while (*pStart == ' ' || *pStart == '\t')
     613           0 :         ++pStart;
     614             : 
     615           8 :     sal_Unicode     cAkt = *pStart;
     616             : 
     617           8 :     if( IsNumber( cAkt ) )
     618           8 :         rRet = ( sal_uInt32 ) ( cAkt - '0' );
     619             :     else
     620           0 :         return NULL;
     621             : 
     622           8 :     pStart++;
     623           8 :     cAkt = *pStart;
     624             : 
     625          16 :     while( IsNumber( cAkt ) && rRet < ( 0xFFFFFFFF / 10 ) )
     626             :     {
     627           0 :         rRet *= 10;
     628           0 :         rRet += ( sal_uInt32 ) ( cAkt - '0' );
     629             : 
     630           0 :         pStart++;
     631           0 :         cAkt = *pStart;
     632             :     }
     633             : 
     634           8 :     return pStart;
     635             : }
     636             : 
     637             : 
     638           0 : sal_Bool DifParser::ScanFloatVal( const sal_Unicode* pStart )
     639             :     {
     640           0 :     sal_Bool                    bNeg = false;
     641           0 :     double                  fFracPos = 1.0;
     642           0 :     sal_Int32                   nExp = 0;
     643           0 :     sal_Bool                    bExpNeg = false;
     644           0 :     sal_Bool                    bExpOverflow = false;
     645             :     static const sal_uInt16     nExpLimit = 4096;   // ACHTUNG: muss genauer ermittelt werden!
     646             : 
     647             :     sal_Unicode             cAkt;
     648           0 :     sal_Bool                    bRet = false;
     649             : 
     650             :     enum STATE { S_FIRST, S_PRE, S_POST, S_EXP_FIRST, S_EXP, S_END, S_FINDEND };
     651             : 
     652           0 :     STATE   eS = S_FIRST;
     653             : 
     654           0 :     double fNewVal = 0.0;
     655             : 
     656           0 :     while( eS != S_END )
     657             :     {
     658           0 :         cAkt = *pStart;
     659           0 :         switch( eS )
     660             :         {
     661             :             case S_FIRST:
     662           0 :                 if( IsNumber( cAkt ) )
     663             :                 {
     664           0 :                     fNewVal *= 10;
     665           0 :                     fNewVal += cAkt - '0';
     666           0 :                     eS = S_PRE;
     667             :                 }
     668             :                 else
     669             :                 {
     670           0 :                     switch( cAkt )
     671             :                     {
     672             :                         case ' ':
     673             :                         case '\t':
     674             :                         case '+':
     675           0 :                             break;
     676             :                         case '-':
     677           0 :                             bNeg = !bNeg;
     678           0 :                             break;
     679             :                         case '.':
     680             :                         case ',':                   //!
     681           0 :                             eS = S_POST;
     682           0 :                             fFracPos = 0.1;
     683           0 :                             break;
     684             :                         default:
     685           0 :                             eS = S_END;
     686             :                     }
     687             :                 }
     688           0 :                 break;
     689             :             case S_PRE:
     690           0 :                 if( IsNumber( cAkt ) )
     691             :                 {
     692           0 :                     fNewVal *= 10;
     693           0 :                     fNewVal += cAkt - '0';
     694             :                 }
     695             :                 else
     696             :                 {
     697           0 :                     switch( cAkt )
     698             :                     {
     699             :                         case '.':
     700             :                         case ',':                   //!
     701           0 :                             eS = S_POST;
     702           0 :                             fFracPos = 0.1;
     703           0 :                             break;
     704             :                         case 'e':
     705             :                         case 'E':
     706           0 :                             eS = S_EXP;
     707           0 :                             break;
     708             :                         case 0x00:              // IsNumberEnding( cAkt )
     709           0 :                             bRet = sal_True;        // no
     710             :                         default:                // break!
     711           0 :                             eS = S_END;
     712             :                     }
     713             :                 }
     714           0 :                 break;
     715             :             case S_POST:
     716           0 :                 if( IsNumber( cAkt ) )
     717             :                 {
     718           0 :                     fNewVal += fFracPos * ( cAkt - '0' );
     719           0 :                     fFracPos /= 10.0;
     720             :                 }
     721             :                 else
     722             :                 {
     723           0 :                     switch( cAkt )
     724             :                     {
     725             :                         case 'e':
     726             :                         case 'E':
     727           0 :                             eS = S_EXP_FIRST;
     728           0 :                             break;
     729             :                         case 0x00:              // IsNumberEnding( cAkt )
     730           0 :                             bRet = sal_True;        // no
     731             :                         default:                // break!
     732           0 :                             eS = S_END;
     733             :                     }
     734             :                 }
     735           0 :                 break;
     736             :             case S_EXP_FIRST:
     737           0 :                 if( IsNumber( cAkt ) )
     738             :                 {
     739           0 :                     if( nExp < nExpLimit )
     740             :                     {
     741           0 :                         nExp *= 10;
     742           0 :                         nExp += ( sal_uInt16 ) ( cAkt - '0' );
     743             :                     }
     744           0 :                     eS = S_EXP;
     745             :                 }
     746             :                 else
     747             :                 {
     748           0 :                     switch( cAkt )
     749             :                     {
     750             :                         case '+':
     751           0 :                             break;
     752             :                         case '-':
     753           0 :                             bExpNeg = !bExpNeg;
     754           0 :                             break;
     755             :                         default:
     756           0 :                             eS = S_END;
     757             :                     }
     758             :                 }
     759           0 :                 break;
     760             :             case S_EXP:
     761           0 :                 if( IsNumber( cAkt ) )
     762             :                 {
     763           0 :                     if( nExp < ( 0xFFFF / 10 ) )
     764             :                     {
     765           0 :                         nExp *= 10;
     766           0 :                         nExp += ( sal_uInt16 ) ( cAkt - '0' );
     767             :                     }
     768             :                     else
     769             :                     {
     770           0 :                         bExpOverflow = sal_True;
     771           0 :                         eS = S_FINDEND;
     772             :                     }
     773             :                 }
     774             :                 else
     775             :                 {
     776           0 :                     bRet = IsNumberEnding( cAkt );
     777           0 :                     eS = S_END;
     778             :                 }
     779           0 :                 break;
     780             :             case S_FINDEND:
     781           0 :                 if( IsNumberEnding( cAkt ) )
     782             :                 {
     783           0 :                     bRet = sal_True;        // damit sinnvoll weitergeparst werden kann
     784           0 :                     eS = S_END;
     785             :                 }
     786           0 :                 break;
     787             :             case S_END:
     788             :                 OSL_FAIL( "DifParser::ScanFloatVal - unexpected state" );
     789           0 :                 break;
     790             :             default:
     791             :                 OSL_FAIL( "DifParser::ScanFloatVal - missing enum" );
     792             :         }
     793           0 :         pStart++;
     794             :     }
     795             : 
     796           0 :     if( bRet )
     797             :     {
     798           0 :         if( bExpOverflow )
     799           0 :             return false;       // ACHTUNG: hier muss noch differenziert werden
     800             : 
     801           0 :         if( bNeg )
     802           0 :             fNewVal *= 1.0;
     803             : 
     804           0 :         if( bExpNeg )
     805           0 :             nExp *= -1;
     806             : 
     807           0 :         if( nExp != 0 )
     808           0 :             fNewVal *= pow( 10.0, ( double ) nExp );
     809           0 :         fVal = fNewVal;
     810             :     }
     811             : 
     812           0 :     return bRet;
     813             : }
     814             : 
     815           2 : DifColumn::DifColumn ()
     816           2 :     : pAkt(NULL)
     817             : {
     818           2 : }
     819             : 
     820           0 : void DifColumn::SetLogical( SCROW nRow )
     821             : {
     822             :     OSL_ENSURE( ValidRow(nRow), "*DifColumn::SetLogical(): Row too big!" );
     823             : 
     824           0 :     if( pAkt )
     825             :     {
     826             :         OSL_ENSURE( nRow > 0, "*DifColumn::SetLogical(): more cannot be zero!" );
     827             : 
     828           0 :         nRow--;
     829             : 
     830           0 :         if( pAkt->nEnd == nRow )
     831           0 :             pAkt->nEnd++;
     832             :         else
     833           0 :             pAkt = NULL;
     834             :     }
     835             :     else
     836             :     {
     837           0 :         pAkt = new ENTRY;
     838           0 :         pAkt->nStart = pAkt->nEnd = nRow;
     839             : 
     840           0 :         aEntries.push_back(pAkt);
     841             :     }
     842           0 : }
     843             : 
     844             : 
     845           6 : void DifColumn::SetNumFormat( SCROW nRow, const sal_uInt32 nNumFormat )
     846             : {
     847             :     OSL_ENSURE( ValidRow(nRow), "*DifColumn::SetNumFormat(): Row too big!" );
     848             : 
     849           6 :     if( nNumFormat > 0 )
     850             :     {
     851           0 :         if(pAkt)
     852             :         {
     853             :             OSL_ENSURE( nRow > 0,
     854             :                 "*DifColumn::SetNumFormat(): more cannot be zero!" );
     855             :             OSL_ENSURE( nRow > pAkt->nEnd,
     856             :                 "*DifColumn::SetNumFormat(): start from scratch?" );
     857             : 
     858           0 :             if( pAkt->nNumFormat == nNumFormat && pAkt->nEnd == nRow - 1 )
     859           0 :                 pAkt->nEnd = nRow;
     860             :             else
     861           0 :                 NewEntry( nRow, nNumFormat );
     862             :         }
     863             :         else
     864           0 :             NewEntry(nRow,nNumFormat );
     865             :     }
     866             :     else
     867           6 :         pAkt = NULL;
     868           6 : }
     869             : 
     870             : 
     871           0 : void DifColumn::NewEntry( const SCROW nPos, const sal_uInt32 nNumFormat )
     872             : {
     873           0 :     pAkt = new ENTRY;
     874           0 :     pAkt->nStart = pAkt->nEnd = nPos;
     875           0 :     pAkt->nNumFormat = nNumFormat;
     876             : 
     877           0 :     aEntries.push_back(pAkt);
     878           0 : }
     879             : 
     880             : 
     881           0 : void DifColumn::Apply( ScDocument& rDoc, const SCCOL nCol, const SCTAB nTab, const ScPatternAttr& rPattAttr )
     882             : {
     883           0 :     for (boost::ptr_vector<ENTRY>::const_iterator it = aEntries.begin(); it != aEntries.end(); ++it)
     884           0 :         rDoc.ApplyPatternAreaTab( nCol, it->nStart, nCol, it->nEnd, nTab, rPattAttr );
     885           0 : }
     886             : 
     887             : 
     888           2 : void DifColumn::Apply( ScDocument& rDoc, const SCCOL nCol, const SCTAB nTab )
     889             : {
     890           2 :     ScPatternAttr aAttr( rDoc.GetPool() );
     891           2 :     SfxItemSet &rItemSet = aAttr.GetItemSet();
     892             : 
     893           2 :     for (boost::ptr_vector<ENTRY>::const_iterator it = aEntries.begin(); it != aEntries.end(); ++it)
     894             :     {
     895             :         OSL_ENSURE( it->nNumFormat > 0,
     896             :             "+DifColumn::Apply(): Numberformat darf hier nicht 0 sein!" );
     897             : 
     898           0 :         rItemSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, it->nNumFormat ) );
     899             : 
     900           0 :         rDoc.ApplyPatternAreaTab( nCol, it->nStart, nCol, it->nEnd, nTab, aAttr );
     901             : 
     902           0 :         rItemSet.ClearItem();
     903           2 :     }
     904           2 : }
     905             : 
     906             : 
     907           1 : DifAttrCache::DifAttrCache( const sal_Bool bNewPlain )
     908             : {
     909           1 :     bPlain = bNewPlain;
     910           1 :     ppCols = new DifColumn *[ MAXCOL + 1 ];
     911        1025 :     for( SCCOL nCnt = 0 ; nCnt <= MAXCOL ; nCnt++ )
     912        1024 :         ppCols[ nCnt ] = NULL;
     913           1 : }
     914             : 
     915             : 
     916           1 : DifAttrCache::~DifAttrCache()
     917             : {
     918        1025 :     for( SCCOL nCnt = 0 ; nCnt <= MAXCOL ; nCnt++ )
     919             :     {
     920        1024 :         if( ppCols[ nCnt ] )
     921           2 :             delete ppCols[ nCnt ];
     922             :     }
     923             : 
     924           1 :     delete[] ppCols;
     925           1 : }
     926             : 
     927           0 : void DifAttrCache::SetLogical( const SCCOL nCol, const SCROW nRow )
     928             : {
     929             :     OSL_ENSURE( ValidCol(nCol), "-DifAttrCache::SetLogical(): Col too big!" );
     930             :     OSL_ENSURE( bPlain, "*DifAttrCache::SetLogical(): has to be Plain!" );
     931             : 
     932           0 :     if( !ppCols[ nCol ] )
     933           0 :         ppCols[ nCol ] = new DifColumn;
     934             : 
     935           0 :     ppCols[ nCol ]->SetLogical( nRow );
     936           0 : }
     937             : 
     938           6 : void DifAttrCache::SetNumFormat( const SCCOL nCol, const SCROW nRow, const sal_uInt32 nNumFormat )
     939             : {
     940             :     OSL_ENSURE( ValidCol(nCol), "-DifAttrCache::SetNumFormat(): Col too big!" );
     941             :     OSL_ENSURE( !bPlain, "*DifAttrCache::SetNumFormat(): should not be Plain!" );
     942             : 
     943           6 :     if( !ppCols[ nCol ] )
     944           2 :         ppCols[ nCol ] = new DifColumn;
     945             : 
     946           6 :     ppCols[ nCol ]->SetNumFormat( nRow, nNumFormat );
     947           6 : }
     948             : 
     949             : 
     950           1 : void DifAttrCache::Apply( ScDocument& rDoc, SCTAB nTab )
     951             : {
     952           1 :     if( bPlain )
     953             :     {
     954           0 :         ScPatternAttr*  pPatt = NULL;
     955             : 
     956           0 :         for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
     957             :         {
     958           0 :             if( ppCols[ nCol ] )
     959             :             {
     960           0 :                 if( !pPatt )
     961             :                 {
     962           0 :                     pPatt = new ScPatternAttr( rDoc.GetPool() );
     963           0 :                     pPatt->GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT,
     964           0 :                         rDoc.GetFormatTable()->GetStandardFormat( NUMBERFORMAT_LOGICAL ) ) );
     965             :                 }
     966             : 
     967           0 :                 ppCols[ nCol ]->Apply( rDoc, nCol, nTab, *pPatt );
     968             :             }
     969             :         }
     970             : 
     971           0 :         if( pPatt )
     972           0 :             delete pPatt;
     973             :     }
     974             :     else
     975             :     {
     976        1025 :         for( SCCOL nCol = 0 ; nCol <= MAXCOL ; nCol++ )
     977             :         {
     978        1024 :             if( ppCols[ nCol ] )
     979           2 :                 ppCols[ nCol ]->Apply( rDoc, nCol, nTab );
     980             :         }
     981             :     }
     982           1 : }
     983             : 
     984             : 
     985             : 
     986             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10