LCOV - code coverage report
Current view: top level - oox/source/mathml - importutils.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 119 158 75.3 %
Date: 2014-04-11 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       17435 : class AttributeListBuilder
      37             :     : public XmlStream::AttributeList
      38             : {
      39             : public:
      40             :     AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a );
      41             : };
      42             : 
      43       17435 : AttributeListBuilder::AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a )
      44             : {
      45       17435 :     if( a.get() == NULL )
      46       29543 :         return;
      47        5327 :     uno::Sequence< xml::FastAttribute > aFastAttrSeq = a->getFastAttributes();
      48        5327 :     const xml::FastAttribute* pFastAttr = aFastAttrSeq.getConstArray();
      49        5327 :     sal_Int32 nFastAttrLength = aFastAttrSeq.getLength();
      50        7917 :     for( int i = 0;
      51             :          i < nFastAttrLength;
      52             :          ++i )
      53             :     {
      54        2590 :         attrs[ pFastAttr[ i ].Token ] = pFastAttr[ i ].Value;
      55        5327 :     }
      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         169 : OUString& XmlStream::AttributeList::operator[] (int token)
      94             : {
      95         169 :     return attrs[token];
      96             : }
      97             : 
      98        1746 : OUString XmlStream::AttributeList::attribute( int token, const OUString& def ) const
      99             : {
     100        1746 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     101        1746 :     if( find != attrs.end())
     102         867 :         return find->second;
     103         879 :     return def;
     104             : }
     105             : 
     106          72 : bool XmlStream::AttributeList::attribute( int token, bool def ) const
     107             : {
     108          72 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     109          72 :     if( find != attrs.end())
     110             :     {
     111          37 :         const OUString sValue = find->second;
     112         111 :         if( sValue.equalsIgnoreAsciiCase("true") ||
     113          67 :             sValue.equalsIgnoreAsciiCase("on") ||
     114          97 :             sValue.equalsIgnoreAsciiCase("t") ||
     115          30 :             sValue.equalsIgnoreAsciiCase("1") )
     116          37 :             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          35 :     return def;
     125             : }
     126             : 
     127         127 : sal_Unicode XmlStream::AttributeList::attribute( int token, sal_Unicode def ) const
     128             : {
     129         127 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     130         127 :     if( find != attrs.end())
     131             :     {
     132         127 :         if( !find->second.isEmpty() )
     133             :         {
     134         127 :             if( find->second.getLength() != 1 )
     135             :                 SAL_WARN( "oox.xmlstream", "Cannot convert \'" << find->second << "\' to sal_Unicode, stripping." );
     136         127 :             return find->second[ 0 ];
     137             :         }
     138             :     }
     139           0 :     return def;
     140             : }
     141             : 
     142       17435 : XmlStream::Tag::Tag( int t, const uno::Reference< xml::sax::XFastAttributeList >& a, const OUString& txt )
     143             : : token( t )
     144             : , attributes( AttributeListBuilder( a ))
     145       17435 : , text( txt )
     146             : {
     147       17435 : }
     148             : 
     149         169 : XmlStream::Tag::Tag( int t, const AttributeList& a )
     150             : : token( t )
     151         169 : , attributes( a )
     152             : {
     153         169 : }
     154             : 
     155             : 
     156        2803 : XmlStream::Tag::operator bool() const
     157             : {
     158        2803 :     return token != XML_TOKEN_INVALID;
     159             : }
     160             : 
     161         580 : XmlStream::XmlStream()
     162         580 : : 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         580 : }
     167             : 
     168       20778 : bool XmlStream::atEnd() const
     169             : {
     170       20778 :     return pos >= tags.size();
     171             : }
     172             : 
     173       11886 : XmlStream::Tag XmlStream::currentTag() const
     174             : {
     175       11886 :     if( pos >= tags.size())
     176           0 :         return Tag();
     177       11886 :     return tags[ pos ];
     178             : }
     179             : 
     180       77020 : int XmlStream::currentToken() const
     181             : {
     182       77020 :     if( pos >= tags.size())
     183           0 :         return XML_TOKEN_INVALID;
     184       77020 :     return tags[ pos ].token;
     185             : }
     186             : 
     187       22478 : void XmlStream::moveToNextTag()
     188             : {
     189       22478 :     if( pos < tags.size())
     190       22478 :         ++pos;
     191       22478 : }
     192             : 
     193        5048 : XmlStream::Tag XmlStream::ensureOpeningTag( int token )
     194             : {
     195        5048 :     return checkTag( OPENING( token ), false );
     196             : }
     197             : 
     198        2803 : XmlStream::Tag XmlStream::checkOpeningTag( int token )
     199             : {
     200        2803 :     return checkTag( OPENING( token ), true );
     201             : }
     202             : 
     203        5943 : void XmlStream::ensureClosingTag( int token )
     204             : {
     205        5943 :     checkTag( CLOSING( token ), false );
     206        5943 : }
     207             : 
     208       13794 : XmlStream::Tag XmlStream::checkTag( int token, bool optional )
     209             : {
     210             :     // either it's the following tag, or find it
     211       13794 :     int savedPos = pos;
     212       13794 :     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        2803 :         if( currentToken() != token && !findTagInternal( token, true ))
     216             :         {
     217        1908 :             pos = savedPos;
     218        1908 :             return Tag();
     219             :         }
     220             :     }
     221       11886 :     if( currentToken() == token || findTag( token ))
     222             :     {
     223       11886 :         Tag ret = currentTag();
     224       11886 :         moveToNextTag();
     225       11886 :         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        1176 : bool XmlStream::findTag( int token )
     237             : {
     238        1176 :     return findTagInternal( token, false );
     239             : }
     240             : 
     241        3087 : bool XmlStream::findTagInternal( int token, bool silent )
     242             : {
     243        3087 :     int depth = 0;
     244       15892 :     for(;
     245       12805 :          !atEnd();
     246        9718 :          moveToNextTag())
     247             :     {
     248       12805 :         if( depth > 0 ) // we're inside a nested element, skip those
     249             :         {
     250        6464 :             if( currentToken() == OPENING( currentToken()))
     251             :             {
     252        1605 :                 if( !silent )
     253             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     254        1605 :                 ++depth;
     255             :             }
     256        4859 :             else if( currentToken() == CLOSING( currentToken()))
     257             :             {
     258        4859 :                 if( !silent )
     259             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     260        4859 :                 --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        6464 :             continue;
     270             :         }
     271        6341 :         if( currentToken() == token )
     272        1002 :             return true; // ok, found
     273        5339 :         if( currentToken() == CLOSING( currentToken()))
     274        2085 :             return false; // that would be leaving current element, so not found
     275        3254 :         if( currentToken() == OPENING( currentToken()))
     276             :         {
     277        3254 :             if( !silent )
     278             :                 SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     279        3254 :             ++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         437 : void XmlStream::skipElementInternal( int token, bool silent )
     290             : {
     291         437 :     int closing = ( token & ~TAG_OPENING ) | TAG_CLOSING; // make it a closing tag
     292             :     assert( currentToken() == OPENING( token ));
     293         437 :     if( !silent )
     294             :         SAL_INFO( "oox.xmlstream", "Skipping unexpected element " << tokenToString( currentToken()));
     295         437 :     moveToNextTag();
     296             :     // and just find the matching closing tag
     297         437 :     if( findTag( closing ))
     298             :     {
     299         437 :         if( !silent )
     300             :             SAL_INFO( "oox.xmlstream", "Skipped unexpected element " << tokenToString( token ));
     301         437 :         moveToNextTag(); // and skip it too
     302         437 :         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         437 : void XmlStream::handleUnexpectedTag()
     309             : {
     310         437 :     if( atEnd())
     311           0 :         return;
     312         437 :     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         437 :     skipElementInternal( currentToken(), false ); // otherwise skip the entire element
     319             : }
     320             : 
     321             : 
     322        7682 : void XmlStreamBuilder::appendOpeningTag( int token, const uno::Reference< xml::sax::XFastAttributeList >& attrs )
     323             : {
     324        7682 :     tags.push_back( Tag( OPENING( token ), attrs ));
     325        7682 : }
     326             : 
     327         169 : void XmlStreamBuilder::appendOpeningTag( int token, const AttributeList& attrs )
     328             : {
     329         169 :     tags.push_back( Tag( OPENING( token ), attrs ));
     330         169 : }
     331             : 
     332        7845 : void XmlStreamBuilder::appendClosingTag( int token )
     333             : {
     334        7845 :     tags.push_back( Tag( CLOSING( token )));
     335        7845 : }
     336             : 
     337        1538 : void XmlStreamBuilder::appendCharacters( const OUString& chars )
     338             : {
     339             :     assert( !tags.empty());
     340        1538 :     tags.back().text += chars;
     341        1538 : }
     342             : 
     343             : } // namespace
     344             : } // namespace
     345             : 
     346             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10