LCOV - code coverage report
Current view: top level - oox/source/mathml - importutils.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 119 159 74.8 %
Date: 2014-11-03 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       34892 : class AttributeListBuilder
      37             :     : public XmlStream::AttributeList
      38             : {
      39             : public:
      40             :     AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a );
      41             : };
      42             : 
      43       34892 : AttributeListBuilder::AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a )
      44             : {
      45       34892 :     if( a.get() == NULL )
      46       59120 :         return;
      47       10664 :     uno::Sequence< xml::FastAttribute > aFastAttrSeq = a->getFastAttributes();
      48       10664 :     const xml::FastAttribute* pFastAttr = aFastAttrSeq.getConstArray();
      49       10664 :     sal_Int32 nFastAttrLength = aFastAttrSeq.getLength();
      50       15848 :     for( int i = 0;
      51             :          i < nFastAttrLength;
      52             :          ++i )
      53             :     {
      54        5184 :         attrs[ pFastAttr[ i ].Token ] = pFastAttr[ i ].Value;
      55       10664 :     }
      56             : }
      57             : 
      58           0 : static OString tokenToString( int token )
      59             : {
      60           0 :     const uno::Sequence< sal_Int8 > aTokenNameSeq = StaticTokenMap::get().getUtf8TokenName( token & TOKEN_MASK );
      61           0 :     OString tokenname( reinterpret_cast< const char* >( aTokenNameSeq.getConstArray() ), aTokenNameSeq.getLength() );
      62           0 :     if( tokenname.isEmpty())
      63           0 :         tokenname = "???";
      64           0 :     int nmsp = ( token & NMSP_MASK & ~( TAG_OPENING | TAG_CLOSING ));
      65             : #if 0 // this is awfully long
      66             :     OString namespacename = StaticNamespaceMap::get().count( nmsp ) != 0
      67             :         ? StaticNamespaceMap::get()[ nmsp ] : OString( "???" );
      68             : #else
      69           0 :     OString namespacename;
      70             :     // only few are needed actually
      71           0 :     switch( nmsp )
      72             :     {
      73             :         case NMSP_officeMath:
      74           0 :             namespacename = "m";
      75           0 :             break;
      76             :         case NMSP_doc:
      77           0 :             namespacename = "w";
      78           0 :             break;
      79             :         default:
      80           0 :             namespacename = "?";
      81           0 :             break;
      82             :     }
      83             : #endif
      84           0 :     if( token == OPENING( token ))
      85           0 :         return "<" + namespacename + ":" + tokenname + ">";
      86           0 :     if( token == CLOSING( token ))
      87           0 :         return "</" + namespacename + ":" + tokenname + ">";
      88             :     // just the name itself, not specified whether opening or closing
      89           0 :     return namespacename + ":" + tokenname;
      90             : }
      91             : 
      92             : } // namespace
      93             : 
      94         338 : OUString& XmlStream::AttributeList::operator[] (int token)
      95             : {
      96         338 :     return attrs[token];
      97             : }
      98             : 
      99        3494 : OUString XmlStream::AttributeList::attribute( int token, const OUString& def ) const
     100             : {
     101        3494 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     102        3494 :     if( find != attrs.end())
     103        1734 :         return find->second;
     104        1760 :     return def;
     105             : }
     106             : 
     107         144 : bool XmlStream::AttributeList::attribute( int token, bool def ) const
     108             : {
     109         144 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     110         144 :     if( find != attrs.end())
     111             :     {
     112          74 :         const OUString sValue = find->second;
     113         222 :         if( sValue.equalsIgnoreAsciiCase("true") ||
     114         134 :             sValue.equalsIgnoreAsciiCase("on") ||
     115         194 :             sValue.equalsIgnoreAsciiCase("t") ||
     116          60 :             sValue.equalsIgnoreAsciiCase("1") )
     117          74 :             return true;
     118           0 :         if( sValue.equalsIgnoreAsciiCase("false") ||
     119           0 :             sValue.equalsIgnoreAsciiCase("off") ||
     120           0 :             sValue.equalsIgnoreAsciiCase("f") ||
     121           0 :             sValue.equalsIgnoreAsciiCase("0") )
     122           0 :             return false;
     123           0 :         SAL_WARN( "oox.xmlstream", "Cannot convert \'" << sValue << "\' to bool." );
     124             :     }
     125          70 :     return def;
     126             : }
     127             : 
     128         254 : sal_Unicode XmlStream::AttributeList::attribute( int token, sal_Unicode def ) const
     129             : {
     130         254 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     131         254 :     if( find != attrs.end())
     132             :     {
     133         254 :         if( !find->second.isEmpty() )
     134             :         {
     135         254 :             if( find->second.getLength() != 1 )
     136             :                 SAL_WARN( "oox.xmlstream", "Cannot convert \'" << find->second << "\' to sal_Unicode, stripping." );
     137         254 :             return find->second[ 0 ];
     138             :         }
     139             :     }
     140           0 :     return def;
     141             : }
     142             : 
     143       34892 : XmlStream::Tag::Tag( int t, const uno::Reference< xml::sax::XFastAttributeList >& a, const OUString& txt )
     144             : : token( t )
     145             : , attributes( AttributeListBuilder( a ))
     146       34892 : , text( txt )
     147             : {
     148       34892 : }
     149             : 
     150         338 : XmlStream::Tag::Tag( int t, const AttributeList& a )
     151             : : token( t )
     152         338 : , attributes( a )
     153             : {
     154         338 : }
     155             : 
     156        5608 : XmlStream::Tag::operator bool() const
     157             : {
     158        5608 :     return token != XML_TOKEN_INVALID;
     159             : }
     160             : 
     161        1352 : XmlStream::XmlStream()
     162        1352 : : 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        1352 : }
     167             : 
     168       41592 : bool XmlStream::atEnd() const
     169             : {
     170       41592 :     return pos >= tags.size();
     171             : }
     172             : 
     173       23784 : XmlStream::Tag XmlStream::currentTag() const
     174             : {
     175       23784 :     if( pos >= tags.size())
     176           0 :         return Tag();
     177       23784 :     return tags[ pos ];
     178             : }
     179             : 
     180      154160 : int XmlStream::currentToken() const
     181             : {
     182      154160 :     if( pos >= tags.size())
     183           0 :         return XML_TOKEN_INVALID;
     184      154160 :     return tags[ pos ].token;
     185             : }
     186             : 
     187       44988 : void XmlStream::moveToNextTag()
     188             : {
     189       44988 :     if( pos < tags.size())
     190       44988 :         ++pos;
     191       44988 : }
     192             : 
     193       10102 : XmlStream::Tag XmlStream::ensureOpeningTag( int token )
     194             : {
     195       10102 :     return checkTag( OPENING( token ), false );
     196             : }
     197             : 
     198        5608 : XmlStream::Tag XmlStream::checkOpeningTag( int token )
     199             : {
     200        5608 :     return checkTag( OPENING( token ), true );
     201             : }
     202             : 
     203       11892 : void XmlStream::ensureClosingTag( int token )
     204             : {
     205       11892 :     checkTag( CLOSING( token ), false );
     206       11892 : }
     207             : 
     208       27602 : XmlStream::Tag XmlStream::checkTag( int token, bool optional )
     209             : {
     210             :     // either it's the following tag, or find it
     211       27602 :     int savedPos = pos;
     212       27602 :     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        5608 :         if( currentToken() != token && !findTagInternal( token, true ))
     216             :         {
     217        3818 :             pos = savedPos;
     218        3818 :             return Tag();
     219             :         }
     220             :     }
     221       23784 :     if( currentToken() == token || findTag( token ))
     222             :     {
     223       23784 :         Tag ret = currentTag();
     224       23784 :         moveToNextTag();
     225       23784 :         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        2354 : bool XmlStream::findTag( int token )
     237             : {
     238        2354 :     return findTagInternal( token, false );
     239             : }
     240             : 
     241        6178 : bool XmlStream::findTagInternal( int token, bool silent )
     242             : {
     243        6178 :     int depth = 0;
     244       31808 :     for(;
     245       25630 :          !atEnd();
     246       19452 :          moveToNextTag())
     247             :     {
     248       25630 :         if( depth > 0 ) // we're inside a nested element, skip those
     249             :         {
     250       12938 :             if( currentToken() == OPENING( currentToken()))
     251             :             {
     252        3212 :                 if( !silent )
     253             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     254        3212 :                 ++depth;
     255             :             }
     256        9726 :             else if( currentToken() == CLOSING( currentToken()))
     257             :             {
     258        9726 :                 if( !silent )
     259             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     260        9726 :                 --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       12938 :             continue;
     270             :         }
     271       12692 :         if( currentToken() == token )
     272        2006 :             return true; // ok, found
     273       10686 :         if( currentToken() == CLOSING( currentToken()))
     274        4172 :             return false; // that would be leaving current element, so not found
     275        6514 :         if( currentToken() == OPENING( currentToken()))
     276             :         {
     277        6514 :             if( !silent )
     278             :                 SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     279        6514 :             ++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         876 : void XmlStream::skipElementInternal( int token, bool silent )
     290             : {
     291         876 :     int closing = ( token & ~TAG_OPENING ) | TAG_CLOSING; // make it a closing tag
     292             :     assert( currentToken() == OPENING( token ));
     293         876 :     if( !silent )
     294             :         SAL_INFO( "oox.xmlstream", "Skipping unexpected element " << tokenToString( currentToken()));
     295         876 :     moveToNextTag();
     296             :     // and just find the matching closing tag
     297         876 :     if( findTag( closing ))
     298             :     {
     299         876 :         if( !silent )
     300             :             SAL_INFO( "oox.xmlstream", "Skipped unexpected element " << tokenToString( token ));
     301         876 :         moveToNextTag(); // and skip it too
     302         876 :         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         876 : void XmlStream::handleUnexpectedTag()
     309             : {
     310         876 :     if( atEnd())
     311           0 :         return;
     312         876 :     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         876 :     skipElementInternal( currentToken(), false ); // otherwise skip the entire element
     319             : }
     320             : 
     321       15374 : void XmlStreamBuilder::appendOpeningTag( int token, const uno::Reference< xml::sax::XFastAttributeList >& attrs )
     322             : {
     323       15374 :     tags.push_back( Tag( OPENING( token ), attrs ));
     324       15374 : }
     325             : 
     326         338 : void XmlStreamBuilder::appendOpeningTag( int token, const AttributeList& attrs )
     327             : {
     328         338 :     tags.push_back( Tag( OPENING( token ), attrs ));
     329         338 : }
     330             : 
     331       15700 : void XmlStreamBuilder::appendClosingTag( int token )
     332             : {
     333       15700 :     tags.push_back( Tag( CLOSING( token )));
     334       15700 : }
     335             : 
     336        3078 : void XmlStreamBuilder::appendCharacters( const OUString& chars )
     337             : {
     338             :     assert( !tags.empty());
     339        3078 :     tags.back().text += chars;
     340        3078 : }
     341             : 
     342             : } // namespace
     343             : } // namespace
     344             : 
     345             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10