LCOV - code coverage report
Current view: top level - svtools/source/svhtml - parhtml.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 333 1000 33.3 %
Date: 2012-08-25 Functions: 16 32 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 388 1706 22.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <ctype.h>
      31                 :            : #include <stdio.h>
      32                 :            : #include <comphelper/string.hxx>
      33                 :            : #include <tools/stream.hxx>
      34                 :            : #include <tools/debug.hxx>
      35                 :            : #include <tools/color.hxx>
      36                 :            : #include <rtl/ustrbuf.hxx>
      37                 :            : #include <rtl/strbuf.hxx>
      38                 :            : 
      39                 :            : #include <tools/tenccvt.hxx>
      40                 :            : #include <tools/datetime.hxx>
      41                 :            : #include <svl/inettype.hxx>
      42                 :            : #include <com/sun/star/beans/PropertyAttribute.hpp>
      43                 :            : #include <com/sun/star/document/XDocumentProperties.hpp>
      44                 :            : 
      45                 :            : #include <svtools/parhtml.hxx>
      46                 :            : #include <svtools/htmltokn.h>
      47                 :            : #include <svtools/htmlkywd.hxx>
      48                 :            : 
      49                 :            : #include <memory>
      50                 :            : 
      51                 :            : using namespace ::com::sun::star;
      52                 :            : 
      53                 :            : 
      54                 :            : const sal_Int32 MAX_LEN( 1024L );
      55                 :            : 
      56                 :            : const sal_Int32 MAX_ENTITY_LEN( 8L );
      57                 :            : 
      58                 :            : 
      59                 :            : // Tables to convert option values into strings
      60                 :            : 
      61                 :            : // <INPUT TYPE=xxx>
      62                 :            : static HTMLOptionEnum const aInputTypeOptEnums[] =
      63                 :            : {
      64                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_text,      HTML_IT_TEXT        },
      65                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_password,  HTML_IT_PASSWORD    },
      66                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_checkbox,  HTML_IT_CHECKBOX    },
      67                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_radio,     HTML_IT_RADIO       },
      68                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_range,     HTML_IT_RANGE       },
      69                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_scribble,  HTML_IT_SCRIBBLE    },
      70                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_file,      HTML_IT_FILE        },
      71                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_hidden,    HTML_IT_HIDDEN      },
      72                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_submit,    HTML_IT_SUBMIT      },
      73                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_image,     HTML_IT_IMAGE       },
      74                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_reset,     HTML_IT_RESET       },
      75                 :            :     { OOO_STRING_SVTOOLS_HTML_IT_button,    HTML_IT_BUTTON      },
      76                 :            :     { 0,                    0                   }
      77                 :            : };
      78                 :            : 
      79                 :            : // <TABLE FRAME=xxx>
      80                 :            : static HTMLOptionEnum const aTableFrameOptEnums[] =
      81                 :            : {
      82                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_void,  HTML_TF_VOID    },
      83                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_above, HTML_TF_ABOVE   },
      84                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_below, HTML_TF_BELOW   },
      85                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_hsides,    HTML_TF_HSIDES  },
      86                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_lhs,       HTML_TF_LHS     },
      87                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_rhs,       HTML_TF_RHS     },
      88                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_vsides,    HTML_TF_VSIDES  },
      89                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_box,       HTML_TF_BOX     },
      90                 :            :     { OOO_STRING_SVTOOLS_HTML_TF_border,    HTML_TF_BOX     },
      91                 :            :     { 0,                0               }
      92                 :            : };
      93                 :            : 
      94                 :            : // <TABLE RULES=xxx>
      95                 :            : static HTMLOptionEnum const aTableRulesOptEnums[] =
      96                 :            : {
      97                 :            :     { OOO_STRING_SVTOOLS_HTML_TR_none,  HTML_TR_NONE    },
      98                 :            :     { OOO_STRING_SVTOOLS_HTML_TR_groups,    HTML_TR_GROUPS  },
      99                 :            :     { OOO_STRING_SVTOOLS_HTML_TR_rows,  HTML_TR_ROWS    },
     100                 :            :     { OOO_STRING_SVTOOLS_HTML_TR_cols,  HTML_TR_COLS    },
     101                 :            :     { OOO_STRING_SVTOOLS_HTML_TR_all,       HTML_TR_ALL     },
     102                 :            :     { 0,                0               }
     103                 :            : };
     104                 :            : 
     105                 :          0 : sal_uInt16 HTMLOption::GetEnum( const HTMLOptionEnum *pOptEnums, sal_uInt16 nDflt ) const
     106                 :            : {
     107                 :          0 :     sal_uInt16 nValue = nDflt;
     108                 :            : 
     109         [ #  # ]:          0 :     while( pOptEnums->pName )
     110         [ #  # ]:          0 :         if( aValue.EqualsIgnoreCaseAscii( pOptEnums->pName ) )
     111                 :          0 :             break;
     112                 :            :         else
     113                 :          0 :             pOptEnums++;
     114                 :            : 
     115         [ #  # ]:          0 :     if( pOptEnums->pName )
     116                 :          0 :         nValue = pOptEnums->nValue;
     117                 :            : 
     118                 :          0 :     return nValue;
     119                 :            : }
     120                 :            : 
     121                 :          8 : bool HTMLOption::GetEnum( sal_uInt16 &rEnum, const HTMLOptionEnum *pOptEnums ) const
     122                 :            : {
     123         [ +  - ]:         44 :     while( pOptEnums->pName )
     124                 :            :     {
     125         [ +  + ]:         44 :         if( aValue.EqualsIgnoreCaseAscii( pOptEnums->pName ) )
     126                 :          8 :             break;
     127                 :            :         else
     128                 :         36 :             pOptEnums++;
     129                 :            :     }
     130                 :            : 
     131                 :          8 :     const sal_Char *pName = pOptEnums->pName;
     132         [ +  - ]:          8 :     if( pName )
     133                 :          8 :         rEnum = pOptEnums->nValue;
     134                 :            : 
     135                 :          8 :     return (pName != 0);
     136                 :            : }
     137                 :            : 
     138                 :         20 : HTMLOption::HTMLOption( sal_uInt16 nTok, const String& rToken,
     139                 :            :                         const String& rValue )
     140                 :            :     : aValue(rValue)
     141                 :            :     , aToken(rToken)
     142         [ +  - ]:         20 :     , nToken( nTok )
     143                 :            : {
     144                 :            :     DBG_ASSERT( nToken>=HTML_OPTION_START && nToken<HTML_OPTION_END,
     145                 :            :         "HTMLOption: unknown token" );
     146                 :         20 : }
     147                 :            : 
     148                 :          0 : sal_uInt32 HTMLOption::GetNumber() const
     149                 :            : {
     150                 :            :     DBG_ASSERT( (nToken>=HTML_OPTION_NUMBER_START &&
     151                 :            :                  nToken<HTML_OPTION_NUMBER_END) ||
     152                 :            :                 (nToken>=HTML_OPTION_CONTEXT_START &&
     153                 :            :                  nToken<HTML_OPTION_CONTEXT_END) ||
     154                 :            :                 nToken==HTML_O_VALUE,
     155                 :            :         "GetNumber: Option not numerical" );
     156 [ #  # ][ #  # ]:          0 :     String aTmp(comphelper::string::stripStart(aValue, ' '));
                 [ #  # ]
     157         [ #  # ]:          0 :     sal_Int32 nTmp = aTmp.ToInt32();
     158         [ #  # ]:          0 :     return nTmp >= 0 ? (sal_uInt32)nTmp : 0;
     159                 :            : }
     160                 :            : 
     161                 :          0 : sal_Int32 HTMLOption::GetSNumber() const
     162                 :            : {
     163                 :            :     DBG_ASSERT( (nToken>=HTML_OPTION_NUMBER_START && nToken<HTML_OPTION_NUMBER_END) ||
     164                 :            :                 (nToken>=HTML_OPTION_CONTEXT_START && nToken<HTML_OPTION_CONTEXT_END),
     165                 :            :         "GetSNumber: Option not numerical" );
     166 [ #  # ][ #  # ]:          0 :     String aTmp(comphelper::string::stripStart(aValue, ' '));
                 [ #  # ]
     167 [ #  # ][ #  # ]:          0 :     return aTmp.ToInt32();
     168                 :            : }
     169                 :            : 
     170                 :          0 : void HTMLOption::GetNumbers( std::vector<sal_uInt32> &rNumbers, bool bSpaceDelim ) const
     171                 :            : {
     172                 :          0 :     rNumbers.clear();
     173                 :            : 
     174         [ #  # ]:          0 :     if( bSpaceDelim )
     175                 :            :     {
     176                 :            :         // This is a very simplified scanner: it only searches all
     177                 :            :         // numerals in the string.
     178                 :          0 :         bool bInNum = false;
     179                 :          0 :         sal_uLong nNum = 0;
     180         [ #  # ]:          0 :         for( xub_StrLen i=0; i<aValue.Len(); i++ )
     181                 :            :         {
     182                 :          0 :             register sal_Unicode c = aValue.GetChar( i );
     183 [ #  # ][ #  # ]:          0 :             if( c>='0' && c<='9' )
     184                 :            :             {
     185                 :          0 :                 nNum *= 10;
     186                 :          0 :                 nNum += (c - '0');
     187                 :          0 :                 bInNum = true;
     188                 :            :             }
     189         [ #  # ]:          0 :             else if( bInNum )
     190                 :            :             {
     191         [ #  # ]:          0 :                 rNumbers.push_back( nNum );
     192                 :          0 :                 bInNum = false;
     193                 :          0 :                 nNum = 0;
     194                 :            :             }
     195                 :            :         }
     196         [ #  # ]:          0 :         if( bInNum )
     197                 :            :         {
     198         [ #  # ]:          0 :             rNumbers.push_back( nNum );
     199                 :            :         }
     200                 :            :     }
     201                 :            :     else
     202                 :            :     {
     203                 :            :         // Check whether numbers are separated by ',' and
     204                 :            :         // insert 0 if necessary
     205                 :          0 :         xub_StrLen nPos = 0;
     206         [ #  # ]:          0 :         while( nPos < aValue.Len() )
     207                 :            :         {
     208                 :            :             register sal_Unicode c;
     209 [ #  # ][ #  # ]:          0 :             while( nPos < aValue.Len() &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     210                 :          0 :                    ((c=aValue.GetChar(nPos)) == ' ' || c == '\t' ||
     211                 :            :                    c == '\n' || c== '\r' ) )
     212                 :          0 :                 nPos++;
     213                 :            : 
     214         [ #  # ]:          0 :             if( nPos==aValue.Len() )
     215         [ #  # ]:          0 :                 rNumbers.push_back(0);
     216                 :            :             else
     217                 :            :             {
     218                 :          0 :                 xub_StrLen nEnd = aValue.Search( (sal_Unicode)',', nPos );
     219         [ #  # ]:          0 :                 if( STRING_NOTFOUND==nEnd )
     220                 :            :                 {
     221         [ #  # ]:          0 :                     sal_Int32 nTmp = aValue.Copy(nPos).ToInt32();
     222         [ #  # ]:          0 :                     rNumbers.push_back( nTmp >= 0 ? (sal_uInt32)nTmp : 0 );
     223                 :          0 :                     nPos = aValue.Len();
     224                 :            :                 }
     225                 :            :                 else
     226                 :            :                 {
     227                 :            :                     sal_Int32 nTmp =
     228         [ #  # ]:          0 :                         aValue.Copy(nPos,nEnd-nPos).ToInt32();
     229         [ #  # ]:          0 :                     rNumbers.push_back( nTmp >= 0 ? (sal_uInt32)nTmp : 0 );
     230                 :          0 :                     nPos = nEnd+1;
     231                 :            :                 }
     232                 :            :             }
     233                 :            :         }
     234                 :            :     }
     235                 :          0 : }
     236                 :            : 
     237                 :          0 : void HTMLOption::GetColor( Color& rColor ) const
     238                 :            : {
     239                 :            :     DBG_ASSERT( (nToken>=HTML_OPTION_COLOR_START && nToken<HTML_OPTION_COLOR_END) || nToken==HTML_O_SIZE,
     240                 :            :         "GetColor: Option is not a color." );
     241                 :            : 
     242         [ #  # ]:          0 :     String aTmp( aValue );
     243         [ #  # ]:          0 :     aTmp.ToUpperAscii();
     244                 :          0 :     sal_uInt32 nColor = SAL_MAX_UINT32;
     245         [ #  # ]:          0 :     if( '#'!=aTmp.GetChar( 0 ) )
     246         [ #  # ]:          0 :         nColor = GetHTMLColor( aTmp );
     247                 :            : 
     248         [ #  # ]:          0 :     if( SAL_MAX_UINT32 == nColor )
     249                 :            :     {
     250                 :          0 :         nColor = 0;
     251                 :          0 :         xub_StrLen nPos = 0;
     252         [ #  # ]:          0 :         for( sal_uInt32 i=0; i<6; i++ )
     253                 :            :         {
     254                 :            :             // Whatever Netscape does to get color values,
     255                 :            :             // at maximum three characters < '0' are ignored.
     256                 :          0 :             register sal_Unicode c = nPos<aTmp.Len() ? aTmp.GetChar( nPos++ )
     257         [ #  # ]:          0 :                                                      : '0';
     258         [ #  # ]:          0 :             if( c < '0' )
     259                 :            :             {
     260         [ #  # ]:          0 :                 c = nPos<aTmp.Len() ? aTmp.GetChar(nPos++) : '0';
     261         [ #  # ]:          0 :                 if( c < '0' )
     262         [ #  # ]:          0 :                     c = nPos<aTmp.Len() ? aTmp.GetChar(nPos++) : '0';
     263                 :            :             }
     264                 :          0 :             nColor *= 16;
     265 [ #  # ][ #  # ]:          0 :             if( c >= '0' && c <= '9' )
     266                 :          0 :                 nColor += (c - 48);
     267 [ #  # ][ #  # ]:          0 :             else if( c >= 'A' && c <= 'F' )
     268                 :          0 :                 nColor += (c - 55);
     269                 :            :         }
     270                 :            :     }
     271                 :            : 
     272         [ #  # ]:          0 :     rColor.SetRed(   (sal_uInt8)((nColor & 0x00ff0000) >> 16) );
     273         [ #  # ]:          0 :     rColor.SetGreen( (sal_uInt8)((nColor & 0x0000ff00) >> 8));
     274 [ #  # ][ #  # ]:          0 :     rColor.SetBlue(  (sal_uInt8)(nColor & 0x000000ff) );
     275                 :          0 : }
     276                 :            : 
     277                 :          0 : HTMLInputType HTMLOption::GetInputType() const
     278                 :            : {
     279                 :            :     DBG_ASSERT( nToken==HTML_O_TYPE, "GetInputType: Option not TYPE" );
     280                 :          0 :     return (HTMLInputType)GetEnum( aInputTypeOptEnums, HTML_IT_TEXT );
     281                 :            : }
     282                 :            : 
     283                 :          0 : HTMLTableFrame HTMLOption::GetTableFrame() const
     284                 :            : {
     285                 :            :     DBG_ASSERT( nToken==HTML_O_FRAME, "GetTableFrame: Option not FRAME" );
     286                 :          0 :     return (HTMLTableFrame)GetEnum( aTableFrameOptEnums, HTML_TF_VOID );
     287                 :            : }
     288                 :            : 
     289                 :          0 : HTMLTableRules HTMLOption::GetTableRules() const
     290                 :            : {
     291                 :            :     DBG_ASSERT( nToken==HTML_O_RULES, "GetTableRules: Option not RULES" );
     292                 :          0 :     return (HTMLTableRules)GetEnum( aTableRulesOptEnums, HTML_TR_NONE );
     293                 :            : }
     294                 :            : 
     295                 :          5 : HTMLParser::HTMLParser( SvStream& rIn, bool bReadNewDoc ) :
     296                 :            :     SvParser( rIn ),
     297                 :            :     bNewDoc(bReadNewDoc),
     298                 :            :     bIsInHeader(true),
     299                 :            :     bIsInBody(false),
     300                 :            :     bReadListing(false),
     301                 :            :     bReadXMP(false),
     302                 :            :     bReadPRE(false),
     303                 :            :     bReadTextArea(false),
     304                 :            :     bReadScript(false),
     305                 :            :     bReadStyle(false),
     306                 :            :     bEndTokenFound(false),
     307                 :            :     bPre_IgnoreNewPara(false),
     308                 :            :     bReadNextChar(false),
     309 [ +  - ][ +  - ]:          5 :     bReadComment(false)
                 [ +  - ]
     310                 :            : {
     311                 :            :     //#i76649, default to UTF-8 for HTML unless we know differently
     312         [ +  - ]:          5 :     SetSrcEncoding(RTL_TEXTENCODING_UTF8);
     313                 :          5 : }
     314                 :            : 
     315 [ +  - ][ +  - ]:          5 : HTMLParser::~HTMLParser()
                 [ +  - ]
     316                 :            : {
     317         [ -  + ]:          5 : }
     318                 :            : 
     319                 :          5 : SvParserState HTMLParser::CallParser()
     320                 :            : {
     321                 :          5 :     eState = SVPAR_WORKING;
     322                 :          5 :     nNextCh = GetNextChar();
     323                 :          5 :     SaveState( 0 );
     324                 :            : 
     325                 :          5 :     nPre_LinePos = 0;
     326                 :          5 :     bPre_IgnoreNewPara = false;
     327                 :            : 
     328                 :          5 :     AddRef();
     329                 :          5 :     Continue( 0 );
     330         [ +  - ]:          5 :     if( SVPAR_PENDING != eState )
     331                 :          5 :         ReleaseRef();       // Parser not needed anymore
     332                 :            : 
     333                 :          5 :     return eState;
     334                 :            : }
     335                 :            : 
     336                 :          5 : void HTMLParser::Continue( int nToken )
     337                 :            : {
     338         [ +  - ]:          5 :     if( !nToken )
     339                 :          5 :         nToken = GetNextToken();
     340                 :            : 
     341         [ +  + ]:        170 :     while( IsParserWorking() )
     342                 :            :     {
     343                 :        165 :         SaveState( nToken );
     344                 :        165 :         nToken = FilterToken( nToken );
     345                 :            : 
     346         [ +  + ]:        165 :         if( nToken )
     347                 :        160 :             NextToken( nToken );
     348                 :            : 
     349         [ +  - ]:        165 :         if( IsParserWorking() )
     350                 :        165 :             SaveState( 0 );         // continue with new token
     351                 :            : 
     352                 :        165 :         nToken = GetNextToken();
     353                 :            :     }
     354                 :          5 : }
     355                 :            : 
     356                 :        165 : int HTMLParser::FilterToken( int nToken )
     357                 :            : {
     358   [ -  +  +  +  :        165 :     switch( nToken )
          +  +  -  -  -  
             -  -  -  + ]
     359                 :            :     {
     360                 :            :     case sal_Unicode(EOF):
     361                 :          0 :         nToken = 0;
     362                 :          0 :         break;          // don't pass
     363                 :            : 
     364                 :            :     case HTML_HEAD_OFF:
     365                 :          2 :         bIsInBody = true;
     366                 :            :     case HTML_HEAD_ON:
     367                 :          4 :         bIsInHeader = HTML_HEAD_ON == nToken;
     368                 :          4 :         break;
     369                 :            : 
     370                 :            :     case HTML_BODY_ON:
     371                 :            :     case HTML_FRAMESET_ON:
     372                 :          5 :         bIsInHeader = false;
     373                 :          5 :         bIsInBody = HTML_BODY_ON == nToken;
     374                 :          5 :         break;
     375                 :            : 
     376                 :            :     case HTML_BODY_OFF:
     377                 :          5 :         bIsInBody = bReadPRE = bReadListing = bReadXMP = false;
     378                 :          5 :         break;
     379                 :            : 
     380                 :            :     case HTML_HTML_OFF:
     381                 :          5 :         nToken = 0;
     382                 :          5 :         bReadPRE = bReadListing = bReadXMP = false;
     383                 :          5 :         break;      // HTML_ON hasn't been passed either !
     384                 :            : 
     385                 :            :     case HTML_PREFORMTXT_ON:
     386                 :          0 :         StartPRE();
     387                 :          0 :         break;
     388                 :            : 
     389                 :            :     case HTML_PREFORMTXT_OFF:
     390                 :          0 :         FinishPRE();
     391                 :          0 :         break;
     392                 :            : 
     393                 :            :     case HTML_LISTING_ON:
     394                 :          0 :         StartListing();
     395                 :          0 :         break;
     396                 :            : 
     397                 :            :     case HTML_LISTING_OFF:
     398                 :          0 :         FinishListing();
     399                 :          0 :         break;
     400                 :            : 
     401                 :            :     case HTML_XMP_ON:
     402                 :          0 :         StartXMP();
     403                 :          0 :         break;
     404                 :            : 
     405                 :            :     case HTML_XMP_OFF:
     406                 :          0 :         FinishXMP();
     407                 :          0 :         break;
     408                 :            : 
     409                 :            :     default:
     410         [ -  + ]:        146 :         if( bReadPRE )
     411                 :          0 :             nToken = FilterPRE( nToken );
     412         [ -  + ]:        146 :         else if( bReadListing )
     413                 :          0 :             nToken = FilterListing( nToken );
     414         [ -  + ]:        146 :         else if( bReadXMP )
     415                 :          0 :             nToken = FilterXMP( nToken );
     416                 :            : 
     417                 :        146 :         break;
     418                 :            :     }
     419                 :            : 
     420                 :        165 :     return nToken;
     421                 :            : }
     422                 :            : 
     423                 :            : #define HTML_ISDIGIT( c ) comphelper::string::isdigitAscii(c)
     424                 :            : #define HTML_ISALPHA( c ) comphelper::string::isalphaAscii(c)
     425                 :            : #define HTML_ISALNUM( c ) comphelper::string::isalnumAscii(c)
     426                 :            : #define HTML_ISSPACE( c ) ( ' ' == c || (c >= 0x09 && c <= 0x0d) )
     427                 :            : #define HTML_ISPRINTABLE( c ) ( c >= 32 && c != 127)
     428                 :            : #define HTML_ISHEXDIGIT( c ) comphelper::string::isxdigitAscii(c)
     429                 :            : 
     430                 :         83 : int HTMLParser::ScanText( const sal_Unicode cBreak )
     431                 :            : {
     432                 :         83 :     ::rtl::OUStringBuffer sTmpBuffer( MAX_LEN );
     433                 :         83 :     int bContinue = true;
     434                 :         83 :     int bEqSignFound = false;
     435                 :         83 :     sal_Unicode cQuote = 0U;
     436                 :            : 
     437 [ +  + ][ +  - ]:        509 :     while( bContinue && IsParserWorking() )
                 [ +  + ]
     438                 :            :     {
     439                 :        429 :         int bNextCh = true;
     440   [ -  +  -  +  :        429 :         switch( nNextCh )
          -  +  -  +  -  
                -  +  + ]
     441                 :            :         {
     442                 :            :         case '&':
     443                 :          0 :             bEqSignFound = false;
     444         [ #  # ]:          0 :             if( bReadXMP )
     445         [ #  # ]:          0 :                 sTmpBuffer.append( (sal_Unicode)'&' );
     446                 :            :             else
     447                 :            :             {
     448                 :          0 :                 sal_uLong nStreamPos = rInput.Tell();
     449                 :          0 :                 sal_uLong nLinePos = GetLinePos();
     450                 :            : 
     451                 :          0 :                 sal_Unicode cChar = 0U;
     452 [ #  # ][ #  # ]:          0 :                 if( '#' == (nNextCh = GetNextChar()) )
     453                 :            :                 {
     454         [ #  # ]:          0 :                     nNextCh = GetNextChar();
     455                 :          0 :                     const bool bIsHex( 'x' == nNextCh );
     456 [ #  # ][ #  # ]:          0 :                     const bool bIsDecOrHex( bIsHex || HTML_ISDIGIT(nNextCh) );
                 [ #  # ]
     457         [ #  # ]:          0 :                     if ( bIsDecOrHex )
     458                 :            :                     {
     459         [ #  # ]:          0 :                         if ( bIsHex )
     460                 :            :                         {
     461         [ #  # ]:          0 :                             nNextCh = GetNextChar();
     462 [ #  # ][ #  # ]:          0 :                             while ( HTML_ISHEXDIGIT(nNextCh) )
     463                 :            :                             {
     464                 :            :                                 cChar = cChar * 16U +
     465                 :            :                                         ( nNextCh <= '9'
     466                 :            :                                           ? sal_Unicode( nNextCh - '0' )
     467                 :            :                                           : ( nNextCh <= 'F'
     468                 :            :                                               ? sal_Unicode( nNextCh - 'A' + 10 )
     469 [ #  # ][ #  # ]:          0 :                                               : sal_Unicode( nNextCh - 'a' + 10 ) ) );
     470         [ #  # ]:          0 :                                 nNextCh = GetNextChar();
     471                 :            :                             }
     472                 :            :                         }
     473                 :            :                         else
     474                 :            :                         {
     475 [ #  # ][ #  # ]:          0 :                             do
     476                 :            :                             {
     477                 :          0 :                                 cChar = cChar * 10U + sal_Unicode( nNextCh - '0');
     478         [ #  # ]:          0 :                                 nNextCh = GetNextChar();
     479                 :            :                             }
     480                 :          0 :                             while( HTML_ISDIGIT(nNextCh) );
     481                 :            :                         }
     482                 :            : 
     483 [ #  # ][ #  # ]:          0 :                         if( RTL_TEXTENCODING_DONTKNOW != eSrcEnc &&
         [ #  # ][ #  # ]
     484                 :            :                             RTL_TEXTENCODING_UCS2 != eSrcEnc &&
     485                 :            :                             RTL_TEXTENCODING_UTF8 != eSrcEnc &&
     486                 :            :                             cChar < 256 )
     487                 :            :                         {
     488                 :            :                             const sal_uInt32 convertFlags =
     489                 :            :                                 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
     490                 :            :                                 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
     491                 :          0 :                                 RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT;
     492                 :            : 
     493                 :          0 :                             sal_Char cEncodedChar = static_cast<sal_Char>(cChar);
     494         [ #  # ]:          0 :                             cChar = rtl::OUString(&cEncodedChar, 1, eSrcEnc, convertFlags).toChar();
     495         [ #  # ]:          0 :                             if( 0U == cChar )
     496                 :            :                             {
     497                 :            :                                 // If the character could not be
     498                 :            :                                 // converted, because a conversion is not
     499                 :            :                                 // available, do no conversion at all.
     500                 :          0 :                                 cChar = cEncodedChar;
     501                 :            :                             }
     502                 :            :                         }
     503                 :            :                     }
     504                 :            :                     else
     505                 :          0 :                         nNextCh = 0U;
     506                 :            :                 }
     507 [ #  # ][ #  # ]:          0 :                 else if( HTML_ISALPHA( nNextCh ) )
     508                 :            :                 {
     509                 :          0 :                     ::rtl::OUStringBuffer sEntityBuffer( MAX_ENTITY_LEN );
     510                 :          0 :                     xub_StrLen nPos = 0L;
     511         [ #  # ]:          0 :                     do
           [ #  #  #  # ]
                 [ #  # ]
     512                 :            :                     {
     513         [ #  # ]:          0 :                         sEntityBuffer.append( nNextCh );
     514                 :          0 :                         nPos++;
     515         [ #  # ]:          0 :                         nNextCh = GetNextChar();
     516                 :            :                     }
     517         [ #  # ]:          0 :                     while( nPos < MAX_ENTITY_LEN && HTML_ISALNUM( nNextCh ) &&
     518                 :          0 :                            !rInput.IsEof() );
     519                 :            : 
     520 [ #  # ][ #  # ]:          0 :                     if( IsParserWorking() && !rInput.IsEof() )
                 [ #  # ]
     521                 :            :                     {
     522                 :          0 :                         rtl::OUString sEntity(sEntityBuffer.getStr(), nPos);
     523 [ #  # ][ #  # ]:          0 :                         cChar = GetHTMLCharName( sEntity );
                 [ #  # ]
     524                 :            : 
     525                 :            :                         // not found ( == 0 ): plain text
     526                 :            :                         // or a character which is inserted as attribute
     527 [ #  # ][ #  # ]:          0 :                         if( 0U == cChar && ';' != nNextCh )
     528                 :            :                         {
     529                 :            :                             DBG_ASSERT( rInput.Tell() - nStreamPos ==
     530                 :            :                                         (sal_uLong)(nPos+1L)*GetCharSize(),
     531                 :            :                                         "UTF-8 is failing here" );
     532         [ #  # ]:          0 :                             for( xub_StrLen i=nPos-1L; i>1L; i-- )
     533                 :            :                             {
     534                 :          0 :                                 nNextCh = sEntityBuffer[i];
     535         [ #  # ]:          0 :                                 sEntityBuffer.setLength( i );
     536                 :          0 :                                 sEntity = rtl::OUString(sEntityBuffer.getStr(), i);
     537 [ #  # ][ #  # ]:          0 :                                 cChar = GetHTMLCharName( sEntity );
                 [ #  # ]
     538         [ #  # ]:          0 :                                 if( cChar )
     539                 :            :                                 {
     540                 :            :                                     rInput.SeekRel( -(long)
     541         [ #  # ]:          0 :                                             ((nPos-i)*GetCharSize()) );
     542                 :          0 :                                     nlLinePos -= sal_uInt32(nPos-i);
     543                 :          0 :                                     nPos = i;
     544         [ #  # ]:          0 :                                     ClearTxtConvContext();
     545                 :          0 :                                     break;
     546                 :            :                                 }
     547                 :            :                             }
     548                 :            :                         }
     549                 :            : 
     550         [ #  # ]:          0 :                         if( !cChar )        // unknown character?
     551                 :            :                         {
     552                 :            :                             // back in stream, insert '&'
     553                 :            :                             // and restart with next character
     554         [ #  # ]:          0 :                             sTmpBuffer.append( (sal_Unicode)'&' );
     555                 :            : 
     556                 :            :                             DBG_ASSERT( rInput.Tell()-nStreamPos ==
     557                 :            :                                         (sal_uLong)(nPos+1)*GetCharSize(),
     558                 :            :                                         "Wrong stream position" );
     559                 :            :                             DBG_ASSERT( nlLinePos-nLinePos ==
     560                 :            :                                         (sal_uLong)(nPos+1),
     561                 :            :                                         "Wrong line position" );
     562         [ #  # ]:          0 :                             rInput.Seek( nStreamPos );
     563                 :          0 :                             nlLinePos = nLinePos;
     564         [ #  # ]:          0 :                             ClearTxtConvContext();
     565                 :            :                             break;
     566                 :            :                         }
     567                 :            : 
     568                 :            :                         // 1 == Non Breaking Space
     569                 :            :                         // 2 == SoftHyphen
     570                 :            : 
     571         [ #  # ]:          0 :                         if( cChar < 3U )
     572                 :            :                         {
     573         [ #  # ]:          0 :                             if( '>' == cBreak )
     574                 :            :                             {
     575                 :            :                                 // When reading the content of a tag we have
     576                 :            :                                 // to change it to ' ' or '-'
     577      [ #  #  # ]:          0 :                                 switch( cChar )
     578                 :            :                                 {
     579                 :          0 :                                 case 1U: cChar = ' '; break;
     580                 :          0 :                                 case 2U: cChar = '-'; break;
     581                 :            :                                 default:
     582                 :            :                                     DBG_ASSERT( cChar==1U,
     583                 :            :                             "\0x00 should be handled already!" );
     584                 :          0 :                                     break;
     585                 :            :                                 }
     586                 :            :                             }
     587                 :            :                             else
     588                 :            :                             {
     589                 :            :                                 // If not scanning a tag return token
     590                 :            :                                 aToken +=
     591 [ #  # ][ #  # ]:          0 :                                     String( sTmpBuffer.makeStringAndClear() );
         [ #  # ][ #  # ]
     592         [ #  # ]:          0 :                                 if( cChar )
     593                 :            :                                 {
     594         [ #  # ]:          0 :                                     if( aToken.Len() )
     595                 :            :                                     {
     596                 :            :                                         // restart with character
     597                 :          0 :                                         nNextCh = '&';
     598                 :            :                                         DBG_ASSERT( rInput.Tell()-nStreamPos ==
     599                 :            :                                                     (sal_uLong)(nPos+1)*GetCharSize(),
     600                 :            :                                                     "Wrong stream position" );
     601                 :            :                                         DBG_ASSERT( nlLinePos-nLinePos ==
     602                 :            :                                                     (sal_uLong)(nPos+1),
     603                 :            :                                                     "Wrong line position" );
     604         [ #  # ]:          0 :                                         rInput.Seek( nStreamPos );
     605                 :          0 :                                         nlLinePos = nLinePos;
     606         [ #  # ]:          0 :                                         ClearTxtConvContext();
     607                 :          0 :                                         return HTML_TEXTTOKEN;
     608                 :            :                                     }
     609                 :            : 
     610                 :            :                                     // Hack: _GetNextChar shall not read the
     611                 :            :                                     // next character
     612         [ #  # ]:          0 :                                     if( ';' != nNextCh )
     613         [ #  # ]:          0 :                                         aToken += ' ';
     614         [ #  # ]:          0 :                                     if( 1U == cChar )
     615                 :          0 :                                         return HTML_NONBREAKSPACE;
     616         [ #  # ]:          0 :                                     if( 2U == cChar )
     617                 :          0 :                                         return HTML_SOFTHYPH;
     618                 :            :                                 }
     619         [ #  # ]:          0 :                                 aToken += (sal_Unicode)'&';
     620                 :            :                                 aToken +=
     621 [ #  # ][ #  # ]:          0 :                                     String(sEntityBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     622                 :            :                                 break;
     623                 :            :                             }
     624      [ #  #  # ]:          0 :                         }
     625                 :            :                     }
     626                 :            :                     else
     627      [ #  #  # ]:          0 :                         nNextCh = 0U;
     628                 :            :                 }
     629                 :            :                 // &{...};-JavaScript-Macros are not supported any longer.
     630         [ #  # ]:          0 :                 else if( IsParserWorking() )
     631                 :            :                 {
     632         [ #  # ]:          0 :                     sTmpBuffer.append( (sal_Unicode)'&' );
     633                 :          0 :                     bNextCh = false;
     634                 :          0 :                     break;
     635                 :            :                 }
     636                 :            : 
     637                 :          0 :                 bNextCh = (';' == nNextCh);
     638 [ #  # ][ #  # ]:          0 :                 if( cBreak=='>' && (cChar=='\\' || cChar=='\'' ||
         [ #  # ][ #  # ]
                 [ #  # ]
     639                 :            :                                     cChar=='\"' || cChar==' ') )
     640                 :            :                 {
     641                 :            :                     // ' and " have to be escaped withing tags to separate
     642                 :            :                     // them from ' and " enclosing options.
     643                 :            :                     // \ has to be escaped as well.
     644                 :            :                     // Space is protected because it's not a delimiter between
     645                 :            :                     // options.
     646         [ #  # ]:          0 :                     sTmpBuffer.append( (sal_Unicode)'\\' );
     647         [ #  # ]:          0 :                     if( MAX_LEN == sTmpBuffer.getLength() )
     648 [ #  # ][ #  # ]:          0 :                         aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     649                 :            :                 }
     650         [ #  # ]:          0 :                 if( IsParserWorking() )
     651                 :            :                 {
     652         [ #  # ]:          0 :                     if( cChar )
     653         [ #  # ]:          0 :                         sTmpBuffer.append( cChar );
     654                 :            :                 }
     655 [ #  # ][ #  # ]:          0 :                 else if( SVPAR_PENDING==eState && '>'!=cBreak )
     656                 :            :                 {
     657                 :            :                     // Restart with '&', the remainder is returned as
     658                 :            :                     // text token.
     659 [ #  # ][ #  # ]:          0 :                     if( aToken.Len() || sTmpBuffer.getLength() )
                 [ #  # ]
     660                 :            :                     {
     661                 :            :                         // _GetNextChar() returns the previous text and
     662                 :            :                         // during the next execution a new character is read.
     663                 :            :                         // Thus we have to position in front of the '&'.
     664                 :          0 :                         nNextCh = 0U;
     665         [ #  # ]:          0 :                         rInput.Seek( nStreamPos-(sal_uInt32)GetCharSize() );
     666                 :          0 :                         nlLinePos = nLinePos-1;
     667         [ #  # ]:          0 :                         ClearTxtConvContext();
     668                 :          0 :                         bReadNextChar = true;
     669                 :            :                     }
     670                 :          0 :                     bNextCh = false;
     671                 :            :                 }
     672                 :            :             }
     673                 :          0 :             break;
     674                 :            :         case '=':
     675 [ +  - ][ +  + ]:         25 :             if( '>'==cBreak && !cQuote )
     676                 :         23 :                 bEqSignFound = true;
     677         [ +  - ]:         25 :             sTmpBuffer.append( nNextCh );
     678                 :         25 :             break;
     679                 :            : 
     680                 :            :         case '\\':
     681         [ #  # ]:          0 :             if( '>'==cBreak )
     682                 :            :             {
     683                 :            :                 // Innerhalb von Tags kennzeichnen
     684         [ #  # ]:          0 :                 sTmpBuffer.append( (sal_Unicode)'\\' );
     685         [ #  # ]:          0 :                 if( MAX_LEN == sTmpBuffer.getLength() )
     686 [ #  # ][ #  # ]:          0 :                     aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     687                 :            :             }
     688         [ #  # ]:          0 :             sTmpBuffer.append( (sal_Unicode)'\\' );
     689                 :          0 :             break;
     690                 :            : 
     691                 :            :         case '\"':
     692                 :            :         case '\'':
     693         [ +  - ]:         50 :             if( '>'==cBreak )
     694                 :            :             {
     695         [ +  + ]:         50 :                 if( bEqSignFound )
     696                 :         23 :                     cQuote = nNextCh;
     697 [ +  + ][ +  - ]:         27 :                 else if( cQuote && (cQuote==nNextCh ) )
     698                 :         23 :                     cQuote = 0U;
     699                 :            :             }
     700         [ +  - ]:         50 :             sTmpBuffer.append( nNextCh );
     701                 :         50 :             bEqSignFound = false;
     702                 :         50 :             break;
     703                 :            : 
     704                 :            :         case sal_Unicode(EOF):
     705         [ #  # ]:          0 :             if( rInput.IsEof() )
     706                 :            :             {
     707                 :          0 :                 bContinue = false;
     708                 :            :             }
     709                 :            :             else
     710                 :            :             {
     711         [ #  # ]:          0 :                 sTmpBuffer.append( nNextCh );
     712                 :            :             }
     713                 :          0 :             break;
     714                 :            : 
     715                 :            :         case '<':
     716                 :         65 :             bEqSignFound = false;
     717         [ -  + ]:         65 :             if( '>'==cBreak )
     718         [ #  # ]:          0 :                 sTmpBuffer.append( nNextCh );
     719                 :            :             else
     720                 :         65 :                 bContinue = false;      // break, String zusammen
     721                 :         65 :             break;
     722                 :            : 
     723                 :            :         case '\f':
     724         [ #  # ]:          0 :             if( '>' == cBreak )
     725                 :            :             {
     726                 :            :                 // If scanning options treat it like a space, ...
     727         [ #  # ]:          0 :                 sTmpBuffer.append( (sal_Unicode)' ' );
     728                 :            :             }
     729                 :            :             else
     730                 :            :             {
     731                 :            :                 // otherwise it's a separate token.
     732                 :          0 :                 bContinue = false;
     733                 :            :             }
     734                 :          0 :             break;
     735                 :            : 
     736                 :            :         case '\r':
     737                 :            :         case '\n':
     738         [ -  + ]:         50 :             if( '>'==cBreak )
     739                 :            :             {
     740                 :            :                 // cr/lf in tag is handled in _GetNextToken()
     741         [ #  # ]:          0 :                 sTmpBuffer.append( nNextCh );
     742                 :          0 :                 break;
     743                 :            :             }
     744 [ +  - ][ +  - ]:         50 :             else if( bReadListing || bReadXMP || bReadPRE || bReadTextArea )
         [ +  - ][ -  + ]
     745                 :            :             {
     746                 :          0 :                 bContinue = false;
     747                 :          0 :                 break;
     748                 :            :             }
     749                 :            :             // Reduce sequence of CR/LF/BLANK/TAB to a single blank
     750                 :            :             // no break!!
     751                 :            :         case '\t':
     752 [ -  + ][ #  # ]:         50 :             if( '\t'==nNextCh && bReadPRE && '>'!=cBreak )
                 [ #  # ]
     753                 :            :             {
     754                 :            :                 // In <PRE>: Tabs nach oben durchreichen
     755                 :          0 :                 bContinue = false;
     756                 :          0 :                 break;
     757                 :            :             }
     758                 :            :             // no break
     759                 :            :         case '\x0b':
     760 [ -  + ][ #  # ]:         50 :             if( '\x0b'==nNextCh && (bReadPRE || bReadXMP ||bReadListing) &&
         [ #  # ][ #  # ]
                 [ #  # ]
     761                 :            :                 '>'!=cBreak )
     762                 :            :             {
     763                 :          0 :                 break;
     764                 :            :             }
     765                 :         50 :             nNextCh = ' ';
     766                 :            :             // no break;
     767                 :            :         case ' ':
     768         [ +  - ]:        111 :             sTmpBuffer.append( nNextCh );
     769 [ +  + ][ +  - ]:        111 :             if( '>'!=cBreak && (!bReadListing && !bReadXMP &&
         [ +  - ][ +  - ]
                 [ +  - ]
     770                 :        166 :                                 !bReadPRE && !bReadTextArea) )
     771                 :            :             {
     772                 :            :                 // Reduce sequences of Blanks/Tabs/CR/LF to a single blank
     773 [ +  + ][ +  + ]:        114 :                 do {
         [ +  - ][ +  - ]
         [ -  + ][ +  + ]
     774         [ +  - ]:        120 :                     if( sal_Unicode(EOF) == (nNextCh = GetNextChar()) &&
           [ +  +  +  - ]
                 [ +  + ]
     775                 :          3 :                         rInput.IsEof() )
     776                 :            :                     {
     777 [ +  - ][ -  + ]:          3 :                         if( aToken.Len() || sTmpBuffer.getLength() > 1L )
                 [ -  + ]
     778                 :            :                         {
     779                 :            :                             // Have seen s.th. aside from blanks?
     780 [ #  # ][ #  # ]:          0 :                             aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     781                 :          0 :                             return HTML_TEXTTOKEN;
     782                 :            :                         }
     783                 :            :                         else
     784                 :            :                             // Only read blanks: no text must be returned
     785                 :            :                             // and _GetNextToken has to read until EOF
     786                 :          3 :                             return 0;
     787                 :            :                     }
     788                 :            :                 } while ( ' ' == nNextCh || '\t' == nNextCh ||
     789                 :            :                           '\r' == nNextCh || '\n' == nNextCh ||
     790                 :            :                           '\x0b' == nNextCh );
     791                 :         80 :                 bNextCh = false;
     792                 :            :             }
     793                 :        108 :             break;
     794                 :            : 
     795                 :            :         default:
     796                 :        178 :             bEqSignFound = false;
     797         [ +  + ]:        341 :             if( (nNextCh==cBreak && !cQuote) ||
           [ -  +  -  + ]
                 [ +  + ]
     798                 :        163 :                 (sal_uLong(aToken.Len()) + MAX_LEN) > sal_uLong(STRING_MAXLEN & ~1 ))
     799                 :         15 :                 bContinue = false;
     800                 :            :             else
     801                 :            :             {
     802 [ +  + ][ +  + ]:        881 :                 do {
                 [ +  + ]
     803                 :            :                     // All remaining characters make their way into the text.
     804         [ +  - ]:        663 :                     sTmpBuffer.append( nNextCh );
     805         [ -  + ]:        663 :                     if( MAX_LEN == sTmpBuffer.getLength() )
     806                 :            :                     {
     807 [ #  # ][ #  # ]:          0 :                         aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     808         [ #  # ]:          0 :                         if( (sal_uLong(aToken.Len()) + MAX_LEN) >
     809                 :            :                                 sal_uLong(STRING_MAXLEN & ~1 ) )
     810                 :            :                         {
     811         [ #  # ]:          0 :                             nNextCh = GetNextChar();
     812                 :          0 :                             return HTML_TEXTTOKEN;
     813                 :            :                         }
     814                 :            :                     }
     815 [ +  - ][ -  +  :       1326 :                     if( ( sal_Unicode(EOF) == (nNextCh = GetNextChar()) &&
             #  #  -  + ]
                 [ -  + ]
     816                 :          0 :                           rInput.IsEof() ) ||
     817                 :        663 :                         !IsParserWorking() )
     818                 :            :                     {
     819         [ #  # ]:          0 :                         if( sTmpBuffer.getLength() )
     820 [ #  # ][ #  # ]:          0 :                             aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     821                 :          0 :                         return HTML_TEXTTOKEN;
     822                 :            :                     }
     823 [ +  - ][ +  - ]:        881 :                 } while( HTML_ISALPHA( nNextCh ) || HTML_ISDIGIT( nNextCh ) );
     824                 :        163 :                 bNextCh = false;
     825                 :            :             }
     826                 :            :         }
     827                 :            : 
     828         [ -  + ]:        426 :         if( MAX_LEN == sTmpBuffer.getLength() )
     829 [ #  # ][ #  # ]:          0 :             aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     830                 :            : 
     831 [ +  + ][ +  + ]:        426 :         if( bContinue && bNextCh )
     832         [ +  - ]:        103 :             nNextCh = GetNextChar();
     833                 :            :     }
     834                 :            : 
     835         [ +  - ]:         80 :     if( sTmpBuffer.getLength() )
     836 [ +  - ][ +  - ]:         80 :         aToken += String(sTmpBuffer.makeStringAndClear());
         [ +  - ][ +  - ]
     837                 :            : 
     838                 :         83 :     return HTML_TEXTTOKEN;
     839                 :            : }
     840                 :            : 
     841                 :          0 : int HTMLParser::_GetNextRawToken()
     842                 :            : {
     843                 :          0 :     ::rtl::OUStringBuffer sTmpBuffer( MAX_LEN );
     844                 :            : 
     845         [ #  # ]:          0 :     if( bEndTokenFound )
     846                 :            :     {
     847                 :            :         // During the last execution we already found the end token,
     848                 :            :         // thus we don't have to search it again.
     849                 :          0 :         bReadScript = false;
     850                 :          0 :         bReadStyle = false;
     851         [ #  # ]:          0 :         aEndToken.Erase();
     852                 :          0 :         bEndTokenFound = false;
     853                 :            : 
     854                 :          0 :         return 0;
     855                 :            :     }
     856                 :            : 
     857                 :            :     // Default return value: HTML_RAWDATA
     858                 :          0 :     int bContinue = true;
     859                 :          0 :     int nToken = HTML_RAWDATA;
     860         [ #  # ]:          0 :     SaveState( 0 );
     861 [ #  # ][ #  # ]:          0 :     while( bContinue && IsParserWorking() )
                 [ #  # ]
     862                 :            :     {
     863                 :          0 :         int bNextCh = true;
     864   [ #  #  #  #  :          0 :         switch( nNextCh )
                   #  # ]
     865                 :            :         {
     866                 :            :         case '<':
     867                 :            :             {
     868                 :            :                 // Maybe we've reached the end.
     869                 :            : 
     870                 :            :                 // Save what we have read previously...
     871 [ #  # ][ #  # ]:          0 :                 aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     872                 :            : 
     873                 :            :                 // and remember position in stream.
     874                 :          0 :                 sal_uLong nStreamPos = rInput.Tell();
     875                 :          0 :                 sal_uLong nLineNr = GetLineNr();
     876                 :          0 :                 sal_uLong nLinePos = GetLinePos();
     877                 :            : 
     878                 :            :                 // Start of an end token?
     879                 :          0 :                 int bOffState = false;
     880 [ #  # ][ #  # ]:          0 :                 if( '/' == (nNextCh = GetNextChar()) )
     881                 :            :                 {
     882                 :          0 :                     bOffState = true;
     883         [ #  # ]:          0 :                     nNextCh = GetNextChar();
     884                 :            :                 }
     885         [ #  # ]:          0 :                 else if( '!' == nNextCh )
     886                 :            :                 {
     887         [ #  # ]:          0 :                     sTmpBuffer.append( nNextCh );
     888         [ #  # ]:          0 :                     nNextCh = GetNextChar();
     889                 :            :                 }
     890                 :            : 
     891                 :            :                 // Read following letters
     892 [ #  # ][ #  # ]:          0 :                 while( (HTML_ISALPHA(nNextCh) || '-'==nNextCh) &&
           [ #  #  #  #  
           #  # ][ #  # ]
     893                 :          0 :                        IsParserWorking() && sTmpBuffer.getLength() < MAX_LEN )
     894                 :            :                 {
     895         [ #  # ]:          0 :                     sTmpBuffer.append( nNextCh );
     896         [ #  # ]:          0 :                     nNextCh = GetNextChar();
     897                 :            :                 }
     898                 :            : 
     899         [ #  # ]:          0 :                 String aTok( sTmpBuffer.toString() );
     900         [ #  # ]:          0 :                 aTok.ToUpperAscii();
     901                 :          0 :                 bool bDone = false;
     902 [ #  # ][ #  # ]:          0 :                 if( bReadScript || aEndToken.Len() )
                 [ #  # ]
     903                 :            :                 {
     904         [ #  # ]:          0 :                     if( !bReadComment )
     905                 :            :                     {
     906 [ #  # ][ #  # ]:          0 :                         if( aTok.CompareToAscii( OOO_STRING_SVTOOLS_HTML_comment, 3 )
     907                 :            :                                 == COMPARE_EQUAL )
     908                 :            :                         {
     909                 :          0 :                             bReadComment = true;
     910                 :            :                         }
     911                 :            :                         else
     912                 :            :                         {
     913                 :            :                             // A script has to end with "</SCRIPT>". But
     914                 :            :                             // ">" is optional for security reasons
     915                 :            :                             bDone = bOffState &&
     916                 :            :                             COMPARE_EQUAL == ( bReadScript
     917         [ #  # ]:          0 :                                 ? aTok.CompareToAscii(OOO_STRING_SVTOOLS_HTML_script)
     918 [ #  # ][ #  # ]:          0 :                                 : aTok.CompareTo(aEndToken) );
         [ #  # ][ #  # ]
                 [ #  # ]
     919                 :            :                         }
     920                 :            :                     }
     921 [ #  # ][ #  # ]:          0 :                     if( bReadComment && '>'==nNextCh && aTok.Len() >= 2 &&
         [ #  # ][ #  # ]
                 [ #  # ]
     922 [ #  # ][ #  # ]:          0 :                         aTok.Copy( aTok.Len()-2 ).EqualsAscii( "--" ) )
         [ #  # ][ #  # ]
                 [ #  # ]
     923                 :            :                     {
     924                 :            :                         // End of comment of style <!----->
     925                 :          0 :                         bReadComment = false;
     926                 :            :                     }
     927                 :            :                 }
     928                 :            :                 else
     929                 :            :                 {
     930                 :            :                     // Style sheets can be closed by </STYLE>, </HEAD> or <BODY>
     931         [ #  # ]:          0 :                     if( bOffState )
     932         [ #  # ]:          0 :                         bDone = aTok.CompareToAscii(OOO_STRING_SVTOOLS_HTML_style)
     933                 :            :                                     == COMPARE_EQUAL ||
     934         [ #  # ]:          0 :                                 aTok.CompareToAscii(OOO_STRING_SVTOOLS_HTML_head)
     935 [ #  # ][ #  # ]:          0 :                                     == COMPARE_EQUAL;
     936                 :            :                     else
     937                 :            :                         bDone =
     938         [ #  # ]:          0 :                             aTok.CompareToAscii(OOO_STRING_SVTOOLS_HTML_body) == COMPARE_EQUAL;
     939                 :            :                 }
     940                 :            : 
     941         [ #  # ]:          0 :                 if( bDone )
     942                 :            :                 {
     943                 :            :                     // Done! Return the previously read string (if requested)
     944                 :            :                     // and continue.
     945                 :            : 
     946                 :          0 :                     bContinue = false;
     947                 :            : 
     948                 :            :                     // nToken==0 means, _GetNextToken continues to read
     949 [ #  # ][ #  # ]:          0 :                     if( !aToken.Len() && (bReadStyle || bReadScript) )
         [ #  # ][ #  # ]
     950                 :            :                     {
     951                 :            :                         // Immediately close environment (or context?)
     952                 :            :                         // and parse the end token
     953                 :          0 :                         bReadScript = false;
     954                 :          0 :                         bReadStyle = false;
     955         [ #  # ]:          0 :                         aEndToken.Erase();
     956                 :          0 :                         nToken = 0;
     957                 :            :                     }
     958                 :            :                     else
     959                 :            :                     {
     960                 :            :                         // Keep bReadScript/bReadStyle alive
     961                 :            :                         // and parse end token during next execution
     962                 :          0 :                         bEndTokenFound = true;
     963                 :            :                     }
     964                 :            : 
     965                 :            :                     // Move backwards in stream to '<'
     966         [ #  # ]:          0 :                     rInput.Seek( nStreamPos );
     967                 :          0 :                     SetLineNr( nLineNr );
     968                 :          0 :                     SetLinePos( nLinePos );
     969         [ #  # ]:          0 :                     ClearTxtConvContext();
     970                 :          0 :                     nNextCh = '<';
     971                 :            : 
     972                 :            :                     // Don't append string to token.
     973         [ #  # ]:          0 :                     sTmpBuffer.setLength( 0L );
     974                 :            :                 }
     975                 :            :                 else
     976                 :            :                 {
     977                 :            :                     // remember "</" , everything else we find in the buffer
     978         [ #  # ]:          0 :                     aToken += (sal_Unicode)'<';
     979         [ #  # ]:          0 :                     if( bOffState )
     980         [ #  # ]:          0 :                         aToken += (sal_Unicode)'/';
     981                 :            : 
     982                 :          0 :                     bNextCh = false;
     983         [ #  # ]:          0 :                 }
     984                 :            :             }
     985                 :          0 :             break;
     986                 :            :         case '-':
     987         [ #  # ]:          0 :             sTmpBuffer.append( nNextCh );
     988         [ #  # ]:          0 :             if( bReadComment )
     989                 :            :             {
     990                 :          0 :                 bool bTwoMinus = false;
     991         [ #  # ]:          0 :                 nNextCh = GetNextChar();
     992 [ #  # ][ #  # ]:          0 :                 while( '-' == nNextCh && IsParserWorking() )
                 [ #  # ]
     993                 :            :                 {
     994                 :          0 :                     bTwoMinus = true;
     995                 :            : 
     996         [ #  # ]:          0 :                     if( MAX_LEN == sTmpBuffer.getLength() )
     997 [ #  # ][ #  # ]:          0 :                         aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
     998         [ #  # ]:          0 :                     sTmpBuffer.append( nNextCh );
     999         [ #  # ]:          0 :                     nNextCh = GetNextChar();
    1000                 :            :                 }
    1001                 :            : 
    1002 [ #  # ][ #  # ]:          0 :                 if( '>' == nNextCh && IsParserWorking() && bTwoMinus )
         [ #  # ][ #  # ]
    1003                 :          0 :                     bReadComment = false;
    1004                 :            : 
    1005                 :          0 :                 bNextCh = false;
    1006                 :            :             }
    1007                 :          0 :             break;
    1008                 :            : 
    1009                 :            :         case '\r':
    1010                 :            :             // \r\n? closes the current text token (even if it's empty)
    1011         [ #  # ]:          0 :             nNextCh = GetNextChar();
    1012         [ #  # ]:          0 :             if( nNextCh=='\n' )
    1013         [ #  # ]:          0 :                 nNextCh = GetNextChar();
    1014                 :          0 :             bContinue = false;
    1015                 :          0 :             break;
    1016                 :            :         case '\n':
    1017                 :            :             // \n closes the current text token (even if it's empty)
    1018         [ #  # ]:          0 :             nNextCh = GetNextChar();
    1019                 :          0 :             bContinue = false;
    1020                 :          0 :             break;
    1021                 :            :         case sal_Unicode(EOF):
    1022                 :            :             // eof closes the current text token and behaves like having read
    1023                 :            :             // an end token
    1024         [ #  # ]:          0 :             if( rInput.IsEof() )
    1025                 :            :             {
    1026                 :          0 :                 bContinue = false;
    1027 [ #  # ][ #  # ]:          0 :                 if( aToken.Len() || sTmpBuffer.getLength() )
                 [ #  # ]
    1028                 :            :                 {
    1029                 :          0 :                     bEndTokenFound = true;
    1030                 :            :                 }
    1031                 :            :                 else
    1032                 :            :                 {
    1033                 :          0 :                     bReadScript = false;
    1034                 :          0 :                     bReadStyle = false;
    1035         [ #  # ]:          0 :                     aEndToken.Erase();
    1036                 :          0 :                     nToken = 0;
    1037                 :            :                 }
    1038                 :          0 :                 break;
    1039                 :            :             }
    1040                 :            :             // no break
    1041                 :            :         default:
    1042                 :            :             // all remaining characters are appended to the buffer
    1043         [ #  # ]:          0 :             sTmpBuffer.append( nNextCh );
    1044                 :          0 :             break;
    1045                 :            :         }
    1046                 :            : 
    1047         [ #  # ]:          0 :         if( (!bContinue && sTmpBuffer.getLength() > 0L) ||
           [ #  #  #  # ]
                 [ #  # ]
    1048                 :          0 :             MAX_LEN == sTmpBuffer.getLength() )
    1049 [ #  # ][ #  # ]:          0 :             aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
    1050                 :            : 
    1051 [ #  # ][ #  # ]:          0 :         if( bContinue && bNextCh )
    1052         [ #  # ]:          0 :             nNextCh = GetNextChar();
    1053                 :            :     }
    1054                 :            : 
    1055         [ #  # ]:          0 :     if( IsParserWorking() )
    1056         [ #  # ]:          0 :         SaveState( 0 );
    1057                 :            :     else
    1058                 :          0 :         nToken = 0;
    1059                 :            : 
    1060                 :          0 :     return nToken;
    1061                 :            : }
    1062                 :            : 
    1063                 :            : // Scan next token
    1064                 :        170 : int HTMLParser::_GetNextToken()
    1065                 :            : {
    1066                 :        170 :     int nRet = 0;
    1067                 :        170 :     sSaveToken.Erase();
    1068                 :            : 
    1069                 :            :     // Delete options
    1070         [ +  + ]:        170 :     if (!maOptions.empty())
    1071                 :         10 :         maOptions.clear();
    1072                 :            : 
    1073         [ -  + ]:        170 :     if( !IsParserWorking() )        // Don't continue if already an error occured
    1074                 :          0 :         return 0;
    1075                 :            : 
    1076                 :        170 :     bool bReadNextCharSave = bReadNextChar;
    1077         [ -  + ]:        170 :     if( bReadNextChar )
    1078                 :            :     {
    1079                 :            :         DBG_ASSERT( !bEndTokenFound,
    1080                 :            :                     "Read a character despite </SCRIPT> was read?" );
    1081                 :          0 :         nNextCh = GetNextChar();
    1082         [ #  # ]:          0 :         if( !IsParserWorking() )        // Don't continue if already an error occured
    1083                 :          0 :             return 0;
    1084                 :          0 :         bReadNextChar = false;
    1085                 :            :     }
    1086                 :            : 
    1087 [ +  - ][ +  - ]:        170 :     if( bReadScript || bReadStyle || aEndToken.Len() )
         [ -  + ][ -  + ]
    1088                 :            :     {
    1089                 :          0 :         nRet = _GetNextRawToken();
    1090 [ #  # ][ #  # ]:          0 :         if( nRet || !IsParserWorking() )
                 [ #  # ]
    1091                 :          0 :             return nRet;
    1092                 :            :     }
    1093                 :            : 
    1094 [ +  + ][ +  - ]:        173 :     do {
                 [ +  + ]
    1095                 :        173 :         int bNextCh = true;
    1096   [ +  +  -  +  :        173 :         switch( nNextCh )
                   -  + ]
    1097                 :            :         {
    1098                 :            :         case '<':
    1099                 :            :             {
    1100                 :        100 :                 sal_uLong nStreamPos = rInput.Tell();
    1101                 :        100 :                 sal_uLong nLineNr = GetLineNr();
    1102                 :        100 :                 sal_uLong nLinePos = GetLinePos();
    1103                 :            : 
    1104                 :        100 :                 int bOffState = false;
    1105         [ +  + ]:        100 :                 if( '/' == (nNextCh = GetNextChar()) )
    1106                 :            :                 {
    1107                 :         43 :                     bOffState = true;
    1108                 :         43 :                     nNextCh = GetNextChar();
    1109                 :            :                 }
    1110 [ +  + ][ +  - ]:        100 :                 if( HTML_ISALPHA( nNextCh ) || '!'==nNextCh )
                 [ +  - ]
    1111                 :            :                 {
    1112                 :        100 :                     ::rtl::OUStringBuffer sTmpBuffer;
    1113 [ +  + ][ +  +  :        706 :                     do {
             +  -  +  - ]
                 [ +  + ]
    1114         [ +  - ]:        302 :                         sTmpBuffer.append( nNextCh );
    1115         [ -  + ]:        302 :                         if( MAX_LEN == sTmpBuffer.getLength() )
    1116 [ #  # ][ #  # ]:          0 :                             aToken += String(sTmpBuffer.makeStringAndClear());
         [ #  # ][ #  # ]
    1117         [ +  - ]:        302 :                         nNextCh = GetNextChar();
    1118 [ +  - ][ +  - ]:        202 :                     } while( '>' != nNextCh && !HTML_ISSPACE( nNextCh ) &&
    1119                 :        404 :                              IsParserWorking() && !rInput.IsEof() );
    1120                 :            : 
    1121         [ +  - ]:        100 :                     if( sTmpBuffer.getLength() )
    1122 [ +  - ][ +  - ]:        100 :                         aToken += String(sTmpBuffer.makeStringAndClear());
         [ +  - ][ +  - ]
    1123                 :            : 
    1124                 :            :                     // Skip blanks
    1125 [ +  + ][ +  - ]:        115 :                     while( HTML_ISSPACE( nNextCh ) && IsParserWorking() )
         [ -  + ][ +  - ]
                 [ +  + ]
    1126         [ +  - ]:         15 :                         nNextCh = GetNextChar();
    1127                 :            : 
    1128         [ -  + ]:        100 :                     if( !IsParserWorking() )
    1129                 :            :                     {
    1130         [ #  # ]:          0 :                         if( SVPAR_PENDING == eState )
    1131                 :          0 :                             bReadNextChar = bReadNextCharSave;
    1132                 :            :                         break;
    1133                 :            :                     }
    1134                 :            : 
    1135                 :            :                     // Search token in table:
    1136         [ +  - ]:        100 :                     sSaveToken = aToken;
    1137         [ +  - ]:        100 :                     aToken.ToUpperAscii();
    1138 [ +  - ][ -  + ]:        100 :                     if( 0 == (nRet = GetHTMLToken( aToken )) )
    1139                 :            :                         // Unknown control
    1140                 :          0 :                         nRet = HTML_UNKNOWNCONTROL_ON;
    1141                 :            : 
    1142                 :            :                     // If it's a token which can be switched off...
    1143         [ +  + ]:        100 :                     if( bOffState )
    1144                 :            :                     {
    1145         [ +  - ]:         43 :                          if( HTML_TOKEN_ONOFF & nRet )
    1146                 :            :                          {
    1147                 :            :                             // and there is an off token, return off token instead
    1148                 :         43 :                             ++nRet;
    1149                 :            :                          }
    1150         [ #  # ]:          0 :                          else if( HTML_LINEBREAK!=nRet )
    1151                 :            :                          {
    1152                 :            :                             // and there is no off token, return unknown token.
    1153                 :            :                             // (except for </BR>, that is treated like <BR>)
    1154                 :          0 :                             nRet = HTML_UNKNOWNCONTROL_OFF;
    1155                 :            :                          }
    1156                 :            :                     }
    1157                 :            : 
    1158         [ -  + ]:        100 :                     if( nRet == HTML_COMMENT )
    1159                 :            :                     {
    1160                 :            :                         // fix: due to being case sensitive use sSaveToken as start of comment
    1161                 :            :                         //      and append a blank.
    1162         [ #  # ]:          0 :                         aToken = sSaveToken;
    1163         [ #  # ]:          0 :                         if( '>'!=nNextCh )
    1164         [ #  # ]:          0 :                             aToken += (sal_Unicode)' ';
    1165                 :          0 :                         sal_uLong nCStreamPos = 0;
    1166                 :          0 :                         sal_uLong nCLineNr = 0;
    1167                 :          0 :                         sal_uLong nCLinePos = 0;
    1168                 :          0 :                         xub_StrLen nCStrLen = 0;
    1169                 :            : 
    1170                 :          0 :                         bool bDone = false;
    1171                 :            :                         // Read until closing -->. If not found restart at first >
    1172 [ #  # ][ #  # ]:          0 :                         while( !bDone && !rInput.IsEof() && IsParserWorking() )
         [ #  # ][ #  # ]
    1173                 :            :                         {
    1174         [ #  # ]:          0 :                             if( '>'==nNextCh )
    1175                 :            :                             {
    1176         [ #  # ]:          0 :                                 if( !nCStreamPos )
    1177                 :            :                                 {
    1178                 :          0 :                                     nCStreamPos = rInput.Tell();
    1179                 :          0 :                                     nCStrLen = aToken.Len();
    1180                 :          0 :                                     nCLineNr = GetLineNr();
    1181                 :          0 :                                     nCLinePos = GetLinePos();
    1182                 :            :                                 }
    1183                 :          0 :                                 bDone = aToken.Len() >= 2 &&
    1184                 :          0 :                                         aToken.Copy(aToken.Len()-2,2).
    1185 [ #  # ][ #  # ]:          0 :                                                         EqualsAscii( "--" );
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
    1186         [ #  # ]:          0 :                                 if( !bDone )
    1187         [ #  # ]:          0 :                                 aToken += nNextCh;
    1188                 :            :                             }
    1189                 :            :                             else
    1190         [ #  # ]:          0 :                                 aToken += nNextCh;
    1191         [ #  # ]:          0 :                             if( !bDone )
    1192         [ #  # ]:          0 :                                 nNextCh = GetNextChar();
    1193                 :            :                         }
    1194 [ #  # ][ #  # ]:          0 :                         if( !bDone && IsParserWorking() && nCStreamPos )
         [ #  # ][ #  # ]
    1195                 :            :                         {
    1196         [ #  # ]:          0 :                             rInput.Seek( nCStreamPos );
    1197                 :          0 :                             SetLineNr( nCLineNr );
    1198                 :          0 :                             SetLinePos( nCLinePos );
    1199         [ #  # ]:          0 :                             ClearTxtConvContext();
    1200         [ #  # ]:          0 :                             aToken.Erase( nCStrLen );
    1201                 :          0 :                             nNextCh = '>';
    1202                 :            :                         }
    1203                 :            :                     }
    1204                 :            :                     else
    1205                 :            :                     {
    1206                 :            :                         // TokenString not needed anymore
    1207         [ +  - ]:        100 :                         aToken.Erase();
    1208                 :            :                     }
    1209                 :            : 
    1210                 :            :                     // Read until closing '>'
    1211 [ +  + ][ +  - ]:        100 :                     if( '>' != nNextCh && IsParserWorking() )
                 [ +  + ]
    1212                 :            :                     {
    1213         [ +  - ]:         15 :                         ScanText( '>' );
    1214                 :            : 
    1215                 :            :                         // fdo#34666 fdo#36080 fdo#36390: closing "/>"?:
    1216                 :            :                         // return HTML_<TOKEN>_OFF instead of HTML_<TOKEN>_ON
    1217         [ +  + ]:         20 :                         if ((HTML_TOKEN_ONOFF & nRet) && (aToken.Len() >= 1) &&
           [ +  -  -  + ]
                 [ -  + ]
    1218                 :          5 :                             ('/' == aToken.GetChar(aToken.Len()-1))) {
    1219                 :          0 :                             ++nRet; // HTML_<TOKEN>_ON -> HTML_<TOKEN>_OFF;
    1220                 :            :                         }
    1221 [ -  + ][ #  # ]:         15 :                         if( sal_Unicode(EOF) == nNextCh && rInput.IsEof() )
                 [ -  + ]
    1222                 :            :                         {
    1223                 :            :                             // Move back in front of < and restart there.
    1224                 :            :                             // Return < as text.
    1225         [ #  # ]:          0 :                             rInput.Seek( nStreamPos );
    1226                 :          0 :                             SetLineNr( nLineNr );
    1227                 :          0 :                             SetLinePos( nLinePos );
    1228         [ #  # ]:          0 :                             ClearTxtConvContext();
    1229                 :            : 
    1230         [ #  # ]:          0 :                             aToken = '<';
    1231                 :          0 :                             nRet = HTML_TEXTTOKEN;
    1232         [ #  # ]:          0 :                             nNextCh = GetNextChar();
    1233                 :          0 :                             bNextCh = false;
    1234                 :            :                             break;
    1235                 :            :                         }
    1236                 :            :                     }
    1237         [ -  + ]:        100 :                     if( SVPAR_PENDING == eState )
    1238         [ +  - ]:        100 :                         bReadNextChar = bReadNextCharSave;
    1239                 :            :                 }
    1240                 :            :                 else
    1241                 :            :                 {
    1242         [ #  # ]:          0 :                     if( bOffState )
    1243                 :            :                     {
    1244                 :            :                         // einfach alles wegschmeissen
    1245                 :          0 :                         ScanText( '>' );
    1246 [ #  # ][ #  # ]:          0 :                         if( sal_Unicode(EOF) == nNextCh && rInput.IsEof() )
                 [ #  # ]
    1247                 :            :                         {
    1248                 :            :                             // Move back in front of < and restart there.
    1249                 :            :                             // Return < as text.
    1250                 :          0 :                             rInput.Seek( nStreamPos );
    1251                 :          0 :                             SetLineNr( nLineNr );
    1252                 :          0 :                             SetLinePos( nLinePos );
    1253                 :          0 :                             ClearTxtConvContext();
    1254                 :            : 
    1255                 :          0 :                             aToken = '<';
    1256                 :          0 :                             nRet = HTML_TEXTTOKEN;
    1257                 :          0 :                             nNextCh = GetNextChar();
    1258                 :          0 :                             bNextCh = false;
    1259                 :          0 :                             break;
    1260                 :            :                         }
    1261         [ #  # ]:          0 :                         if( SVPAR_PENDING == eState )
    1262                 :          0 :                             bReadNextChar = bReadNextCharSave;
    1263                 :          0 :                         aToken.Erase();
    1264                 :            :                     }
    1265         [ #  # ]:          0 :                     else if( '%' == nNextCh )
    1266                 :            :                     {
    1267                 :          0 :                         nRet = HTML_UNKNOWNCONTROL_ON;
    1268                 :            : 
    1269                 :          0 :                         sal_uLong nCStreamPos = rInput.Tell();
    1270                 :          0 :                         sal_uLong nCLineNr = GetLineNr(), nCLinePos = GetLinePos();
    1271                 :            : 
    1272                 :          0 :                         bool bDone = false;
    1273                 :            :                         // Read until closing %>. If not found restart at first >.
    1274 [ #  # ][ #  # ]:          0 :                         while( !bDone && !rInput.IsEof() && IsParserWorking() )
         [ #  # ][ #  # ]
    1275                 :            :                         {
    1276                 :          0 :                             bDone = '>'==nNextCh && aToken.Len() >= 1 &&
    1277   [ #  #  #  # ]:          0 :                                     '%' == aToken.GetChar( aToken.Len()-1 );
                 [ #  # ]
    1278         [ #  # ]:          0 :                             if( !bDone )
    1279                 :            :                             {
    1280                 :          0 :                                 aToken += nNextCh;
    1281                 :          0 :                                 nNextCh = GetNextChar();
    1282                 :            :                             }
    1283                 :            :                         }
    1284 [ #  # ][ #  # ]:          0 :                         if( !bDone && IsParserWorking() )
                 [ #  # ]
    1285                 :            :                         {
    1286                 :          0 :                             rInput.Seek( nCStreamPos );
    1287                 :          0 :                             SetLineNr( nCLineNr );
    1288                 :          0 :                             SetLinePos( nCLinePos );
    1289                 :          0 :                             ClearTxtConvContext();
    1290                 :          0 :                             aToken.AssignAscii( "<%", 2 );
    1291                 :          0 :                             nRet = HTML_TEXTTOKEN;
    1292                 :          0 :                             break;
    1293                 :            :                         }
    1294         [ #  # ]:          0 :                         if( IsParserWorking() )
    1295                 :            :                         {
    1296                 :          0 :                             sSaveToken = aToken;
    1297                 :          0 :                             aToken.Erase();
    1298                 :            :                         }
    1299                 :            :                     }
    1300                 :            :                     else
    1301                 :            :                     {
    1302                 :          0 :                         aToken = '<';
    1303                 :          0 :                         nRet = HTML_TEXTTOKEN;
    1304                 :          0 :                         bNextCh = false;
    1305                 :          0 :                         break;
    1306                 :            :                     }
    1307                 :            :                 }
    1308                 :            : 
    1309         [ +  - ]:        100 :                 if( IsParserWorking() )
    1310                 :            :                 {
    1311                 :        100 :                     bNextCh = '>' == nNextCh;
    1312   [ -  -  -  -  :        100 :                     switch( nRet )
                -  -  + ]
    1313                 :            :                     {
    1314                 :            :                     case HTML_TEXTAREA_ON:
    1315                 :          0 :                         bReadTextArea = true;
    1316                 :          0 :                         break;
    1317                 :            :                     case HTML_TEXTAREA_OFF:
    1318                 :          0 :                         bReadTextArea = false;
    1319                 :          0 :                         break;
    1320                 :            :                     case HTML_SCRIPT_ON:
    1321         [ #  # ]:          0 :                         if( !bReadTextArea )
    1322                 :          0 :                             bReadScript = true;
    1323                 :          0 :                         break;
    1324                 :            :                     case HTML_SCRIPT_OFF:
    1325         [ #  # ]:          0 :                         if( !bReadTextArea )
    1326                 :            :                         {
    1327                 :          0 :                             bReadScript = false;
    1328                 :            :                             // JavaScript might modify the stream,
    1329                 :            :                             // thus the last character has to be read again.
    1330                 :          0 :                             bReadNextChar = true;
    1331                 :          0 :                             bNextCh = false;
    1332                 :            :                         }
    1333                 :          0 :                         break;
    1334                 :            : 
    1335                 :            :                     case HTML_STYLE_ON:
    1336                 :          0 :                         bReadStyle = true;
    1337                 :          0 :                         break;
    1338                 :            :                     case HTML_STYLE_OFF:
    1339                 :          0 :                         bReadStyle = false;
    1340                 :        100 :                         break;
    1341                 :            :                     }
    1342                 :            :                 }
    1343                 :            :             }
    1344                 :        100 :             break;
    1345                 :            : 
    1346                 :            :         case sal_Unicode(EOF):
    1347         [ +  - ]:          5 :             if( rInput.IsEof() )
    1348                 :            :             {
    1349                 :          5 :                 eState = SVPAR_ACCEPTED;
    1350                 :          5 :                 nRet = nNextCh;
    1351                 :            :             }
    1352                 :            :             else
    1353                 :            :             {
    1354                 :            :                 // Read normal text.
    1355                 :          0 :                 goto scan_text;
    1356                 :            :             }
    1357                 :          5 :             break;
    1358                 :            : 
    1359                 :            :         case '\f':
    1360                 :            :             // form feeds are passed upwards separately
    1361                 :          0 :             nRet = HTML_LINEFEEDCHAR; // !!! should be FORMFEEDCHAR
    1362                 :          0 :             break;
    1363                 :            : 
    1364                 :            :         case '\n':
    1365                 :            :         case '\r':
    1366 [ +  - ][ +  - ]:         50 :             if( bReadListing || bReadXMP || bReadPRE || bReadTextArea )
         [ +  - ][ -  + ]
    1367                 :            :             {
    1368                 :          0 :                 sal_Unicode c = GetNextChar();
    1369 [ #  # ][ #  # ]:          0 :                 if( ( '\n' != nNextCh || '\r' != c ) &&
         [ #  # ][ #  # ]
    1370                 :            :                     ( '\r' != nNextCh || '\n' != c ) )
    1371                 :            :                 {
    1372                 :          0 :                     bNextCh = false;
    1373                 :          0 :                     nNextCh = c;
    1374                 :            :                 }
    1375                 :          0 :                 nRet = HTML_NEWPARA;
    1376                 :          0 :                 break;
    1377                 :            :             }
    1378                 :            :             // no break !
    1379                 :            :         case '\t':
    1380         [ -  + ]:         50 :             if( bReadPRE )
    1381                 :            :             {
    1382                 :          0 :                 nRet = HTML_TABCHAR;
    1383                 :          0 :                 break;
    1384                 :            :             }
    1385                 :            :             // no break !
    1386                 :            :         case ' ':
    1387                 :            :             // no break !
    1388                 :            :         default:
    1389                 :            : 
    1390                 :            : scan_text:
    1391                 :            :             // "normal" text to come
    1392                 :         68 :             nRet = ScanText();
    1393                 :         68 :             bNextCh = 0 == aToken.Len();
    1394                 :            : 
    1395                 :            :             // the text should be processed
    1396 [ -  + ][ +  + ]:         68 :             if( !bNextCh && eState == SVPAR_PENDING )
    1397                 :            :             {
    1398                 :          0 :                 eState = SVPAR_WORKING;
    1399                 :          0 :                 bReadNextChar = true;
    1400                 :            :             }
    1401                 :            : 
    1402                 :         68 :             break;
    1403                 :            :         }
    1404                 :            : 
    1405 [ +  + ][ +  + ]:        173 :         if( bNextCh && SVPAR_WORKING == eState )
    1406                 :            :         {
    1407                 :        103 :             nNextCh = GetNextChar();
    1408 [ #  # ][ #  # ]:        103 :             if( SVPAR_PENDING == eState && nRet && HTML_TEXTTOKEN != nRet )
                 [ -  + ]
    1409                 :            :             {
    1410                 :          0 :                 bReadNextChar = true;
    1411                 :          0 :                 eState = SVPAR_WORKING;
    1412                 :            :             }
    1413                 :            :         }
    1414                 :            : 
    1415                 :            :     } while( !nRet && SVPAR_WORKING == eState );
    1416                 :            : 
    1417         [ -  + ]:        170 :     if( SVPAR_PENDING == eState )
    1418                 :          0 :         nRet = -1;      // s.th. invalid
    1419                 :            : 
    1420                 :        170 :     return nRet;
    1421                 :            : }
    1422                 :            : 
    1423                 :          0 : void HTMLParser::UnescapeToken()
    1424                 :            : {
    1425                 :          0 :     xub_StrLen nPos=0;
    1426                 :            : 
    1427                 :          0 :     bool bEscape = false;
    1428         [ #  # ]:          0 :     while( nPos < aToken.Len() )
    1429                 :            :     {
    1430                 :          0 :         bool bOldEscape = bEscape;
    1431                 :          0 :         bEscape = false;
    1432 [ #  # ][ #  # ]:          0 :         if( '\\'==aToken.GetChar(nPos) && !bOldEscape )
                 [ #  # ]
    1433                 :            :         {
    1434                 :          0 :             aToken.Erase( nPos, 1 );
    1435                 :          0 :             bEscape = true;
    1436                 :            :         }
    1437                 :            :         else
    1438                 :            :         {
    1439                 :          0 :             nPos++;
    1440                 :            :         }
    1441                 :            :     }
    1442                 :          0 : }
    1443                 :            : 
    1444                 :         73 : const HTMLOptions& HTMLParser::GetOptions( sal_uInt16 *pNoConvertToken ) const
    1445                 :            : {
    1446                 :            :     // If the options for the current token have already been returned,
    1447                 :            :     // return them once again.
    1448         [ +  + ]:         73 :     if (!maOptions.empty())
    1449                 :          4 :         return maOptions;
    1450                 :            : 
    1451                 :         69 :     xub_StrLen nPos = 0;
    1452         [ +  + ]:         99 :     while( nPos < aToken.Len() )
    1453                 :            :     {
    1454                 :            :         // A letter? Option beginning here.
    1455         [ +  + ]:         30 :         if( HTML_ISALPHA( aToken.GetChar(nPos) ) )
    1456                 :            :         {
    1457                 :            :             int nToken;
    1458         [ +  - ]:         20 :             String aValue;
    1459                 :         20 :             xub_StrLen nStt = nPos;
    1460                 :         20 :             sal_Unicode cChar = 0;
    1461                 :            : 
    1462                 :            :             // Actually only certain characters allowed.
    1463                 :            :             // Netscape only looks for "=" and white space (c.f.
    1464                 :            :             // Mozilla: PA_FetchRequestedNameValues in lipparse/pa_mdl.c)
    1465 [ +  - ][ +  + ]:        248 :             while( nPos < aToken.Len() && '=' != (cChar=aToken.GetChar(nPos)) &&
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
    1466 [ +  - ][ +  - ]:        114 :                    HTML_ISPRINTABLE(cChar) && !HTML_ISSPACE(cChar) )
    1467                 :        114 :                 nPos++;
    1468                 :            : 
    1469         [ +  - ]:         20 :             String sName( aToken.Copy( nStt, nPos-nStt ) );
    1470                 :            : 
    1471                 :            :             // PlugIns require original token name. Convert to upper case only for searching.
    1472         [ +  - ]:         20 :             String sNameUpperCase( sName );
    1473         [ +  - ]:         20 :             sNameUpperCase.ToUpperAscii();
    1474                 :            : 
    1475         [ +  - ]:         20 :             nToken = GetHTMLOption( sNameUpperCase ); // Name is ready
    1476                 :            :             DBG_ASSERTWARNING( nToken!=HTML_O_UNKNOWN,
    1477                 :            :                         "GetOption: unknown HTML option" );
    1478                 :            :             bool bStripCRLF = (nToken < HTML_OPTION_SCRIPT_START ||
    1479                 :            :                                nToken >= HTML_OPTION_SCRIPT_END) &&
    1480 [ -  + ][ #  # ]:         20 :                               (!pNoConvertToken || nToken != *pNoConvertToken);
         [ +  + ][ +  + ]
    1481                 :            : 
    1482 [ +  - ][ +  - ]:         40 :             while( nPos < aToken.Len() &&
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
    1483         [ +  - ]:         20 :                    ( !HTML_ISPRINTABLE( (cChar=aToken.GetChar(nPos)) ) ||
    1484                 :            :                      HTML_ISSPACE(cChar) ) )
    1485                 :          0 :                 nPos++;
    1486                 :            : 
    1487                 :            :             // Option with value?
    1488 [ +  - ][ +  - ]:         20 :             if( nPos!=aToken.Len() && '='==cChar )
                 [ +  - ]
    1489                 :            :             {
    1490                 :         20 :                 nPos++;
    1491                 :            : 
    1492 [ +  - ][ +  - ]:         40 :                 while( nPos < aToken.Len() &&
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
                 [ -  + ]
    1493         [ +  - ]:         20 :                         ( !HTML_ISPRINTABLE( (cChar=aToken.GetChar(nPos)) ) ||
    1494                 :            :                           ' '==cChar || '\t'==cChar || '\r'==cChar || '\n'==cChar ) )
    1495                 :          0 :                     nPos++;
    1496                 :            : 
    1497         [ +  - ]:         20 :                 if( nPos != aToken.Len() )
    1498                 :            :                 {
    1499                 :         20 :                     xub_StrLen nLen = 0;
    1500                 :         20 :                     nStt = nPos;
    1501 [ -  + ][ #  # ]:         20 :                     if( ('"'==cChar) || ('\'')==cChar )
    1502                 :            :                     {
    1503                 :         20 :                         sal_Unicode cEnd = cChar;
    1504                 :         20 :                         nPos++; nStt++;
    1505                 :         20 :                         bool bDone = false;
    1506                 :         20 :                         bool bEscape = false;
    1507 [ +  - ][ +  + ]:        262 :                         while( nPos < aToken.Len() && !bDone )
                 [ +  + ]
    1508                 :            :                         {
    1509                 :        242 :                             bool bOldEscape = bEscape;
    1510                 :        242 :                             bEscape = false;
    1511                 :        242 :                             cChar = aToken.GetChar(nPos);
    1512   [ -  -  +  + ]:        242 :                             switch( cChar )
    1513                 :            :                             {
    1514                 :            :                             case '\r':
    1515                 :            :                             case '\n':
    1516         [ #  # ]:          0 :                                 if( bStripCRLF )
    1517         [ #  # ]:          0 :                                     ((String &)aToken).Erase( nPos, 1 );
    1518                 :            :                                 else
    1519                 :          0 :                                     nPos++, nLen++;
    1520                 :          0 :                                 break;
    1521                 :            :                             case '\\':
    1522         [ #  # ]:          0 :                                 if( bOldEscape )
    1523                 :            :                                 {
    1524                 :          0 :                                     nPos++, nLen++;
    1525                 :            :                                 }
    1526                 :            :                                 else
    1527                 :            :                                 {
    1528         [ #  # ]:          0 :                                     ((String &)aToken).Erase( nPos, 1 );
    1529                 :          0 :                                     bEscape = true;
    1530                 :            :                                 }
    1531                 :          0 :                                 break;
    1532                 :            :                             case '"':
    1533                 :            :                             case '\'':
    1534 [ +  - ][ +  - ]:         20 :                                 bDone = !bOldEscape && cChar==cEnd;
    1535         [ -  + ]:         20 :                                 if( !bDone )
    1536                 :          0 :                                     nPos++, nLen++;
    1537                 :         20 :                                 break;
    1538                 :            :                             default:
    1539                 :        222 :                                 nPos++, nLen++;
    1540                 :        222 :                                 break;
    1541                 :            :                             }
    1542                 :            :                         }
    1543         [ +  - ]:         20 :                         if( nPos!=aToken.Len() )
    1544                 :         20 :                             nPos++;
    1545                 :            :                     }
    1546                 :            :                     else
    1547                 :            :                     {
    1548                 :            :                         // More liberal than the standard: allow all printable characters
    1549                 :          0 :                         bool bEscape = false;
    1550                 :          0 :                         bool bDone = false;
    1551 [ #  # ][ #  # ]:          0 :                         while( nPos < aToken.Len() && !bDone )
                 [ #  # ]
    1552                 :            :                         {
    1553                 :          0 :                             bool bOldEscape = bEscape;
    1554                 :          0 :                             bEscape = false;
    1555                 :          0 :                             sal_Unicode c = aToken.GetChar(nPos);
    1556   [ #  #  #  # ]:          0 :                             switch( c )
    1557                 :            :                             {
    1558                 :            :                             case ' ':
    1559                 :          0 :                                 bDone = !bOldEscape;
    1560         [ #  # ]:          0 :                                 if( !bDone )
    1561                 :          0 :                                     nPos++, nLen++;
    1562                 :          0 :                                 break;
    1563                 :            : 
    1564                 :            :                             case '\t':
    1565                 :            :                             case '\r':
    1566                 :            :                             case '\n':
    1567                 :          0 :                                 bDone = true;
    1568                 :          0 :                                 break;
    1569                 :            : 
    1570                 :            :                             case '\\':
    1571         [ #  # ]:          0 :                                 if( bOldEscape )
    1572                 :            :                                 {
    1573                 :          0 :                                     nPos++, nLen++;
    1574                 :            :                                 }
    1575                 :            :                                 else
    1576                 :            :                                 {
    1577         [ #  # ]:          0 :                                     ((String &)aToken).Erase( nPos, 1 );
    1578                 :          0 :                                     bEscape = true;
    1579                 :            :                                 }
    1580                 :          0 :                                 break;
    1581                 :            : 
    1582                 :            :                             default:
    1583 [ #  # ][ #  # ]:          0 :                                 if( HTML_ISPRINTABLE( c ) )
    1584                 :          0 :                                     nPos++, nLen++;
    1585                 :            :                                 else
    1586                 :          0 :                                     bDone = true;
    1587                 :          0 :                                 break;
    1588                 :            :                             }
    1589                 :            :                         }
    1590                 :            :                     }
    1591                 :            : 
    1592         [ +  - ]:         20 :                     if( nLen )
    1593 [ +  - ][ +  - ]:         20 :                         aValue = aToken.Copy( nStt, nLen );
                 [ +  - ]
    1594                 :            :                 }
    1595                 :            :             }
    1596                 :            : 
    1597                 :            :             // Token is known and can be saved
    1598                 :            :             std::auto_ptr<HTMLOption> pOption(
    1599 [ +  - ][ +  - ]:         20 :                 new HTMLOption(sal::static_int_cast<sal_uInt16>(nToken), sName, aValue));
    1600                 :            : 
    1601 [ +  - ][ +  - ]:         20 :             maOptions.push_back(pOption);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1602                 :            : 
    1603                 :            :         }
    1604                 :            :         else
    1605                 :            :             // Ignore white space and unexpected characters
    1606                 :         10 :             nPos++;
    1607                 :            :     }
    1608                 :            : 
    1609                 :         73 :     return maOptions;
    1610                 :            : }
    1611                 :            : 
    1612                 :          0 : int HTMLParser::FilterPRE( int nToken )
    1613                 :            : {
    1614   [ #  #  #  #  :          0 :     switch( nToken )
                   #  # ]
    1615                 :            :     {
    1616                 :            : #ifdef HTML_BEHAVIOUR
    1617                 :            :     // These become LFs according to the definition
    1618                 :            :     case HTML_PARABREAK_ON:
    1619                 :            :     case HTML_LINEBREAK:
    1620                 :            :         nToken = HTML_NEWPARA;
    1621                 :            : #else
    1622                 :            :     // in Netscape they only have impact in not empty paragraphs
    1623                 :            :     case HTML_PARABREAK_ON:
    1624                 :          0 :         nToken = HTML_LINEBREAK;
    1625                 :            :     case HTML_LINEBREAK:
    1626                 :            : #endif
    1627                 :            :     case HTML_NEWPARA:
    1628                 :          0 :         nPre_LinePos = 0;
    1629         [ #  # ]:          0 :         if( bPre_IgnoreNewPara )
    1630                 :          0 :             nToken = 0;
    1631                 :          0 :         break;
    1632                 :            : 
    1633                 :            :     case HTML_TABCHAR:
    1634                 :            :         {
    1635                 :            :             xub_StrLen nSpaces = sal::static_int_cast< xub_StrLen >(
    1636                 :          0 :                 8 - (nPre_LinePos % 8));
    1637                 :            :             DBG_ASSERT( !aToken.Len(), "Why is the token not empty?" );
    1638                 :          0 :             aToken.Expand( nSpaces, ' ' );
    1639                 :          0 :             nPre_LinePos += nSpaces;
    1640                 :          0 :             nToken = HTML_TEXTTOKEN;
    1641                 :            :         }
    1642                 :          0 :         break;
    1643                 :            :     // Keep those
    1644                 :            :     case HTML_TEXTTOKEN:
    1645                 :          0 :         nPre_LinePos += aToken.Len();
    1646                 :          0 :         break;
    1647                 :            : 
    1648                 :            :     case HTML_SELECT_ON:
    1649                 :            :     case HTML_SELECT_OFF:
    1650                 :            :     case HTML_BODY_ON:
    1651                 :            :     case HTML_FORM_ON:
    1652                 :            :     case HTML_FORM_OFF:
    1653                 :            :     case HTML_INPUT:
    1654                 :            :     case HTML_OPTION:
    1655                 :            :     case HTML_TEXTAREA_ON:
    1656                 :            :     case HTML_TEXTAREA_OFF:
    1657                 :            : 
    1658                 :            :     case HTML_IMAGE:
    1659                 :            :     case HTML_APPLET_ON:
    1660                 :            :     case HTML_APPLET_OFF:
    1661                 :            :     case HTML_PARAM:
    1662                 :            :     case HTML_EMBED:
    1663                 :            : 
    1664                 :            :     case HTML_HEAD1_ON:
    1665                 :            :     case HTML_HEAD1_OFF:
    1666                 :            :     case HTML_HEAD2_ON:
    1667                 :            :     case HTML_HEAD2_OFF:
    1668                 :            :     case HTML_HEAD3_ON:
    1669                 :            :     case HTML_HEAD3_OFF:
    1670                 :            :     case HTML_HEAD4_ON:
    1671                 :            :     case HTML_HEAD4_OFF:
    1672                 :            :     case HTML_HEAD5_ON:
    1673                 :            :     case HTML_HEAD5_OFF:
    1674                 :            :     case HTML_HEAD6_ON:
    1675                 :            :     case HTML_HEAD6_OFF:
    1676                 :            :     case HTML_BLOCKQUOTE_ON:
    1677                 :            :     case HTML_BLOCKQUOTE_OFF:
    1678                 :            :     case HTML_ADDRESS_ON:
    1679                 :            :     case HTML_ADDRESS_OFF:
    1680                 :            :     case HTML_HORZRULE:
    1681                 :            : 
    1682                 :            :     case HTML_CENTER_ON:
    1683                 :            :     case HTML_CENTER_OFF:
    1684                 :            :     case HTML_DIVISION_ON:
    1685                 :            :     case HTML_DIVISION_OFF:
    1686                 :            : 
    1687                 :            :     case HTML_SCRIPT_ON:
    1688                 :            :     case HTML_SCRIPT_OFF:
    1689                 :            :     case HTML_RAWDATA:
    1690                 :            : 
    1691                 :            :     case HTML_TABLE_ON:
    1692                 :            :     case HTML_TABLE_OFF:
    1693                 :            :     case HTML_CAPTION_ON:
    1694                 :            :     case HTML_CAPTION_OFF:
    1695                 :            :     case HTML_COLGROUP_ON:
    1696                 :            :     case HTML_COLGROUP_OFF:
    1697                 :            :     case HTML_COL_ON:
    1698                 :            :     case HTML_COL_OFF:
    1699                 :            :     case HTML_THEAD_ON:
    1700                 :            :     case HTML_THEAD_OFF:
    1701                 :            :     case HTML_TFOOT_ON:
    1702                 :            :     case HTML_TFOOT_OFF:
    1703                 :            :     case HTML_TBODY_ON:
    1704                 :            :     case HTML_TBODY_OFF:
    1705                 :            :     case HTML_TABLEROW_ON:
    1706                 :            :     case HTML_TABLEROW_OFF:
    1707                 :            :     case HTML_TABLEDATA_ON:
    1708                 :            :     case HTML_TABLEDATA_OFF:
    1709                 :            :     case HTML_TABLEHEADER_ON:
    1710                 :            :     case HTML_TABLEHEADER_OFF:
    1711                 :            : 
    1712                 :            :     case HTML_ANCHOR_ON:
    1713                 :            :     case HTML_ANCHOR_OFF:
    1714                 :            :     case HTML_BOLD_ON:
    1715                 :            :     case HTML_BOLD_OFF:
    1716                 :            :     case HTML_ITALIC_ON:
    1717                 :            :     case HTML_ITALIC_OFF:
    1718                 :            :     case HTML_STRIKE_ON:
    1719                 :            :     case HTML_STRIKE_OFF:
    1720                 :            :     case HTML_STRIKETHROUGH_ON:
    1721                 :            :     case HTML_STRIKETHROUGH_OFF:
    1722                 :            :     case HTML_UNDERLINE_ON:
    1723                 :            :     case HTML_UNDERLINE_OFF:
    1724                 :            :     case HTML_BASEFONT_ON:
    1725                 :            :     case HTML_BASEFONT_OFF:
    1726                 :            :     case HTML_FONT_ON:
    1727                 :            :     case HTML_FONT_OFF:
    1728                 :            :     case HTML_BLINK_ON:
    1729                 :            :     case HTML_BLINK_OFF:
    1730                 :            :     case HTML_SPAN_ON:
    1731                 :            :     case HTML_SPAN_OFF:
    1732                 :            :     case HTML_SUBSCRIPT_ON:
    1733                 :            :     case HTML_SUBSCRIPT_OFF:
    1734                 :            :     case HTML_SUPERSCRIPT_ON:
    1735                 :            :     case HTML_SUPERSCRIPT_OFF:
    1736                 :            :     case HTML_BIGPRINT_ON:
    1737                 :            :     case HTML_BIGPRINT_OFF:
    1738                 :            :     case HTML_SMALLPRINT_OFF:
    1739                 :            :     case HTML_SMALLPRINT_ON:
    1740                 :            : 
    1741                 :            :     case HTML_EMPHASIS_ON:
    1742                 :            :     case HTML_EMPHASIS_OFF:
    1743                 :            :     case HTML_CITIATION_ON:
    1744                 :            :     case HTML_CITIATION_OFF:
    1745                 :            :     case HTML_STRONG_ON:
    1746                 :            :     case HTML_STRONG_OFF:
    1747                 :            :     case HTML_CODE_ON:
    1748                 :            :     case HTML_CODE_OFF:
    1749                 :            :     case HTML_SAMPLE_ON:
    1750                 :            :     case HTML_SAMPLE_OFF:
    1751                 :            :     case HTML_KEYBOARD_ON:
    1752                 :            :     case HTML_KEYBOARD_OFF:
    1753                 :            :     case HTML_VARIABLE_ON:
    1754                 :            :     case HTML_VARIABLE_OFF:
    1755                 :            :     case HTML_DEFINSTANCE_ON:
    1756                 :            :     case HTML_DEFINSTANCE_OFF:
    1757                 :            :     case HTML_SHORTQUOTE_ON:
    1758                 :            :     case HTML_SHORTQUOTE_OFF:
    1759                 :            :     case HTML_LANGUAGE_ON:
    1760                 :            :     case HTML_LANGUAGE_OFF:
    1761                 :            :     case HTML_AUTHOR_ON:
    1762                 :            :     case HTML_AUTHOR_OFF:
    1763                 :            :     case HTML_PERSON_ON:
    1764                 :            :     case HTML_PERSON_OFF:
    1765                 :            :     case HTML_ACRONYM_ON:
    1766                 :            :     case HTML_ACRONYM_OFF:
    1767                 :            :     case HTML_ABBREVIATION_ON:
    1768                 :            :     case HTML_ABBREVIATION_OFF:
    1769                 :            :     case HTML_INSERTEDTEXT_ON:
    1770                 :            :     case HTML_INSERTEDTEXT_OFF:
    1771                 :            :     case HTML_DELETEDTEXT_ON:
    1772                 :            :     case HTML_DELETEDTEXT_OFF:
    1773                 :            :     case HTML_TELETYPE_ON:
    1774                 :            :     case HTML_TELETYPE_OFF:
    1775                 :            : 
    1776                 :          0 :         break;
    1777                 :            : 
    1778                 :            :     // The remainder is treated as an unknown token.
    1779                 :            :     default:
    1780         [ #  # ]:          0 :         if( nToken )
    1781                 :            :         {
    1782                 :            :             nToken =
    1783                 :            :                 ( ((HTML_TOKEN_ONOFF & nToken) && (1 & nToken))
    1784                 :            :                     ? HTML_UNKNOWNCONTROL_OFF
    1785 [ #  # ][ #  # ]:          0 :                     : HTML_UNKNOWNCONTROL_ON );
    1786                 :            :         }
    1787                 :          0 :         break;
    1788                 :            :     }
    1789                 :            : 
    1790                 :          0 :     bPre_IgnoreNewPara = false;
    1791                 :            : 
    1792                 :          0 :     return nToken;
    1793                 :            : }
    1794                 :            : 
    1795                 :          0 : int HTMLParser::FilterXMP( int nToken )
    1796                 :            : {
    1797      [ #  #  # ]:          0 :     switch( nToken )
    1798                 :            :     {
    1799                 :            :     case HTML_NEWPARA:
    1800         [ #  # ]:          0 :         if( bPre_IgnoreNewPara )
    1801                 :          0 :             nToken = 0;
    1802                 :            :     case HTML_TEXTTOKEN:
    1803                 :            :     case HTML_NONBREAKSPACE:
    1804                 :            :     case HTML_SOFTHYPH:
    1805                 :          0 :         break;              // kept
    1806                 :            : 
    1807                 :            :     default:
    1808         [ #  # ]:          0 :         if( nToken )
    1809                 :            :         {
    1810 [ #  # ][ #  # ]:          0 :             if( (HTML_TOKEN_ONOFF & nToken) && (1 & nToken) )
    1811                 :            :             {
    1812                 :          0 :                 sSaveToken.Insert( '<', 0 );
    1813                 :          0 :                 sSaveToken.Insert( '/', 1 );
    1814                 :            :             }
    1815                 :            :             else
    1816                 :          0 :                 sSaveToken.Insert( '<', 0 );
    1817         [ #  # ]:          0 :             if( aToken.Len() )
    1818                 :            :             {
    1819                 :          0 :                 UnescapeToken();
    1820                 :          0 :                 sSaveToken += (sal_Unicode)' ';
    1821                 :          0 :                 aToken.Insert( sSaveToken, 0 );
    1822                 :            :             }
    1823                 :            :             else
    1824                 :          0 :                 aToken = sSaveToken;
    1825                 :          0 :             aToken += (sal_Unicode)'>';
    1826                 :          0 :             nToken = HTML_TEXTTOKEN;
    1827                 :            :         }
    1828                 :          0 :         break;
    1829                 :            :     }
    1830                 :            : 
    1831                 :          0 :     bPre_IgnoreNewPara = false;
    1832                 :            : 
    1833                 :          0 :     return nToken;
    1834                 :            : }
    1835                 :            : 
    1836                 :          0 : int HTMLParser::FilterListing( int nToken )
    1837                 :            : {
    1838      [ #  #  # ]:          0 :     switch( nToken )
    1839                 :            :     {
    1840                 :            :     case HTML_NEWPARA:
    1841         [ #  # ]:          0 :         if( bPre_IgnoreNewPara )
    1842                 :          0 :             nToken = 0;
    1843                 :            :     case HTML_TEXTTOKEN:
    1844                 :            :     case HTML_NONBREAKSPACE:
    1845                 :            :     case HTML_SOFTHYPH:
    1846                 :          0 :         break;      // kept
    1847                 :            : 
    1848                 :            :     default:
    1849         [ #  # ]:          0 :         if( nToken )
    1850                 :            :         {
    1851                 :            :             nToken =
    1852                 :            :                 ( ((HTML_TOKEN_ONOFF & nToken) && (1 & nToken))
    1853                 :            :                     ? HTML_UNKNOWNCONTROL_OFF
    1854 [ #  # ][ #  # ]:          0 :                     : HTML_UNKNOWNCONTROL_ON );
    1855                 :            :         }
    1856                 :          0 :         break;
    1857                 :            :     }
    1858                 :            : 
    1859                 :          0 :     bPre_IgnoreNewPara = false;
    1860                 :            : 
    1861                 :          0 :     return nToken;
    1862                 :            : }
    1863                 :            : 
    1864                 :          2 : bool HTMLParser::IsHTMLFormat( const sal_Char* pHeader,
    1865                 :            :                                bool bSwitchToUCS2,
    1866                 :            :                                rtl_TextEncoding eEnc )
    1867                 :            : {
    1868                 :            :     // If the string matches one of the following regular expressions then
    1869                 :            :     // the document is a HTML document.
    1870                 :            :     //
    1871                 :            :     // ^[^<]*<[^ \t]*[> \t]
    1872                 :            :     //        -------
    1873                 :            :     // ^<!
    1874                 :            :     //
    1875                 :            :     // where the underlined subexpression has to be a HTML token
    1876                 :          2 :     rtl::OString sCmp;
    1877                 :          2 :     bool bUCS2B = false;
    1878         [ +  - ]:          2 :     if( bSwitchToUCS2 )
    1879                 :            :     {
    1880 [ -  + ][ #  # ]:          2 :         if( 0xfeU == (sal_uChar)pHeader[0] &&
    1881                 :          0 :             0xffU == (sal_uChar)pHeader[1] )
    1882                 :            :         {
    1883                 :          0 :             eEnc = RTL_TEXTENCODING_UCS2;
    1884                 :          0 :             bUCS2B = true;
    1885                 :            :         }
    1886 [ -  + ][ #  # ]:          2 :         else if( 0xffU == (sal_uChar)pHeader[0] &&
    1887                 :          0 :                  0xfeU == (sal_uChar)pHeader[1] )
    1888                 :            :         {
    1889                 :          2 :             eEnc = RTL_TEXTENCODING_UCS2;
    1890                 :            :         }
    1891                 :            :     }
    1892 [ -  + ][ #  # ]:          2 :     if
         [ #  # ][ #  # ]
                 [ #  # ]
    1893                 :            :        (
    1894                 :            :         RTL_TEXTENCODING_UCS2 == eEnc &&
    1895                 :            :         (
    1896                 :          0 :          (0xfe == (sal_uChar)pHeader[0] && 0xff == (sal_uChar)pHeader[1]) ||
    1897                 :          0 :          (0xff == (sal_uChar)pHeader[0] && 0xfe == (sal_uChar)pHeader[1])
    1898                 :            :         )
    1899                 :            :        )
    1900                 :            :     {
    1901         [ #  # ]:          0 :         if( 0xfe == (sal_uChar)pHeader[0] )
    1902                 :          0 :             bUCS2B = true;
    1903                 :            : 
    1904                 :            :         xub_StrLen nLen;
    1905 [ #  # ][ #  # ]:          0 :         for( nLen = 2;
                 [ #  # ]
    1906                 :          0 :              pHeader[nLen] != 0 || pHeader[nLen+1] != 0;
    1907                 :            :              nLen+=2 )
    1908                 :            :             ;
    1909                 :            : 
    1910                 :          0 :         ::rtl::OStringBuffer sTmp( (nLen - 2)/2 );
    1911         [ #  # ]:          0 :         for( xub_StrLen nPos = 2; nPos < nLen; nPos += 2 )
    1912                 :            :         {
    1913                 :            :             sal_Unicode cUC;
    1914         [ #  # ]:          0 :             if( bUCS2B )
    1915                 :          0 :                 cUC = (sal_Unicode(pHeader[nPos]) << 8) | pHeader[nPos+1];
    1916                 :            :             else
    1917                 :          0 :                 cUC = (sal_Unicode(pHeader[nPos+1]) << 8) | pHeader[nPos];
    1918         [ #  # ]:          0 :             if( 0U == cUC )
    1919                 :          0 :                 break;
    1920                 :            : 
    1921 [ #  # ][ #  # ]:          0 :             sTmp.append( cUC < 256U ? (sal_Char)cUC : '.' );
    1922                 :            :         }
    1923                 :          0 :         sCmp = sTmp.makeStringAndClear();
    1924                 :            :     }
    1925                 :            :     else
    1926                 :            :     {
    1927                 :          2 :         sCmp = pHeader;
    1928                 :            :     }
    1929                 :            : 
    1930                 :          2 :     sCmp = sCmp.toAsciiUpperCase();
    1931                 :            : 
    1932                 :            :     // A HTML document must have a '<' in the first line
    1933                 :          2 :     sal_Int32 nStart = sCmp.indexOf('<');
    1934         [ -  + ]:          2 :     if (nStart == -1)
    1935                 :          0 :         return false;
    1936                 :          2 :     nStart++;
    1937                 :            : 
    1938                 :            :     // followed by arbitrary characters followed by a blank or '>'
    1939                 :            :     sal_Char c;
    1940                 :            :     sal_Int32 nPos;
    1941         [ +  - ]:         18 :     for( nPos = nStart; nPos < sCmp.getLength(); ++nPos )
    1942                 :            :     {
    1943 [ +  - ][ +  + ]:         18 :         if( '>'==(c=sCmp[nPos]) || HTML_ISSPACE(c) )
         [ +  - ][ -  + ]
                 [ +  + ]
    1944                 :          2 :             break;
    1945                 :            :     }
    1946                 :            : 
    1947                 :            :     // If the document ends after < it's no HTML
    1948         [ -  + ]:          2 :     if( nPos==nStart )
    1949                 :          0 :         return false;
    1950                 :            : 
    1951                 :            :     // the string following '<' has to be a known HTML token.
    1952                 :            :     // <DIR> is not interpreted as HTML. Otherwise the output of the DOS command "DIR"
    1953                 :            :     // could be interpreted as HTML.
    1954         [ +  - ]:          2 :     rtl::OUString sTest(rtl::OStringToOUString(sCmp.copy(nStart, nPos-nStart), RTL_TEXTENCODING_ASCII_US));
    1955 [ +  - ][ +  - ]:          2 :     int nTok = GetHTMLToken( sTest );
                 [ +  - ]
    1956 [ +  - ][ +  - ]:          2 :     if( 0 != nTok && HTML_DIRLIST_ON != nTok )
    1957                 :          2 :         return true;
    1958                 :            : 
    1959                 :            :     // "<!" at the very beginning of the file?
    1960 [ #  # ][ #  # ]:          0 :     if( nStart == 1 && '!' == sCmp[1] )
                 [ #  # ]
    1961                 :          0 :         return true;
    1962                 :            : 
    1963                 :            :     // <HTML> somewhere in the first 80 characters of the document
    1964                 :          0 :     nStart = sCmp.indexOfL(RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_html));
    1965   [ #  #  #  #  :          0 :     if( nStart>0 && '<'==sCmp[nStart-1] &&
           #  # ][ #  # ]
                 [ #  # ]
    1966                 :          0 :         nStart+4 < sCmp.getLength() && '>'==sCmp[nStart+4] )
    1967                 :          0 :         return true;
    1968                 :            : 
    1969                 :            :     // Else it's rather not a HTML document
    1970                 :          2 :     return false;
    1971                 :            : }
    1972                 :            : 
    1973                 :          0 : bool HTMLParser::InternalImgToPrivateURL( String& rURL )
    1974                 :            : {
    1975         [ #  # ]:          0 :     if( rURL.Len() < 19 || 'i' != rURL.GetChar(0) ||
           [ #  #  #  # ]
                 [ #  # ]
    1976                 :          0 :         rURL.CompareToAscii( OOO_STRING_SVTOOLS_HTML_internal_gopher, 9 ) != COMPARE_EQUAL )
    1977                 :          0 :         return false;
    1978                 :            : 
    1979                 :          0 :     bool bFound = false;
    1980                 :            : 
    1981         [ #  # ]:          0 :     if( rURL.CompareToAscii( OOO_STRING_SVTOOLS_HTML_internal_gopher,16) == COMPARE_EQUAL )
    1982                 :            :     {
    1983         [ #  # ]:          0 :         String aName( rURL.Copy(16) );
    1984   [ #  #  #  #  :          0 :         switch( aName.GetChar(0) )
                #  #  # ]
    1985                 :            :         {
    1986                 :            :         case 'b':
    1987         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_binary );
    1988                 :          0 :             break;
    1989                 :            :         case 'i':
    1990         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_image ) ||
    1991 [ #  # ][ #  # ]:          0 :                      aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_index );
                 [ #  # ]
    1992                 :          0 :             break;
    1993                 :            :         case 'm':
    1994         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_menu ) ||
    1995 [ #  # ][ #  # ]:          0 :                      aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_movie );
                 [ #  # ]
    1996                 :          0 :             break;
    1997                 :            :         case 's':
    1998         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_sound );
    1999                 :          0 :             break;
    2000                 :            :         case 't':
    2001         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_telnet ) ||
    2002 [ #  # ][ #  # ]:          0 :                      aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_text );
                 [ #  # ]
    2003                 :          0 :             break;
    2004                 :            :         case 'u':
    2005         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_GOPHER_unknown );
    2006                 :          0 :             break;
    2007         [ #  # ]:          0 :         }
    2008                 :            :     }
    2009         [ #  # ]:          0 :     else if( rURL.CompareToAscii( OOO_STRING_SVTOOLS_HTML_internal_icon,14) == COMPARE_EQUAL )
    2010                 :            :     {
    2011         [ #  # ]:          0 :         String aName( rURL.Copy(14) );
    2012   [ #  #  #  #  :          0 :         switch( aName.GetChar(0) )
                   #  # ]
    2013                 :            :         {
    2014                 :            :         case 'b':
    2015         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_baddata );
    2016                 :          0 :             break;
    2017                 :            :         case 'd':
    2018         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_delayed );
    2019                 :          0 :             break;
    2020                 :            :         case 'e':
    2021         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_embed );
    2022                 :          0 :             break;
    2023                 :            :         case 'i':
    2024         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_insecure );
    2025                 :          0 :             break;
    2026                 :            :         case 'n':
    2027         [ #  # ]:          0 :             bFound = aName.EqualsAscii( OOO_STRING_SVTOOLS_HTML_INT_ICON_notfound );
    2028                 :          0 :             break;
    2029         [ #  # ]:          0 :         }
    2030                 :            :     }
    2031         [ #  # ]:          0 :     if( bFound )
    2032                 :            :     {
    2033         [ #  # ]:          0 :         String sTmp ( rURL );
    2034         [ #  # ]:          0 :         rURL.AssignAscii( OOO_STRING_SVTOOLS_HTML_private_image );
    2035 [ #  # ][ #  # ]:          0 :         rURL.Append( sTmp );
    2036                 :            :     }
    2037                 :            : 
    2038                 :          0 :     return bFound;
    2039                 :            : }
    2040                 :            : 
    2041                 :            : enum eHtmlMetas {
    2042                 :            :     HTML_META_NONE = 0,
    2043                 :            :     HTML_META_AUTHOR,
    2044                 :            :     HTML_META_DESCRIPTION,
    2045                 :            :     HTML_META_KEYWORDS,
    2046                 :            :     HTML_META_REFRESH,
    2047                 :            :     HTML_META_CLASSIFICATION,
    2048                 :            :     HTML_META_CREATED,
    2049                 :            :     HTML_META_CHANGEDBY,
    2050                 :            :     HTML_META_CHANGED,
    2051                 :            :     HTML_META_GENERATOR,
    2052                 :            :     HTML_META_SDFOOTNOTE,
    2053                 :            :     HTML_META_SDENDNOTE,
    2054                 :            :     HTML_META_CONTENT_TYPE
    2055                 :            : };
    2056                 :            : 
    2057                 :            : // <META NAME=xxx>
    2058                 :            : static HTMLOptionEnum const aHTMLMetaNameTable[] =
    2059                 :            : {
    2060                 :            :     { OOO_STRING_SVTOOLS_HTML_META_author,        HTML_META_AUTHOR        },
    2061                 :            :     { OOO_STRING_SVTOOLS_HTML_META_changed,       HTML_META_CHANGED       },
    2062                 :            :     { OOO_STRING_SVTOOLS_HTML_META_changedby,     HTML_META_CHANGEDBY     },
    2063                 :            :     { OOO_STRING_SVTOOLS_HTML_META_classification,HTML_META_CLASSIFICATION},
    2064                 :            :     { OOO_STRING_SVTOOLS_HTML_META_content_type,  HTML_META_CONTENT_TYPE  },
    2065                 :            :     { OOO_STRING_SVTOOLS_HTML_META_created,       HTML_META_CREATED       },
    2066                 :            :     { OOO_STRING_SVTOOLS_HTML_META_description,   HTML_META_DESCRIPTION   },
    2067                 :            :     { OOO_STRING_SVTOOLS_HTML_META_keywords,      HTML_META_KEYWORDS      },
    2068                 :            :     { OOO_STRING_SVTOOLS_HTML_META_generator,     HTML_META_GENERATOR     },
    2069                 :            :     { OOO_STRING_SVTOOLS_HTML_META_refresh,       HTML_META_REFRESH       },
    2070                 :            :     { OOO_STRING_SVTOOLS_HTML_META_sdendnote,     HTML_META_SDENDNOTE     },
    2071                 :            :     { OOO_STRING_SVTOOLS_HTML_META_sdfootnote,    HTML_META_SDFOOTNOTE    },
    2072                 :            :     { 0,                                          0                       }
    2073                 :            : };
    2074                 :            : 
    2075                 :            : 
    2076                 :          0 : void HTMLParser::AddMetaUserDefined( ::rtl::OUString const & )
    2077                 :            : {
    2078                 :          0 : }
    2079                 :            : 
    2080                 :          8 : bool HTMLParser::ParseMetaOptionsImpl(
    2081                 :            :         const uno::Reference<document::XDocumentProperties> & i_xDocProps,
    2082                 :            :         SvKeyValueIterator *i_pHTTPHeader,
    2083                 :            :         const HTMLOptions& aOptions,
    2084                 :            :         rtl_TextEncoding& o_rEnc )
    2085                 :            : {
    2086 [ +  - ][ +  - ]:          8 :     String aName, aContent;
    2087                 :          8 :     sal_uInt16 nAction = HTML_META_NONE;
    2088                 :          8 :     bool bHTTPEquiv = false, bChanged = false;
    2089                 :            : 
    2090         [ +  + ]:         24 :     for ( size_t i = aOptions.size(); i; )
    2091                 :            :     {
    2092         [ +  - ]:         16 :         const HTMLOption& aOption = aOptions[--i];
    2093   [ +  +  +  - ]:         16 :         switch ( aOption.GetToken() )
    2094                 :            :         {
    2095                 :            :             case HTML_O_NAME:
    2096         [ +  - ]:          6 :                 aName = aOption.GetString();
    2097         [ +  - ]:          6 :                 if ( HTML_META_NONE==nAction )
    2098                 :            :                 {
    2099         [ +  - ]:          6 :                     aOption.GetEnum( nAction, aHTMLMetaNameTable );
    2100                 :            :                 }
    2101                 :          6 :                 break;
    2102                 :            :             case HTML_O_HTTPEQUIV:
    2103         [ +  - ]:          2 :                 aName = aOption.GetString();
    2104         [ +  - ]:          2 :                 aOption.GetEnum( nAction, aHTMLMetaNameTable );
    2105                 :          2 :                 bHTTPEquiv = true;
    2106                 :          2 :                 break;
    2107                 :            :             case HTML_O_CONTENT:
    2108         [ +  - ]:          8 :                 aContent = aOption.GetString();
    2109                 :          8 :                 break;
    2110                 :            :         }
    2111                 :            :     }
    2112                 :            : 
    2113 [ +  + ][ +  - ]:          8 :     if ( bHTTPEquiv || HTML_META_DESCRIPTION != nAction )
    2114                 :            :     {
    2115                 :            :         // if it is not a Description, remove CRs and LFs from CONTENT
    2116 [ +  - ][ +  - ]:          8 :         aContent = comphelper::string::remove(aContent, _CR);
    2117 [ +  - ][ +  - ]:          8 :         aContent = comphelper::string::remove(aContent, _LF);
    2118                 :            :     }
    2119                 :            :     else
    2120                 :            :     {
    2121                 :            :         // convert line endings for Description
    2122 [ #  # ][ #  # ]:          0 :         aContent = convertLineEnd(aContent, GetSystemLineEnd());
                 [ #  # ]
    2123                 :            :     }
    2124                 :            : 
    2125                 :            : 
    2126 [ +  + ][ +  - ]:          8 :     if ( bHTTPEquiv && i_pHTTPHeader )
    2127                 :            :     {
    2128                 :            :         // Netscape seems to just ignore a closing ", so we do too
    2129 [ +  - ][ -  + ]:          2 :         if ( aContent.Len() && '"' == aContent.GetChar( aContent.Len()-1 ) )
                 [ -  + ]
    2130                 :            :         {
    2131         [ #  # ]:          0 :             aContent.Erase( aContent.Len() - 1 );
    2132                 :            :         }
    2133         [ +  - ]:          2 :         SvKeyValue aKeyValue( aName, aContent );
    2134 [ +  - ][ +  - ]:          2 :         i_pHTTPHeader->Append( aKeyValue );
    2135                 :            :     }
    2136                 :            : 
    2137   [ -  -  -  -  :          8 :     switch ( nAction )
          -  +  -  +  -  
                      + ]
    2138                 :            :     {
    2139                 :            :         case HTML_META_AUTHOR:
    2140         [ #  # ]:          0 :             if (i_xDocProps.is()) {
    2141 [ #  # ][ #  # ]:          0 :                 i_xDocProps->setAuthor( aContent );
                 [ #  # ]
    2142                 :          0 :                 bChanged = true;
    2143                 :            :             }
    2144                 :          0 :             break;
    2145                 :            :         case HTML_META_DESCRIPTION:
    2146         [ #  # ]:          0 :             if (i_xDocProps.is()) {
    2147 [ #  # ][ #  # ]:          0 :                 i_xDocProps->setDescription( aContent );
                 [ #  # ]
    2148                 :          0 :                 bChanged = true;
    2149                 :            :             }
    2150                 :          0 :             break;
    2151                 :            :         case HTML_META_KEYWORDS:
    2152         [ #  # ]:          0 :             if (i_xDocProps.is()) {
    2153         [ #  # ]:          0 :                 i_xDocProps->setKeywords(
    2154 [ #  # ][ #  # ]:          0 :                     ::comphelper::string::convertCommaSeparated(aContent));
         [ #  # ][ #  # ]
    2155                 :          0 :                 bChanged = true;
    2156                 :            :             }
    2157                 :          0 :             break;
    2158                 :            :         case HTML_META_CLASSIFICATION:
    2159         [ #  # ]:          0 :             if (i_xDocProps.is()) {
    2160 [ #  # ][ #  # ]:          0 :                 i_xDocProps->setSubject( aContent );
                 [ #  # ]
    2161                 :          0 :                 bChanged = true;
    2162                 :            :             }
    2163                 :          0 :             break;
    2164                 :            : 
    2165                 :            :         case HTML_META_CHANGEDBY:
    2166         [ #  # ]:          0 :             if (i_xDocProps.is()) {
    2167 [ #  # ][ #  # ]:          0 :                 i_xDocProps->setModifiedBy( aContent );
                 [ #  # ]
    2168                 :            :             }
    2169                 :          0 :             break;
    2170                 :            : 
    2171                 :            :         case HTML_META_CREATED:
    2172                 :            :         case HTML_META_CHANGED:
    2173 [ +  - ][ +  - ]:         12 :             if ( i_xDocProps.is() && aContent.Len() &&
         [ +  - ][ +  - ]
    2174 [ +  - ][ +  - ]:          8 :                  comphelper::string::getTokenCount(aContent, ';') == 2 )
         [ +  - ][ #  # ]
    2175                 :            :             {
    2176 [ +  - ][ +  - ]:          4 :                 Date aDate( (sal_uLong)aContent.GetToken(0).ToInt32() );
                 [ +  - ]
    2177 [ +  - ][ +  - ]:          4 :                 Time aTime( (sal_uLong)aContent.GetToken(1).ToInt32() );
                 [ +  - ]
    2178         [ +  - ]:          4 :                 DateTime aDateTime( aDate, aTime );
    2179                 :          4 :                 ::util::DateTime uDT(aDateTime.Get100Sec(),
    2180                 :          4 :                     aDateTime.GetSec(), aDateTime.GetMin(),
    2181                 :          4 :                     aDateTime.GetHour(), aDateTime.GetDay(),
    2182                 :          8 :                     aDateTime.GetMonth(), aDateTime.GetYear());
    2183         [ +  + ]:          4 :                 if ( HTML_META_CREATED==nAction )
    2184 [ +  - ][ +  - ]:          2 :                     i_xDocProps->setCreationDate( uDT );
    2185                 :            :                 else
    2186 [ +  - ][ +  - ]:          2 :                     i_xDocProps->setModificationDate( uDT );
    2187                 :          4 :                 bChanged = true;
    2188                 :            :             }
    2189                 :          4 :             break;
    2190                 :            : 
    2191                 :            :         case HTML_META_REFRESH:
    2192                 :            :             DBG_ASSERT( !bHTTPEquiv || i_pHTTPHeader,
    2193                 :            :         "Reload-URL aufgrund unterlassener MUSS-Aenderung verlorengegangen" );
    2194                 :          0 :             break;
    2195                 :            : 
    2196                 :            :         case HTML_META_CONTENT_TYPE:
    2197         [ +  - ]:          2 :             if ( aContent.Len() )
    2198                 :            :             {
    2199         [ +  - ]:          2 :                 o_rEnc = GetEncodingByMIME( aContent );
    2200                 :            :             }
    2201                 :          2 :             break;
    2202                 :            : 
    2203                 :            :         case HTML_META_NONE:
    2204         [ #  # ]:          0 :             if ( !bHTTPEquiv )
    2205                 :            :             {
    2206         [ #  # ]:          0 :                 if (i_xDocProps.is())
    2207                 :            :                 {
    2208                 :            :                     uno::Reference<beans::XPropertyContainer> xUDProps
    2209 [ #  # ][ #  # ]:          0 :                         = i_xDocProps->getUserDefinedProperties();
    2210                 :            :                     try {
    2211         [ #  # ]:          0 :                         xUDProps->addProperty(aName,
    2212                 :            :                             beans::PropertyAttribute::REMOVEABLE,
    2213 [ #  # ][ #  # ]:          0 :                             uno::makeAny(::rtl::OUString(aContent)));
         [ #  # ][ #  # ]
    2214 [ #  # ][ #  # ]:          0 :                         AddMetaUserDefined(aName);
                 [ #  # ]
    2215                 :          0 :                         bChanged = true;
    2216         [ #  # ]:          0 :                     } catch (uno::Exception &) {
    2217                 :            :                         // ignore
    2218                 :          0 :                     }
    2219                 :            :                 }
    2220                 :            :             }
    2221                 :          0 :             break;
    2222                 :            :         default:
    2223                 :          2 :             break;
    2224                 :            :     }
    2225                 :            : 
    2226 [ +  - ][ +  - ]:          8 :     return bChanged;
    2227                 :            : }
    2228                 :            : 
    2229                 :          8 : bool HTMLParser::ParseMetaOptions(
    2230                 :            :         const uno::Reference<document::XDocumentProperties> & i_xDocProps,
    2231                 :            :         SvKeyValueIterator *i_pHeader )
    2232                 :            : {
    2233                 :          8 :     sal_uInt16 nContentOption = HTML_O_CONTENT;
    2234                 :          8 :     rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW;
    2235                 :            : 
    2236                 :            :     bool bRet = ParseMetaOptionsImpl( i_xDocProps, i_pHeader,
    2237         [ +  - ]:          8 :                       GetOptions(&nContentOption),
    2238         [ +  - ]:          8 :                       eEnc );
    2239                 :            : 
    2240                 :            :     // If the encoding is set by a META tag, it may only overwrite the
    2241                 :            :     // current encoding if both, the current and the new encoding, are 1-sal_uInt8
    2242                 :            :     // encodings. Everything else cannot lead to reasonable results.
    2243 [ +  + ][ +  - ]:         12 :     if (RTL_TEXTENCODING_DONTKNOW != eEnc &&
         [ +  - ][ +  + ]
    2244         [ +  - ]:          2 :         rtl_isOctetTextEncoding( eEnc ) &&
    2245         [ +  - ]:          2 :         rtl_isOctetTextEncoding( GetSrcEncoding() ) )
    2246                 :            :     {
    2247         [ +  - ]:          2 :         eEnc = GetExtendedCompatibilityTextEncoding( eEnc );
    2248         [ +  - ]:          2 :         SetSrcEncoding( eEnc );
    2249                 :            :     }
    2250                 :            : 
    2251                 :          8 :     return bRet;
    2252                 :            : }
    2253                 :            : 
    2254                 :          2 : rtl_TextEncoding HTMLParser::GetEncodingByMIME( const String& rMime )
    2255                 :            : {
    2256         [ +  - ]:          2 :     String sType;
    2257         [ +  - ]:          2 :     String sSubType;
    2258         [ +  - ]:          2 :     INetContentTypeParameterList aParameters;
    2259 [ +  - ][ +  - ]:          2 :     if (INetContentTypes::parse(rMime, sType, sSubType, &aParameters))
    2260                 :            :     {
    2261                 :            :         const INetContentTypeParameter * pCharset
    2262         [ +  - ]:          2 :             = aParameters.find("charset");
    2263         [ +  - ]:          2 :         if (pCharset != 0)
    2264                 :            :         {
    2265                 :            :             rtl::OString sValue(rtl::OUStringToOString(pCharset->m_sValue,
    2266         [ +  - ]:          2 :                 RTL_TEXTENCODING_ASCII_US));
    2267                 :            :             return GetExtendedCompatibilityTextEncoding(
    2268 [ +  - ][ +  - ]:          2 :                     rtl_getTextEncodingFromMimeCharset( sValue.getStr() ) );
    2269                 :            :         }
    2270                 :            :     }
    2271 [ +  - ][ +  - ]:          2 :     return RTL_TEXTENCODING_DONTKNOW;
                 [ +  - ]
    2272                 :            : }
    2273                 :            : 
    2274                 :          5 : rtl_TextEncoding HTMLParser::GetEncodingByHttpHeader( SvKeyValueIterator *pHTTPHeader )
    2275                 :            : {
    2276                 :          5 :     rtl_TextEncoding eRet = RTL_TEXTENCODING_DONTKNOW;
    2277         [ +  - ]:          5 :     if( pHTTPHeader )
    2278                 :            :     {
    2279         [ +  - ]:          5 :         SvKeyValue aKV;
    2280 [ +  - ][ +  + ]:         10 :         for( bool bCont = pHTTPHeader->GetFirst( aKV ); bCont;
    2281         [ +  - ]:          5 :              bCont = pHTTPHeader->GetNext( aKV ) )
    2282                 :            :         {
    2283 [ +  - ][ +  - ]:          5 :             if( aKV.GetKey().EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_content_type ) )
    2284                 :            :             {
    2285         [ -  + ]:          5 :                 if( aKV.GetValue().Len() )
    2286                 :            :                 {
    2287         [ #  # ]:          0 :                     eRet = HTMLParser::GetEncodingByMIME( aKV.GetValue() );
    2288                 :            :                 }
    2289                 :            :             }
    2290         [ +  - ]:          5 :         }
    2291                 :            :     }
    2292                 :          5 :     return eRet;
    2293                 :            : }
    2294                 :            : 
    2295                 :          5 : bool HTMLParser::SetEncodingByHTTPHeader( SvKeyValueIterator *pHTTPHeader )
    2296                 :            : {
    2297                 :          5 :     bool bRet = false;
    2298                 :          5 :     rtl_TextEncoding eEnc = HTMLParser::GetEncodingByHttpHeader( pHTTPHeader );
    2299         [ -  + ]:          5 :     if(RTL_TEXTENCODING_DONTKNOW != eEnc)
    2300                 :            :     {
    2301                 :          0 :         SetSrcEncoding( eEnc );
    2302                 :          0 :         bRet = true;
    2303                 :            :     }
    2304                 :          5 :     return bRet;
    2305                 :            : }
    2306                 :            : 
    2307                 :            : 
    2308                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10