LCOV - code coverage report
Current view: top level - oox/source/mathml - importutils.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 119 159 74.8 %
Date: 2015-06-13 12:38:46 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             : 
      14             : #include <oox/token/namespacemap.hxx>
      15             : #include <oox/token/tokenmap.hxx>
      16             : #include <oox/token/tokens.hxx>
      17             : #include <oox/token/namespaces.hxx>
      18             : #include <rtl/ustring.hxx>
      19             : 
      20             : #define OPENING( token ) XML_STREAM_OPENING( token )
      21             : #define CLOSING( token ) XML_STREAM_CLOSING( token )
      22             : 
      23             : using namespace com::sun::star;
      24             : 
      25             : namespace oox
      26             : {
      27             : 
      28             : namespace formulaimport
      29             : {
      30             : 
      31             : namespace
      32             : {
      33             : // a class that inherits from AttributeList, builds the internal data and then will be sliced off
      34             : // during conversion to the base class
      35       17439 : class AttributeListBuilder
      36             :     : public XmlStream::AttributeList
      37             : {
      38             : public:
      39             :     explicit AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a );
      40             : };
      41             : 
      42       17439 : AttributeListBuilder::AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a )
      43             : {
      44       17439 :     if( a.get() == NULL )
      45       29551 :         return;
      46        5327 :     uno::Sequence< xml::FastAttribute > aFastAttrSeq = a->getFastAttributes();
      47        5327 :     const xml::FastAttribute* pFastAttr = aFastAttrSeq.getConstArray();
      48        5327 :     sal_Int32 nFastAttrLength = aFastAttrSeq.getLength();
      49        7917 :     for( int i = 0;
      50             :          i < nFastAttrLength;
      51             :          ++i )
      52             :     {
      53        2590 :         attrs[ pFastAttr[ i ].Token ] = pFastAttr[ i ].Value;
      54        5327 :     }
      55             : }
      56             : 
      57           0 : static OString tokenToString( int token )
      58             : {
      59           0 :     const uno::Sequence< sal_Int8 > aTokenNameSeq = StaticTokenMap::get().getUtf8TokenName( token & TOKEN_MASK );
      60           0 :     OString tokenname( reinterpret_cast< const char* >( aTokenNameSeq.getConstArray() ), aTokenNameSeq.getLength() );
      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             :     OString namespacename = StaticNamespaceMap::get().count( nmsp ) != 0
      66             :         ? StaticNamespaceMap::get()[ nmsp ] : OString( "???" );
      67             : #else
      68           0 :     OString 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        1747 : OUString XmlStream::AttributeList::attribute( int token, const OUString& def ) const
      99             : {
     100        1747 :     std::map< int, OUString >::const_iterator find = attrs.find( token );
     101        1747 :     if( find != attrs.end())
     102         867 :         return find->second;
     103         880 :     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       17439 : XmlStream::Tag::Tag( int t, const uno::Reference< xml::sax::XFastAttributeList >& a, const OUString& txt )
     143             : : token( t )
     144             : , attributes( AttributeListBuilder( a ))
     145       17439 : , text( txt )
     146             : {
     147       17439 : }
     148             : 
     149         169 : XmlStream::Tag::Tag( int t, const AttributeList& a )
     150             : : token( t )
     151         169 : , attributes( a )
     152             : {
     153         169 : }
     154             : 
     155        2804 : XmlStream::Tag::operator bool() const
     156             : {
     157        2804 :     return token != XML_TOKEN_INVALID;
     158             : }
     159             : 
     160         772 : XmlStream::XmlStream()
     161         772 : : pos( 0 )
     162             : {
     163             :     // make sure our extra bit does not conflict with values used by oox
     164             :     assert( TAG_OPENING > ( 1024 << NMSP_SHIFT ));
     165         772 : }
     166             : 
     167       20796 : bool XmlStream::atEnd() const
     168             : {
     169       20796 :     return pos >= tags.size();
     170             : }
     171             : 
     172       11892 : XmlStream::Tag XmlStream::currentTag() const
     173             : {
     174       11892 :     if( pos >= tags.size())
     175           0 :         return Tag();
     176       11892 :     return tags[ pos ];
     177             : }
     178             : 
     179       77080 : int XmlStream::currentToken() const
     180             : {
     181       77080 :     if( pos >= tags.size())
     182           0 :         return XML_TOKEN_INVALID;
     183       77080 :     return tags[ pos ].token;
     184             : }
     185             : 
     186       22494 : void XmlStream::moveToNextTag()
     187             : {
     188       22494 :     if( pos < tags.size())
     189       22494 :         ++pos;
     190       22494 : }
     191             : 
     192        5051 : XmlStream::Tag XmlStream::ensureOpeningTag( int token )
     193             : {
     194        5051 :     return checkTag( OPENING( token ), false );
     195             : }
     196             : 
     197        2804 : XmlStream::Tag XmlStream::checkOpeningTag( int token )
     198             : {
     199        2804 :     return checkTag( OPENING( token ), true );
     200             : }
     201             : 
     202        5946 : void XmlStream::ensureClosingTag( int token )
     203             : {
     204        5946 :     checkTag( CLOSING( token ), false );
     205        5946 : }
     206             : 
     207       13801 : XmlStream::Tag XmlStream::checkTag( int token, bool optional )
     208             : {
     209             :     // either it's the following tag, or find it
     210       13801 :     int savedPos = pos;
     211       13801 :     if( optional )
     212             :     { // avoid printing debug messages about skipping tags if the optional one
     213             :       // will not be found and the position will be reset back
     214        2804 :         if( currentToken() != token && !findTagInternal( token, true ))
     215             :         {
     216        1909 :             pos = savedPos;
     217        1909 :             return Tag();
     218             :         }
     219             :     }
     220       11892 :     if( currentToken() == token || findTag( token ))
     221             :     {
     222       11892 :         Tag ret = currentTag();
     223       11892 :         moveToNextTag();
     224       11892 :         return ret; // ok
     225             :     }
     226           0 :     if( optional )
     227             :     { // not a problem, just rewind
     228           0 :         pos = savedPos;
     229           0 :         return Tag();
     230             :     }
     231             :     SAL_WARN( "oox.xmlstream", "Expected tag " << tokenToString( token ) << " not found." );
     232           0 :     return Tag();
     233             : }
     234             : 
     235        1177 : bool XmlStream::findTag( int token )
     236             : {
     237        1177 :     return findTagInternal( token, false );
     238             : }
     239             : 
     240        3089 : bool XmlStream::findTagInternal( int token, bool silent )
     241             : {
     242        3089 :     int depth = 0;
     243       15904 :     for(;
     244       12815 :          !atEnd();
     245        9726 :          moveToNextTag())
     246             :     {
     247       12815 :         if( depth > 0 ) // we're inside a nested element, skip those
     248             :         {
     249        6469 :             if( currentToken() == OPENING( currentToken()))
     250             :             {
     251        1606 :                 if( !silent )
     252             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     253        1606 :                 ++depth;
     254             :             }
     255        4863 :             else if( currentToken() == CLOSING( currentToken()))
     256             :             {
     257        4863 :                 if( !silent )
     258             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     259        4863 :                 --depth;
     260             :             }
     261             :             else
     262             :             {
     263           0 :                 if( !silent )
     264             :                     SAL_WARN( "oox.xmlstream", "Malformed token " << currentToken() << " ("
     265             :                         << tokenToString( currentToken()) << ")" );
     266           0 :                 abort();
     267             :             }
     268        6469 :             continue;
     269             :         }
     270        6346 :         if( currentToken() == token )
     271        1003 :             return true; // ok, found
     272        5343 :         if( currentToken() == CLOSING( currentToken()))
     273        2086 :             return false; // that would be leaving current element, so not found
     274        3257 :         if( currentToken() == OPENING( currentToken()))
     275             :         {
     276        3257 :             if( !silent )
     277             :                 SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     278        3257 :             ++depth;
     279             :         }
     280             :         else
     281           0 :             abort();
     282             :     }
     283           0 :     if( !silent )
     284             :         SAL_WARN( "oox.xmlstream", "Unexpected end of stream reached." );
     285           0 :     return false;
     286             : }
     287             : 
     288         438 : void XmlStream::skipElementInternal( int token, bool silent )
     289             : {
     290         438 :     int closing = ( token & ~TAG_OPENING ) | TAG_CLOSING; // make it a closing tag
     291             :     assert( currentToken() == OPENING( token ));
     292         438 :     if( !silent )
     293             :         SAL_INFO( "oox.xmlstream", "Skipping unexpected element " << tokenToString( currentToken()));
     294         438 :     moveToNextTag();
     295             :     // and just find the matching closing tag
     296         438 :     if( findTag( closing ))
     297             :     {
     298         438 :         if( !silent )
     299             :             SAL_INFO( "oox.xmlstream", "Skipped unexpected element " << tokenToString( token ));
     300         438 :         moveToNextTag(); // and skip it too
     301         438 :         return;
     302             :     }
     303             :     // this one is an unexpected problem, do not silent it
     304             :     SAL_WARN( "oox.xmlstream", "Expected end of element " << tokenToString( token ) << " not found." );
     305             : }
     306             : 
     307         438 : void XmlStream::handleUnexpectedTag()
     308             : {
     309         438 :     if( atEnd())
     310           0 :         return;
     311         438 :     if( currentToken() == CLOSING( currentToken()))
     312             :     {
     313             :         SAL_INFO( "oox.xmlstream", "Skipping unexpected tag " << tokenToString( currentToken()));
     314           0 :         moveToNextTag(); // just skip it
     315           0 :         return;
     316             :     }
     317         438 :     skipElementInternal( currentToken(), false ); // otherwise skip the entire element
     318             : }
     319             : 
     320        7682 : void XmlStreamBuilder::appendOpeningTag( int token, const uno::Reference< xml::sax::XFastAttributeList >& attrs )
     321             : {
     322        7682 :     tags.push_back( Tag( OPENING( token ), attrs ));
     323        7682 : }
     324             : 
     325         169 : void XmlStreamBuilder::appendOpeningTag( int token, const AttributeList& attrs )
     326             : {
     327         169 :     tags.push_back( Tag( OPENING( token ), attrs ));
     328         169 : }
     329             : 
     330        7848 : void XmlStreamBuilder::appendClosingTag( int token )
     331             : {
     332        7848 :     tags.push_back( Tag( CLOSING( token )));
     333        7848 : }
     334             : 
     335        1498 : void XmlStreamBuilder::appendCharacters( const OUString& chars )
     336             : {
     337             :     assert( !tags.empty());
     338        1498 :     tags.back().text += chars;
     339        1498 : }
     340             : 
     341             : } // namespace
     342             : } // namespace
     343             : 
     344             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11