LCOV - code coverage report
Current view: top level - libreoffice/xmlhelp/source/cxxhelp/provider - urlparameter.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 525 0.0 %
Date: 2012-12-27 Functions: 0 53 0.0 %
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             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "bufferedinputstream.hxx"
      22             : 
      23             : #include <string.h>
      24             : #include <osl/diagnose.hxx>
      25             : #include <osl/thread.h>
      26             : #include <osl/file.hxx>
      27             : #include <cppuhelper/weak.hxx>
      28             : #include <cppuhelper/queryinterface.hxx>
      29             : #include <comphelper/processfactory.hxx>
      30             : #include <rtl/uri.hxx>
      31             : #include <rtl/ustrbuf.hxx>
      32             : #include <libxslt/xslt.h>
      33             : #include <libxslt/transform.h>
      34             : #include <libxslt/xsltutils.h>
      35             : #include "db.hxx"
      36             : #include <com/sun/star/io/XActiveDataSink.hpp>
      37             : #include <com/sun/star/io/XInputStream.hpp>
      38             : #include <com/sun/star/io/XSeekable.hpp>
      39             : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
      40             : #include <com/sun/star/ucb/OpenMode.hpp>
      41             : #include <com/sun/star/ucb/XCommandProcessor.hpp>
      42             : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
      43             : #include <com/sun/star/ucb/XContentIdentifier.hpp>
      44             : #include <com/sun/star/ucb/XContentProvider.hpp>
      45             : #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
      46             : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
      47             : 
      48             : #include "urlparameter.hxx"
      49             : #include "databases.hxx"
      50             : 
      51             : namespace chelp {
      52             : 
      53           0 :     inline bool ascii_isDigit( sal_Unicode ch )
      54             :     {
      55           0 :         return ((ch >= 0x0030) && (ch <= 0x0039));
      56             :     }
      57             : 
      58           0 :     inline bool ascii_isLetter( sal_Unicode ch )
      59             :     {
      60             :         return ( ( (ch >= 0x0041) && (ch <= 0x005A) ) ||
      61           0 :                  ( (ch >= 0x0061) && (ch <= 0x007A) ) );
      62             :     }
      63             : 
      64           0 :     inline bool isLetterOrDigit( sal_Unicode ch )
      65             :     {
      66           0 :         return ascii_isLetter( ch ) || ascii_isDigit( ch );
      67             :     }
      68             : 
      69             : }
      70             : 
      71             : using namespace cppu;
      72             : using namespace com::sun::star::io;
      73             : using namespace com::sun::star::uno;
      74             : using namespace com::sun::star::lang;
      75             : using namespace com::sun::star::ucb;
      76             : using namespace com::sun::star::beans;
      77             : using namespace com::sun::star::container;
      78             : using namespace chelp;
      79             : 
      80             : 
      81           0 : URLParameter::URLParameter( const rtl::OUString& aURL,
      82             :                             Databases* pDatabases )
      83             :     throw( com::sun::star::ucb::IllegalIdentifierException )
      84             :     : m_pDatabases( pDatabases ),
      85           0 :       m_aURL( aURL )
      86             : {
      87           0 :     init( false );
      88           0 :     parse();
      89           0 : }
      90             : 
      91             : 
      92           0 : bool URLParameter::isErrorDocument()
      93             : {
      94           0 :     bool bErrorDoc = false;
      95             : 
      96           0 :     if( isFile() )
      97             :     {
      98             :         Reference< XHierarchicalNameAccess > xNA =
      99           0 :             m_pDatabases->findJarFileForPath( get_jar(), get_language(), get_path() );
     100           0 :         bErrorDoc = !xNA.is();
     101             :     }
     102             : 
     103           0 :     return bErrorDoc;
     104             : }
     105             : 
     106             : 
     107           0 : rtl::OString URLParameter::getByName( const char* par )
     108             : {
     109           0 :     rtl::OUString val;
     110             : 
     111           0 :     if( strcmp( par,"Program" ) == 0 )
     112           0 :         val = get_program();
     113           0 :     else if( strcmp( par,"Database" ) == 0 )
     114           0 :         val = get_module();
     115           0 :     else if( strcmp( par,"DatabasePar" ) == 0 )
     116           0 :         val = get_dbpar();
     117           0 :     else if( strcmp( par,"Id" ) == 0 )
     118           0 :         val = get_id();
     119           0 :     else if( strcmp( par,"Path" ) == 0 )
     120           0 :         val = get_path();
     121           0 :     else if( strcmp( par,"Language" ) == 0 )
     122           0 :         val = get_language();
     123           0 :     else if( strcmp( par,"System" ) == 0 )
     124           0 :         val = get_system();
     125           0 :     else if( strcmp( par,"HelpPrefix" ) == 0 )
     126           0 :         val = get_prefix();
     127             : 
     128           0 :     return rtl::OString( val.getStr(),val.getLength(),RTL_TEXTENCODING_UTF8 );
     129             : }
     130             : 
     131             : 
     132           0 : rtl::OUString URLParameter::get_id()
     133             : {
     134           0 :     if( m_aId.compareToAscii("start") == 0 )
     135             :     {   // module is set
     136             :         StaticModuleInformation* inf =
     137             :             m_pDatabases->getStaticInformationForModule( get_module(),
     138           0 :                                                          get_language() );
     139           0 :         if( inf )
     140           0 :             m_aId = inf->get_id();
     141             : 
     142           0 :         m_bStart = true;
     143             :     }
     144             : 
     145           0 :     return m_aId;
     146             : }
     147             : 
     148           0 : rtl::OUString URLParameter::get_tag()
     149             : {
     150           0 :     if( isFile() )
     151           0 :         return get_the_tag();
     152             :     else
     153           0 :         return m_aTag;
     154             : }
     155             : 
     156             : 
     157           0 : rtl::OUString URLParameter::get_title()
     158             : {
     159           0 :     if( isFile() )
     160           0 :         return get_the_title();
     161           0 :     else if( m_aModule.compareToAscii("") != 0 )
     162             :     {
     163             :         StaticModuleInformation* inf =
     164             :             m_pDatabases->getStaticInformationForModule( get_module(),
     165           0 :                                                          get_language() );
     166           0 :         if( inf )
     167           0 :             m_aTitle = inf->get_title();
     168             :     }
     169             :     else   // This must be the root
     170           0 :         m_aTitle = rtl::OUString("root");
     171             : 
     172           0 :     return m_aTitle;
     173             : }
     174             : 
     175             : 
     176           0 : rtl::OUString URLParameter::get_language()
     177             : {
     178           0 :     if( m_aLanguage.isEmpty() )
     179           0 :         return m_aDefaultLanguage;
     180             : 
     181           0 :     return m_aLanguage;
     182             : }
     183             : 
     184             : 
     185           0 : rtl::OUString URLParameter::get_program()
     186             : {
     187           0 :     if( m_aProgram.isEmpty() )
     188             :     {
     189             :         StaticModuleInformation* inf =
     190             :             m_pDatabases->getStaticInformationForModule( get_module(),
     191           0 :                                                          get_language() );
     192           0 :         if( inf )
     193           0 :             m_aProgram = inf->get_program();
     194             :     }
     195           0 :     return m_aProgram;
     196             : }
     197             : 
     198             : 
     199           0 : void URLParameter::init( bool bDefaultLanguageIsInitialized )
     200             : {
     201             :     (void)bDefaultLanguageIsInitialized;
     202             : 
     203           0 :     m_bHelpDataFileRead = false;
     204           0 :     m_bStart = false;
     205           0 :     m_bUseDB = true;
     206           0 :     m_nHitCount = 100;                // The default maximum hitcount
     207           0 : }
     208             : 
     209             : 
     210           0 : rtl::OUString URLParameter::get_the_tag()
     211             : {
     212           0 :     if(m_bUseDB) {
     213           0 :         if( ! m_bHelpDataFileRead )
     214           0 :             readHelpDataFile();
     215             : 
     216           0 :         m_bHelpDataFileRead = true;
     217             : 
     218           0 :         return m_aTag;
     219             :     }
     220             :     else
     221           0 :         return rtl::OUString();
     222             : }
     223             : 
     224             : 
     225             : 
     226           0 : rtl::OUString URLParameter::get_the_path()
     227             : {
     228           0 :     if(m_bUseDB) {
     229           0 :         if( ! m_bHelpDataFileRead )
     230           0 :             readHelpDataFile();
     231           0 :         m_bHelpDataFileRead = true;
     232             : 
     233           0 :         return m_aPath;
     234             :     }
     235             :     else
     236           0 :         return get_id();
     237             : }
     238             : 
     239             : 
     240             : 
     241           0 : rtl::OUString URLParameter::get_the_title()
     242             : {
     243           0 :     if(m_bUseDB) {
     244           0 :         if( ! m_bHelpDataFileRead )
     245           0 :             readHelpDataFile();
     246           0 :         m_bHelpDataFileRead = true;
     247             : 
     248           0 :         return m_aTitle;
     249             :     }
     250             :     else
     251           0 :         return rtl::OUString();
     252             : }
     253             : 
     254             : 
     255           0 : rtl::OUString URLParameter::get_the_jar()
     256             : {
     257           0 :     if(m_bUseDB) {
     258           0 :         if( ! m_bHelpDataFileRead )
     259           0 :             readHelpDataFile();
     260           0 :         m_bHelpDataFileRead = true;
     261             : 
     262           0 :         return m_aJar;
     263             :     }
     264             :     else
     265           0 :         return get_module() + rtl::OUString(".jar");
     266             : }
     267             : 
     268             : 
     269           0 : void URLParameter::readHelpDataFile()
     270             : {
     271           0 :     if( get_id().compareToAscii("") == 0 )
     272           0 :         return;
     273             : 
     274           0 :     rtl::OUString aModule = get_module();
     275           0 :     rtl::OUString aLanguage = get_language();
     276             : 
     277           0 :     DataBaseIterator aDbIt( *m_pDatabases, aModule, aLanguage, false );
     278           0 :     bool bSuccess = false;
     279             : 
     280           0 :     const sal_Char* pData = NULL;
     281             : 
     282           0 :     helpdatafileproxy::HDFData aHDFData;
     283           0 :     rtl::OUString aExtensionPath;
     284           0 :     rtl::OUString aExtensionRegistryPath;
     285           0 :     while( true )
     286             :     {
     287           0 :         helpdatafileproxy::Hdf* pHdf = aDbIt.nextHdf( &aExtensionPath, &aExtensionRegistryPath );
     288           0 :         if( !pHdf )
     289             :             break;
     290             : 
     291           0 :         rtl::OString keyStr( m_aId.getStr(),m_aId.getLength(),RTL_TEXTENCODING_UTF8 );
     292           0 :         bSuccess = pHdf->getValueForKey( keyStr, aHDFData );
     293           0 :         if( bSuccess )
     294             :         {
     295           0 :             pData = aHDFData.getData();
     296             :             break;
     297             :         }
     298           0 :     }
     299             : 
     300           0 :     if( bSuccess )
     301             :     {
     302           0 :         DbtToStringConverter converter( pData );
     303           0 :         m_aTitle = converter.getTitle();
     304           0 :         m_pDatabases->replaceName( m_aTitle );
     305           0 :         m_aPath  = converter.getFile();
     306           0 :         m_aJar   = converter.getDatabase();
     307           0 :         if( !aExtensionPath.isEmpty() )
     308             :         {
     309           0 :             rtl::OUStringBuffer aExtendedJarStrBuf;
     310           0 :             aExtendedJarStrBuf.append( '?' );
     311           0 :             aExtendedJarStrBuf.append( aExtensionPath );
     312           0 :             aExtendedJarStrBuf.append( '?' );
     313           0 :             aExtendedJarStrBuf.append( m_aJar );
     314           0 :             m_aJar = aExtendedJarStrBuf.makeStringAndClear();
     315           0 :             m_aExtensionRegistryPath = aExtensionRegistryPath;
     316             :         }
     317           0 :         m_aTag   = converter.getHash();
     318           0 :     }
     319             : }
     320             : 
     321             : 
     322             : 
     323             : // Class encapsulating the transformation of the XInputStream to XHTML
     324             : 
     325             : 
     326             : class InputStreamTransformer
     327             :     : public OWeakObject,
     328             :       public XInputStream,
     329             :       public XSeekable
     330             : {
     331             : public:
     332             : 
     333             :     InputStreamTransformer( URLParameter* urlParam,
     334             :                             Databases*    pDatatabases,
     335             :                             bool isRoot = false );
     336             : 
     337             :     ~InputStreamTransformer();
     338             : 
     339             :     virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
     340             :     virtual void SAL_CALL acquire( void ) throw();
     341             :     virtual void SAL_CALL release( void ) throw();
     342             : 
     343             :     virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
     344             :         throw( NotConnectedException,
     345             :                BufferSizeExceededException,
     346             :                IOException,
     347             :                RuntimeException);
     348             : 
     349             :     virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
     350             :         throw( NotConnectedException,
     351             :                BufferSizeExceededException,
     352             :                IOException,
     353             :                RuntimeException);
     354             : 
     355             :     virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException,
     356             :                                                                      BufferSizeExceededException,
     357             :                                                                      IOException,
     358             :                                                                      RuntimeException );
     359             : 
     360             :     virtual sal_Int32 SAL_CALL available( void ) throw( NotConnectedException,
     361             :                                                         IOException,
     362             :                                                         RuntimeException );
     363             : 
     364             :     virtual void SAL_CALL closeInput( void ) throw( NotConnectedException,
     365             :                                                     IOException,
     366             :                                                     RuntimeException );
     367             : 
     368             :     virtual void SAL_CALL seek( sal_Int64 location ) throw( IllegalArgumentException,
     369             :                                                             IOException,
     370             :                                                             RuntimeException );
     371             : 
     372             :     virtual sal_Int64 SAL_CALL getPosition( void ) throw( IOException,RuntimeException );
     373             : 
     374             :     virtual sal_Int64 SAL_CALL getLength( void ) throw( IOException,RuntimeException );
     375             : 
     376             :     void addToBuffer( const char* buffer,int len );
     377             : 
     378           0 :     sal_Int8* getData() const { return (sal_Int8*) buffer; }
     379             : 
     380           0 :     sal_Int32 getLen() const { return sal_Int32( len ); }
     381             : 
     382             : private:
     383             : 
     384             :     osl::Mutex m_aMutex;
     385             : 
     386             :     int len,pos;
     387             :     char *buffer;
     388             : };
     389             : 
     390             : 
     391             : 
     392           0 : void URLParameter::open( const Command& aCommand,
     393             :                          sal_Int32 CommandId,
     394             :                          const Reference< XCommandEnvironment >& Environment,
     395             :                          const Reference< XOutputStream >& xDataSink )
     396             : {
     397             :     (void)aCommand;
     398             :     (void)CommandId;
     399             :     (void)Environment;
     400             : 
     401           0 :     if( ! xDataSink.is() )
     402           0 :         return;
     403             : 
     404           0 :     if( isPicture() )
     405             :     {
     406           0 :         Reference< XInputStream > xStream;
     407             :         Reference< XHierarchicalNameAccess > xNA =
     408             :             m_pDatabases->jarFile( rtl::OUString( "picture.jar" ),
     409           0 :                                    get_language() );
     410             : 
     411           0 :         rtl::OUString path = get_path();
     412           0 :         if( xNA.is() )
     413             :         {
     414             :             try
     415             :             {
     416           0 :                 Any aEntry = xNA->getByHierarchicalName( path );
     417           0 :                 Reference< XActiveDataSink > xSink;
     418           0 :                 if( ( aEntry >>= xSink ) && xSink.is() )
     419           0 :                     xStream = xSink->getInputStream();
     420             :             }
     421           0 :             catch ( NoSuchElementException & )
     422             :             {
     423             :             }
     424             :         }
     425           0 :         if( xStream.is() )
     426             :         {
     427             :             sal_Int32 ret;
     428           0 :             Sequence< sal_Int8 > aSeq( 4096 );
     429           0 :             while( true )
     430             :             {
     431             :                 try
     432             :                 {
     433           0 :                     ret = xStream->readBytes( aSeq,4096 );
     434           0 :                     xDataSink->writeBytes( aSeq );
     435           0 :                     if( ret < 4096 )
     436           0 :                         break;
     437             :                 }
     438           0 :                 catch( const Exception& )
     439             :                 {
     440             :                     break;
     441             :                 }
     442           0 :             }
     443           0 :         }
     444             :     }
     445             :     else
     446             :     {
     447             :         // a standard document or else an active help text, plug in the new input stream
     448           0 :         InputStreamTransformer* p = new InputStreamTransformer( this,m_pDatabases,isRoot() );
     449             :         try
     450             :         {
     451           0 :             xDataSink->writeBytes( Sequence< sal_Int8 >( p->getData(),p->getLen() ) );
     452             :         }
     453           0 :         catch( const Exception& )
     454             :         {
     455             :         }
     456           0 :         delete p;
     457             :     }
     458           0 :     xDataSink->closeOutput();
     459             : }
     460             : 
     461             : 
     462             : 
     463           0 : void URLParameter::open( const Command& aCommand,
     464             :                          sal_Int32 CommandId,
     465             :                          const Reference< XCommandEnvironment >& Environment,
     466             :                          const Reference< XActiveDataSink >& xDataSink )
     467             : {
     468             :     (void)aCommand;
     469             :     (void)CommandId;
     470             :     (void)Environment;
     471             : 
     472           0 :     if( isPicture() )
     473             :     {
     474           0 :         Reference< XInputStream > xStream;
     475             :         Reference< XHierarchicalNameAccess > xNA =
     476             :             m_pDatabases->jarFile( rtl::OUString( "picture.jar" ),
     477           0 :                                    get_language() );
     478             : 
     479           0 :         rtl::OUString path = get_path();
     480           0 :         if( xNA.is() )
     481             :         {
     482             :             try
     483             :             {
     484           0 :                 Any aEntry = xNA->getByHierarchicalName( path );
     485           0 :                 Reference< XActiveDataSink > xSink;
     486           0 :                 if( ( aEntry >>= xSink ) && xSink.is() )
     487           0 :                     xStream = xSink->getInputStream();
     488             :             }
     489           0 :             catch ( NoSuchElementException & )
     490             :             {
     491             :             }
     492             :         }
     493           0 :         xDataSink->setInputStream( turnToSeekable(xStream) );
     494             :     }
     495             :     else
     496             :         // a standard document or else an active help text, plug in the new input stream
     497           0 :         xDataSink->setInputStream( new InputStreamTransformer( this,m_pDatabases,isRoot() ) );
     498           0 : }
     499             : 
     500             : 
     501           0 : void URLParameter::parse() throw( com::sun::star::ucb::IllegalIdentifierException )
     502             : {
     503           0 :     m_aExpr = m_aURL;
     504             : 
     505           0 :     sal_Int32 lstIdx = m_aExpr.lastIndexOf( sal_Unicode( '#' ) );
     506           0 :     if( lstIdx != -1 )
     507           0 :         m_aExpr = m_aExpr.copy( 0,lstIdx );
     508             : 
     509           0 :     if( ! scheme() ||
     510           0 :         ! name( module() ) ||
     511           0 :         ! query() ||
     512           0 :         m_aLanguage.isEmpty() ||
     513           0 :         m_aSystem.isEmpty() )
     514           0 :         throw com::sun::star::ucb::IllegalIdentifierException();
     515           0 : }
     516             : 
     517             : 
     518           0 : bool URLParameter::scheme()
     519             : {
     520             :     // Correct extension help links as sometimes the
     521             :     // module is missing resulting in a misformed URL
     522           0 :     if( m_aExpr.compareToAscii( "vnd.sun.star.help:///", 21 ) == 0 )
     523             :     {
     524           0 :         sal_Int32 nLen = m_aExpr.getLength();
     525             :         rtl::OUString aLastStr =
     526           0 :             m_aExpr.copy(sal::static_int_cast<sal_uInt32>(nLen) - 6);
     527           0 :         if( aLastStr.compareToAscii( "DbPAR=" ) == 0 )
     528             :         {
     529           0 :             rtl::OUString aNewExpr = m_aExpr.copy( 0, 20 );
     530           0 :             rtl::OUString aSharedStr("shared");
     531           0 :             aNewExpr += aSharedStr;
     532           0 :             aNewExpr += m_aExpr.copy( 20 );
     533           0 :             aNewExpr += aSharedStr;
     534           0 :             m_aExpr = aNewExpr;
     535           0 :         }
     536             :     }
     537             : 
     538           0 :     for( sal_Int32 nPrefixLen = 20 ; nPrefixLen >= 18 ; --nPrefixLen )
     539             :     {
     540           0 :         if( m_aExpr.compareToAscii( "vnd.sun.star.help://", nPrefixLen ) == 0 )
     541             :         {
     542           0 :             m_aExpr = m_aExpr.copy( nPrefixLen );
     543           0 :             return true;
     544             :         }
     545             :     }
     546           0 :     return false;
     547             : }
     548             : 
     549             : 
     550           0 : bool URLParameter::module()
     551             : {
     552           0 :     sal_Int32 idx = 0,length = m_aExpr.getLength();
     553             : 
     554           0 :     while( idx < length && isLetterOrDigit( (m_aExpr.getStr())[idx] ) )
     555           0 :         ++idx;
     556             : 
     557           0 :     if( idx != 0 )
     558             :     {
     559           0 :         m_aModule = m_aExpr.copy( 0,idx );
     560           0 :         m_aExpr = m_aExpr.copy( idx );
     561           0 :         return true;
     562             :     }
     563             :     else
     564           0 :         return false;
     565             : }
     566             : 
     567             : 
     568             : 
     569           0 : bool URLParameter::name( bool modulePresent )
     570             : {
     571             :     // if modulepresent, a name may be present, but must not
     572             : 
     573           0 :     sal_Int32 length = m_aExpr.getLength();
     574             : 
     575           0 :     if( length != 0 && (m_aExpr.getStr())[0] == sal_Unicode( '/' ) )
     576             :     {
     577           0 :         sal_Int32 idx = 1;
     578           0 :         while( idx < length && (m_aExpr.getStr())[idx] != '?' )
     579           0 :             ++idx;
     580             : 
     581           0 :         if( idx != 1 && ! modulePresent )
     582           0 :             return false;
     583             :         else
     584             :         {
     585           0 :             m_aId = m_aExpr.copy( 1,idx-1 );
     586           0 :             m_aExpr = m_aExpr.copy( idx );
     587             :         }
     588             :     }
     589             : 
     590           0 :     return true;
     591             : }
     592             : 
     593             : 
     594           0 : bool URLParameter::query()
     595             : {
     596           0 :     rtl::OUString query_;
     597             : 
     598           0 :     if( m_aExpr.isEmpty() )
     599           0 :         return true;
     600           0 :     else if( (m_aExpr.getStr())[0] == sal_Unicode( '?' ) )
     601           0 :         query_ = m_aExpr.copy( 1 ).trim();
     602             :     else
     603           0 :         return false;
     604             : 
     605             : 
     606           0 :     bool ret = true;
     607             :     sal_Int32 delimIdx,equalIdx;
     608           0 :     rtl::OUString parameter,value;
     609             : 
     610           0 :     while( !query_.isEmpty() )
     611             :     {
     612           0 :         delimIdx = query_.indexOf( sal_Unicode( '&' ) );
     613           0 :         equalIdx = query_.indexOf( sal_Unicode( '=' ) );
     614           0 :         parameter = query_.copy( 0,equalIdx ).trim();
     615           0 :         if( delimIdx == -1 )
     616             :         {
     617           0 :             value = query_.copy( equalIdx + 1 ).trim();
     618           0 :             query_ = rtl::OUString();
     619             :         }
     620             :         else
     621             :         {
     622           0 :             value = query_.copy( equalIdx+1,delimIdx - equalIdx - 1 ).trim();
     623           0 :             query_ = query_.copy( delimIdx+1 ).trim();
     624             :         }
     625             : 
     626           0 :         if( parameter.compareToAscii( "Language" ) == 0 )
     627           0 :             m_aLanguage = value;
     628           0 :         else if( parameter.compareToAscii( "Device" ) == 0 )
     629           0 :             m_aDevice = value;
     630           0 :         else if( parameter.compareToAscii( "Program" ) == 0 )
     631           0 :             m_aProgram = value;
     632           0 :         else if( parameter.compareToAscii( "Eid" ) == 0 )
     633           0 :             m_aEid = value;
     634           0 :         else if( parameter.compareToAscii( "UseDB" ) == 0 )
     635           0 :             m_bUseDB = ! ( value.compareToAscii("no") == 0 );
     636           0 :         else if( parameter.compareToAscii( "DbPAR" ) == 0 )
     637           0 :             m_aDbPar = value;
     638           0 :         else if( parameter.compareToAscii( "Query" ) == 0 )
     639             :         {
     640           0 :             if( m_aQuery.isEmpty() )
     641           0 :                 m_aQuery = value;
     642             :             else
     643           0 :                 m_aQuery += ( rtl::OUString( " " ) + value );
     644             :         }
     645           0 :         else if( parameter.compareToAscii( "Scope" ) == 0 )
     646           0 :             m_aScope = value;
     647           0 :         else if( parameter.compareToAscii( "System" ) == 0 )
     648           0 :             m_aSystem = value;
     649           0 :         else if( parameter.compareToAscii( "HelpPrefix" ) == 0 )
     650             :             m_aPrefix = rtl::Uri::decode(
     651             :                 value,
     652             :                 rtl_UriDecodeWithCharset,
     653           0 :                 RTL_TEXTENCODING_UTF8 );
     654           0 :         else if( parameter.compareToAscii( "HitCount" ) == 0 )
     655           0 :             m_nHitCount = value.toInt32();
     656           0 :         else if( parameter.compareToAscii( "Active" ) == 0 )
     657           0 :             m_aActive = value;
     658           0 :         else if( parameter.compareToAscii( "Version" ) == 0 )
     659             :             ; // ignored (but accepted) in the build-in help, useful only for the online help
     660             :         else
     661           0 :             ret = false;
     662             :     }
     663             : 
     664           0 :     return ret;
     665             : }
     666             : 
     667             : struct UserData {
     668             : 
     669           0 :     UserData( InputStreamTransformer* pTransformer,
     670             :               URLParameter*           pInitial,
     671             :               Databases*              pDatabases )
     672             :         : m_pTransformer( pTransformer ),
     673             :           m_pDatabases( pDatabases ),
     674           0 :           m_pInitial( pInitial )
     675             :     {
     676           0 :     }
     677             : 
     678             :     InputStreamTransformer*             m_pTransformer;
     679             :     Databases*                          m_pDatabases;
     680             :     URLParameter*                       m_pInitial;
     681             : };
     682             : 
     683             : UserData *ugblData = 0;
     684             : 
     685             : extern "C" {
     686             : 
     687             : static int
     688           0 : fileMatch(const char * URI) {
     689           0 :     if ((URI != NULL) && !strncmp(URI, "file:/", 6))
     690           0 :         return 1;
     691           0 :     return 0;
     692             : }
     693             : 
     694             : static int
     695           0 : zipMatch(const char * URI) {
     696           0 :     if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.zip:/", 18))
     697           0 :         return 1;
     698           0 :     return 0;
     699             : }
     700             : 
     701             : static int
     702           0 : helpMatch(const char * URI) {
     703           0 :     if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.help:/", 19))
     704           0 :         return 1;
     705           0 :     return 0;
     706             : }
     707             : 
     708             : static void *
     709           0 : fileOpen(const char *URI) {
     710           0 :     osl::File *pRet = new osl::File(rtl::OUString(URI, strlen(URI), RTL_TEXTENCODING_UTF8));
     711           0 :     pRet->open(osl_File_OpenFlag_Read);
     712           0 :     return pRet;
     713             : }
     714             : 
     715             : static void *
     716           0 : zipOpen(SAL_UNUSED_PARAMETER const char *) {
     717           0 :     rtl::OUString language,jar,path;
     718             : 
     719           0 :     if( !ugblData->m_pInitial->get_eid().isEmpty() )
     720           0 :         return (void*)(new Reference< XHierarchicalNameAccess >);
     721             :     else
     722             :     {
     723           0 :         jar = ugblData->m_pInitial->get_jar();
     724           0 :         language = ugblData->m_pInitial->get_language();
     725           0 :         path = ugblData->m_pInitial->get_path();
     726             :     }
     727             : 
     728             :     Reference< XHierarchicalNameAccess > xNA =
     729           0 :         ugblData->m_pDatabases->findJarFileForPath( jar, language, path );
     730             : 
     731           0 :     Reference< XInputStream > xInputStream;
     732             : 
     733           0 :     if( xNA.is() )
     734             :     {
     735             :         try
     736             :         {
     737           0 :             Any aEntry = xNA->getByHierarchicalName( path );
     738           0 :             Reference< XActiveDataSink > xSink;
     739           0 :             if( ( aEntry >>= xSink ) && xSink.is() )
     740           0 :                 xInputStream = xSink->getInputStream();
     741             :         }
     742           0 :         catch ( NoSuchElementException & )
     743             :         {
     744             :         }
     745             :     }
     746             : 
     747           0 :     if( xInputStream.is() )
     748             :     {
     749           0 :         return new Reference<XInputStream>(xInputStream);
     750             :     }
     751           0 :     return 0;
     752             : }
     753             : 
     754             : static void *
     755           0 : helpOpen(const char * URI) {
     756           0 :     rtl::OUString language,jar,path;
     757             : 
     758             :     URLParameter urlpar( rtl::OUString::createFromAscii( URI ),
     759           0 :                          ugblData->m_pDatabases );
     760             : 
     761           0 :     jar = urlpar.get_jar();
     762           0 :     language = urlpar.get_language();
     763           0 :     path = urlpar.get_path();
     764             : 
     765             :     Reference< XHierarchicalNameAccess > xNA =
     766           0 :         ugblData->m_pDatabases->findJarFileForPath( jar, language, path );
     767             : 
     768           0 :     Reference< XInputStream > xInputStream;
     769             : 
     770           0 :     if( xNA.is() )
     771             :     {
     772             :         try
     773             :         {
     774           0 :             Any aEntry = xNA->getByHierarchicalName( path );
     775           0 :             Reference< XActiveDataSink > xSink;
     776           0 :             if( ( aEntry >>= xSink ) && xSink.is() )
     777           0 :                 xInputStream = xSink->getInputStream();
     778             :         }
     779           0 :         catch ( NoSuchElementException & )
     780             :         {
     781             :         }
     782             :     }
     783             : 
     784           0 :     if( xInputStream.is() )
     785           0 :         return new Reference<XInputStream>(xInputStream);
     786           0 :     return 0;
     787             : }
     788             : 
     789             : static int
     790           0 : helpRead(void * context, char * buffer, int len) {
     791           0 :     Reference< XInputStream > *pRef = (Reference< XInputStream >*)context;
     792             : 
     793           0 :     Sequence< sal_Int8 > aSeq;
     794           0 :     len = (*pRef)->readBytes( aSeq,len);
     795           0 :     memcpy(buffer, aSeq.getConstArray(), len);
     796             : 
     797           0 :     return len;
     798             : }
     799             : 
     800             : static int
     801           0 : zipRead(void * context, char * buffer, int len) {
     802           0 :     if( !ugblData->m_pInitial->get_eid().isEmpty() )
     803             :     {
     804           0 :         ugblData->m_pDatabases->popupDocument( ugblData->m_pInitial,&buffer,&len);
     805           0 :         return len;
     806             :     }
     807             :     else
     808           0 :         return helpRead(context, buffer, len);
     809             : }
     810             : 
     811             : static int
     812           0 : fileRead(void * context, char * buffer, int len) {
     813           0 :     int nRead = 0;
     814           0 :     osl::File *pFile = (osl::File*)context;
     815           0 :     if (pFile)
     816             :     {
     817           0 :         sal_uInt64 uRead = 0;
     818           0 :         if (osl::FileBase::E_None == pFile->read(buffer, len, uRead))
     819           0 :             nRead = static_cast<int>(uRead);
     820             :     }
     821           0 :     return nRead;
     822             : }
     823             : 
     824             : static int
     825           0 : uriClose(void * context) {
     826           0 :     Reference< XInputStream > *pRef = (Reference< XInputStream >*)context;
     827           0 :     delete pRef;
     828           0 :     return 0;
     829             : }
     830             : 
     831             : static int
     832           0 : fileClose(void * context) {
     833           0 :     osl::File *pFile = (osl::File*)context;
     834           0 :     if (pFile)
     835             :     {
     836           0 :         pFile->close();
     837           0 :         delete pFile;
     838             :     }
     839           0 :     return 0;
     840             : }
     841             : 
     842             : } // extern "C"
     843             : 
     844           0 : InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam,
     845             :                                                 Databases*    pDatabases,
     846             :                                                 bool isRoot )
     847             :     : len( 0 ),
     848             :       pos( 0 ),
     849           0 :       buffer( new char[1] ) // Initializing with one element to avoid gcc compiler warning
     850             : {
     851           0 :     if( isRoot )
     852             :     {
     853           0 :         delete[] buffer;
     854             :         pDatabases->cascadingStylesheet( urlParam->get_language(),
     855             :                                          &buffer,
     856           0 :                                          &len );
     857             :     }
     858           0 :     else if( urlParam->isActive() )
     859             :     {
     860           0 :         delete[] buffer;
     861             :         pDatabases->setActiveText( urlParam->get_module(),
     862             :                                    urlParam->get_language(),
     863             :                                    urlParam->get_id(),
     864             :                                    &buffer,
     865           0 :                                    &len );
     866             :     }
     867             :     else
     868             :     {
     869           0 :         UserData userData( this,urlParam,pDatabases );
     870             : 
     871             :         // Uses the implementation detail, that rtl::OString::getStr returns a zero terminated character-array
     872             : 
     873             :         const char* parameter[47];
     874           0 :         rtl::OString parString[46];
     875           0 :         int last = 0;
     876             : 
     877           0 :         parString[last++] = "Program";
     878           0 :         rtl::OString aPureProgramm( urlParam->getByName( "Program" ) );
     879           0 :         parString[last++] = rtl::OString('\'') + aPureProgramm + rtl::OString('\'');
     880           0 :         parString[last++] = "Database";
     881           0 :         parString[last++] = rtl::OString('\'') + urlParam->getByName( "DatabasePar" ) + rtl::OString('\'');
     882           0 :         parString[last++] = "Id";
     883           0 :         parString[last++] = rtl::OString('\'') + urlParam->getByName( "Id" ) + rtl::OString('\'');
     884           0 :         parString[last++] = "Path";
     885           0 :         rtl::OString aPath( urlParam->getByName( "Path" ) );
     886           0 :         parString[last++] = rtl::OString('\'') + aPath + rtl::OString('\'');
     887             : 
     888           0 :         rtl::OString aPureLanguage = urlParam->getByName( "Language" );
     889           0 :         parString[last++] = "Language";
     890           0 :         parString[last++] = rtl::OString('\'') + aPureLanguage + rtl::OString('\'');
     891           0 :         parString[last++] = "System";
     892           0 :         parString[last++] = rtl::OString('\'') + urlParam->getByName( "System" ) + rtl::OString('\'');
     893           0 :         parString[last++] = "productname";
     894           0 :         parString[last++] = rtl::OString('\'') + rtl::OString(
     895             :             pDatabases->getProductName().getStr(),
     896             :             pDatabases->getProductName().getLength(),
     897           0 :             RTL_TEXTENCODING_UTF8 ) + rtl::OString('\'');
     898           0 :         parString[last++] = "productversion";
     899           0 :         parString[last++] = rtl::OString('\'') +
     900             :             rtl::OString(  pDatabases->getProductVersion().getStr(),
     901             :                           pDatabases->getProductVersion().getLength(),
     902           0 :                           RTL_TEXTENCODING_UTF8 ) + rtl::OString('\'');
     903             : 
     904           0 :         parString[last++] = "imgrepos";
     905           0 :         parString[last++] = rtl::OString('\'') + pDatabases->getImagesZipFileURL() + rtl::OString('\'');
     906           0 :         parString[last++] = "hp";
     907           0 :         parString[last++] = rtl::OString('\'') + urlParam->getByName( "HelpPrefix" ) + rtl::OString('\'');
     908             : 
     909           0 :         if( !parString[last-1].isEmpty() )
     910             :         {
     911           0 :             parString[last++] = "sm";
     912           0 :             parString[last++] = "'vnd.sun.star.help%3A%2F%2F'";
     913           0 :             parString[last++] = "qm";
     914           0 :             parString[last++] = "'%3F'";
     915           0 :             parString[last++] = "es";
     916           0 :             parString[last++] = "'%3D'";
     917           0 :             parString[last++] = "am";
     918           0 :             parString[last++] = "'%26'";
     919           0 :             parString[last++] = "cl";
     920           0 :             parString[last++] = "'%3A'";
     921           0 :             parString[last++] = "sl";
     922           0 :             parString[last++] = "'%2F'";
     923           0 :             parString[last++] = "hm";
     924           0 :             parString[last++] = "'%23'";
     925           0 :             parString[last++] = "cs";
     926           0 :             parString[last++] = "'css'";
     927             : 
     928           0 :             parString[last++] = "vendorname";
     929           0 :             parString[last++] = rtl::OString("''");
     930           0 :             parString[last++] = "vendorversion";
     931           0 :             parString[last++] = rtl::OString("''");
     932           0 :             parString[last++] = "vendorshort";
     933           0 :             parString[last++] = rtl::OString("''");
     934             :         }
     935             : 
     936             :         // Do we need to add extension path?
     937           0 :         ::rtl::OUString aExtensionPath;
     938           0 :         rtl::OUString aJar = urlParam->get_jar();
     939             : 
     940           0 :         bool bAddExtensionPath = false;
     941           0 :         rtl::OUString aExtensionRegistryPath;
     942           0 :         sal_Int32 nQuestionMark1 = aJar.indexOf( sal_Unicode('?') );
     943           0 :         sal_Int32 nQuestionMark2 = aJar.lastIndexOf( sal_Unicode('?') );
     944           0 :         if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 )
     945             :         {
     946           0 :             aExtensionPath = aJar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 );
     947           0 :             aExtensionRegistryPath = urlParam->get_ExtensionRegistryPath();
     948           0 :             bAddExtensionPath = true;
     949             :         }
     950             :         else
     951             :         {
     952             :             // Path not yet specified, search directly
     953             :             Reference< XHierarchicalNameAccess > xNA = pDatabases->findJarFileForPath
     954           0 :                 ( aJar, urlParam->get_language(), urlParam->get_path(), &aExtensionPath, &aExtensionRegistryPath );
     955           0 :             if( xNA.is() && !aExtensionPath.isEmpty() )
     956           0 :                 bAddExtensionPath = true;
     957             :         }
     958             : 
     959           0 :         if( bAddExtensionPath )
     960             :         {
     961             :             Reference< XComponentContext > xContext(
     962           0 :                 comphelper::getProcessComponentContext() );
     963             : 
     964           0 :             rtl::OUString aOUExpandedExtensionPath = Databases::expandURL( aExtensionRegistryPath, xContext );
     965           0 :             rtl::OString aExpandedExtensionPath = rtl::OUStringToOString( aOUExpandedExtensionPath, osl_getThreadTextEncoding() );
     966             : 
     967           0 :             parString[last++] = "ExtensionPath";
     968           0 :             parString[last++] = rtl::OString('\'') + aExpandedExtensionPath + rtl::OString('\'');
     969             : 
     970             :             // ExtensionId
     971           0 :             rtl::OString aPureExtensionId;
     972           0 :             sal_Int32 iSlash = aPath.indexOf( '/' );
     973           0 :             if( iSlash != -1 )
     974           0 :                 aPureExtensionId = aPath.copy( 0, iSlash );
     975             : 
     976           0 :             parString[last++] = "ExtensionId";
     977           0 :             parString[last++] = rtl::OString('\'') + aPureExtensionId + rtl::OString('\'');
     978             :         }
     979             : 
     980           0 :         for( int i = 0; i < last; ++i )
     981           0 :             parameter[i] = parString[i].getStr();
     982           0 :         parameter[last] = 0;
     983             : 
     984           0 :         rtl::OUString xslURL = pDatabases->getInstallPathAsURL();
     985             : 
     986             :         rtl::OString xslURLascii(
     987             :             xslURL.getStr(),
     988             :             xslURL.getLength(),
     989           0 :             RTL_TEXTENCODING_UTF8);
     990           0 :         xslURLascii += "main_transform.xsl";
     991             : 
     992           0 :         ugblData = &userData;
     993             : 
     994           0 :         xmlInitParser();
     995           0 :         xmlRegisterInputCallbacks(zipMatch, zipOpen, zipRead, uriClose);
     996           0 :         xmlRegisterInputCallbacks(helpMatch, helpOpen, helpRead, uriClose);
     997           0 :         xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose);
     998             : 
     999             :         xsltStylesheetPtr cur =
    1000           0 :             xsltParseStylesheetFile((const xmlChar *)xslURLascii.getStr());
    1001             : 
    1002           0 :         xmlDocPtr doc = xmlParseFile("vnd.sun.star.zip:/");
    1003             : 
    1004           0 :         xmlDocPtr res = xsltApplyStylesheet(cur, doc, parameter);
    1005           0 :         if (res)
    1006             :         {
    1007           0 :             xmlChar *doc_txt_ptr=0;
    1008             :             int doc_txt_len;
    1009           0 :             xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, res, cur);
    1010           0 :             addToBuffer((const char*)doc_txt_ptr, doc_txt_len);
    1011           0 :             xmlFree(doc_txt_ptr);
    1012             :         }
    1013           0 :         xmlPopInputCallbacks(); //filePatch
    1014           0 :         xmlPopInputCallbacks(); //helpPatch
    1015           0 :         xmlPopInputCallbacks(); //zipMatch
    1016           0 :         xmlFreeDoc(res);
    1017           0 :         xmlFreeDoc(doc);
    1018           0 :         xsltFreeStylesheet(cur);
    1019             :     }
    1020           0 : }
    1021             : 
    1022             : 
    1023           0 : InputStreamTransformer::~InputStreamTransformer()
    1024             : {
    1025           0 :     delete[] buffer;
    1026           0 : }
    1027             : 
    1028             : 
    1029           0 : Any SAL_CALL InputStreamTransformer::queryInterface( const Type& rType ) throw( RuntimeException )
    1030             : {
    1031             :     Any aRet = ::cppu::queryInterface( rType,
    1032             :                                        (static_cast< XInputStream* >(this)),
    1033           0 :                                        (static_cast< XSeekable* >(this)) );
    1034             : 
    1035           0 :     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
    1036             : }
    1037             : 
    1038             : 
    1039             : 
    1040           0 : void SAL_CALL InputStreamTransformer::acquire( void ) throw()
    1041             : {
    1042           0 :     OWeakObject::acquire();
    1043           0 : }
    1044             : 
    1045             : 
    1046             : 
    1047           0 : void SAL_CALL InputStreamTransformer::release( void ) throw()
    1048             : {
    1049           0 :     OWeakObject::release();
    1050           0 : }
    1051             : 
    1052             : 
    1053             : 
    1054           0 : sal_Int32 SAL_CALL InputStreamTransformer::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
    1055             :     throw( NotConnectedException,
    1056             :            BufferSizeExceededException,
    1057             :            IOException,
    1058             :            RuntimeException)
    1059             : {
    1060           0 :     osl::MutexGuard aGuard( m_aMutex );
    1061             : 
    1062           0 :     int curr,available_ = len-pos;
    1063           0 :     if( nBytesToRead <= available_ )
    1064           0 :         curr = nBytesToRead;
    1065             :     else
    1066           0 :         curr = available_;
    1067             : 
    1068           0 :     if( 0 <= curr && aData.getLength() < curr )
    1069           0 :         aData.realloc( curr );
    1070             : 
    1071           0 :     for( int k = 0; k < curr; ++k )
    1072           0 :         aData[k] = buffer[pos++];
    1073             : 
    1074           0 :     return curr > 0 ? curr : 0;
    1075             : }
    1076             : 
    1077             : 
    1078           0 : sal_Int32 SAL_CALL InputStreamTransformer::readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
    1079             :     throw( NotConnectedException,
    1080             :            BufferSizeExceededException,
    1081             :            IOException,
    1082             :            RuntimeException)
    1083             : {
    1084           0 :     return readBytes( aData,nMaxBytesToRead );
    1085             : }
    1086             : 
    1087             : 
    1088             : 
    1089           0 : void SAL_CALL InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException,
    1090             :                                                                                  BufferSizeExceededException,
    1091             :                                                                                  IOException,
    1092             :                                                                                  RuntimeException )
    1093             : {
    1094           0 :     osl::MutexGuard aGuard( m_aMutex );
    1095           0 :     while( nBytesToSkip-- ) ++pos;
    1096           0 : }
    1097             : 
    1098             : 
    1099             : 
    1100           0 : sal_Int32 SAL_CALL InputStreamTransformer::available( void ) throw( NotConnectedException,
    1101             :                                                                     IOException,
    1102             :                                                                     RuntimeException )
    1103             : {
    1104           0 :     osl::MutexGuard aGuard( m_aMutex );
    1105           0 :     return len-pos > 0 ? len - pos : 0 ;
    1106             : }
    1107             : 
    1108             : 
    1109             : 
    1110           0 : void SAL_CALL InputStreamTransformer::closeInput( void ) throw( NotConnectedException,
    1111             :                                                                 IOException,
    1112             :                                                                 RuntimeException )
    1113             : {
    1114           0 : }
    1115             : 
    1116             : 
    1117             : 
    1118           0 : void SAL_CALL InputStreamTransformer::seek( sal_Int64 location ) throw( IllegalArgumentException,
    1119             :                                                                         IOException,
    1120             :                                                                         RuntimeException )
    1121             : {
    1122           0 :     osl::MutexGuard aGuard( m_aMutex );
    1123           0 :     if( location < 0 )
    1124           0 :         throw IllegalArgumentException();
    1125             :     else
    1126           0 :         pos = sal::static_int_cast<sal_Int32>( location );
    1127             : 
    1128           0 :     if( pos > len )
    1129           0 :         pos = len;
    1130           0 : }
    1131             : 
    1132             : 
    1133             : 
    1134           0 : sal_Int64 SAL_CALL InputStreamTransformer::getPosition( void ) throw( IOException,
    1135             :                                                                       RuntimeException )
    1136             : {
    1137           0 :     osl::MutexGuard aGuard( m_aMutex );
    1138           0 :     return sal_Int64( pos );
    1139             : }
    1140             : 
    1141             : 
    1142             : 
    1143           0 : sal_Int64 SAL_CALL InputStreamTransformer::getLength( void ) throw( IOException,RuntimeException )
    1144             : {
    1145           0 :     osl::MutexGuard aGuard( m_aMutex );
    1146             : 
    1147           0 :     return len;
    1148             : }
    1149             : 
    1150             : 
    1151           0 : void InputStreamTransformer::addToBuffer( const char* buffer_,int len_ )
    1152             : {
    1153           0 :     osl::MutexGuard aGuard( m_aMutex );
    1154             : 
    1155           0 :     char* tmp = buffer;
    1156           0 :     buffer = new char[ len+len_ ];
    1157           0 :     memcpy( (void*)(buffer),(void*)(tmp),sal_uInt32( len ) );
    1158           0 :     memcpy( (void*)(buffer+len),(void*)(buffer_),sal_uInt32( len_ ) );
    1159           0 :     delete[] tmp;
    1160           0 :     len += len_;
    1161           0 : }
    1162             : 
    1163             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10