LCOV - code coverage report
Current view: top level - writerfilter/source/rtftok - rtftokenizer.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 139 162 85.8 %
Date: 2012-08-25 Functions: 10 10 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 149 241 61.8 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       3                 :            :  *
       4                 :            :  * The contents of this file are subject to the Mozilla Public License Version
       5                 :            :  * 1.1 (the "License"); you may not use this file except in compliance with
       6                 :            :  * the License. You may obtain a copy of the License at
       7                 :            :  * http://www.mozilla.org/MPL/
       8                 :            :  *
       9                 :            :  * Software distributed under the License is distributed on an "AS IS" basis,
      10                 :            :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      11                 :            :  * for the specific language governing rights and limitations under the
      12                 :            :  * License.
      13                 :            :  *
      14                 :            :  * The Initial Developer of the Original Code is
      15                 :            :  *       Miklos Vajna <vmiklos@frugalware.org>
      16                 :            :  * Portions created by the Initial Developer are Copyright (C) 2011 the
      17                 :            :  * Initial Developer. All Rights Reserved.
      18                 :            :  *
      19                 :            :  * Contributor(s):
      20                 :            :  *
      21                 :            :  * Alternatively, the contents of this file may be used under the terms of
      22                 :            :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      23                 :            :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      24                 :            :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      25                 :            :  * instead of those above.
      26                 :            :  */
      27                 :            : 
      28                 :            : #include <tools/stream.hxx>
      29                 :            : #include <tools/resmgr.hxx>
      30                 :            : #include <svx/dialogs.hrc>
      31                 :            : #include <vcl/svapp.hxx>
      32                 :            : 
      33                 :            : #include <rtftokenizer.hxx>
      34                 :            : #include <rtfskipdestination.hxx>
      35                 :            : 
      36                 :            : using rtl::OString;
      37                 :            : using rtl::OStringBuffer;
      38                 :            : using rtl::OUString;
      39                 :            : using rtl::OUStringBuffer;
      40                 :            : using rtl::OUStringToOString;
      41                 :            : 
      42                 :            : namespace writerfilter {
      43                 :            : namespace rtftok {
      44                 :            : 
      45                 :        336 : RTFTokenizer::RTFTokenizer(RTFDocumentImpl& rImport, SvStream* pInStream, uno::Reference<task::XStatusIndicator> const& xStatusIndicator)
      46                 :            :     : m_rImport(rImport),
      47                 :            :     m_pInStream(pInStream),
      48                 :            :     m_xStatusIndicator(xStatusIndicator),
      49         [ +  - ]:        336 :     m_aRTFControlWords(std::vector<RTFSymbol>(aRTFControlWords, aRTFControlWords + nRTFControlWords))
      50                 :            : {
      51         [ +  - ]:        336 :     std::sort(m_aRTFControlWords.begin(), m_aRTFControlWords.end());
      52                 :        336 : }
      53                 :            : 
      54                 :        336 : RTFTokenizer::~RTFTokenizer()
      55                 :            : {
      56         [ -  + ]:        672 : }
      57                 :            : 
      58                 :    2292714 : SvStream& RTFTokenizer::Strm()
      59                 :            : {
      60                 :    2292714 :     return *m_pInStream;
      61                 :            : }
      62                 :            : 
      63                 :        336 : int RTFTokenizer::resolveParse()
      64                 :            : {
      65                 :            :     SAL_INFO( "writerfilter", OSL_THIS_FUNC );
      66                 :            :     char ch;
      67                 :            :     int ret;
      68                 :            :     // for hex chars
      69                 :        336 :     int b = 0, count = 2;
      70                 :        336 :     sal_uInt32 nPercentSize = 0;
      71                 :        336 :     sal_uInt32 nLastPos = 0;
      72                 :            : 
      73         [ +  + ]:        336 :     if (m_xStatusIndicator.is())
      74                 :            :     {
      75 [ +  + ][ +  - ]:        303 :         static ResMgr* pResMgr = ResMgr::CreateResMgr("svx", Application::GetSettings().GetUILocale());
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
      76         [ +  - ]:        303 :         OUString sDocLoad(ResId(RID_SVXSTR_DOC_LOAD, *pResMgr).toString());
      77                 :            : 
      78                 :        303 :         sal_uInt32 nCurrentPos = Strm().Tell();
      79         [ +  - ]:        303 :         Strm().Seek(STREAM_SEEK_TO_END);
      80                 :        303 :         sal_uInt32 nEndPos = Strm().Tell();
      81         [ +  - ]:        303 :         Strm().Seek(nCurrentPos);
      82 [ +  - ][ +  - ]:        303 :         m_xStatusIndicator->start(sDocLoad, nEndPos);
      83                 :        303 :         nPercentSize = nEndPos / 100;
      84                 :            : 
      85 [ +  - ][ +  - ]:        306 :         m_xStatusIndicator->setValue(nLastPos = nCurrentPos);
      86                 :            :     }
      87                 :            : 
      88 [ +  - ][ +  + ]:     362127 :     while ((Strm() >> ch, !Strm().IsEof()))
      89                 :            :     {
      90                 :            :         //SAL_INFO("writerfilter", OSL_THIS_FUNC << ": parsing character '" << ch << "'");
      91                 :            : 
      92                 :            :         sal_uInt32 nCurrentPos;
      93 [ +  + ][ +  + ]:     362121 :         if (m_xStatusIndicator.is() && (nCurrentPos = Strm().Tell()) > (nLastPos + nPercentSize))
                 [ +  + ]
      94 [ +  - ][ +  - ]:      11697 :             m_xStatusIndicator->setValue(nLastPos = nCurrentPos);
      95                 :            : 
      96 [ +  - ][ -  + ]:     362121 :         if (m_rImport.getGroup() < 0)
      97                 :          0 :             return ERROR_GROUP_UNDER;
      98 [ +  - ][ +  + ]:     362121 :         if (m_rImport.getGroup() > 0 && m_rImport.getState().nInternalState == INTERNAL_BIN)
         [ +  - ][ +  + ]
                 [ +  + ]
      99                 :            :         {
     100         [ +  - ]:          3 :             ret = m_rImport.resolveChars(ch);
     101         [ -  + ]:          3 :             if (ret)
     102                 :          0 :                 return ret;
     103                 :            :         }
     104                 :            :         else
     105                 :            :         {
     106   [ +  +  +  +  :     362118 :             switch (ch)
                      + ]
     107                 :            :             {
     108                 :            :                 case '{':
     109         [ +  - ]:      15081 :                     ret = m_rImport.pushState();
     110         [ -  + ]:      15081 :                     if (ret)
     111                 :          0 :                         return ret;
     112                 :      15081 :                     break;
     113                 :            :                 case '}':
     114         [ +  - ]:      15072 :                     ret = m_rImport.popState();
     115         [ -  + ]:      15072 :                     if (ret)
     116                 :          0 :                         return ret;
     117 [ +  - ][ +  + ]:      15072 :                     if (m_rImport.getGroup() == 0)
     118                 :            :                     {
     119 [ +  - ][ +  + ]:        327 :                         if (m_rImport.isSubstream())
     120         [ +  - ]:         21 :                             m_rImport.finishSubstream();
     121                 :        327 :                         return 0;
     122                 :            :                     }
     123                 :      14745 :                     break;
     124                 :            :                 case '\\':
     125         [ +  + ]:     156591 :                     ret = resolveKeyword();
     126         [ -  + ]:     156588 :                     if (ret)
     127                 :          0 :                         return ret;
     128                 :     156588 :                     break;
     129                 :            :                 case 0x0d:
     130                 :            :                 case 0x0a:
     131                 :      22302 :                     break; // ignore these
     132                 :            :                 default:
     133 [ +  - ][ -  + ]:     153072 :                     if (m_rImport.getGroup() == 0)
     134                 :          0 :                         return ERROR_CHAR_OVER;
     135 [ +  - ][ +  + ]:     153072 :                     if (m_rImport.getState().nInternalState == INTERNAL_NORMAL)
     136                 :            :                     {
     137         [ +  - ]:      12930 :                         ret = m_rImport.resolveChars(ch);
     138         [ -  + ]:      12930 :                         if (ret)
     139                 :          0 :                             return ret;
     140                 :            :                     }
     141                 :            :                     else
     142                 :            :                     {
     143                 :            :                         SAL_INFO("writerfilter", OSL_THIS_FUNC << ": hex internal state");
     144                 :     140142 :                         b = b << 4;
     145                 :     140142 :                         sal_Int8 parsed = asHex(ch);
     146         [ -  + ]:     140142 :                         if (parsed == -1)
     147                 :          0 :                             return ERROR_HEX_INVALID;
     148                 :     140142 :                         b += parsed;
     149                 :     140142 :                         count--;
     150         [ +  + ]:     140142 :                         if (!count)
     151                 :            :                         {
     152         [ +  - ]:      70071 :                             ret = m_rImport.resolveChars(b);
     153         [ -  + ]:      70071 :                             if (ret)
     154                 :          0 :                                 return ret;
     155                 :      70071 :                             count = 2;
     156                 :      70071 :                             b = 0;
     157         [ +  - ]:      70071 :                             m_rImport.getState().nInternalState = INTERNAL_NORMAL;
     158                 :            :                         }
     159                 :            :                     }
     160                 :     153072 :                     break;
     161                 :            :             }
     162                 :            :         }
     163                 :            :     }
     164                 :            : 
     165 [ +  - ][ -  + ]:          6 :     if (m_rImport.getGroup() < 0)
     166                 :          0 :         return ERROR_GROUP_UNDER;
     167 [ +  - ][ +  - ]:          6 :     else if (m_rImport.getGroup() > 0)
     168                 :          6 :         return ERROR_GROUP_OVER;
     169                 :        333 :     return 0;
     170                 :            : }
     171                 :            : 
     172                 :     148026 : int RTFTokenizer::asHex(char ch)
     173                 :            : {
     174                 :     148026 :     int ret = 0;
     175         [ +  + ]:     148026 :     if (isdigit(ch))
     176                 :     125508 :         ret = ch - '0';
     177                 :            :     else
     178                 :            :     {
     179         [ +  - ]:      22518 :         if (islower(ch))
     180                 :            :         {
     181 [ +  - ][ -  + ]:      22518 :             if (ch < 'a' || ch > 'f')
     182                 :          0 :                 return -1;
     183                 :      22518 :             ret = ch - 'a';
     184                 :            :         }
     185                 :            :         else
     186                 :            :         {
     187 [ #  # ][ #  # ]:          0 :             if (ch < 'A' || ch > 'F')
     188                 :          0 :                 return -1;
     189                 :          0 :             ret = ch - 'A';
     190                 :            :         }
     191                 :      22518 :         ret += 10;
     192                 :            :     }
     193                 :     148026 :     return ret;
     194                 :            : }
     195                 :            : 
     196                 :     156591 : int RTFTokenizer::resolveKeyword()
     197                 :            : {
     198                 :            :     char ch;
     199                 :     156591 :     OStringBuffer aBuf;
     200                 :     156591 :     bool bNeg = false;
     201                 :     156591 :     bool bParam = false;
     202                 :     156591 :     int nParam = 0;
     203                 :            : 
     204         [ +  - ]:     156591 :     Strm() >> ch;
     205         [ -  + ]:     156591 :     if (Strm().IsEof())
     206                 :          0 :         return ERROR_EOF;
     207                 :            : 
     208         [ +  + ]:     156591 :     if (!isalpha(ch))
     209                 :            :     {
     210         [ +  - ]:      72165 :         aBuf.append(ch);
     211                 :      72165 :         OString aKeyword = aBuf.makeStringAndClear();
     212                 :            :         // control symbols aren't followed by a space, so we can return here
     213                 :            :         // without doing any SeekRel()
     214         [ +  - ]:      72165 :         return dispatchKeyword(aKeyword, bParam, nParam);
     215                 :            :     }
     216         [ +  + ]:     507558 :     while(isalpha(ch))
     217                 :            :     {
     218         [ +  - ]:     423135 :         aBuf.append(ch);
     219         [ +  - ]:     423135 :         Strm() >> ch;
     220         [ +  + ]:     423135 :         if (Strm().IsEof())
     221                 :            :         {
     222                 :          3 :             ch = ' ';
     223                 :          3 :             break;
     224                 :            :         }
     225                 :            :     }
     226         [ +  + ]:      84426 :     if (aBuf.getLength() > 32)
     227                 :            :         // See RTF spec v1.9.1, page 7
     228                 :            :         // A control word's name cannot be longer than 32 letters.
     229         [ +  - ]:          3 :         throw io::BufferSizeExceededException();
     230                 :            : 
     231         [ +  + ]:      84423 :     if (ch == '-')
     232                 :            :     {
     233                 :            :         // in case we'll have a parameter, that will be negative
     234                 :        300 :         bNeg = true;
     235         [ +  - ]:        300 :         Strm() >> ch;
     236         [ -  + ]:        300 :         if (Strm().IsEof())
     237                 :          0 :             return ERROR_EOF;
     238                 :            :     }
     239         [ +  + ]:      84423 :     if (isdigit(ch))
     240                 :            :     {
     241                 :      47220 :         OStringBuffer aParameter;
     242                 :            : 
     243                 :            :         // we have a parameter
     244                 :      47220 :         bParam = true;
     245         [ +  + ]:     153543 :         while(isdigit(ch))
     246                 :            :         {
     247         [ +  - ]:     106323 :             aParameter.append(ch);
     248         [ +  - ]:     106323 :             Strm() >> ch;
     249         [ -  + ]:     106323 :             if (Strm().IsEof())
     250                 :            :             {
     251                 :          0 :                 ch = ' ';
     252                 :          0 :                 break;
     253                 :            :             }
     254                 :            :         }
     255                 :      47220 :         nParam = aParameter.makeStringAndClear().toInt32();
     256         [ +  + ]:      47220 :         if (bNeg)
     257                 :      47220 :             nParam = -nParam;
     258                 :            :     }
     259         [ +  + ]:      84423 :     if (ch != ' ')
     260         [ +  - ]:      61131 :         Strm().SeekRel(-1);
     261                 :      84423 :     OString aKeyword = aBuf.makeStringAndClear();
     262         [ +  - ]:     156591 :     return dispatchKeyword(aKeyword, bParam, nParam);
     263                 :            : }
     264                 :            : 
     265                 :     156588 : int RTFTokenizer::dispatchKeyword(OString& rKeyword, bool bParam, int nParam)
     266                 :            : {
     267 [ +  - ][ +  + ]:     156588 :     if (m_rImport.getState().nDestinationState == DESTINATION_SKIP)
     268                 :       9336 :         return 0;
     269                 :            :     /*SAL_INFO("writefilter", OSL_THIS_FUNC << ": keyword '\\" << rKeyword.getStr() <<
     270                 :            :                "' with param? " << (bParam ? 1 : 0) <<" param val: '" << (bParam ? nParam : 0) << "'");*/
     271                 :            :     RTFSymbol aSymbol;
     272                 :     147252 :     aSymbol.sKeyword = rKeyword.getStr();
     273         [ +  - ]:     147252 :     std::vector<RTFSymbol>::iterator low = std::lower_bound(m_aRTFControlWords.begin(), m_aRTFControlWords.end(), aSymbol);
     274         [ +  - ]:     147252 :     int i = low - m_aRTFControlWords.begin();
     275 [ +  - ][ +  - ]:     147252 :     if (low == m_aRTFControlWords.end() || aSymbol < *low)
         [ +  - ][ +  + ]
                 [ +  - ]
           [ +  +  #  # ]
     276                 :            :     {
     277                 :            :         SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unknown keyword '\\" << rKeyword.getStr() << "'");
     278         [ +  - ]:        528 :         RTFSkipDestination aSkip(m_rImport);
     279         [ +  - ]:        528 :         aSkip.setParsed(false);
     280         [ +  - ]:        528 :         return 0;
     281                 :            :     }
     282                 :            : 
     283                 :            :     int ret;
     284   [ +  +  +  +  :     146724 :     switch (m_aRTFControlWords[i].nControlType)
                   +  - ]
     285                 :            :     {
     286                 :            :         case CONTROL_FLAG:
     287                 :            :             // flags ignore any parameter by definition
     288         [ +  - ]:      23511 :             ret = m_rImport.dispatchFlag(m_aRTFControlWords[i].nIndex);
     289         [ -  + ]:      23511 :             if (ret)
     290                 :          0 :                 return ret;
     291                 :      23511 :             break;
     292                 :            :         case CONTROL_DESTINATION:
     293                 :            :             // same for destinations
     294         [ +  - ]:       8187 :             ret = m_rImport.dispatchDestination(m_aRTFControlWords[i].nIndex);
     295         [ -  + ]:       8187 :             if (ret)
     296                 :          0 :                 return ret;
     297                 :       8187 :             break;
     298                 :            :         case CONTROL_SYMBOL:
     299                 :            :             // and symbols
     300         [ +  - ]:      73734 :             ret = m_rImport.dispatchSymbol(m_aRTFControlWords[i].nIndex);
     301         [ -  + ]:      73734 :             if (ret)
     302                 :          0 :                 return ret;
     303                 :      73734 :             break;
     304                 :            :         case CONTROL_TOGGLE:
     305         [ +  - ]:       1299 :             ret = m_rImport.dispatchToggle(m_aRTFControlWords[i].nIndex, bParam, nParam);
     306         [ -  + ]:       1299 :             if (ret)
     307                 :          0 :                 return ret;
     308                 :       1299 :             break;
     309                 :            :         case CONTROL_VALUE:
     310                 :            :             // values require a parameter by definition
     311         [ +  + ]:      39993 :             if (bParam) {
     312         [ +  - ]:      39879 :                 ret = m_rImport.dispatchValue(m_aRTFControlWords[i].nIndex, nParam);
     313         [ -  + ]:      39879 :                 if (ret)
     314                 :          0 :                     return ret;
     315                 :            :             }
     316                 :      39993 :             break;
     317                 :            :     }
     318                 :            : 
     319                 :     156588 :     return 0;
     320                 :            : }
     321                 :            : 
     322                 :            : } // namespace rtftok
     323 [ +  - ][ +  - ]:         60 : } // namespace writerfilter
     324                 :            : 
     325                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10