LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/svrtf - svparser.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 114 283 40.3 %
Date: 2012-12-27 Functions: 14 25 56.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <stdio.h>
      21             : #include <svtools/svparser.hxx>
      22             : #include <tools/stream.hxx>
      23             : #include <tools/debug.hxx>
      24             : #include <rtl/textcvt.h>
      25             : #include <rtl/tencinfo.h>
      26             : 
      27             : // Struktur, um sich die akt. Daten zumerken
      28           1 : struct SvParser_Impl
      29             : {
      30             :     String          aToken;             // gescanntes Token
      31             :     sal_uLong           nFilePos;           // akt. Position im Stream
      32             :     sal_uLong           nlLineNr;           // akt. Zeilen Nummer
      33             :     sal_uLong           nlLinePos;          // akt. Spalten Nummer
      34             :     long            nTokenValue;        // zusaetzlicher Wert (RTF)
      35             :     sal_Bool            bTokenHasValue;     // indicates whether nTokenValue is valid
      36             :     int             nToken;             // akt. Token
      37             :     sal_Unicode     nNextCh;            // akt. Zeichen
      38             : 
      39             :     int             nSaveToken;         // das Token vom Continue
      40             : 
      41             :     rtl_TextToUnicodeConverter hConv;
      42             :     rtl_TextToUnicodeContext   hContext;
      43             : 
      44           1 :     SvParser_Impl() :
      45           1 :         nSaveToken(0), hConv( 0 ), hContext( (rtl_TextToUnicodeContext)1 )
      46             :     {
      47           1 :     }
      48             : 
      49             : };
      50             : 
      51             : 
      52             : 
      53             : // Konstruktor
      54           1 : SvParser::SvParser( SvStream& rIn, sal_uInt8 nStackSize )
      55             :     : rInput( rIn )
      56             :     , nlLineNr( 1 )
      57             :     , nlLinePos( 1 )
      58             :     , pImplData( 0 )
      59             :     , nTokenValue( 0 )
      60             :     , bTokenHasValue( false )
      61             :     , eState( SVPAR_NOTSTARTED )
      62             :     , eSrcEnc( RTL_TEXTENCODING_DONTKNOW )
      63             :     , bDownloadingFile( sal_False )
      64             :     , nTokenStackSize( nStackSize )
      65           1 :     , nTokenStackPos( 0 )
      66             : {
      67           1 :     bUCS2BSrcEnc = bSwitchToUCS2 = sal_False;
      68           1 :     eState = SVPAR_NOTSTARTED;
      69           1 :     if( nTokenStackSize < 3 )
      70           0 :         nTokenStackSize = 3;
      71           1 :     pTokenStack = new TokenStackType[ nTokenStackSize ];
      72           1 :     pTokenStackPos = pTokenStack;
      73           1 : }
      74             : 
      75           2 : SvParser::~SvParser()
      76             : {
      77           1 :     if( pImplData && pImplData->hConv )
      78             :     {
      79             :         rtl_destroyTextToUnicodeContext( pImplData->hConv,
      80           1 :                                          pImplData->hContext );
      81           1 :         rtl_destroyTextToUnicodeConverter( pImplData->hConv );
      82             :     }
      83             : 
      84           1 :     delete pImplData;
      85             : 
      86           1 :     delete [] pTokenStack;
      87           1 : }
      88             : 
      89           0 : void SvParser::ClearTxtConvContext()
      90             : {
      91           0 :     if( pImplData && pImplData->hConv )
      92           0 :         rtl_resetTextToUnicodeContext( pImplData->hConv, pImplData->hContext );
      93           0 : }
      94             : 
      95           2 : void SvParser::SetSrcEncoding( rtl_TextEncoding eEnc )
      96             : {
      97             : 
      98           2 :     if( eEnc != eSrcEnc )
      99             :     {
     100           2 :         if( pImplData && pImplData->hConv )
     101             :         {
     102             :             rtl_destroyTextToUnicodeContext( pImplData->hConv,
     103           1 :                                              pImplData->hContext );
     104           1 :             rtl_destroyTextToUnicodeConverter( pImplData->hConv );
     105           1 :             pImplData->hConv = 0;
     106           1 :             pImplData->hContext = (rtl_TextToUnicodeContext )1;
     107             :         }
     108             : 
     109           2 :         if( rtl_isOctetTextEncoding(eEnc) ||
     110             :             RTL_TEXTENCODING_UCS2 == eEnc  )
     111             :         {
     112           2 :             eSrcEnc = eEnc;
     113           2 :             if( !pImplData )
     114           1 :                 pImplData = new SvParser_Impl;
     115           2 :             pImplData->hConv = rtl_createTextToUnicodeConverter( eSrcEnc );
     116             :             DBG_ASSERT( pImplData->hConv,
     117             :                         "SvParser::SetSrcEncoding: no converter for source encoding" );
     118           2 :             if( !pImplData->hConv )
     119           0 :                 eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
     120             :             else
     121             :                 pImplData->hContext =
     122           2 :                     rtl_createTextToUnicodeContext( pImplData->hConv );
     123             :         }
     124             :         else
     125             :         {
     126             :             DBG_ASSERT( !this,
     127             :                         "SvParser::SetSrcEncoding: invalid source encoding" );
     128           0 :             eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
     129             :         }
     130             :     }
     131           2 : }
     132             : 
     133           0 : void SvParser::RereadLookahead()
     134             : {
     135           0 :     rInput.Seek(nNextChPos);
     136           0 :     nNextCh = GetNextChar();
     137           0 : }
     138             : 
     139         229 : sal_Unicode SvParser::GetNextChar()
     140             : {
     141         229 :     sal_Unicode c = 0U;
     142             : 
     143             :     // When reading muliple bytes, we don't have to care about the file
     144             :     // position when we run inti the pending state. The file position is
     145             :     // maintained by SaveState/RestoreState.
     146             :     sal_Bool bErr;
     147         229 :     if( bSwitchToUCS2 && 0 == rInput.Tell() )
     148             :     {
     149             :         sal_uChar c1, c2;
     150           1 :         sal_Bool bSeekBack = sal_True;
     151             : 
     152           1 :         rInput >> c1;
     153           1 :         bErr = rInput.IsEof() || rInput.GetError();
     154           1 :         if( !bErr )
     155             :         {
     156           1 :             if( 0xff == c1 || 0xfe == c1 )
     157             :             {
     158           0 :                 rInput >> c2;
     159           0 :                 bErr = rInput.IsEof() || rInput.GetError();
     160           0 :                 if( !bErr )
     161             :                 {
     162           0 :                     if( 0xfe == c1 && 0xff == c2 )
     163             :                     {
     164           0 :                         eSrcEnc = RTL_TEXTENCODING_UCS2;
     165           0 :                         bUCS2BSrcEnc = sal_True;
     166           0 :                         bSeekBack = sal_False;
     167             :                     }
     168           0 :                     else if( 0xff == c1 && 0xfe == c2 )
     169             :                     {
     170           0 :                         eSrcEnc = RTL_TEXTENCODING_UCS2;
     171           0 :                         bUCS2BSrcEnc = sal_False;
     172           0 :                         bSeekBack = sal_False;
     173             :                     }
     174             :                 }
     175             :             }
     176             :         }
     177           1 :         if( bSeekBack )
     178           1 :             rInput.Seek( 0 );
     179             : 
     180           1 :         bSwitchToUCS2 = sal_False;
     181             :     }
     182             : 
     183         229 :     nNextChPos = rInput.Tell();
     184             : 
     185         229 :     if( RTL_TEXTENCODING_UCS2 == eSrcEnc )
     186             :     {
     187           0 :         sal_Unicode cUC = USHRT_MAX;
     188             :         sal_uChar c1, c2;
     189             : 
     190           0 :         rInput >> c1 >> c2;
     191           0 :         if( 2 == rInput.Tell() &&
     192           0 :             !(rInput.IsEof() || rInput.GetError()) &&
     193             :             ( (bUCS2BSrcEnc && 0xfe == c1 && 0xff == c2) ||
     194           0 :               (!bUCS2BSrcEnc && 0xff == c1 && 0xfe == c2) ) )
     195           0 :             rInput >> c1 >> c2;
     196             : 
     197           0 :         bErr = rInput.IsEof() || rInput.GetError();
     198           0 :         if( !bErr )
     199             :         {
     200           0 :             if( bUCS2BSrcEnc )
     201           0 :                 cUC = (sal_Unicode(c1) << 8) | c2;
     202             :             else
     203           0 :                 cUC = (sal_Unicode(c2) << 8) | c1;
     204             :         }
     205             : 
     206           0 :         if( !bErr )
     207             :         {
     208           0 :             c = cUC;
     209             :         }
     210             :     }
     211             :     else
     212             :     {
     213         229 :         sal_Size nChars = 0;
     214         229 :         do
     215             :         {
     216             :             sal_Char c1;    // signed, that's the text converter expects
     217         229 :             rInput >> c1;
     218         229 :             bErr = rInput.IsEof() || rInput.GetError();
     219         229 :             if( !bErr )
     220             :             {
     221         227 :                 if (
     222             :                      RTL_TEXTENCODING_DONTKNOW == eSrcEnc ||
     223             :                      RTL_TEXTENCODING_SYMBOL == eSrcEnc
     224             :                    )
     225             :                 {
     226             :                     // no convserion shall take place
     227           0 :                     c = (sal_Unicode)c1;
     228           0 :                     nChars = 1;
     229             :                 }
     230             :                 else
     231             :                 {
     232             :                     DBG_ASSERT( pImplData && pImplData->hConv,
     233             :                                 "no text converter!" );
     234             : 
     235             :                     sal_Unicode cUC;
     236         227 :                     sal_uInt32 nInfo = 0;
     237             :                     sal_Size nCvtBytes;
     238             :                     nChars = rtl_convertTextToUnicode(
     239             :                                 pImplData->hConv, pImplData->hContext,
     240             :                                 &c1, 1, &cUC, 1,
     241             :                                 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
     242             :                                 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
     243             :                                 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
     244         227 :                                 &nInfo, &nCvtBytes);
     245         227 :                     if( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 )
     246             :                     {
     247             :                         // The conversion wasn't successfull because we haven't
     248             :                         // read enough characters.
     249           0 :                         if( pImplData->hContext != (rtl_TextToUnicodeContext)1 )
     250             :                         {
     251           0 :                             while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 )
     252             :                             {
     253           0 :                                 rInput >> c1;
     254           0 :                                 bErr = rInput.IsEof() || rInput.GetError();
     255           0 :                                 if( bErr )
     256           0 :                                     break;
     257             : 
     258             :                                 nChars = rtl_convertTextToUnicode(
     259             :                                             pImplData->hConv, pImplData->hContext,
     260             :                                             &c1, 1, &cUC, 1,
     261             :                                             RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
     262             :                                             RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
     263             :                                             RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
     264           0 :                                             &nInfo, &nCvtBytes);
     265             :                             }
     266           0 :                             if( !bErr )
     267             :                             {
     268           0 :                                 if( 1 == nChars && 0 == nInfo )
     269             :                                 {
     270           0 :                                     c = cUC;
     271             :                                 }
     272           0 :                                 else if( 0 != nChars || 0 != nInfo )
     273             :                                 {
     274             :                                     DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) == 0,
     275             :                                         "source buffer is to small" );
     276             :                                     DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL)) == 0,
     277             :                                          "there is a conversion error" );
     278             :                                     DBG_ASSERT( 0 == nChars,
     279             :                                        "there is a converted character, but an error" );
     280             :                                     // There are still errors, but nothing we can
     281             :                                     // do
     282           0 :                                     c = (sal_Unicode)'?';
     283           0 :                                     nChars = 1;
     284             :                                 }
     285             :                             }
     286             :                         }
     287             :                         else
     288             :                         {
     289             :                             sal_Char sBuffer[10];
     290           0 :                             sBuffer[0] = c1;
     291           0 :                             sal_uInt16 nLen = 1;
     292           0 :                             while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 &&
     293             :                                     nLen < 10 )
     294             :                             {
     295           0 :                                 rInput >> c1;
     296           0 :                                 bErr = rInput.IsEof() || rInput.GetError();
     297           0 :                                 if( bErr )
     298           0 :                                     break;
     299             : 
     300           0 :                                 sBuffer[nLen++] = c1;
     301             :                                 nChars = rtl_convertTextToUnicode(
     302             :                                             pImplData->hConv, 0, sBuffer, nLen, &cUC, 1,
     303             :                                             RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
     304             :                                             RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
     305             :                                             RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
     306           0 :                                             &nInfo, &nCvtBytes);
     307             :                             }
     308           0 :                             if( !bErr )
     309             :                             {
     310           0 :                                 if( 1 == nChars && 0 == nInfo )
     311             :                                 {
     312             :                                     DBG_ASSERT( nCvtBytes == nLen,
     313             :                                                 "no all bytes have been converted!" );
     314           0 :                                     c = cUC;
     315             :                                 }
     316             :                                 else
     317             :                                 {
     318             :                                     DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) == 0,
     319             :                                         "source buffer is to small" );
     320             :                                     DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL)) == 0,
     321             :                                          "there is a conversion error" );
     322             :                                     DBG_ASSERT( 0 == nChars,
     323             :                                        "there is a converted character, but an error" );
     324             : 
     325             :                                     // There are still errors, so we use the first
     326             :                                     // character and restart after that.
     327           0 :                                     c = (sal_Unicode)sBuffer[0];
     328           0 :                                     rInput.SeekRel( -(nLen-1) );
     329           0 :                                     nChars = 1;
     330             :                                 }
     331             :                             }
     332             :                         }
     333             :                     }
     334         227 :                     else if( 1 == nChars && 0 == nInfo )
     335             :                     {
     336             :                         // The conversion was successfull
     337             :                         DBG_ASSERT( nCvtBytes == 1,
     338             :                                     "no all bytes have been converted!" );
     339         227 :                         c = cUC;
     340             :                     }
     341           0 :                     else if( 0 != nChars || 0 != nInfo )
     342             :                     {
     343             :                         DBG_ASSERT( 0 == nChars,
     344             :                                 "there is a converted character, but an error" );
     345             :                         DBG_ASSERT( 0 != nInfo,
     346             :                                 "there is no converted character and no error" );
     347             :                         // #73398#: If the character could not be converted,
     348             :                         // because a conversion is not available, do no conversion at all.
     349           0 :                         c = (sal_Unicode)c1;
     350           0 :                         nChars = 1;
     351             : 
     352             :                     }
     353             :                 }
     354             :             }
     355             :         }
     356             :         while( 0 == nChars  && !bErr );
     357             :     }
     358         229 :     if( bErr )
     359             :     {
     360           2 :         if( ERRCODE_IO_PENDING == rInput.GetError() )
     361             :         {
     362           0 :             eState = SVPAR_PENDING;
     363           0 :             return c;
     364             :         }
     365             :         else
     366           2 :             return sal_Unicode(EOF);
     367             :     }
     368             : 
     369         227 :     if( c == '\n' )
     370             :     {
     371           8 :         IncLineNr();
     372           8 :         SetLinePos( 1L );
     373             :     }
     374             :     else
     375         219 :         IncLinePos();
     376         227 :     return c;
     377             : }
     378             : 
     379          36 : int SvParser::GetNextToken()
     380             : {
     381          36 :     int nRet = 0;
     382             : 
     383          36 :     if( !nTokenStackPos )
     384             :     {
     385          36 :         aToken.Erase();     // Token-Buffer loeschen
     386          36 :         nTokenValue = -1;   // Kennzeichen fuer kein Value gelesen
     387          36 :         bTokenHasValue = false;
     388             : 
     389          36 :         nRet = _GetNextToken();
     390          36 :         if( SVPAR_PENDING == eState )
     391           0 :             return nRet;
     392             :     }
     393             : 
     394          36 :     ++pTokenStackPos;
     395          36 :     if( pTokenStackPos == pTokenStack + nTokenStackSize )
     396          12 :         pTokenStackPos = pTokenStack;
     397             : 
     398             :     // vom Stack holen ??
     399          36 :     if( nTokenStackPos )
     400             :     {
     401           0 :         --nTokenStackPos;
     402           0 :         nTokenValue = pTokenStackPos->nTokenValue;
     403           0 :         bTokenHasValue = pTokenStackPos->bTokenHasValue;
     404           0 :         aToken = pTokenStackPos->sToken;
     405           0 :         nRet = pTokenStackPos->nTokenId;
     406             :     }
     407             :     // nein, dann das aktuelle auf den Stack
     408          36 :     else if( SVPAR_WORKING == eState )
     409             :     {
     410          35 :         pTokenStackPos->sToken = aToken;
     411          35 :         pTokenStackPos->nTokenValue = nTokenValue;
     412          35 :         pTokenStackPos->bTokenHasValue = bTokenHasValue;
     413          35 :         pTokenStackPos->nTokenId = nRet;
     414             :     }
     415           1 :     else if( SVPAR_ACCEPTED != eState && SVPAR_PENDING != eState )
     416           0 :         eState = SVPAR_ERROR;       // irgend ein Fehler
     417             : 
     418          36 :     return nRet;
     419             : }
     420             : 
     421           0 : int SvParser::SkipToken( short nCnt )       // n Tokens zurueck "skippen"
     422             : {
     423           0 :     pTokenStackPos = GetStackPtr( nCnt );
     424           0 :     short nTmp = nTokenStackPos - nCnt;
     425           0 :     if( nTmp < 0 )
     426           0 :         nTmp = 0;
     427           0 :     else if( nTmp > nTokenStackSize )
     428           0 :         nTmp = nTokenStackSize;
     429           0 :     nTokenStackPos = sal_uInt8(nTmp);
     430             : 
     431             :     // und die Werte zurueck
     432           0 :     aToken = pTokenStackPos->sToken;
     433           0 :     nTokenValue = pTokenStackPos->nTokenValue;
     434           0 :     bTokenHasValue = pTokenStackPos->bTokenHasValue;
     435             : 
     436           0 :     return pTokenStackPos->nTokenId;
     437             : }
     438             : 
     439           0 : SvParser::TokenStackType* SvParser::GetStackPtr( short nCnt )
     440             : {
     441           0 :     sal_uInt8 nAktPos = sal_uInt8(pTokenStackPos - pTokenStack );
     442           0 :     if( nCnt > 0 )
     443             :     {
     444           0 :         if( nCnt >= nTokenStackSize )
     445           0 :             nCnt = (nTokenStackSize-1);
     446           0 :         if( nAktPos + nCnt < nTokenStackSize )
     447           0 :             nAktPos = sal::static_int_cast< sal_uInt8 >(nAktPos + nCnt);
     448             :         else
     449             :             nAktPos = sal::static_int_cast< sal_uInt8 >(
     450           0 :                 nAktPos + (nCnt - nTokenStackSize));
     451             :     }
     452           0 :     else if( nCnt < 0 )
     453             :     {
     454           0 :         if( -nCnt >= nTokenStackSize )
     455           0 :             nCnt = -nTokenStackSize+1;
     456           0 :         if( -nCnt <= nAktPos )
     457           0 :             nAktPos = sal::static_int_cast< sal_uInt8 >(nAktPos + nCnt);
     458             :         else
     459             :             nAktPos = sal::static_int_cast< sal_uInt8 >(
     460           0 :                 nAktPos + (nCnt + nTokenStackSize));
     461             :     }
     462           0 :     return pTokenStack + nAktPos;
     463             : }
     464             : 
     465             : // wird fuer jedes Token gerufen, das in CallParser erkannt wird
     466           0 : void SvParser::NextToken( int )
     467             : {
     468           0 : }
     469             : 
     470             : 
     471             : // fuers asynchrone lesen aus dem SvStream
     472             : 
     473           0 : int SvParser::GetSaveToken() const
     474             : {
     475           0 :     return pImplData ? pImplData->nSaveToken : 0;
     476             : }
     477             : 
     478          71 : void SvParser::SaveState( int nToken )
     479             : {
     480             :     // aktuellen Status merken
     481          71 :     if( !pImplData )
     482             :     {
     483           0 :         pImplData = new SvParser_Impl;
     484           0 :         pImplData->nSaveToken = 0;
     485             :     }
     486             : 
     487          71 :     pImplData->nFilePos = rInput.Tell();
     488          71 :     pImplData->nToken = nToken;
     489             : 
     490          71 :     pImplData->aToken = aToken;
     491          71 :     pImplData->nlLineNr = nlLineNr;
     492          71 :     pImplData->nlLinePos = nlLinePos;
     493          71 :     pImplData->nTokenValue= nTokenValue;
     494          71 :     pImplData->bTokenHasValue = bTokenHasValue;
     495          71 :     pImplData->nNextCh = nNextCh;
     496          71 : }
     497             : 
     498           0 : void SvParser::RestoreState()
     499             : {
     500             :     // alten Status wieder zurueck setzen
     501           0 :     if( pImplData )
     502             :     {
     503           0 :         if( ERRCODE_IO_PENDING == rInput.GetError() )
     504           0 :             rInput.ResetError();
     505           0 :         aToken = pImplData->aToken;
     506           0 :         nlLineNr = pImplData->nlLineNr;
     507           0 :         nlLinePos = pImplData->nlLinePos;
     508           0 :         nTokenValue= pImplData->nTokenValue;
     509           0 :         bTokenHasValue=pImplData->bTokenHasValue;
     510           0 :         nNextCh = pImplData->nNextCh;
     511             : 
     512           0 :         pImplData->nSaveToken = pImplData->nToken;
     513             : 
     514           0 :         rInput.Seek( pImplData->nFilePos );
     515             :     }
     516           0 : }
     517             : 
     518           0 : void SvParser::Continue( int )
     519             : {
     520           0 : }
     521             : 
     522           0 : void SvParser::BuildWhichTbl( std::vector<sal_uInt16> &rWhichMap,
     523             :                               sal_uInt16 *pWhichIds,
     524             :                               sal_uInt16 nWhichIds )
     525             : {
     526             :     sal_uInt16 aNewRange[2];
     527             : 
     528           0 :     for( sal_uInt16 nCnt = 0; nCnt < nWhichIds; ++nCnt, ++pWhichIds )
     529           0 :         if( *pWhichIds )
     530             :         {
     531           0 :             aNewRange[0] = aNewRange[1] = *pWhichIds;
     532           0 :             sal_Bool bIns = sal_True;
     533             : 
     534             :             // Position suchen
     535           0 :             for ( sal_uInt16 nOfs = 0; rWhichMap[nOfs]; nOfs += 2 )
     536             :             {
     537           0 :                 if( *pWhichIds < rWhichMap[nOfs] - 1 )
     538             :                 {
     539             :                     // neuen Range davor
     540           0 :                     rWhichMap.insert( rWhichMap.begin() + nOfs, aNewRange, aNewRange + 2 );
     541           0 :                     bIns = sal_False;
     542           0 :                     break;
     543             :                 }
     544           0 :                 else if( *pWhichIds == rWhichMap[nOfs] - 1 )
     545             :                 {
     546             :                     // diesen Range nach unten erweitern
     547           0 :                     rWhichMap[nOfs] = *pWhichIds;
     548           0 :                     bIns = sal_False;
     549           0 :                     break;
     550             :                 }
     551           0 :                 else if( *pWhichIds == rWhichMap[nOfs+1] + 1 )
     552             :                 {
     553           0 :                     if( rWhichMap[nOfs+2] != 0 && rWhichMap[nOfs+2] == *pWhichIds + 1 )
     554             :                     {
     555             :                         // mit dem naechsten Bereich mergen
     556           0 :                         rWhichMap[nOfs+1] = rWhichMap[nOfs+3];
     557           0 :                         rWhichMap.erase( rWhichMap.begin() + nOfs + 2,
     558           0 :                                 rWhichMap.begin() + nOfs + 4 );
     559             :                     }
     560             :                     else
     561             :                         // diesen Range nach oben erweitern
     562           0 :                         rWhichMap[nOfs+1] = *pWhichIds;
     563           0 :                     bIns = sal_False;
     564           0 :                     break;
     565             :                 }
     566             :             }
     567             : 
     568             :             // einen Range hinten anhaengen
     569           0 :             if( bIns )
     570             :             {
     571           0 :                 rWhichMap.insert( rWhichMap.begin() + rWhichMap.size() - 1,
     572           0 :                         aNewRange, aNewRange + 2 );
     573             :             }
     574             :         }
     575           0 : }
     576             : 
     577             : 
     578           0 : IMPL_STATIC_LINK( SvParser, NewDataRead, void*, EMPTYARG )
     579             : {
     580           0 :     switch( pThis->eState )
     581             :     {
     582             :     case SVPAR_PENDING:
     583             :         // Wenn gerade ein File geladen wird duerfen wir nicht weiterlaufen,
     584             :         // sondern muessen den Aufruf ignorieren.
     585           0 :         if( pThis->IsDownloadingFile() )
     586           0 :             break;
     587             : 
     588           0 :         pThis->eState = SVPAR_WORKING;
     589           0 :         pThis->RestoreState();
     590             : 
     591           0 :         pThis->Continue( pThis->pImplData->nToken );
     592             : 
     593           0 :         if( ERRCODE_IO_PENDING == pThis->rInput.GetError() )
     594           0 :             pThis->rInput.ResetError();
     595             : 
     596           0 :         if( SVPAR_PENDING != pThis->eState )
     597           0 :             pThis->ReleaseRef();                    // ansonsten sind wir fertig!
     598           0 :         break;
     599             : 
     600             :     case SVPAR_WAITFORDATA:
     601           0 :         pThis->eState = SVPAR_WORKING;
     602           0 :         break;
     603             : 
     604             :     case SVPAR_NOTSTARTED:
     605             :     case SVPAR_WORKING:
     606           0 :         break;
     607             : 
     608             :     default:
     609           0 :         pThis->ReleaseRef();                    // ansonsten sind wir fertig!
     610           0 :         break;
     611             :     }
     612             : 
     613           0 :     return 0;
     614             : }
     615             : 
     616             : /*========================================================================
     617             :  *
     618             :  * SvKeyValueIterator.
     619             :  *
     620             :  *======================================================================*/
     621             : 
     622             : /*
     623             :  * SvKeyValueIterator.
     624             :  */
     625         680 : SvKeyValueIterator::SvKeyValueIterator (void)
     626         680 :     : m_pList (new SvKeyValueList_Impl),
     627        1360 :       m_nPos  (0)
     628             : {
     629         680 : }
     630             : 
     631             : /*
     632             :  * ~SvKeyValueIterator.
     633             :  */
     634         795 : SvKeyValueIterator::~SvKeyValueIterator (void)
     635             : {
     636         318 :     delete m_pList;
     637         477 : }
     638             : 
     639             : /*
     640             :  * GetFirst.
     641             :  */
     642         341 : sal_Bool SvKeyValueIterator::GetFirst (SvKeyValue &rKeyVal)
     643             : {
     644         341 :     m_nPos = m_pList->size();
     645         341 :     return GetNext (rKeyVal);
     646             : }
     647             : 
     648             : /*
     649             :  * GetNext.
     650             :  */
     651         682 : sal_Bool SvKeyValueIterator::GetNext (SvKeyValue &rKeyVal)
     652             : {
     653         682 :     if (m_nPos > 0)
     654             :     {
     655         341 :         rKeyVal = (*m_pList)[--m_nPos];
     656         341 :         return sal_True;
     657             :     }
     658             :     else
     659             :     {
     660             :         // Nothing to do.
     661         341 :         return sal_False;
     662             :     }
     663             : }
     664             : 
     665             : /*
     666             :  * Append.
     667             :  */
     668         340 : void SvKeyValueIterator::Append (const SvKeyValue &rKeyVal)
     669             : {
     670         340 :     m_pList->push_back(new SvKeyValue(rKeyVal));
     671         340 : }
     672             : 
     673             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10