LCOV - code coverage report
Current view: top level - svtools/source/svrtf - svparser.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 183 286 64.0 %
Date: 2014-04-11 Functions: 18 25 72.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             : // structure to store the actuel data
      28           7 : struct SvParser_Impl
      29             : {
      30             :     OUString        aToken;             // gescanntes Token
      31             :     sal_uLong       nFilePos;           // actual position in stream
      32             :     sal_uLong       nlLineNr;           // actual line number
      33             :     sal_uLong       nlLinePos;          // actual column number
      34             :     long            nTokenValue;        // extra value (RTF)
      35             :     sal_Bool        bTokenHasValue;     // indicates whether nTokenValue is valid
      36             :     int             nToken;             // actual Token
      37             :     sal_Unicode     nNextCh;            // actual character
      38             :     int             nSaveToken;         // the token from Continue
      39             : 
      40             :     rtl_TextToUnicodeConverter hConv;
      41             :     rtl_TextToUnicodeContext   hContext;
      42             : 
      43           7 :     SvParser_Impl() :
      44           7 :         nTokenValue(0), nToken(0), nSaveToken(0), hConv( 0 ), hContext( (rtl_TextToUnicodeContext)1 )
      45             :     {
      46           7 :     }
      47             : 
      48             : };
      49             : 
      50             : 
      51             : 
      52             : // Construktor
      53           7 : SvParser::SvParser( SvStream& rIn, sal_uInt8 nStackSize )
      54             :     : rInput( rIn )
      55             :     , nlLineNr( 1 )
      56             :     , nlLinePos( 1 )
      57             :     , pImplData( 0 )
      58             :     , nTokenValue( 0 )
      59             :     , bTokenHasValue( false )
      60             :     , eState( SVPAR_NOTSTARTED )
      61             :     , eSrcEnc( RTL_TEXTENCODING_DONTKNOW )
      62             :     , nNextChPos(0)
      63             :     , bDownloadingFile(false)
      64             :     , bUCS2BSrcEnc(false)
      65             :     , bSwitchToUCS2(false)
      66             :     , bRTF_InTextRead(false)
      67             :     , nTokenStackSize( nStackSize )
      68           7 :     , nTokenStackPos( 0 )
      69             : {
      70           7 :     eState = SVPAR_NOTSTARTED;
      71           7 :     if( nTokenStackSize < 3 )
      72           0 :         nTokenStackSize = 3;
      73           7 :     pTokenStack = new TokenStackType[ nTokenStackSize ];
      74           7 :     pTokenStackPos = pTokenStack;
      75           7 : }
      76             : 
      77          14 : SvParser::~SvParser()
      78             : {
      79           7 :     if( pImplData && pImplData->hConv )
      80             :     {
      81             :         rtl_destroyTextToUnicodeContext( pImplData->hConv,
      82           7 :                                          pImplData->hContext );
      83           7 :         rtl_destroyTextToUnicodeConverter( pImplData->hConv );
      84             :     }
      85             : 
      86           7 :     delete pImplData;
      87             : 
      88           7 :     delete [] pTokenStack;
      89           7 : }
      90             : 
      91           2 : void SvParser::ClearTxtConvContext()
      92             : {
      93           2 :     if( pImplData && pImplData->hConv )
      94           2 :         rtl_resetTextToUnicodeContext( pImplData->hConv, pImplData->hContext );
      95           2 : }
      96             : 
      97          11 : void SvParser::SetSrcEncoding( rtl_TextEncoding eEnc )
      98             : {
      99             : 
     100          11 :     if( eEnc != eSrcEnc )
     101             :     {
     102           8 :         if( pImplData && pImplData->hConv )
     103             :         {
     104             :             rtl_destroyTextToUnicodeContext( pImplData->hConv,
     105           1 :                                              pImplData->hContext );
     106           1 :             rtl_destroyTextToUnicodeConverter( pImplData->hConv );
     107           1 :             pImplData->hConv = 0;
     108           1 :             pImplData->hContext = (rtl_TextToUnicodeContext )1;
     109             :         }
     110             : 
     111           8 :         if( rtl_isOctetTextEncoding(eEnc) ||
     112             :             RTL_TEXTENCODING_UCS2 == eEnc  )
     113             :         {
     114           8 :             eSrcEnc = eEnc;
     115           8 :             if( !pImplData )
     116           7 :                 pImplData = new SvParser_Impl;
     117           8 :             pImplData->hConv = rtl_createTextToUnicodeConverter( eSrcEnc );
     118             :             DBG_ASSERT( pImplData->hConv,
     119             :                         "SvParser::SetSrcEncoding: no converter for source encoding" );
     120           8 :             if( !pImplData->hConv )
     121           0 :                 eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
     122             :             else
     123             :                 pImplData->hContext =
     124           8 :                     rtl_createTextToUnicodeContext( pImplData->hConv );
     125             :         }
     126             :         else
     127             :         {
     128             :             DBG_ASSERT( !this,
     129             :                         "SvParser::SetSrcEncoding: invalid source encoding" );
     130           0 :             eSrcEnc = RTL_TEXTENCODING_DONTKNOW;
     131             :         }
     132             :     }
     133          11 : }
     134             : 
     135           0 : void SvParser::RereadLookahead()
     136             : {
     137           0 :     rInput.Seek(nNextChPos);
     138           0 :     nNextCh = GetNextChar();
     139           0 : }
     140             : 
     141       67896 : sal_Unicode SvParser::GetNextChar()
     142             : {
     143       67896 :     sal_Unicode c = 0U;
     144             : 
     145             :     // When reading muliple bytes, we don't have to care about the file
     146             :     // position when we run inti the pending state. The file position is
     147             :     // maintained by SaveState/RestoreState.
     148             :     sal_Bool bErr;
     149       67896 :     if( bSwitchToUCS2 && 0 == rInput.Tell() )
     150             :     {
     151             :         unsigned char c1, c2;
     152           7 :         sal_Bool bSeekBack = sal_True;
     153             : 
     154           7 :         rInput.ReadUChar( c1 );
     155           7 :         bErr = rInput.IsEof() || rInput.GetError();
     156           7 :         if( !bErr )
     157             :         {
     158           7 :             if( 0xff == c1 || 0xfe == c1 )
     159             :             {
     160           0 :                 rInput.ReadUChar( c2 );
     161           0 :                 bErr = rInput.IsEof() || rInput.GetError();
     162           0 :                 if( !bErr )
     163             :                 {
     164           0 :                     if( 0xfe == c1 && 0xff == c2 )
     165             :                     {
     166           0 :                         eSrcEnc = RTL_TEXTENCODING_UCS2;
     167           0 :                         bUCS2BSrcEnc = true;
     168           0 :                         bSeekBack = false;
     169             :                     }
     170           0 :                     else if( 0xff == c1 && 0xfe == c2 )
     171             :                     {
     172           0 :                         eSrcEnc = RTL_TEXTENCODING_UCS2;
     173           0 :                         bUCS2BSrcEnc = false;
     174           0 :                         bSeekBack = false;
     175             :                     }
     176             :                 }
     177             :             }
     178             :         }
     179           7 :         if( bSeekBack )
     180           7 :             rInput.Seek( 0 );
     181             : 
     182           7 :         bSwitchToUCS2 = false;
     183             :     }
     184             : 
     185       67896 :     nNextChPos = rInput.Tell();
     186             : 
     187       67896 :     if( RTL_TEXTENCODING_UCS2 == eSrcEnc )
     188             :     {
     189           0 :         sal_Unicode cUC = USHRT_MAX;
     190             :         unsigned char c1, c2;
     191             : 
     192           0 :         rInput.ReadUChar( c1 ).ReadUChar( c2 );
     193           0 :         if( 2 == rInput.Tell() &&
     194           0 :             !(rInput.IsEof() || rInput.GetError()) &&
     195           0 :             ( (bUCS2BSrcEnc && 0xfe == c1 && 0xff == c2) ||
     196           0 :               (!bUCS2BSrcEnc && 0xff == c1 && 0xfe == c2) ) )
     197           0 :             rInput.ReadUChar( c1 ).ReadUChar( c2 );
     198             : 
     199           0 :         bErr = rInput.IsEof() || rInput.GetError();
     200           0 :         if( !bErr )
     201             :         {
     202           0 :             if( bUCS2BSrcEnc )
     203           0 :                 cUC = (sal_Unicode(c1) << 8) | c2;
     204             :             else
     205           0 :                 cUC = (sal_Unicode(c2) << 8) | c1;
     206             :         }
     207             : 
     208           0 :         if( !bErr )
     209             :         {
     210           0 :             c = cUC;
     211             :         }
     212             :     }
     213             :     else
     214             :     {
     215       67896 :         sal_Size nChars = 0;
     216       67896 :         do
     217             :         {
     218             :             sal_Char c1;    // signed, that's the text converter expects
     219       67896 :             rInput.ReadChar( c1 );
     220       67896 :             bErr = rInput.IsEof() || rInput.GetError();
     221       67896 :             if( !bErr )
     222             :             {
     223       67886 :                 if (
     224      135772 :                      RTL_TEXTENCODING_DONTKNOW == eSrcEnc ||
     225       67886 :                      RTL_TEXTENCODING_SYMBOL == eSrcEnc
     226             :                    )
     227             :                 {
     228             :                     // no convserion shall take place
     229           0 :                     c = (sal_Unicode)c1;
     230           0 :                     nChars = 1;
     231             :                 }
     232             :                 else
     233             :                 {
     234             :                     DBG_ASSERT( pImplData && pImplData->hConv,
     235             :                                 "no text converter!" );
     236             : 
     237             :                     sal_Unicode cUC;
     238       67886 :                     sal_uInt32 nInfo = 0;
     239             :                     sal_Size nCvtBytes;
     240             :                     nChars = rtl_convertTextToUnicode(
     241             :                                 pImplData->hConv, pImplData->hContext,
     242             :                                 &c1, 1, &cUC, 1,
     243             :                                 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
     244             :                                 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
     245             :                                 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
     246       67886 :                                 &nInfo, &nCvtBytes);
     247       67886 :                     if( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 )
     248             :                     {
     249             :                         // The conversion wasn't successful because we haven't
     250             :                         // read enough characters.
     251           2 :                         if( pImplData->hContext != (rtl_TextToUnicodeContext)1 )
     252             :                         {
     253           6 :                             while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 )
     254             :                             {
     255           2 :                                 rInput.ReadChar( c1 );
     256           2 :                                 bErr = rInput.IsEof() || rInput.GetError();
     257           2 :                                 if( bErr )
     258           0 :                                     break;
     259             : 
     260             :                                 nChars = rtl_convertTextToUnicode(
     261             :                                             pImplData->hConv, pImplData->hContext,
     262             :                                             &c1, 1, &cUC, 1,
     263             :                                             RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
     264             :                                             RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
     265             :                                             RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
     266           2 :                                             &nInfo, &nCvtBytes);
     267             :                             }
     268           2 :                             if( !bErr )
     269             :                             {
     270           2 :                                 if( 1 == nChars && 0 == nInfo )
     271             :                                 {
     272           0 :                                     c = cUC;
     273             :                                 }
     274           2 :                                 else if( 0 != nChars || 0 != nInfo )
     275             :                                 {
     276             :                                     DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) == 0,
     277             :                                         "source buffer is to small" );
     278             :                                     DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL)) == 0,
     279             :                                          "there is a conversion error" );
     280             :                                     DBG_ASSERT( 0 == nChars,
     281             :                                        "there is a converted character, but an error" );
     282             :                                     // There are still errors, but nothing we can
     283             :                                     // do
     284           2 :                                     c = (sal_Unicode)'?';
     285           2 :                                     nChars = 1;
     286             :                                 }
     287             :                             }
     288             :                         }
     289             :                         else
     290             :                         {
     291             :                             sal_Char sBuffer[10];
     292           0 :                             sBuffer[0] = c1;
     293           0 :                             sal_uInt16 nLen = 1;
     294           0 :                             while( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) != 0 &&
     295             :                                     nLen < 10 )
     296             :                             {
     297           0 :                                 rInput.ReadChar( c1 );
     298           0 :                                 bErr = rInput.IsEof() || rInput.GetError();
     299           0 :                                 if( bErr )
     300           0 :                                     break;
     301             : 
     302           0 :                                 sBuffer[nLen++] = c1;
     303             :                                 nChars = rtl_convertTextToUnicode(
     304             :                                             pImplData->hConv, 0, sBuffer, nLen, &cUC, 1,
     305             :                                             RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|
     306             :                                             RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|
     307             :                                             RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR,
     308           0 :                                             &nInfo, &nCvtBytes);
     309             :                             }
     310           0 :                             if( !bErr )
     311             :                             {
     312           0 :                                 if( 1 == nChars && 0 == nInfo )
     313             :                                 {
     314             :                                     DBG_ASSERT( nCvtBytes == nLen,
     315             :                                                 "no all bytes have been converted!" );
     316           0 :                                     c = cUC;
     317             :                                 }
     318             :                                 else
     319             :                                 {
     320             :                                     DBG_ASSERT( (nInfo&RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL) == 0,
     321             :                                         "source buffer is to small" );
     322             :                                     DBG_ASSERT( (nInfo&~(RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL)) == 0,
     323             :                                          "there is a conversion error" );
     324             :                                     DBG_ASSERT( 0 == nChars,
     325             :                                        "there is a converted character, but an error" );
     326             : 
     327             :                                     // There are still errors, so we use the first
     328             :                                     // character and restart after that.
     329           0 :                                     c = (sal_Unicode)sBuffer[0];
     330           0 :                                     rInput.SeekRel( -(nLen-1) );
     331           0 :                                     nChars = 1;
     332             :                                 }
     333             :                             }
     334             :                         }
     335             :                     }
     336       67884 :                     else if( 1 == nChars && 0 == nInfo )
     337             :                     {
     338             :                         // The conversion was successful
     339             :                         DBG_ASSERT( nCvtBytes == 1,
     340             :                                     "no all bytes have been converted!" );
     341       67857 :                         c = cUC;
     342             :                     }
     343          27 :                     else if( 0 != nChars || 0 != nInfo )
     344             :                     {
     345             :                         DBG_ASSERT( 0 == nChars,
     346             :                                 "there is a converted character, but an error" );
     347             :                         DBG_ASSERT( 0 != nInfo,
     348             :                                 "there is no converted character and no error" );
     349             :                         // #73398#: If the character could not be converted,
     350             :                         // because a conversion is not available, do no conversion at all.
     351          27 :                         c = (sal_Unicode)c1;
     352          27 :                         nChars = 1;
     353             : 
     354             :                     }
     355             :                 }
     356             :             }
     357             :         }
     358          10 :         while( 0 == nChars  && !bErr );
     359             :     }
     360       67896 :     if( bErr )
     361             :     {
     362          10 :         if( ERRCODE_IO_PENDING == rInput.GetError() )
     363             :         {
     364           0 :             eState = SVPAR_PENDING;
     365           0 :             return c;
     366             :         }
     367             :         else
     368          10 :             return sal_Unicode(EOF);
     369             :     }
     370             : 
     371       67886 :     if( c == '\n' )
     372             :     {
     373        1526 :         IncLineNr();
     374        1526 :         SetLinePos( 1L );
     375             :     }
     376             :     else
     377       66360 :         IncLinePos();
     378       67886 :     return c;
     379             : }
     380             : 
     381        2888 : int SvParser::GetNextToken()
     382             : {
     383        2888 :     int nRet = 0;
     384             : 
     385        2888 :     if( !nTokenStackPos )
     386             :     {
     387        2884 :         aToken = "";     // empty token buffer
     388        2884 :         nTokenValue = -1;   // marker for no value read
     389        2884 :         bTokenHasValue = false;
     390             : 
     391        2884 :         nRet = _GetNextToken();
     392        2884 :         if( SVPAR_PENDING == eState )
     393           0 :             return nRet;
     394             :     }
     395             : 
     396        2888 :     ++pTokenStackPos;
     397        2888 :     if( pTokenStackPos == pTokenStack + nTokenStackSize )
     398         959 :         pTokenStackPos = pTokenStack;
     399             : 
     400             :     // pop from stack ??
     401        2888 :     if( nTokenStackPos )
     402             :     {
     403           4 :         --nTokenStackPos;
     404           4 :         nTokenValue = pTokenStackPos->nTokenValue;
     405           4 :         bTokenHasValue = pTokenStackPos->bTokenHasValue;
     406           4 :         aToken = pTokenStackPos->sToken;
     407           4 :         nRet = pTokenStackPos->nTokenId;
     408             :     }
     409             :     // no, now push actual value on stack
     410        2884 :     else if( SVPAR_WORKING == eState )
     411             :     {
     412        2877 :         pTokenStackPos->sToken = aToken;
     413        2877 :         pTokenStackPos->nTokenValue = nTokenValue;
     414        2877 :         pTokenStackPos->bTokenHasValue = bTokenHasValue;
     415        2877 :         pTokenStackPos->nTokenId = nRet;
     416             :     }
     417           7 :     else if( SVPAR_ACCEPTED != eState && SVPAR_PENDING != eState )
     418           0 :         eState = SVPAR_ERROR;       // an error occured
     419             : 
     420        2888 :     return nRet;
     421             : }
     422             : 
     423           4 : int SvParser::SkipToken( short nCnt )       // "skip" n Tokens backward
     424             : {
     425           4 :     pTokenStackPos = GetStackPtr( nCnt );
     426           4 :     short nTmp = nTokenStackPos - nCnt;
     427           4 :     if( nTmp < 0 )
     428           0 :         nTmp = 0;
     429           4 :     else if( nTmp > nTokenStackSize )
     430           0 :         nTmp = nTokenStackSize;
     431           4 :     nTokenStackPos = sal_uInt8(nTmp);
     432             : 
     433             :     // restore values
     434           4 :     aToken = pTokenStackPos->sToken;
     435           4 :     nTokenValue = pTokenStackPos->nTokenValue;
     436           4 :     bTokenHasValue = pTokenStackPos->bTokenHasValue;
     437             : 
     438           4 :     return pTokenStackPos->nTokenId;
     439             : }
     440             : 
     441           4 : SvParser::TokenStackType* SvParser::GetStackPtr( short nCnt )
     442             : {
     443           4 :     sal_uInt8 nAktPos = sal_uInt8(pTokenStackPos - pTokenStack );
     444           4 :     if( nCnt > 0 )
     445             :     {
     446           0 :         if( nCnt >= nTokenStackSize )
     447           0 :             nCnt = (nTokenStackSize-1);
     448           0 :         if( nAktPos + nCnt < nTokenStackSize )
     449           0 :             nAktPos = sal::static_int_cast< sal_uInt8 >(nAktPos + nCnt);
     450             :         else
     451             :             nAktPos = sal::static_int_cast< sal_uInt8 >(
     452           0 :                 nAktPos + (nCnt - nTokenStackSize));
     453             :     }
     454           4 :     else if( nCnt < 0 )
     455             :     {
     456           4 :         if( -nCnt >= nTokenStackSize )
     457           0 :             nCnt = -nTokenStackSize+1;
     458           4 :         if( -nCnt <= nAktPos )
     459           4 :             nAktPos = sal::static_int_cast< sal_uInt8 >(nAktPos + nCnt);
     460             :         else
     461             :             nAktPos = sal::static_int_cast< sal_uInt8 >(
     462           0 :                 nAktPos + (nCnt + nTokenStackSize));
     463             :     }
     464           4 :     return pTokenStack + nAktPos;
     465             : }
     466             : 
     467             : // is called for each token which is recognised by CallParser
     468           0 : void SvParser::NextToken( int )
     469             : {
     470           0 : }
     471             : 
     472             : 
     473             : // to read asynchronous from SvStream
     474             : 
     475           0 : int SvParser::GetSaveToken() const
     476             : {
     477           0 :     return pImplData ? pImplData->nSaveToken : 0;
     478             : }
     479             : 
     480        6108 : void SvParser::SaveState( int nToken )
     481             : {
     482             :     // save actual status
     483        6108 :     if( !pImplData )
     484             :     {
     485           0 :         pImplData = new SvParser_Impl;
     486           0 :         pImplData->nSaveToken = 0;
     487             :     }
     488             : 
     489        6108 :     pImplData->nFilePos = rInput.Tell();
     490        6108 :     pImplData->nToken = nToken;
     491             : 
     492        6108 :     pImplData->aToken = aToken;
     493        6108 :     pImplData->nlLineNr = nlLineNr;
     494        6108 :     pImplData->nlLinePos = nlLinePos;
     495        6108 :     pImplData->nTokenValue= nTokenValue;
     496        6108 :     pImplData->bTokenHasValue = bTokenHasValue;
     497        6108 :     pImplData->nNextCh = nNextCh;
     498        6108 : }
     499             : 
     500           0 : void SvParser::RestoreState()
     501             : {
     502             :     // restore old status
     503           0 :     if( pImplData )
     504             :     {
     505           0 :         if( ERRCODE_IO_PENDING == rInput.GetError() )
     506           0 :             rInput.ResetError();
     507           0 :         aToken = pImplData->aToken;
     508           0 :         nlLineNr = pImplData->nlLineNr;
     509           0 :         nlLinePos = pImplData->nlLinePos;
     510           0 :         nTokenValue= pImplData->nTokenValue;
     511           0 :         bTokenHasValue=pImplData->bTokenHasValue;
     512           0 :         nNextCh = pImplData->nNextCh;
     513             : 
     514           0 :         pImplData->nSaveToken = pImplData->nToken;
     515             : 
     516           0 :         rInput.Seek( pImplData->nFilePos );
     517             :     }
     518           0 : }
     519             : 
     520           0 : void SvParser::Continue( int )
     521             : {
     522           0 : }
     523             : 
     524          12 : void SvParser::BuildWhichTbl( std::vector<sal_uInt16> &rWhichMap,
     525             :                               sal_uInt16 *pWhichIds,
     526             :                               sal_uInt16 nWhichIds )
     527             : {
     528             :     sal_uInt16 aNewRange[2];
     529             : 
     530         222 :     for( sal_uInt16 nCnt = 0; nCnt < nWhichIds; ++nCnt, ++pWhichIds )
     531         210 :         if( *pWhichIds )
     532             :         {
     533         210 :             aNewRange[0] = aNewRange[1] = *pWhichIds;
     534         210 :             sal_Bool bIns = sal_True;
     535             : 
     536             :             // search position
     537        1464 :             for ( sal_uInt16 nOfs = 0; rWhichMap[nOfs]; nOfs += 2 )
     538             :             {
     539        1404 :                 if( *pWhichIds < rWhichMap[nOfs] - 1 )
     540             :                 {
     541             :                     // new range before
     542          54 :                     rWhichMap.insert( rWhichMap.begin() + nOfs, aNewRange, aNewRange + 2 );
     543          54 :                     bIns = sal_False;
     544          54 :                     break;
     545             :                 }
     546        1350 :                 else if( *pWhichIds == rWhichMap[nOfs] - 1 )
     547             :                 {
     548             :                     // extend range downwards
     549          18 :                     rWhichMap[nOfs] = *pWhichIds;
     550          18 :                     bIns = sal_False;
     551          18 :                     break;
     552             :                 }
     553        1332 :                 else if( *pWhichIds == rWhichMap[nOfs+1] + 1 )
     554             :                 {
     555          78 :                     if( rWhichMap[nOfs+2] != 0 && rWhichMap[nOfs+2] == *pWhichIds + 1 )
     556             :                     {
     557             :                         // merge with next field
     558          36 :                         rWhichMap[nOfs+1] = rWhichMap[nOfs+3];
     559          72 :                         rWhichMap.erase( rWhichMap.begin() + nOfs + 2,
     560         108 :                                 rWhichMap.begin() + nOfs + 4 );
     561             :                     }
     562             :                     else
     563             :                         // extend range upwards
     564          42 :                         rWhichMap[nOfs+1] = *pWhichIds;
     565          78 :                     bIns = sal_False;
     566          78 :                     break;
     567             :                 }
     568             :             }
     569             : 
     570             :             // append range
     571         210 :             if( bIns )
     572             :             {
     573         120 :                 rWhichMap.insert( rWhichMap.begin() + rWhichMap.size() - 1,
     574         180 :                         aNewRange, aNewRange + 2 );
     575             :             }
     576             :         }
     577          12 : }
     578             : 
     579             : 
     580           0 : IMPL_STATIC_LINK( SvParser, NewDataRead, void*, EMPTYARG )
     581             : {
     582           0 :     switch( pThis->eState )
     583             :     {
     584             :     case SVPAR_PENDING:
     585             :         // if file is loaded we are not allowed to continue
     586             :         // instead should ignore the call.
     587           0 :         if( pThis->IsDownloadingFile() )
     588           0 :             break;
     589             : 
     590           0 :         pThis->eState = SVPAR_WORKING;
     591           0 :         pThis->RestoreState();
     592             : 
     593           0 :         pThis->Continue( pThis->pImplData->nToken );
     594             : 
     595           0 :         if( ERRCODE_IO_PENDING == pThis->rInput.GetError() )
     596           0 :             pThis->rInput.ResetError();
     597             : 
     598           0 :         if( SVPAR_PENDING != pThis->eState )
     599           0 :             pThis->ReleaseRef();                    // ready otherwise!
     600           0 :         break;
     601             : 
     602             :     case SVPAR_WAITFORDATA:
     603           0 :         pThis->eState = SVPAR_WORKING;
     604           0 :         break;
     605             : 
     606             :     case SVPAR_NOTSTARTED:
     607             :     case SVPAR_WORKING:
     608           0 :         break;
     609             : 
     610             :     default:
     611           0 :         pThis->ReleaseRef();                    // ready otherwise!
     612           0 :         break;
     613             :     }
     614             : 
     615           0 :     return 0;
     616             : }
     617             : 
     618             : /*========================================================================
     619             :  *
     620             :  * SvKeyValueIterator.
     621             :  *
     622             :  *======================================================================*/
     623             : 
     624             : /*
     625             :  * SvKeyValueIterator.
     626             :  */
     627        3302 : SvKeyValueIterator::SvKeyValueIterator (void)
     628        3302 :     : m_pList (new SvKeyValueList_Impl),
     629        6604 :       m_nPos  (0)
     630             : {
     631        3302 : }
     632             : 
     633             : /*
     634             :  * ~SvKeyValueIterator.
     635             :  */
     636        8195 : SvKeyValueIterator::~SvKeyValueIterator (void)
     637             : {
     638        3278 :     delete m_pList;
     639        4917 : }
     640             : 
     641             : /*
     642             :  * GetFirst.
     643             :  */
     644        1663 : bool SvKeyValueIterator::GetFirst (SvKeyValue &rKeyVal)
     645             : {
     646        1663 :     m_nPos = m_pList->size();
     647        1663 :     return GetNext (rKeyVal);
     648             : }
     649             : 
     650             : /*
     651             :  * GetNext.
     652             :  */
     653        3320 : bool SvKeyValueIterator::GetNext (SvKeyValue &rKeyVal)
     654             : {
     655        3320 :     if (m_nPos > 0)
     656             :     {
     657        1657 :         rKeyVal = (*m_pList)[--m_nPos];
     658        1657 :         return true;
     659             :     }
     660             :     else
     661             :     {
     662             :         // Nothing to do.
     663        1663 :         return false;
     664             :     }
     665             : }
     666             : 
     667             : /*
     668             :  * Append.
     669             :  */
     670        1642 : void SvKeyValueIterator::Append (const SvKeyValue &rKeyVal)
     671             : {
     672        1642 :     m_pList->push_back(new SvKeyValue(rKeyVal));
     673        1642 : }
     674             : 
     675             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10