LCOV - code coverage report
Current view: top level - writerfilter/source/rtftok - rtftokenizer.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 199 0.0 %
Date: 2014-04-14 Functions: 0 16 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <tools/stream.hxx>
      11             : #include <tools/resmgr.hxx>
      12             : #include <svx/dialogs.hrc>
      13             : #include <vcl/svapp.hxx>
      14             : #include <vcl/settings.hxx>
      15             : #include <rtl/strbuf.hxx>
      16             : 
      17             : #include <rtftokenizer.hxx>
      18             : #include <rtfskipdestination.hxx>
      19             : #include <com/sun/star/io/BufferSizeExceededException.hpp>
      20             : 
      21             : using namespace com::sun::star;
      22             : 
      23             : namespace writerfilter {
      24             : namespace rtftok {
      25             : 
      26           0 : std::vector<RTFSymbol> RTFTokenizer::m_aRTFControlWords;
      27             : bool RTFTokenizer::m_bControlWordsSorted;
      28           0 : std::vector<RTFMathSymbol> RTFTokenizer::m_aRTFMathControlWords;
      29             : bool RTFTokenizer::m_bMathControlWordsSorted;
      30             : 
      31           0 : RTFTokenizer::RTFTokenizer(RTFListener& rImport, SvStream* pInStream, uno::Reference<task::XStatusIndicator> const& xStatusIndicator)
      32             :     : m_rImport(rImport),
      33             :     m_pInStream(pInStream),
      34             :     m_xStatusIndicator(xStatusIndicator),
      35             :     m_nGroup(0),
      36             :     m_nLineNumber(0),
      37             :     m_nLineStartPos(0),
      38           0 :     m_nGroupStart(0)
      39             : {
      40           0 :     if (!RTFTokenizer::m_bControlWordsSorted)
      41             :     {
      42           0 :         RTFTokenizer::m_bControlWordsSorted = true;
      43           0 :         m_aRTFControlWords = std::vector<RTFSymbol>(aRTFControlWords, aRTFControlWords + nRTFControlWords);
      44           0 :         std::sort(m_aRTFControlWords.begin(), m_aRTFControlWords.end());
      45             :     }
      46           0 :     if (!RTFTokenizer::m_bMathControlWordsSorted)
      47             :     {
      48           0 :         RTFTokenizer::m_bMathControlWordsSorted = true;
      49           0 :         m_aRTFMathControlWords = std::vector<RTFMathSymbol>(aRTFMathControlWords, aRTFMathControlWords + nRTFMathControlWords);
      50           0 :         std::sort(m_aRTFMathControlWords.begin(), m_aRTFMathControlWords.end());
      51             :     }
      52           0 : }
      53             : 
      54           0 : RTFTokenizer::~RTFTokenizer()
      55             : {
      56           0 : }
      57             : 
      58           0 : SvStream& RTFTokenizer::Strm()
      59             : {
      60           0 :     return *m_pInStream;
      61             : }
      62             : 
      63           0 : int RTFTokenizer::resolveParse()
      64             : {
      65             :     SAL_INFO( "writerfilter", OSL_THIS_FUNC );
      66             :     char ch;
      67             :     int ret;
      68             :     // for hex chars
      69           0 :     int b = 0, count = 2;
      70           0 :     sal_uInt32 nPercentSize = 0;
      71           0 :     sal_uInt32 nLastPos = 0;
      72             : 
      73           0 :     if (m_xStatusIndicator.is())
      74             :     {
      75           0 :         static ResMgr* pResMgr = ResMgr::CreateResMgr("svx", Application::GetSettings().GetUILanguageTag());
      76           0 :         OUString sDocLoad(ResId(RID_SVXSTR_DOC_LOAD, *pResMgr).toString());
      77             : 
      78           0 :         sal_Size nCurrentPos = Strm().Tell();
      79           0 :         Strm().Seek(STREAM_SEEK_TO_END);
      80           0 :         sal_Size nEndPos = Strm().Tell();
      81           0 :         Strm().Seek(nCurrentPos);
      82           0 :         m_xStatusIndicator->start(sDocLoad, nEndPos);
      83           0 :         nPercentSize = nEndPos / 100;
      84             : 
      85           0 :         m_xStatusIndicator->setValue(nLastPos = nCurrentPos);
      86             :     }
      87             : 
      88           0 :     while ((Strm().ReadChar( ch ), !Strm().IsEof()))
      89             :     {
      90             :         //SAL_INFO("writerfilter", OSL_THIS_FUNC << ": parsing character '" << ch << "'");
      91             : 
      92           0 :         sal_Size nCurrentPos = Strm().Tell();
      93           0 :         if (m_xStatusIndicator.is() && nCurrentPos > (nLastPos + nPercentSize))
      94           0 :             m_xStatusIndicator->setValue(nLastPos = nCurrentPos);
      95             : 
      96           0 :         if (m_nGroup < 0)
      97           0 :             return ERROR_GROUP_UNDER;
      98           0 :         if (m_nGroup > 0 && m_rImport.getInternalState() == INTERNAL_BIN)
      99             :         {
     100           0 :             ret = m_rImport.resolveChars(ch);
     101           0 :             if (ret)
     102           0 :                 return ret;
     103             :         }
     104             :         else
     105             :         {
     106           0 :             switch (ch)
     107             :             {
     108             :                 case '{':
     109           0 :                     m_nGroupStart = Strm().Tell() - 1;
     110           0 :                     ret = m_rImport.pushState();
     111           0 :                     if (ret)
     112           0 :                         return ret;
     113           0 :                     break;
     114             :                 case '}':
     115           0 :                     ret = m_rImport.popState();
     116           0 :                     if (ret)
     117           0 :                         return ret;
     118           0 :                     if (m_nGroup == 0)
     119             :                     {
     120           0 :                         if (m_rImport.isSubstream())
     121           0 :                             m_rImport.finishSubstream();
     122           0 :                         return 0;
     123             :                     }
     124           0 :                     break;
     125             :                 case '\\':
     126           0 :                     ret = resolveKeyword();
     127           0 :                     if (ret)
     128           0 :                         return ret;
     129           0 :                     break;
     130             :                 case 0x0d:
     131           0 :                     break; // ignore this
     132             :                 case 0x0a:
     133           0 :                     m_nLineNumber++;
     134           0 :                     m_nLineStartPos = nCurrentPos;
     135           0 :                     break;
     136             :                 default:
     137           0 :                     if (m_nGroup == 0)
     138           0 :                         return ERROR_CHAR_OVER;
     139           0 :                     if (m_rImport.getInternalState() == INTERNAL_NORMAL)
     140             :                     {
     141           0 :                         ret = m_rImport.resolveChars(ch);
     142           0 :                         if (ret)
     143           0 :                             return ret;
     144             :                     }
     145             :                     else
     146             :                     {
     147             :                         SAL_INFO("writerfilter", OSL_THIS_FUNC << ": hex internal state");
     148           0 :                         b = b << 4;
     149           0 :                         sal_Int8 parsed = asHex(ch);
     150           0 :                         if (parsed == -1)
     151           0 :                             return ERROR_HEX_INVALID;
     152           0 :                         b += parsed;
     153           0 :                         count--;
     154           0 :                         if (!count)
     155             :                         {
     156           0 :                             ret = m_rImport.resolveChars(b);
     157           0 :                             if (ret)
     158           0 :                                 return ret;
     159           0 :                             count = 2;
     160           0 :                             b = 0;
     161           0 :                             m_rImport.setInternalState(INTERNAL_NORMAL);
     162             :                         }
     163             :                     }
     164           0 :                     break;
     165             :             }
     166             :         }
     167             :     }
     168             : 
     169           0 :     if (m_nGroup < 0)
     170           0 :         return ERROR_GROUP_UNDER;
     171           0 :     else if (m_nGroup > 0)
     172           0 :         return ERROR_GROUP_OVER;
     173           0 :     return 0;
     174             : }
     175             : 
     176           0 : int RTFTokenizer::asHex(char ch)
     177             : {
     178           0 :     int ret = 0;
     179           0 :     if (isdigit(ch))
     180           0 :         ret = ch - '0';
     181             :     else
     182             :     {
     183           0 :         if (islower(ch))
     184             :         {
     185           0 :             if (ch < 'a' || ch > 'f')
     186           0 :                 return -1;
     187           0 :             ret = ch - 'a';
     188             :         }
     189             :         else
     190             :         {
     191           0 :             if (ch < 'A' || ch > 'F')
     192           0 :                 return -1;
     193           0 :             ret = ch - 'A';
     194             :         }
     195           0 :         ret += 10;
     196             :     }
     197           0 :     return ret;
     198             : }
     199             : 
     200           0 : int RTFTokenizer::getGroup() const
     201             : {
     202           0 :     return m_nGroup;
     203             : }
     204             : 
     205           0 : void RTFTokenizer::pushGroup()
     206             : {
     207           0 :     m_nGroup++;
     208           0 : }
     209             : 
     210           0 : void RTFTokenizer::popGroup()
     211             : {
     212           0 :     m_nGroup--;
     213           0 : }
     214             : 
     215           0 : int RTFTokenizer::resolveKeyword()
     216             : {
     217             :     char ch;
     218           0 :     OStringBuffer aBuf;
     219           0 :     bool bNeg = false;
     220           0 :     bool bParam = false;
     221           0 :     int nParam = 0;
     222             : 
     223           0 :     Strm().ReadChar( ch );
     224           0 :     if (Strm().IsEof())
     225           0 :         return ERROR_EOF;
     226             : 
     227           0 :     if (!isalpha(ch))
     228             :     {
     229           0 :         aBuf.append(ch);
     230           0 :         OString aKeyword = aBuf.makeStringAndClear();
     231             :         // control symbols aren't followed by a space, so we can return here
     232             :         // without doing any SeekRel()
     233           0 :         return dispatchKeyword(aKeyword, bParam, nParam);
     234             :     }
     235           0 :     while(isalpha(ch))
     236             :     {
     237           0 :         aBuf.append(ch);
     238           0 :         Strm().ReadChar( ch );
     239           0 :         if (Strm().IsEof())
     240             :         {
     241           0 :             ch = ' ';
     242           0 :             break;
     243             :         }
     244             :     }
     245           0 :     if (aBuf.getLength() > 32)
     246             :         // See RTF spec v1.9.1, page 7
     247             :         // A control word's name cannot be longer than 32 letters.
     248           0 :         throw io::BufferSizeExceededException();
     249             : 
     250           0 :     if (ch == '-')
     251             :     {
     252             :         // in case we'll have a parameter, that will be negative
     253           0 :         bNeg = true;
     254           0 :         Strm().ReadChar( ch );
     255           0 :         if (Strm().IsEof())
     256           0 :             return ERROR_EOF;
     257             :     }
     258           0 :     if (isdigit(ch))
     259             :     {
     260           0 :         OStringBuffer aParameter;
     261             : 
     262             :         // we have a parameter
     263           0 :         bParam = true;
     264           0 :         while(isdigit(ch))
     265             :         {
     266           0 :             aParameter.append(ch);
     267           0 :             Strm().ReadChar( ch );
     268           0 :             if (Strm().IsEof())
     269             :             {
     270           0 :                 ch = ' ';
     271           0 :                 break;
     272             :             }
     273             :         }
     274           0 :         nParam = aParameter.makeStringAndClear().toInt32();
     275           0 :         if (bNeg)
     276           0 :             nParam = -nParam;
     277             :     }
     278           0 :     if (ch != ' ')
     279           0 :         Strm().SeekRel(-1);
     280           0 :     OString aKeyword = aBuf.makeStringAndClear();
     281           0 :     return dispatchKeyword(aKeyword, bParam, nParam);
     282             : }
     283             : 
     284           0 : bool RTFTokenizer::lookupMathKeyword(RTFMathSymbol& rSymbol)
     285             : {
     286           0 :     std::vector<RTFMathSymbol>::iterator low = std::lower_bound(m_aRTFMathControlWords.begin(), m_aRTFMathControlWords.end(), rSymbol);
     287           0 :     int i = low - m_aRTFMathControlWords.begin();
     288           0 :     if (low == m_aRTFMathControlWords.end() || rSymbol < *low)
     289           0 :         return false;
     290           0 :     rSymbol = m_aRTFMathControlWords[i];
     291           0 :     return true;
     292             : }
     293             : 
     294           0 : int RTFTokenizer::dispatchKeyword(OString& rKeyword, bool bParam, int nParam)
     295             : {
     296           0 :     if (m_rImport.getDestinationState() == DESTINATION_SKIP)
     297           0 :         return 0;
     298             : #if OSL_DEBUG_LEVEL > 1
     299             :     SAL_INFO("writerfilter.rtf", OSL_THIS_FUNC << ": keyword '\\" << rKeyword.getStr() <<
     300             :                "' with param? " << (bParam ? 1 : 0) <<" param val: '" << (bParam ? nParam : 0) << "'");
     301             : #endif
     302             :     RTFSymbol aSymbol;
     303           0 :     aSymbol.sKeyword = rKeyword.getStr();
     304           0 :     std::vector<RTFSymbol>::iterator low = std::lower_bound(m_aRTFControlWords.begin(), m_aRTFControlWords.end(), aSymbol);
     305           0 :     int i = low - m_aRTFControlWords.begin();
     306           0 :     if (low == m_aRTFControlWords.end() || aSymbol < *low)
     307             :     {
     308             :         SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unknown keyword '\\" << rKeyword.getStr() << "'");
     309           0 :         RTFSkipDestination aSkip(m_rImport);
     310           0 :         aSkip.setParsed(false);
     311           0 :         return 0;
     312             :     }
     313             : 
     314             :     int ret;
     315           0 :     switch (m_aRTFControlWords[i].nControlType)
     316             :     {
     317             :         case CONTROL_FLAG:
     318             :             // flags ignore any parameter by definition
     319           0 :             ret = m_rImport.dispatchFlag(m_aRTFControlWords[i].nIndex);
     320           0 :             if (ret)
     321           0 :                 return ret;
     322           0 :             break;
     323             :         case CONTROL_DESTINATION:
     324             :             // same for destinations
     325           0 :             ret = m_rImport.dispatchDestination(m_aRTFControlWords[i].nIndex);
     326           0 :             if (ret)
     327           0 :                 return ret;
     328           0 :             break;
     329             :         case CONTROL_SYMBOL:
     330             :             // and symbols
     331           0 :             ret = m_rImport.dispatchSymbol(m_aRTFControlWords[i].nIndex);
     332           0 :             if (ret)
     333           0 :                 return ret;
     334           0 :             break;
     335             :         case CONTROL_TOGGLE:
     336           0 :             ret = m_rImport.dispatchToggle(m_aRTFControlWords[i].nIndex, bParam, nParam);
     337           0 :             if (ret)
     338           0 :                 return ret;
     339           0 :             break;
     340             :         case CONTROL_VALUE:
     341             :             // values require a parameter by definition
     342           0 :             if (bParam) {
     343           0 :                 ret = m_rImport.dispatchValue(m_aRTFControlWords[i].nIndex, nParam);
     344           0 :                 if (ret)
     345           0 :                     return ret;
     346             :             }
     347           0 :             break;
     348             :     }
     349             : 
     350           0 :     return 0;
     351             : }
     352             : 
     353           0 : OUString RTFTokenizer::getPosition()
     354             : {
     355           0 :     OUStringBuffer aRet;
     356           0 :     aRet.append(m_nLineNumber + 1);
     357           0 :     aRet.append(",");
     358           0 :     aRet.append(sal_Int32(Strm().Tell() - m_nLineStartPos + 1));
     359           0 :     return aRet.makeStringAndClear();
     360             : }
     361             : 
     362           0 : sal_Size RTFTokenizer::getGroupStart()
     363             : {
     364           0 :     return m_nGroupStart;
     365             : }
     366             : 
     367             : } // namespace rtftok
     368           0 : } // namespace writerfilter
     369             : 
     370             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10