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

Generated by: LCOV version 1.10