LCOV - code coverage report
Current view: top level - filter/source/xsltdialog - xmlfilterjar.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 175 0.0 %
Date: 2012-08-25 Functions: 0 9 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <com/sun/star/io/XActiveDataControl.hpp>
      30                 :            : #include <com/sun/star/io/XActiveDataSource.hpp>
      31                 :            : #include <com/sun/star/frame/XConfigManager.hpp>
      32                 :            : #include <com/sun/star/io/XInputStream.hpp>
      33                 :            : #include <com/sun/star/io/XActiveDataSink.hpp>
      34                 :            : #include <com/sun/star/beans/PropertyValue.hpp>
      35                 :            : #include <com/sun/star/beans/NamedValue.hpp>
      36                 :            : #include <com/sun/star/container/XNamed.hpp>
      37                 :            : #include <com/sun/star/container/XChild.hpp>
      38                 :            : #include <com/sun/star/util/XChangesBatch.hpp>
      39                 :            : 
      40                 :            : 
      41                 :            : #include <comphelper/oslfile2streamwrap.hxx>
      42                 :            : #include <comphelper/storagehelper.hxx>
      43                 :            : #include <unotools/streamwrap.hxx>
      44                 :            : #include <tools/stream.hxx>
      45                 :            : #include <tools/urlobj.hxx>
      46                 :            : #include <unotools/tempfile.hxx>
      47                 :            : #include <svl/urihelper.hxx>
      48                 :            : #include <osl/file.hxx>
      49                 :            : 
      50                 :            : #include <rtl/uri.hxx>
      51                 :            : 
      52                 :            : #include "xmlfilterjar.hxx"
      53                 :            : #include "xmlfilterdialogstrings.hrc"
      54                 :            : #include "xmlfiltersettingsdialog.hxx"
      55                 :            : #include "typedetectionexport.hxx"
      56                 :            : #include "typedetectionimport.hxx"
      57                 :            : 
      58                 :            : using namespace osl;
      59                 :            : using namespace comphelper;
      60                 :            : using namespace com::sun::star;
      61                 :            : using namespace com::sun::star::lang;
      62                 :            : using namespace com::sun::star::frame;
      63                 :            : using namespace com::sun::star::uno;
      64                 :            : using namespace com::sun::star::util;
      65                 :            : using namespace com::sun::star::container;
      66                 :            : using namespace com::sun::star::beans;
      67                 :            : using namespace com::sun::star::io;
      68                 :            : 
      69                 :            : using ::rtl::OUString;
      70                 :            : using ::rtl::Uri;
      71                 :            : 
      72                 :          0 : XMLFilterJarHelper::XMLFilterJarHelper( Reference< XMultiServiceFactory >& xMSF )
      73                 :            : : mxMSF( xMSF ),
      74                 :            :     sVndSunStarPackage( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package:" ) ),
      75                 :            :     sXSLTPath( RTL_CONSTASCII_USTRINGPARAM( "$(user)/xslt/" ) ),
      76                 :            :     sDTDPath( RTL_CONSTASCII_USTRINGPARAM( "$(user)/dtd/" ) ),
      77                 :            :     sTemplatePath( RTL_CONSTASCII_USTRINGPARAM( "$(user)/template/") ),
      78                 :            :     sSpecialConfigManager( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.config.SpecialConfigManager" ) ),
      79                 :            :     sPump( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.Pump" ) ),
      80                 :          0 :     sProgPath( RTL_CONSTASCII_USTRINGPARAM( "$(prog)/" ) )
      81                 :            : {
      82                 :            :     try
      83                 :            :     {
      84                 :          0 :         Reference< XConfigManager > xCfgMgr( xMSF->createInstance(OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.config.SpecialConfigManager" ))), UNO_QUERY );
      85                 :          0 :         if( xCfgMgr.is() )
      86                 :            :         {
      87                 :          0 :             sProgPath = xCfgMgr->substituteVariables( sProgPath );
      88                 :          0 :             sXSLTPath = xCfgMgr->substituteVariables( sXSLTPath );
      89                 :          0 :             sDTDPath = xCfgMgr->substituteVariables( sDTDPath );
      90                 :          0 :             sTemplatePath = xCfgMgr->substituteVariables( sTemplatePath );
      91                 :          0 :         }
      92                 :            :     }
      93                 :          0 :     catch(const Exception&)
      94                 :            :     {
      95                 :            :     }
      96                 :          0 : }
      97                 :            : 
      98                 :          0 : static OUString encodeZipUri( const OUString& rURI )
      99                 :            : {
     100                 :          0 :     return Uri::encode( rURI, rtl_UriCharClassUric, rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8 );
     101                 :            : }
     102                 :            : 
     103                 :          0 : static Reference< XInterface > addFolder( Reference< XInterface >& xRootFolder, Reference< XSingleServiceFactory >& xFactory, const OUString& rName ) throw( Exception )
     104                 :            : {
     105                 :          0 :     if ( rName == ".." || rName == "." )
     106                 :          0 :         throw lang::IllegalArgumentException();
     107                 :            : 
     108                 :          0 :     Sequence< Any > aArgs(1);
     109                 :          0 :     aArgs[0] <<= (sal_Bool)sal_True;
     110                 :            : 
     111                 :          0 :     Reference< XInterface > xFolder( xFactory->createInstanceWithArguments(aArgs) );
     112                 :          0 :     Reference< XNamed > xNamed( xFolder, UNO_QUERY );
     113                 :          0 :     Reference< XChild > xChild( xFolder, UNO_QUERY );
     114                 :            : 
     115                 :          0 :     if( xNamed.is() && xChild.is() )
     116                 :            :     {
     117                 :          0 :         OUString aName( encodeZipUri( rName ) );
     118                 :          0 :         xNamed->setName( aName );
     119                 :          0 :         xChild->setParent( xRootFolder );
     120                 :            :     }
     121                 :            : 
     122                 :          0 :     return xFolder;
     123                 :            : }
     124                 :            : 
     125                 :          0 : static void _addFile( Reference< XInterface >& xRootFolder, Reference< XSingleServiceFactory >& xFactory, Reference< XInputStream >& xInput, OUString aName ) throw( Exception )
     126                 :            : {
     127                 :            : 
     128                 :          0 :     Reference< XActiveDataSink > xSink( xFactory->createInstance(), UNO_QUERY );
     129                 :          0 :     Reference< XUnoTunnel > xTunnel( xSink, UNO_QUERY );
     130                 :          0 :     if( xSink.is() && xTunnel.is())
     131                 :            :     {
     132                 :          0 :         Reference< XNameContainer > xNameContainer(xRootFolder, UNO_QUERY );
     133                 :          0 :         xNameContainer->insertByName(aName = encodeZipUri( aName ), makeAny(xTunnel));
     134                 :          0 :         xSink->setInputStream( xInput );
     135                 :          0 :     }
     136                 :          0 : }
     137                 :            : 
     138                 :          0 : void XMLFilterJarHelper::addFile( Reference< XInterface > xRootFolder, Reference< XSingleServiceFactory > xFactory, const OUString& rSourceFile ) throw( Exception )
     139                 :            : {
     140                 :          0 :     if( !rSourceFile.isEmpty() &&
     141                 :          0 :         (rSourceFile.compareToAscii( RTL_CONSTASCII_STRINGPARAM("http:") ) != 0) &&
     142                 :          0 :         (rSourceFile.compareToAscii( RTL_CONSTASCII_STRINGPARAM("shttp:") ) != 0) &&
     143                 :          0 :         (rSourceFile.compareToAscii( RTL_CONSTASCII_STRINGPARAM("jar:") ) != 0) &&
     144                 :          0 :         (rSourceFile.compareToAscii( RTL_CONSTASCII_STRINGPARAM("ftp:") ) != 0))
     145                 :            :     {
     146                 :          0 :         OUString aFileURL( rSourceFile );
     147                 :            : 
     148                 :          0 :         if( !aFileURL.matchIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("file://") ) ) )
     149                 :            :         {
     150                 :          0 :             aFileURL = URIHelper::SmartRel2Abs( sProgPath, aFileURL, Link(), false );
     151                 :            :         }
     152                 :            : 
     153                 :          0 :         INetURLObject aURL( aFileURL );
     154                 :          0 :         OUString aName( aURL.getName() );
     155                 :            : 
     156                 :          0 :         SvFileStream* pStream = new SvFileStream(aFileURL, STREAM_READ );
     157                 :          0 :         Reference< XInputStream > xInput(  new utl::OSeekableInputStreamWrapper( pStream, true ) );
     158                 :          0 :         _addFile( xRootFolder, xFactory, xInput, aName );
     159                 :            :     }
     160                 :          0 : }
     161                 :            : 
     162                 :          0 : bool XMLFilterJarHelper::savePackage( const OUString& rPackageURL, const XMLFilterVector& rFilters )
     163                 :            : {
     164                 :            :     try
     165                 :            :     {
     166                 :          0 :         osl::File::remove( rPackageURL );
     167                 :            : 
     168                 :            :         // create the package jar file
     169                 :            : 
     170                 :          0 :         Sequence< Any > aArguments( 2 );
     171                 :          0 :         aArguments[ 0 ] <<= rPackageURL;
     172                 :            : 
     173                 :            :         // let ZipPackage be used ( no manifest.xml is required )
     174                 :          0 :         beans::NamedValue aArg;
     175                 :          0 :         aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
     176                 :          0 :         aArg.Value <<= ZIP_STORAGE_FORMAT_STRING;
     177                 :          0 :         aArguments[ 1 ] <<= aArg;
     178                 :            : 
     179                 :            :         Reference< XHierarchicalNameAccess > xIfc(
     180                 :          0 :             mxMSF->createInstanceWithArguments(
     181                 :            :                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.packages.comp.ZipPackage" )),
     182                 :          0 :                 aArguments ), UNO_QUERY );
     183                 :            : 
     184                 :          0 :         if( xIfc.is() )
     185                 :            :         {
     186                 :          0 :             Reference< XSingleServiceFactory > xFactory( xIfc, UNO_QUERY );
     187                 :            : 
     188                 :            :             // get root zip folder
     189                 :          0 :             Reference< XInterface > xRootFolder;
     190                 :          0 :             OUString szRootFolder( RTL_CONSTASCII_USTRINGPARAM("/") );
     191                 :          0 :             xIfc->getByHierarchicalName( szRootFolder ) >>= xRootFolder;
     192                 :            : 
     193                 :            :             // export filters files
     194                 :          0 :             XMLFilterVector::const_iterator aIter( rFilters.begin() );
     195                 :          0 :             while( aIter != rFilters.end() )
     196                 :            :             {
     197                 :          0 :                 const filter_info_impl* pFilter = (*aIter);
     198                 :            : 
     199                 :          0 :                 Reference< XInterface > xFilterRoot( addFolder( xRootFolder, xFactory, pFilter->maFilterName ) );
     200                 :            : 
     201                 :          0 :                 if( xFilterRoot.is() )
     202                 :            :                 {
     203                 :          0 :                     if( !pFilter->maDTD.isEmpty() )
     204                 :          0 :                         addFile( xFilterRoot, xFactory, pFilter->maDTD );
     205                 :            : 
     206                 :          0 :                     if( !pFilter->maExportXSLT.isEmpty() )
     207                 :          0 :                         addFile( xFilterRoot, xFactory, pFilter->maExportXSLT );
     208                 :            :                     try
     209                 :            :                     {
     210                 :          0 :                         if( !pFilter->maImportXSLT.isEmpty() )
     211                 :          0 :                             addFile( xFilterRoot, xFactory, pFilter->maImportXSLT );
     212                 :            :                     }
     213                 :          0 :                     catch(const com::sun::star::container::ElementExistException&)
     214                 :            :                     {
     215                 :            :                     // in case of same named import / export XSLT the latter
     216                 :            :                     // is ignored
     217                 :            :                         OSL_FAIL( "XMLFilterJarHelper::same named xslt filter exception!" );
     218                 :            :                     }
     219                 :            : 
     220                 :          0 :                     if( !pFilter->maImportTemplate.isEmpty() )
     221                 :          0 :                         addFile( xFilterRoot, xFactory, pFilter->maImportTemplate );
     222                 :            :                 }
     223                 :            : 
     224                 :          0 :                 ++aIter;
     225                 :          0 :             }
     226                 :            : 
     227                 :            :             // create TypeDetection.xcu
     228                 :          0 :             utl::TempFile aTempFile;
     229                 :          0 :             aTempFile.EnableKillingFile();
     230                 :          0 :             OUString aTempFileURL( aTempFile.GetURL() );
     231                 :            : 
     232                 :            :             {
     233                 :          0 :                 osl::File aOutputFile( aTempFileURL );
     234                 :          0 :                 /* osl::File::RC rc = */ aOutputFile.open( osl_File_OpenFlag_Write );
     235                 :          0 :                 Reference< XOutputStream > xOS( new OSLOutputStreamWrapper( aOutputFile ) );
     236                 :            : 
     237                 :          0 :                 TypeDetectionExporter aExporter( mxMSF );
     238                 :          0 :                 aExporter.doExport(xOS,rFilters);
     239                 :            :             }
     240                 :            : 
     241                 :          0 :             Reference< XInputStream > XIS(  new utl::OSeekableInputStreamWrapper( new SvFileStream(aTempFileURL, STREAM_READ ), true ) );
     242                 :          0 :             OUString szTypeDetection( RTL_CONSTASCII_USTRINGPARAM( "TypeDetection.xcu" ) );
     243                 :          0 :             _addFile( xRootFolder, xFactory,  XIS, szTypeDetection );
     244                 :            : 
     245                 :          0 :             Reference< XChangesBatch > xBatch( xIfc, UNO_QUERY );
     246                 :          0 :             if( xBatch.is() )
     247                 :          0 :                 xBatch->commitChanges();
     248                 :            : 
     249                 :          0 :             return true;
     250                 :          0 :         }
     251                 :            :     }
     252                 :          0 :     catch( const Exception& )
     253                 :            :     {
     254                 :            :         OSL_FAIL( "XMLFilterJarHelper::savePackage exception catched!" );
     255                 :            :     }
     256                 :            : 
     257                 :          0 :     osl::File::remove( rPackageURL );
     258                 :            : 
     259                 :          0 :     return false;
     260                 :            : }
     261                 :            : 
     262                 :            : 
     263                 :            : 
     264                 :            : //
     265                 :            : 
     266                 :          0 : void XMLFilterJarHelper::openPackage( const OUString& rPackageURL, XMLFilterVector& rFilters )
     267                 :            : {
     268                 :            :     try
     269                 :            :     {
     270                 :            :         // create the package jar file
     271                 :            : 
     272                 :          0 :         Sequence< Any > aArguments( 2 );
     273                 :          0 :         aArguments[ 0 ] <<= rPackageURL;
     274                 :            : 
     275                 :            :         // let ZipPackage be used ( no manifest.xml is required )
     276                 :          0 :         beans::NamedValue aArg;
     277                 :          0 :         aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
     278                 :          0 :         aArg.Value <<= ZIP_STORAGE_FORMAT_STRING;
     279                 :          0 :         aArguments[ 1 ] <<= aArg;
     280                 :            : 
     281                 :            :         Reference< XHierarchicalNameAccess > xIfc(
     282                 :          0 :             mxMSF->createInstanceWithArguments(
     283                 :            :                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.packages.comp.ZipPackage" )),
     284                 :          0 :                 aArguments ), UNO_QUERY );
     285                 :            : 
     286                 :          0 :         if( xIfc.is() )
     287                 :            :         {
     288                 :          0 :             Reference< XSingleServiceFactory > xFactory( xIfc, UNO_QUERY );
     289                 :            : 
     290                 :            :             // get root zip folder
     291                 :          0 :             Reference< XInterface > xRootFolder;
     292                 :          0 :             OUString szRootFolder( RTL_CONSTASCII_USTRINGPARAM("/") );
     293                 :          0 :             xIfc->getByHierarchicalName( szRootFolder ) >>= xRootFolder;
     294                 :            : 
     295                 :          0 :             OUString szTypeDetection( RTL_CONSTASCII_USTRINGPARAM("TypeDetection.xcu") );
     296                 :          0 :             if( xIfc->hasByHierarchicalName( szTypeDetection ) )
     297                 :            :             {
     298                 :          0 :                 Reference< XActiveDataSink > xTypeDetection;
     299                 :          0 :                 xIfc->getByHierarchicalName( szTypeDetection ) >>= xTypeDetection;
     300                 :            : 
     301                 :          0 :                 if( xTypeDetection.is() )
     302                 :            :                 {
     303                 :          0 :                     Reference< XInputStream > xIS( xTypeDetection->getInputStream() );
     304                 :            : 
     305                 :          0 :                     XMLFilterVector aFilters;
     306                 :          0 :                     TypeDetectionImporter::doImport( mxMSF, xIS, aFilters );
     307                 :            : 
     308                 :            :                     // copy all files used by the filters imported from the
     309                 :            :                     // typedetection to office/user/xslt
     310                 :          0 :                     XMLFilterVector::iterator aIter( aFilters.begin() );
     311                 :          0 :                     while( aIter != aFilters.end() )
     312                 :            :                     {
     313                 :          0 :                         if( copyFiles( xIfc, (*aIter) ) )
     314                 :            :                         {
     315                 :          0 :                             rFilters.push_back( (*aIter) );
     316                 :            :                         }
     317                 :            :                         else
     318                 :            :                         {
     319                 :            :                             // failed to copy all files
     320                 :          0 :                             delete (*aIter);
     321                 :            :                         }
     322                 :          0 :                         ++aIter;
     323                 :          0 :                     }
     324                 :          0 :                 }
     325                 :          0 :             }
     326                 :          0 :         }
     327                 :            :     }
     328                 :          0 :     catch( const Exception& )
     329                 :            :     {
     330                 :            :         OSL_FAIL( "XMLFilterJarHelper::savePackage exception catched!" );
     331                 :            :     }
     332                 :          0 : }
     333                 :            : 
     334                 :          0 : bool XMLFilterJarHelper::copyFiles( Reference< XHierarchicalNameAccess > xIfc, filter_info_impl* pFilter )
     335                 :            : {
     336                 :          0 :     bool bOk = copyFile( xIfc, pFilter->maDTD, sDTDPath );
     337                 :            : 
     338                 :          0 :     if( bOk )
     339                 :          0 :         bOk = copyFile( xIfc, pFilter->maExportXSLT, sXSLTPath );
     340                 :            : 
     341                 :          0 :     if( bOk )
     342                 :          0 :         bOk = copyFile( xIfc, pFilter->maImportXSLT, sXSLTPath );
     343                 :            : 
     344                 :          0 :     if( bOk )
     345                 :          0 :         bOk = copyFile( xIfc, pFilter->maImportTemplate, sTemplatePath );
     346                 :            : 
     347                 :          0 :     return bOk;
     348                 :            : }
     349                 :            : 
     350                 :          0 : bool XMLFilterJarHelper::copyFile( Reference< XHierarchicalNameAccess > xIfc, OUString& rURL, const OUString& rTargetURL )
     351                 :            : {
     352                 :          0 :     if( !rURL.matchIgnoreAsciiCase( sVndSunStarPackage ) )
     353                 :          0 :         return true;
     354                 :            : 
     355                 :            :     try
     356                 :            :     {
     357                 :          0 :         OUString szPackagePath( encodeZipUri( rURL.copy( sVndSunStarPackage.getLength() ) ) );
     358                 :            : 
     359                 :          0 :         if ( ::comphelper::OStorageHelper::PathHasSegment( szPackagePath, OUString( RTL_CONSTASCII_USTRINGPARAM( ".." ) ) )
     360                 :          0 :           || ::comphelper::OStorageHelper::PathHasSegment( szPackagePath, OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) ) ) )
     361                 :          0 :             throw lang::IllegalArgumentException();
     362                 :            : 
     363                 :          0 :         if( xIfc->hasByHierarchicalName( szPackagePath ) )
     364                 :            :         {
     365                 :          0 :             Reference< XActiveDataSink > xFileEntry;
     366                 :          0 :             xIfc->getByHierarchicalName( szPackagePath ) >>= xFileEntry;
     367                 :            : 
     368                 :          0 :             if( xFileEntry.is() )
     369                 :            :             {
     370                 :          0 :                 Reference< XInputStream > xIS( xFileEntry->getInputStream() );
     371                 :            : 
     372                 :          0 :                 INetURLObject aBaseURL( rTargetURL );
     373                 :            : 
     374                 :          0 :                 rURL = URIHelper::SmartRel2Abs( aBaseURL, szPackagePath, Link(), false );
     375                 :            : 
     376                 :          0 :                 if( !rURL.isEmpty() )
     377                 :            :                 {
     378                 :            :                     // create output directory if needed
     379                 :          0 :                     if( !createDirectory( rURL ) )
     380                 :          0 :                         return false;
     381                 :            : 
     382                 :          0 :                     ::osl::File file(rURL);
     383                 :            :                     ::osl::FileBase::RC rc =
     384                 :          0 :                         file.open(osl_File_OpenFlag_Write|osl_File_OpenFlag_Create);
     385                 :          0 :                     if (::osl::FileBase::E_EXIST == rc) {
     386                 :          0 :                         rc = file.open(osl_File_OpenFlag_Write);
     387                 :          0 :                         if (::osl::FileBase::E_None == rc) {
     388                 :          0 :                             file.setSize(0); // #i97170# truncate
     389                 :            :                         }
     390                 :            :                     }
     391                 :          0 :                     if (::osl::FileBase::E_None != rc) {
     392                 :          0 :                         throw RuntimeException();
     393                 :            :                     }
     394                 :            :                     Reference< XOutputStream > const xOS(
     395                 :          0 :                             new comphelper::OSLOutputStreamWrapper(file));
     396                 :            : 
     397                 :          0 :                     return copyStreams( xIS, xOS );
     398                 :          0 :                 }
     399                 :          0 :             }
     400                 :          0 :         }
     401                 :            :     }
     402                 :          0 :     catch( const Exception& )
     403                 :            :     {
     404                 :            :         OSL_FAIL( "XMLFilterJarHelper::copyFile exception catched" );
     405                 :            :     }
     406                 :          0 :     return false;
     407                 :            : }
     408                 :            : 
     409                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10