LCOV - code coverage report
Current view: top level - svtools/source/svrtf - svparser.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 185 297 62.3 %
Date: 2014-11-03 Functions: 18 26 69.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10