LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/oox/source/mathml - importutils.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 119 158 75.3 %
Date: 2013-07-09 Functions: 26 27 96.3 %
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 "oox/mathml/importutils.hxx"
      11             : 
      12             : #include <assert.h>
      13             : #include <stdio.h>
      14             : 
      15             : #include <oox/token/namespacemap.hxx>
      16             : #include <oox/token/tokenmap.hxx>
      17             : #include <oox/token/tokens.hxx>
      18             : #include <oox/token/namespaces.hxx>
      19             : #include <rtl/ustring.hxx>
      20             : 
      21             : #define OPENING( token ) XML_STREAM_OPENING( token )
      22             : #define CLOSING( token ) XML_STREAM_CLOSING( token )
      23             : 
      24             : using namespace com::sun::star;
      25             : 
      26             : namespace oox
      27             : {
      28             : 
      29             : namespace formulaimport
      30             : {
      31             : 
      32             : namespace
      33             : {
      34             : // a class that inherits from AttributeList, builds the internal data and then will be sliced off
      35             : // during conversion to the base class
      36       10249 : class AttributeListBuilder
      37             :     : public XmlStream::AttributeList
      38             : {
      39             : public:
      40             :     AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a );
      41             : };
      42             : 
      43       10249 : AttributeListBuilder::AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a )
      44             : {
      45       10249 :     if( a.get() == NULL )
      46       18028 :         return;
      47        2470 :     uno::Sequence< xml::FastAttribute > aFastAttrSeq = a->getFastAttributes();
      48        2470 :     const xml::FastAttribute* pFastAttr = aFastAttrSeq.getConstArray();
      49        2470 :     sal_Int32 nFastAttrLength = aFastAttrSeq.getLength();
      50        3683 :     for( int i = 0;
      51             :          i < nFastAttrLength;
      52             :          ++i )
      53             :     {
      54        1213 :         attrs[ pFastAttr[ i ].Token ] = pFastAttr[ i ].Value;
      55        2470 :     }
      56             : }
      57             : 
      58           0 : static OUString tokenToString( int token )
      59             : {
      60           0 :     OUString tokenname = StaticTokenMap::get().getUnicodeTokenName( token & TOKEN_MASK );
      61           0 :     if( tokenname.isEmpty())
      62           0 :         tokenname = "???";
      63           0 :     int nmsp = ( token & NMSP_MASK & ~( TAG_OPENING | TAG_CLOSING ));
      64             : #if 0 // this is awfully long
      65             :     OUString namespacename = StaticNamespaceMap::get().count( nmsp ) != 0
      66             :         ? StaticNamespaceMap::get()[ nmsp ] : OUString( "???" );
      67             : #else
      68           0 :     OUString namespacename;
      69             :     // only few are needed actually
      70           0 :     switch( nmsp )
      71             :     {
      72             :         case NMSP_officeMath:
      73           0 :             namespacename = "m";
      74           0 :             break;
      75             :         case NMSP_doc:
      76           0 :             namespacename = "w";
      77           0 :             break;
      78             :         default:
      79           0 :             namespacename = "?";
      80           0 :             break;
      81             :     }
      82             : #endif
      83           0 :     if( token == OPENING( token ))
      84           0 :         return "<" + namespacename + ":" + tokenname + ">";
      85           0 :     if( token == CLOSING( token ))
      86           0 :         return "</" + namespacename + ":" + tokenname + ">";
      87             :     // just the name itself, not specified whether opening or closing
      88           0 :     return namespacename + ":" + tokenname;
      89             : }
      90             : 
      91             : } // namespace
      92             : 
      93         134 : OUString& XmlStream::AttributeList::operator[] (int token)
      94             : {
      95         134 :     return attrs[token];
      96             : }
      97             : 
      98        1156 : OUString XmlStream::AttributeList::attribute( int token, const OUString& def ) const
      99             : {
     100        1156 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     101        1156 :     if( find != attrs.end())
     102         534 :         return find->second;
     103         622 :     return def;
     104             : }
     105             : 
     106          42 : bool XmlStream::AttributeList::attribute( int token, bool def ) const
     107             : {
     108          42 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     109          42 :     if( find != attrs.end())
     110             :     {
     111          20 :         const OUString sValue = find->second;
     112          60 :         if( sValue.equalsIgnoreAsciiCase("true") ||
     113          34 :             sValue.equalsIgnoreAsciiCase("on") ||
     114          48 :             sValue.equalsIgnoreAsciiCase("t") ||
     115          14 :             sValue.equalsIgnoreAsciiCase("1") )
     116          20 :             return true;
     117           0 :         if( sValue.equalsIgnoreAsciiCase("false") ||
     118           0 :             sValue.equalsIgnoreAsciiCase("off") ||
     119           0 :             sValue.equalsIgnoreAsciiCase("f") ||
     120           0 :             sValue.equalsIgnoreAsciiCase("0") )
     121           0 :             return false;
     122           0 :         SAL_WARN( "oox.xmlstream", "Cannot convert \'" << sValue << "\' to bool." );
     123             :     }
     124          22 :     return def;
     125             : }
     126             : 
     127          86 : sal_Unicode XmlStream::AttributeList::attribute( int token, sal_Unicode def ) const
     128             : {
     129          86 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     130          86 :     if( find != attrs.end())
     131             :     {
     132          86 :         if( !find->second.isEmpty() )
     133             :         {
     134          86 :             if( find->second.getLength() != 1 )
     135             :                 SAL_WARN( "oox.xmlstream", "Cannot convert \'" << find->second << "\' to sal_Unicode, stripping." );
     136          86 :             return find->second[ 0 ];
     137             :         }
     138             :     }
     139           0 :     return def;
     140             : }
     141             : 
     142       10249 : XmlStream::Tag::Tag( int t, const uno::Reference< xml::sax::XFastAttributeList >& a, const OUString& txt )
     143             : : token( t )
     144             : , attributes( AttributeListBuilder( a ))
     145       10249 : , text( txt )
     146             : {
     147       10249 : }
     148             : 
     149         134 : XmlStream::Tag::Tag( int t, const AttributeList& a )
     150             : : token( t )
     151         134 : , attributes( a )
     152             : {
     153         134 : }
     154             : 
     155             : 
     156        1781 : XmlStream::Tag::operator bool() const
     157             : {
     158        1781 :     return token != XML_TOKEN_INVALID;
     159             : }
     160             : 
     161         355 : XmlStream::XmlStream()
     162         355 : : pos( 0 )
     163             : {
     164             :     // make sure our extra bit does not conflict with values used by oox
     165             :     assert( TAG_OPENING > ( 1024 << NMSP_SHIFT ));
     166         355 : }
     167             : 
     168       11763 : bool XmlStream::atEnd() const
     169             : {
     170       11763 :     return pos >= tags.size();
     171             : }
     172             : 
     173        7670 : XmlStream::Tag XmlStream::currentTag() const
     174             : {
     175        7670 :     if( pos >= tags.size())
     176           0 :         return Tag();
     177        7670 :     return tags[ pos ];
     178             : }
     179             : 
     180       44206 : int XmlStream::currentToken() const
     181             : {
     182       44206 :     if( pos >= tags.size())
     183           0 :         return XML_TOKEN_INVALID;
     184       44206 :     return tags[ pos ].token;
     185             : }
     186             : 
     187       13006 : void XmlStream::moveToNextTag()
     188             : {
     189       13006 :     if( pos < tags.size())
     190       13006 :         ++pos;
     191       13006 : }
     192             : 
     193        3288 : XmlStream::Tag XmlStream::ensureOpeningTag( int token )
     194             : {
     195        3288 :     return checkTag( OPENING( token ), false );
     196             : }
     197             : 
     198        1781 : XmlStream::Tag XmlStream::checkOpeningTag( int token )
     199             : {
     200        1781 :     return checkTag( OPENING( token ), true );
     201             : }
     202             : 
     203        3835 : void XmlStream::ensureClosingTag( int token )
     204             : {
     205        3835 :     checkTag( CLOSING( token ), false );
     206        3835 : }
     207             : 
     208        8904 : XmlStream::Tag XmlStream::checkTag( int token, bool optional )
     209             : {
     210             :     // either it's the following tag, or find it
     211        8904 :     int savedPos = pos;
     212        8904 :     if( optional )
     213             :     { // avoid printing debug messages about skipping tags if the optional one
     214             :       // will not be found and the position will be reset back
     215        1781 :         if( currentToken() != token && !findTagInternal( token, true ))
     216             :         {
     217        1234 :             pos = savedPos;
     218        1234 :             return Tag();
     219             :         }
     220             :     }
     221        7670 :     if( currentToken() == token || findTag( token ))
     222             :     {
     223        7670 :         Tag ret = currentTag();
     224        7670 :         moveToNextTag();
     225        7670 :         return ret; // ok
     226             :     }
     227           0 :     if( optional )
     228             :     { // not a problem, just rewind
     229           0 :         pos = savedPos;
     230           0 :         return Tag();
     231             :     }
     232             :     SAL_WARN( "oox.xmlstream", "Expected tag " << tokenToString( token ) << " not found." );
     233           0 :     return Tag();
     234             : }
     235             : 
     236         593 : bool XmlStream::findTag( int token )
     237             : {
     238         593 :     return findTagInternal( token, false );
     239             : }
     240             : 
     241        1829 : bool XmlStream::findTagInternal( int token, bool silent )
     242             : {
     243        1829 :     int depth = 0;
     244        8634 :     for(;
     245        6805 :          !atEnd();
     246        4976 :          moveToNextTag())
     247             :     {
     248        6805 :         if( depth > 0 ) // we're inside a nested element, skip those
     249             :         {
     250        3191 :             if( currentToken() == OPENING( currentToken()))
     251             :             {
     252         703 :                 if( !silent )
     253             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     254         703 :                 ++depth;
     255             :             }
     256        2488 :             else if( currentToken() == CLOSING( currentToken()))
     257             :             {
     258        2488 :                 if( !silent )
     259             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     260        2488 :                 --depth;
     261             :             }
     262             :             else
     263             :             {
     264           0 :                 if( !silent )
     265             :                     SAL_WARN( "oox.xmlstream", "Malformed token " << currentToken() << " ("
     266             :                         << tokenToString( currentToken()) << ")" );
     267           0 :                 abort();
     268             :             }
     269        3191 :             continue;
     270             :         }
     271        3614 :         if( currentToken() == token )
     272         486 :             return true; // ok, found
     273        3128 :         if( currentToken() == CLOSING( currentToken()))
     274        1343 :             return false; // that would be leaving current element, so not found
     275        1785 :         if( currentToken() == OPENING( currentToken()))
     276             :         {
     277        1785 :             if( !silent )
     278             :                 SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     279        1785 :             ++depth;
     280             :         }
     281             :         else
     282           0 :             abort();
     283             :     }
     284           0 :     if( !silent )
     285             :         SAL_WARN( "oox.xmlstream", "Unexpected end of stream reached." );
     286           0 :     return false;
     287             : }
     288             : 
     289         180 : void XmlStream::skipElementInternal( int token, bool silent )
     290             : {
     291         180 :     int closing = ( token & ~TAG_OPENING ) | TAG_CLOSING; // make it a closing tag
     292             :     assert( currentToken() == OPENING( token ));
     293         180 :     if( !silent )
     294             :         SAL_INFO( "oox.xmlstream", "Skipping unexpected element " << tokenToString( currentToken()));
     295         180 :     moveToNextTag();
     296             :     // and just find the matching closing tag
     297         180 :     if( findTag( closing ))
     298             :     {
     299         180 :         if( !silent )
     300             :             SAL_INFO( "oox.xmlstream", "Skipped unexpected element " << tokenToString( token ));
     301         180 :         moveToNextTag(); // and skip it too
     302         180 :         return;
     303             :     }
     304             :     // this one is an unexpected problem, do not silent it
     305             :     SAL_WARN( "oox.xmlstream", "Expected end of element " << tokenToString( token ) << " not found." );
     306             : }
     307             : 
     308         180 : void XmlStream::handleUnexpectedTag()
     309             : {
     310         180 :     if( atEnd())
     311           0 :         return;
     312         180 :     if( currentToken() == CLOSING( currentToken()))
     313             :     {
     314             :         SAL_INFO( "oox.xmlstream", "Skipping unexpected tag " << tokenToString( currentToken()));
     315           0 :         moveToNextTag(); // just skip it
     316           0 :         return;
     317             :     }
     318         180 :     skipElementInternal( currentToken(), false ); // otherwise skip the entire element
     319             : }
     320             : 
     321             : 
     322        4442 : void XmlStreamBuilder::appendOpeningTag( int token, const uno::Reference< xml::sax::XFastAttributeList >& attrs )
     323             : {
     324        4442 :     tags.push_back( Tag( OPENING( token ), attrs ));
     325        4442 : }
     326             : 
     327         134 : void XmlStreamBuilder::appendOpeningTag( int token, const AttributeList& attrs )
     328             : {
     329         134 :     tags.push_back( Tag( OPENING( token ), attrs ));
     330         134 : }
     331             : 
     332        4573 : void XmlStreamBuilder::appendClosingTag( int token )
     333             : {
     334        4573 :     tags.push_back( Tag( CLOSING( token )));
     335        4573 : }
     336             : 
     337        1050 : void XmlStreamBuilder::appendCharacters( const OUString& chars )
     338             : {
     339             :     assert( !tags.empty());
     340        1050 :     tags.back().text += chars;
     341        1050 : }
     342             : 
     343             : } // namespace
     344             : } // namespace
     345             : 
     346             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10