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

Generated by: LCOV version 1.11