LCOV - code coverage report
Current view: top level - libreoffice/oox/source/mathml - importutils.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 107 158 67.7 %
Date: 2012-12-27 Functions: 24 27 88.9 %
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             :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       4             :  *
       5             :  * The contents of this file are subject to the Mozilla Public License Version
       6             :  * 1.1 (the "License"); you may not use this file except in compliance with
       7             :  * the License or as specified alternatively below. You may obtain a copy of
       8             :  * the License at http://www.mozilla.org/MPL/
       9             :  *
      10             :  * Software distributed under the License is distributed on an "AS IS" basis,
      11             :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12             :  * for the specific language governing rights and limitations under the
      13             :  * License.
      14             :  *
      15             :  * Major Contributor(s):
      16             :  * Copyright (C) 2011 Tor Lillqvist <tlillqvist@suse.com> (initial developer)
      17             :  *
      18             :  * All Rights Reserved.
      19             :  *
      20             :  * For minor contributions see the git repository.
      21             :  *
      22             :  * Alternatively, the contents of this file may be used under the terms of
      23             :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      24             :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      25             :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      26             :  * instead of those above.
      27             :  */
      28             : 
      29             : #include "oox/mathml/importutils.hxx"
      30             : 
      31             : #include <assert.h>
      32             : #include <stdio.h>
      33             : 
      34             : #include <oox/token/namespacemap.hxx>
      35             : #include <oox/token/tokenmap.hxx>
      36             : #include <oox/token/tokens.hxx>
      37             : #include <oox/token/namespaces.hxx>
      38             : #include <rtl/ustring.hxx>
      39             : 
      40             : // *sigh*
      41             : #define STR( str ) OUString( RTL_CONSTASCII_USTRINGPARAM( str ))
      42             : 
      43             : #define OPENING( token ) XML_STREAM_OPENING( token )
      44             : #define CLOSING( token ) XML_STREAM_CLOSING( token )
      45             : 
      46             : using namespace com::sun::star;
      47             : using rtl::OUString;
      48             : 
      49             : namespace oox
      50             : {
      51             : 
      52             : namespace formulaimport
      53             : {
      54             : 
      55             : namespace
      56             : {
      57             : // a class that inherits from AttributeList, builds the internal data and then will be sliced off
      58             : // during conversion to the base class
      59        9638 : class AttributeListBuilder
      60             :     : public XmlStream::AttributeList
      61             : {
      62             : public:
      63             :     AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a );
      64             : };
      65             : 
      66        9638 : AttributeListBuilder::AttributeListBuilder( const uno::Reference< xml::sax::XFastAttributeList >& a )
      67             : {
      68        9638 :     if( a.get() == NULL )
      69        9638 :         return;
      70        2353 :     uno::Sequence< xml::FastAttribute > aFastAttrSeq = a->getFastAttributes();
      71        2353 :     const xml::FastAttribute* pFastAttr = aFastAttrSeq.getConstArray();
      72        2353 :     sal_Int32 nFastAttrLength = aFastAttrSeq.getLength();
      73        3516 :     for( int i = 0;
      74             :          i < nFastAttrLength;
      75             :          ++i )
      76             :     {
      77        1163 :         attrs[ pFastAttr[ i ].Token ] = pFastAttr[ i ].Value;
      78        2353 :     }
      79             : }
      80             : 
      81           0 : static OUString tokenToString( int token )
      82             : {
      83           0 :     OUString tokenname = StaticTokenMap::get().getUnicodeTokenName( token & TOKEN_MASK );
      84           0 :     if( tokenname.isEmpty())
      85           0 :         tokenname = STR( "???" );
      86           0 :     int nmsp = ( token & NMSP_MASK & ~( TAG_OPENING | TAG_CLOSING ));
      87             : #if 0 // this is awfully long
      88             :     OUString namespacename = StaticNamespaceMap::get().count( nmsp ) != 0
      89             :         ? StaticNamespaceMap::get()[ nmsp ] : STR( "???" );
      90             : #else
      91           0 :     OUString namespacename;
      92             :     // only few are needed actually
      93           0 :     switch( nmsp )
      94             :     {
      95             :         case NMSP_officeMath:
      96           0 :             namespacename = STR( "m" );
      97           0 :             break;
      98             :         case NMSP_doc:
      99           0 :             namespacename = STR( "w" );
     100           0 :             break;
     101             :         default:
     102           0 :             namespacename = STR( "?" );
     103           0 :             break;
     104             :     }
     105             : #endif
     106           0 :     if( token == OPENING( token ))
     107           0 :         return STR( "<" ) + namespacename + STR( ":" ) + tokenname + STR ( ">" );
     108           0 :     if( token == CLOSING( token ))
     109           0 :         return STR( "</" ) + namespacename + STR( ":" ) + tokenname + STR ( ">" );
     110             :     // just the name itself, not specified whether opening or closing
     111           0 :     return namespacename + STR( ":" ) + tokenname;
     112             : }
     113             : 
     114             : } // namespace
     115             : 
     116         130 : OUString& XmlStream::AttributeList::operator[] (int token)
     117             : {
     118         130 :     return attrs[token];
     119             : }
     120             : 
     121        1117 : rtl::OUString XmlStream::AttributeList::attribute( int token, const rtl::OUString& def ) const
     122             : {
     123        1117 :     std::map< int, rtl::OUString >::const_iterator find = attrs.find( token );
     124        1117 :     if( find != attrs.end())
     125         514 :         return find->second;
     126         603 :     return def;
     127             : }
     128             : 
     129          20 : bool XmlStream::AttributeList::attribute( int token, bool def ) const
     130             : {
     131          20 :     std::map< int, rtl::OUString >::const_iterator find = attrs.find( token );
     132          20 :     if( find != attrs.end())
     133             :     {
     134          20 :         const rtl::OUString sValue = find->second;
     135          68 :         if( sValue.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("true")) ||
     136          20 :             sValue.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("on")) ||
     137          14 :             sValue.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("t")) ||
     138          14 :             sValue.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("1")) )
     139          20 :             return true;
     140           0 :         if( sValue.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("false")) ||
     141           0 :             sValue.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("off")) ||
     142           0 :             sValue.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("f")) ||
     143           0 :             sValue.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("0")) )
     144           0 :             return false;
     145          20 :         SAL_WARN( "oox.xmlstream", "Cannot convert \'" << sValue << "\' to bool." );
     146             :     }
     147           0 :     return def;
     148             : }
     149             : 
     150          78 : sal_Unicode XmlStream::AttributeList::attribute( int token, sal_Unicode def ) const
     151             : {
     152          78 :     std::map< int, rtl::OUString >::const_iterator find = attrs.find( token );
     153          78 :     if( find != attrs.end())
     154             :     {
     155          78 :         if( !find->second.isEmpty() )
     156             :         {
     157          78 :             if( find->second.getLength() != 1 )
     158             :                 SAL_WARN( "oox.xmlstream", "Cannot convert \'" << find->second << "\' to sal_Unicode, stripping." );
     159          78 :             return find->second[ 0 ];
     160             :         }
     161             :     }
     162           0 :     return def;
     163             : }
     164             : 
     165        9638 : XmlStream::Tag::Tag( int t, const uno::Reference< xml::sax::XFastAttributeList >& a, const rtl::OUString& txt )
     166             : : token( t )
     167             : , attributes( AttributeListBuilder( a ))
     168        9638 : , text( txt )
     169             : {
     170        9638 : }
     171             : 
     172         130 : XmlStream::Tag::Tag( int t, const AttributeList& a )
     173             : : token( t )
     174         130 : , attributes( a )
     175             : {
     176         130 : }
     177             : 
     178             : 
     179        1648 : XmlStream::Tag::operator bool() const
     180             : {
     181        1648 :     return token != XML_TOKEN_INVALID;
     182             : }
     183             : 
     184         282 : XmlStream::XmlStream()
     185         282 : : pos( 0 )
     186             : {
     187             :     // make sure our extra bit does not conflict with values used by oox
     188             :     assert( TAG_OPENING > ( 1024 << NMSP_SHIFT ));
     189         282 : }
     190             : 
     191        9917 : bool XmlStream::atEnd() const
     192             : {
     193        9917 :     return pos >= tags.size();
     194             : }
     195             : 
     196        7640 : XmlStream::Tag XmlStream::currentTag() const
     197             : {
     198        7640 :     if( pos >= tags.size())
     199           0 :         return Tag();
     200        7640 :     return tags[ pos ];
     201             : }
     202             : 
     203       37524 : int XmlStream::currentToken() const
     204             : {
     205       37524 :     if( pos >= tags.size())
     206           0 :         return XML_TOKEN_INVALID;
     207       37524 :     return tags[ pos ].token;
     208             : }
     209             : 
     210       11538 : void XmlStream::moveToNextTag()
     211             : {
     212       11538 :     if( pos < tags.size())
     213       11538 :         ++pos;
     214       11538 : }
     215             : 
     216        3173 : XmlStream::Tag XmlStream::ensureOpeningTag( int token )
     217             : {
     218        3173 :     return checkTag( OPENING( token ), false );
     219             : }
     220             : 
     221        1648 : XmlStream::Tag XmlStream::checkOpeningTag( int token )
     222             : {
     223        1648 :     return checkTag( OPENING( token ), true );
     224             : }
     225             : 
     226        3820 : void XmlStream::ensureClosingTag( int token )
     227             : {
     228        3820 :     checkTag( CLOSING( token ), false );
     229        3820 : }
     230             : 
     231        8641 : XmlStream::Tag XmlStream::checkTag( int token, bool optional )
     232             : {
     233             :     // either it's the following tag, or find it
     234        8641 :     int savedPos = pos;
     235        8641 :     if( optional )
     236             :     { // avoid printing debug messages about skipping tags if the optional one
     237             :       // will not be found and the position will be reset back
     238        1648 :         if( currentToken() != token && !findTagInternal( token, true ))
     239             :         {
     240        1001 :             pos = savedPos;
     241        1001 :             return Tag();
     242             :         }
     243             :     }
     244        7640 :     if( currentToken() == token || findTag( token ))
     245             :     {
     246        7640 :         Tag ret = currentTag();
     247        7640 :         moveToNextTag();
     248        7640 :         return ret; // ok
     249             :     }
     250           0 :     if( optional )
     251             :     { // not a problem, just rewind
     252           0 :         pos = savedPos;
     253           0 :         return Tag();
     254             :     }
     255             :     SAL_WARN( "oox.xmlstream", "Expected tag " << tokenToString( token ) << " not found." );
     256           0 :     return Tag();
     257             : }
     258             : 
     259         565 : bool XmlStream::findTag( int token )
     260             : {
     261         565 :     return findTagInternal( token, false );
     262             : }
     263             : 
     264        1585 : bool XmlStream::findTagInternal( int token, bool silent )
     265             : {
     266        1585 :     int depth = 0;
     267        7068 :     for(;
     268        5483 :          !atEnd();
     269        3898 :          moveToNextTag())
     270             :     {
     271        5483 :         if( depth > 0 ) // we're inside a nested element, skip those
     272             :         {
     273        2502 :             if( currentToken() == OPENING( currentToken()))
     274             :             {
     275         553 :                 if( !silent )
     276             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     277         553 :                 ++depth;
     278             :             }
     279        1949 :             else if( currentToken() == CLOSING( currentToken()))
     280             :             {
     281        1949 :                 if( !silent )
     282             :                     SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     283        1949 :                 --depth;
     284             :             }
     285             :             else
     286             :             {
     287           0 :                 if( !silent )
     288             :                     SAL_WARN( "oox.xmlstream", "Malformed token " << currentToken() << " ("
     289             :                         << tokenToString( currentToken()) << ")" );
     290           0 :                 abort();
     291             :             }
     292        2502 :             continue;
     293             :         }
     294        2981 :         if( currentToken() == token )
     295         475 :             return true; // ok, found
     296        2506 :         if( currentToken() == CLOSING( currentToken()))
     297        1110 :             return false; // that would be leaving current element, so not found
     298        1396 :         if( currentToken() == OPENING( currentToken()))
     299             :         {
     300        1396 :             if( !silent )
     301             :                 SAL_INFO( "oox.xmlstream", "Skipping tag " << tokenToString( currentToken()));
     302        1396 :             ++depth;
     303             :         }
     304             :         else
     305           0 :             abort();
     306             :     }
     307           0 :     if( !silent )
     308             :         SAL_WARN( "oox.xmlstream", "Unexpected end of stream reached." );
     309           0 :     return false;
     310             : }
     311             : 
     312           0 : void XmlStream::skipElementInternal( int token, bool silent )
     313             : {
     314           0 :     int closing = ( token & ~TAG_OPENING ) | TAG_CLOSING; // make it a closing tag
     315             :     assert( currentToken() == OPENING( token ));
     316           0 :     if( !silent )
     317             :         SAL_INFO( "oox.xmlstream", "Skipping unexpected element " << tokenToString( currentToken()));
     318           0 :     moveToNextTag();
     319             :     // and just find the matching closing tag
     320           0 :     if( findTag( closing ))
     321             :     {
     322           0 :         if( !silent )
     323             :             SAL_INFO( "oox.xmlstream", "Skipped unexpected element " << tokenToString( token ));
     324           0 :         moveToNextTag(); // and skip it too
     325           0 :         return;
     326             :     }
     327             :     // this one is an unexpected problem, do not silent it
     328             :     SAL_WARN( "oox.xmlstream", "Expected end of element " << tokenToString( token ) << " not found." );
     329             : }
     330             : 
     331           0 : void XmlStream::handleUnexpectedTag()
     332             : {
     333           0 :     if( atEnd())
     334           0 :         return;
     335           0 :     if( currentToken() == CLOSING( currentToken()))
     336             :     {
     337             :         SAL_INFO( "oox.xmlstream", "Skipping unexpected tag " << tokenToString( currentToken()));
     338           0 :         moveToNextTag(); // just skip it
     339           0 :         return;
     340             :     }
     341           0 :     skipElementInternal( currentToken(), false ); // otherwise skip the entire element
     342             : }
     343             : 
     344             : 
     345        4255 : void XmlStreamBuilder::appendOpeningTag( int token, const uno::Reference< xml::sax::XFastAttributeList >& attrs )
     346             : {
     347        4255 :     tags.push_back( Tag( OPENING( token ), attrs ));
     348        4255 : }
     349             : 
     350         130 : void XmlStreamBuilder::appendOpeningTag( int token, const AttributeList& attrs )
     351             : {
     352         130 :     tags.push_back( Tag( OPENING( token ), attrs ));
     353         130 : }
     354             : 
     355        4382 : void XmlStreamBuilder::appendClosingTag( int token )
     356             : {
     357        4382 :     tags.push_back( Tag( CLOSING( token )));
     358        4382 : }
     359             : 
     360         993 : void XmlStreamBuilder::appendCharacters( const rtl::OUString& chars )
     361             : {
     362             :     assert( !tags.empty());
     363         993 :     tags.back().text += chars;
     364         993 : }
     365             : 
     366             : } // namespace
     367             : } // namespace
     368             : 
     369             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10