LCOV - code coverage report
Current view: top level - extensions/source/plugin/base - xplugin.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 585 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 50 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             :  *
       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             : #ifdef AIX
      30             : #define _LINUX_SOURCE_COMPAT
      31             : #include <sys/timer.h>
      32             : #undef _LINUX_SOURCE_COMPAT
      33             : #endif
      34             : 
      35             : #ifdef WNT
      36             : #include <prewin.h>
      37             : #include <postwin.h>
      38             : #endif
      39             : 
      40             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      41             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      42             : #include <com/sun/star/loader/XImplementationLoader.hpp>
      43             : #include <com/sun/star/plugin/PluginManager.hpp>
      44             : 
      45             : #include <cppuhelper/queryinterface.hxx>
      46             : #include <comphelper/processfactory.hxx>
      47             : #include <plugin/impl.hxx>
      48             : #include <sal/log.hxx>
      49             : #include <ucbhelper/content.hxx>
      50             : #include <tools/urlobj.hxx>
      51             : #include <vcl/svapp.hxx>
      52             : #include <salhelper/timer.hxx>
      53             : #include <osl/file.hxx>
      54             : 
      55             : #ifdef UNX
      56             : #include <sys/types.h>
      57             : #include <sys/socket.h>
      58             : #endif
      59             : 
      60             : #if OSL_DEBUG_LEVEL > 1
      61             : #include <stdio.h>
      62             : #endif
      63             : 
      64             : #include <boost/scoped_array.hpp>
      65             : 
      66             : using namespace com::sun::star;
      67             : using namespace com::sun::star::io;
      68             : using namespace com::sun::star::beans;
      69             : using namespace com::sun::star::plugin;
      70             : using namespace osl;
      71             : 
      72             : class PluginDisposer : public salhelper::Timer
      73             : {
      74             : private:
      75             :     XPlugin_Impl*       m_pPlugin;
      76             : 
      77             :     virtual void SAL_CALL onShot() SAL_OVERRIDE;
      78             : public:
      79           0 :     PluginDisposer( XPlugin_Impl* pPlugin ) :
      80             :         salhelper::Timer( salhelper::TTimeValue( 2, 0 ),
      81             :                           salhelper::TTimeValue( 2, 0 ) ),
      82           0 :         m_pPlugin( pPlugin )
      83           0 :         { start(); }
      84           0 :     virtual ~PluginDisposer() {}
      85             : };
      86             : 
      87           0 : void PluginDisposer::onShot()
      88             : {
      89           0 :     if( m_pPlugin )
      90             :     {
      91           0 :         if( m_pPlugin->isDisposable() )
      92             :         {
      93           0 :             Application::PostUserEvent( LINK( m_pPlugin, XPlugin_Impl, secondLevelDispose ), static_cast<void*>(m_pPlugin) );
      94             :         }
      95             :     }
      96             :     else
      97           0 :         release();
      98           0 : }
      99             : 
     100           0 : Any XPlugin_Impl::queryInterface( const Type& type ) throw( RuntimeException, std::exception )
     101             : {
     102           0 :     return OWeakAggObject::queryInterface( type );
     103             : }
     104             : 
     105           0 : Any XPlugin_Impl::queryAggregation( const Type& type ) throw( RuntimeException, std::exception )
     106             : {
     107           0 :     Any aRet( cppu::queryInterface( type, static_cast< XPlugin* >(this) ) );
     108           0 :     if( ! aRet.hasValue() )
     109           0 :         aRet = PluginControl_Impl::queryAggregation( type );
     110           0 :     return aRet;
     111             : }
     112             : 
     113             : 
     114           0 : XPlugin_Impl::XPlugin_Impl( const uno::Reference< com::sun::star::lang::XMultiServiceFactory >  & rSMgr) :
     115             :         PluginControl_Impl(),
     116             :         m_xSMgr( rSMgr ),
     117             :         m_pPluginComm( NULL ),
     118             :         m_pSysPlugData( CreateSysPlugData() ),
     119           0 :         m_aEncoding( osl_getThreadTextEncoding() ),
     120             :         m_pArgv( NULL ),
     121             :         m_pArgn( NULL ),
     122             :         m_nArgs( 0 ),
     123             :         m_aPluginMode( NP_FULL ),
     124             :         m_nProvidingState( PROVIDING_NONE ),
     125             :         m_nCalledFromPlugin( 0 ),
     126             :         m_pDisposer( NULL ),
     127           0 :         m_bIsDisposed( false )
     128             : {
     129           0 :     memset( &m_aInstance, 0, sizeof( m_aInstance ) );
     130           0 :     memset( &m_aNPWindow, 0, sizeof( m_aNPWindow ) );
     131             : 
     132           0 :     m_xModel = new PluginModel();
     133           0 :     uno::Reference< com::sun::star::beans::XPropertySet >  xPS( m_xModel, UNO_QUERY );
     134           0 :     xPS->addPropertyChangeListener( OUString(), this );
     135             : 
     136           0 :     Guard< Mutex > aGuard( ::PluginManager::get().getPluginMutex() );
     137           0 :     ::PluginManager::get().getPlugins().push_back( this );
     138           0 : }
     139             : 
     140           0 : void XPlugin_Impl::destroyInstance()
     141             : {
     142           0 :     Guard< Mutex > aGuard( m_aMutex );
     143             : 
     144           0 :     NPSavedData* pSavedData = NULL;
     145             : 
     146           0 :     destroyStreams();
     147           0 :     if( getPluginComm() )
     148             :     {
     149           0 :         getPluginComm()->NPP_Destroy( this, &pSavedData );
     150           0 :         getPluginComm()->decRef();
     151           0 :         m_pPluginComm = NULL;
     152             :     }
     153             : 
     154           0 :     freeArgs();
     155             : 
     156           0 :     while( m_aPEventListeners.size() )
     157             :     {
     158           0 :         delete *m_aPEventListeners.begin();
     159           0 :         m_aPEventListeners.pop_front();
     160           0 :     }
     161           0 : }
     162             : 
     163           0 : XPlugin_Impl::~XPlugin_Impl()
     164             : {
     165           0 :     destroyInstance();
     166           0 : }
     167             : 
     168           0 : void XPlugin_Impl::checkListeners( const char* normalizedURL )
     169             : {
     170           0 :     if( ! normalizedURL )
     171           0 :         return;
     172             : 
     173           0 :     Guard< Mutex > aGuard( m_aMutex );
     174             : 
     175           0 :     std::list<PluginEventListener*>::iterator iter;
     176           0 :     for( iter = m_aPEventListeners.begin();
     177           0 :          iter != m_aPEventListeners.end();
     178             :          ++iter )
     179             :     {
     180           0 :         if( ! strcmp( normalizedURL, (*iter)->getURL() ) ||
     181           0 :             ! strcmp( normalizedURL, (*iter)->getNormalizedURL() ) )
     182             :         {
     183           0 :             (*iter)->disposing( com::sun::star::lang::EventObject() );
     184           0 :             delete *iter;
     185           0 :             m_aPEventListeners.remove( *iter );
     186           0 :             return;
     187             :         }
     188           0 :     }
     189             : }
     190             : 
     191           0 : IMPL_LINK( XPlugin_Impl, secondLevelDispose, XPlugin_Impl*, /*pThis*/ )
     192             : {
     193           0 :     Guard< Mutex > aGuard( m_aMutex );
     194             : 
     195             :     // may have become undisposable between PostUserEvent and here
     196             :     // or may have disposed and receive a second UserEvent
     197           0 :     std::list<XPlugin_Impl*>& rList = ::PluginManager::get().getPlugins();
     198           0 :     std::list<XPlugin_Impl*>::iterator iter;
     199             : 
     200             :     {
     201           0 :         Guard< Mutex > aPluginGuard( ::PluginManager::get().getPluginMutex() );
     202           0 :         for( iter = rList.begin(); iter != rList.end(); ++iter )
     203             :         {
     204           0 :             if( *iter == this )
     205           0 :                 break;
     206             :         }
     207           0 :         if( iter == rList.end() || ! isDisposable() )
     208           0 :             return 0;
     209             :     }
     210             : 
     211           0 :     if (m_pDisposer)
     212             :     {
     213           0 :         m_pDisposer->release();
     214           0 :         m_pDisposer = NULL;
     215             :     }
     216             : 
     217           0 :     uno::Reference< XPlugin >  xProtection( this );
     218           0 :     uno::Reference< com::sun::star::beans::XPropertySet >  xPS( m_xModel, UNO_QUERY );
     219           0 :     xPS->removePropertyChangeListener( OUString(), this );
     220             :     {
     221           0 :         Guard< Mutex > aPluginGuard( ::PluginManager::get().getPluginMutex() );
     222           0 :         rList.remove( this );
     223             :     }
     224           0 :     m_aNPWindow.window = NULL;
     225             : #ifndef UNX
     226             :     // acrobat does an unconditional XtParent on the windows widget
     227             :     getPluginComm()->NPP_SetWindow( this );
     228             : #endif
     229           0 :     destroyInstance();
     230           0 :     PluginControl_Impl::dispose();
     231           0 :     return 0;
     232             : }
     233             : 
     234           0 : void XPlugin_Impl::dispose() throw(std::exception)
     235             : {
     236           0 :     Guard< Mutex > aGuard( m_aMutex );
     237             : 
     238           0 :     if (m_bIsDisposed || !getPluginComm())
     239           0 :         return;
     240           0 :     m_bIsDisposed = true;
     241             : 
     242           0 :     if( isDisposable() )
     243           0 :         secondLevelDispose( this );
     244             :     else
     245             :     {
     246           0 :         m_pDisposer = new PluginDisposer( this );
     247           0 :         m_pDisposer->acquire();
     248           0 :     }
     249             : }
     250             : 
     251           0 : void XPlugin_Impl::initArgs( const Sequence< OUString >& argn,
     252             :                              const Sequence< OUString >& argv,
     253             :                              sal_Int16 mode )
     254             : {
     255           0 :     m_aPluginMode = mode;
     256             : 
     257           0 :     m_nArgs = argn.getLength();
     258           0 :     m_pArgn = new const char*[m_nArgs];
     259           0 :     m_pArgv = new const char*[m_nArgs];
     260           0 :     const OUString* pUArgn = argn.getConstArray();
     261           0 :     const OUString* pUArgv = argv.getConstArray();
     262           0 :     for( int i = 0; i < m_nArgs; i++ )
     263             :     {
     264           0 :         m_pArgn[i] = strdup(
     265           0 :             OUStringToOString( pUArgn[i], m_aEncoding ).getStr()
     266           0 :             );
     267           0 :         m_pArgv[i] = strdup(
     268           0 :             OUStringToOString( pUArgv[i], m_aEncoding ).getStr()
     269           0 :             );
     270             :     }
     271           0 : }
     272             : 
     273           0 : void XPlugin_Impl::freeArgs()
     274             : {
     275           0 :     if( m_nArgs > 0 )
     276             :     {
     277           0 :         for( ; m_nArgs--; )
     278             :         {
     279           0 :             free( const_cast<char *>(m_pArgn[m_nArgs]) );
     280           0 :             free( const_cast<char *>(m_pArgv[m_nArgs]) );
     281             :         }
     282           0 :         delete [] m_pArgn;
     283           0 :         delete [] m_pArgv;
     284             :     }
     285           0 : }
     286             : 
     287           0 : void XPlugin_Impl::prependArg( const char* pName, const char* pValue )
     288             : {
     289           0 :     const char** pNewNames      = new const char*[m_nArgs+1];
     290           0 :     const char** pNewValues = new const char*[m_nArgs+1];
     291             : 
     292           0 :     pNewNames[0]        = strdup( pName );
     293           0 :     pNewValues[0]       = strdup( pValue );
     294           0 :     for( int nIndex = 0; nIndex < m_nArgs; ++nIndex )
     295             :     {
     296           0 :         pNewNames[nIndex+1] = m_pArgn[nIndex];
     297           0 :         pNewValues[nIndex+1]= m_pArgv[nIndex];
     298             :     }
     299             :     // free old arrays
     300           0 :     delete [] m_pArgn;
     301           0 :     delete [] m_pArgv;
     302             :     // set new arrays
     303           0 :     m_pArgn = pNewNames;
     304           0 :     m_pArgv = pNewValues;
     305             :     // set new number of arguments
     306           0 :     m_nArgs++;
     307             : #if OSL_DEBUG_LEVEL > 1
     308             :     fprintf( stderr, "inserted %s=%s\n", pNewNames[0], pNewValues[0] );
     309             : #endif
     310           0 : }
     311             : 
     312           0 : void XPlugin_Impl::handleSpecialArgs()
     313             : {
     314             :     // special handling for real audio which needs a lot of parameters
     315             :     // or won't function at all
     316           0 :     if( m_aDescription.Mimetype == "audio/x-pn-realaudio-plugin" && m_nArgs < 1 )
     317             :     {
     318           0 :         OUString aURL;
     319           0 :         if( m_xModel.is() )
     320             :         {
     321             :             try
     322             :             {
     323           0 :                 uno::Reference< XPropertySet > xProp( m_xModel, UNO_QUERY );
     324           0 :                 Any aProp = xProp->getPropertyValue("URL");
     325           0 :                 aProp >>= aURL;
     326             :             }
     327           0 :             catch(const UnknownPropertyException &)
     328             :             {
     329             :             }
     330             :         }
     331             : 
     332           0 :         if( !aURL.isEmpty() )
     333             :         {
     334             :             // set new args, old args need not be freed as there were none set
     335           0 :             m_nArgs = 6;
     336           0 :             m_pArgn = new const char*[m_nArgs];
     337           0 :             m_pArgv = new const char*[m_nArgs];
     338             : 
     339             :             // SRC
     340           0 :             m_pArgn[0]      = strdup( "SRC" );
     341           0 :             m_pArgv[0]      = strdup( OUStringToOString( aURL, m_aEncoding ).getStr() );
     342             :             // WIDTH
     343           0 :             m_pArgn[1]      = strdup( "WIDTH" );
     344           0 :             m_pArgv[1]      = strdup( "200" );
     345             :             // HEIGHT
     346           0 :             m_pArgn[2]      = strdup( "HEIGHT" );
     347           0 :             m_pArgv[2]      = strdup( "200" );
     348             :             // CONTROLS
     349           0 :             m_pArgn[3]      = strdup( "CONTROLS" );
     350           0 :             m_pArgv[3]      = strdup( "PlayButton,StopButton,ImageWindow" );
     351             :             // AUTOSTART
     352           0 :             m_pArgn[4]      = strdup( "AUTOSTART" );
     353           0 :             m_pArgv[4]      = strdup( "TRUE" );
     354             :             // NOJAVA
     355           0 :             m_pArgn[5]      = strdup( "NOJAVA" );
     356           0 :             m_pArgv[5]      = strdup( "TRUE" );
     357           0 :         }
     358             :     }
     359             :     // #69333# special for pdf
     360           0 :     else if( m_aDescription.Mimetype == "application/pdf" )
     361           0 :         m_aPluginMode = PluginMode::FULL;
     362             : 
     363             :     // see if we have a TYPE tag
     364             :     int nIndex;
     365           0 :     for( nIndex = 0; nIndex < m_nArgs; ++nIndex )
     366           0 :         if( m_pArgn[nIndex][0] == 'T' &&
     367           0 :             m_pArgn[nIndex][1] == 'Y' &&
     368           0 :             m_pArgn[nIndex][2] == 'P' &&
     369           0 :             m_pArgn[nIndex][3] == 'E' &&
     370           0 :             m_pArgn[nIndex][4] == 0 )
     371           0 :             break;
     372           0 :     if( nIndex >= m_nArgs )
     373             :     {
     374             :         // TYPE
     375           0 :         prependArg( "TYPE", OUStringToOString( m_aDescription.Mimetype, m_aEncoding ).getStr() );
     376             :     }
     377             : 
     378             :     // see if we have a SRC tag
     379           0 :     for( nIndex = 0; nIndex < m_nArgs; ++nIndex )
     380           0 :         if( m_pArgn[nIndex][0] == 'S' &&
     381           0 :             m_pArgn[nIndex][1] == 'R' &&
     382           0 :             m_pArgn[nIndex][2] == 'C' &&
     383           0 :             m_pArgn[nIndex][3] == 0 )
     384           0 :             break;
     385           0 :     if( nIndex >= m_nArgs )
     386             :     {
     387             :         // need a SRC parameter (as all browser set one on the plugin
     388           0 :         OUString aURL;
     389           0 :         if( m_xModel.is() )
     390             :         {
     391             :             try
     392             :             {
     393           0 :                 uno::Reference< XPropertySet > xProp( m_xModel, UNO_QUERY );
     394           0 :                 Any aProp = xProp->getPropertyValue("URL");
     395           0 :                 aProp >>= aURL;
     396             :             }
     397           0 :             catch(const UnknownPropertyException &)
     398             :             {
     399             :             }
     400             :         }
     401             : 
     402           0 :         if( !aURL.isEmpty() )
     403             :         {
     404             :             // SRC
     405           0 :             prependArg( "SRC", OUStringToOString( aURL, m_aEncoding ).getStr() );
     406           0 :         }
     407             :     }
     408           0 : }
     409             : 
     410           0 : void XPlugin_Impl::initInstance( const PluginDescription& rDescription,
     411             :                                  const Sequence< OUString >& argn,
     412             :                                  const Sequence< OUString >& argv,
     413             :                                  sal_Int16 mode )
     414             : {
     415           0 :     Guard< Mutex > aGuard( m_aMutex );
     416             : 
     417           0 :     m_aDescription = rDescription;
     418           0 :     initArgs( argn, argv, mode );
     419           0 :     handleSpecialArgs();
     420           0 : }
     421             : 
     422           0 : void XPlugin_Impl::initInstance( const OUString& rURL,
     423             :                                  const Sequence< OUString >& argn,
     424             :                                  const Sequence< OUString >& argv,
     425             :                                  sal_Int16 mode )
     426             : {
     427           0 :     Guard< Mutex > aGuard( m_aMutex );
     428             : 
     429           0 :     initArgs( argn, argv, mode );
     430           0 :     m_aDescription = fitDescription( rURL );
     431             : 
     432           0 :     m_xModel = new PluginModel( rURL, m_aDescription.Mimetype );
     433           0 :     handleSpecialArgs();
     434           0 : }
     435             : 
     436           0 : void XPlugin_Impl::modelChanged()
     437             : {
     438           0 :     Guard< Mutex > aGuard( m_aMutex );
     439             : 
     440           0 :     m_nProvidingState = PROVIDING_MODEL_UPDATE;
     441             : 
     442           0 :     m_aDescription = fitDescription( getCreationURL() );
     443           0 :     destroyInstance();
     444           0 :     if( m_aDescription.Mimetype.isEmpty() )
     445             :     {
     446           0 :         m_nProvidingState = PROVIDING_NONE;
     447           0 :         return;
     448             :     }
     449             : 
     450           0 :     OUString aURL = getCreationURL();
     451             :     provideNewStream( m_aDescription.Mimetype,
     452             :                       uno::Reference< XActiveDataSource >(),
     453             :                       aURL,
     454           0 :                       0, 0, aURL.startsWith("file:") );
     455           0 :     m_nProvidingState = PROVIDING_NONE;
     456             : }
     457             : 
     458           0 : OUString XPlugin_Impl::getCreationURL()
     459             : {
     460           0 :     Guard< Mutex > aGuard( m_aMutex );
     461             : 
     462           0 :     OUString aRet;
     463           0 :     uno::Reference< com::sun::star::beans::XPropertySet >  xPS( m_xModel, UNO_QUERY );
     464           0 :     if( xPS.is() )
     465             :     {
     466           0 :         Any aValue = xPS->getPropertyValue("URL");
     467           0 :         aValue >>= aRet;
     468             :     }
     469           0 :     return aRet;
     470             : }
     471             : 
     472             : 
     473           0 : sal_Bool XPlugin_Impl::setModel( const uno::Reference< com::sun::star::awt::XControlModel > & Model )
     474             :     throw( RuntimeException, std::exception )
     475             : {
     476           0 :     Guard< Mutex > aGuard( m_aMutex );
     477             : 
     478           0 :     uno::Reference< com::sun::star::beans::XPropertySet >  xPS( Model, UNO_QUERY );
     479           0 :     if( ! xPS.is() )
     480           0 :         return sal_False;
     481             : 
     482           0 :     if( !getCreationURL().isEmpty() )
     483             :     {
     484           0 :         m_xModel = Model;
     485           0 :         modelChanged();
     486           0 :         xPS->addPropertyChangeListener( OUString(), this );
     487           0 :         return sal_True;
     488             :     }
     489           0 :     return sal_False;
     490             : }
     491             : 
     492           0 : void XPlugin_Impl::createPeer( const uno::Reference< com::sun::star::awt::XToolkit > & xToolkit, const uno::Reference< com::sun::star::awt::XWindowPeer > & Parent )
     493             :     throw( RuntimeException, std::exception )
     494             : {
     495           0 :     Guard< Mutex > aGuard( m_aMutex );
     496             : 
     497           0 :     if( ! _xPeer.is() )
     498             :     {
     499           0 :         if( ! Parent.is() )
     500           0 :             throw  RuntimeException();
     501           0 :         PluginControl_Impl::createPeer( xToolkit, Parent );
     502           0 :     }
     503           0 : }
     504             : 
     505           0 : void XPlugin_Impl::loadPlugin()
     506             : {
     507           0 :     Guard< Mutex > aGuard( m_aMutex );
     508             : 
     509           0 :     std::list<PluginComm*>::iterator iter;
     510           0 :     for( iter = ::PluginManager::get().getPluginComms().begin();
     511           0 :          iter != ::PluginManager::get().getPluginComms().end(); ++iter )
     512             :     {
     513           0 :         if( OStringToOUString( (*iter)->getLibName(), m_aEncoding ) == m_aDescription.PluginName )
     514             :         {
     515           0 :             setPluginComm( *iter );
     516           0 :             break;
     517             :         }
     518             :     }
     519           0 :     const SystemEnvData* pEnvData = getSysChildSysData();
     520             : #if defined( UNX ) && !(defined(MACOSX))
     521           0 :     if (pEnvData->pDisplay) // headless?
     522             :     {
     523           0 :         XSync( static_cast<Display*>(pEnvData->pDisplay), False );
     524             :     }
     525             : #endif
     526           0 :     if( ! getPluginComm() )
     527             :     {
     528           0 :         if( !m_aDescription.PluginName.isEmpty() )
     529             :         {
     530             : #if defined MACOSX
     531             :             PluginComm* pComm = new MacPluginComm( m_aDescription.Mimetype,
     532             :                                                    m_aDescription.PluginName,
     533             :                                                    pEnvData->mpNSView );
     534             : #elif defined UNX
     535             :             // need a new PluginComm
     536           0 :             PluginComm* pComm = NULL;
     537             :             int sv[2];
     538           0 :             if( !socketpair( AF_UNIX, SOCK_STREAM, 0, sv ) )
     539             :                 pComm = new UnxPluginComm( m_aDescription.Mimetype,
     540             :                                            m_aDescription.PluginName,
     541             :                                            (Window)pEnvData->aWindow,
     542             :                                            sv[0],
     543             :                                            sv[1]
     544           0 :                                            );
     545             : 
     546             :             SAL_WARN_IF( !pComm, "extensions.plugin", "no PluginComm");
     547           0 :             if (!pComm)
     548           0 :                 return;
     549             : 
     550             : #elif defined WNT
     551             :             PluginComm* pComm = new PluginComm_Impl( m_aDescription.Mimetype,
     552             :                                                      m_aDescription.PluginName,
     553             :                                                      (HWND)pEnvData->hWnd );
     554             : #endif
     555             : 
     556           0 :             setPluginComm( pComm );
     557             :         }
     558             :         else
     559           0 :             return;
     560             :     }
     561             : 
     562           0 :     getPluginComm()->
     563             :         NPP_New( const_cast<char*>(OUStringToOString( m_aDescription.Mimetype,
     564           0 :                                                   m_aEncoding).getStr()),
     565           0 :                  &getNPPInstance(),
     566           0 :                  m_aPluginMode == PluginMode::FULL ? NP_FULL : NP_EMBED,
     567           0 :                  ::sal::static_int_cast< int16_t, int >( m_nArgs ),
     568             :                  const_cast<char**>(m_nArgs ? m_pArgn : NULL),
     569             :                  const_cast<char**>(m_nArgs ? m_pArgv : NULL),
     570           0 :                  NULL );
     571             : #ifdef MACOSX
     572             :     // m_aNPWindow is set up in the MacPluginComm from the view
     573             :     SetSysPlugDataParentView(*pEnvData);
     574             : #elif defined( UNX )
     575           0 :     if (pEnvData->pDisplay) // headless?
     576             :     {
     577           0 :         XSync( static_cast<Display*>(pEnvData->pDisplay), False );
     578           0 :         m_aNPWindow.window  = reinterpret_cast<void*>(pEnvData->aWindow);
     579             :     }
     580             :     else
     581             :     {
     582           0 :         m_aNPWindow.window  = NULL;
     583             :     }
     584           0 :     m_aNPWindow.ws_info     = NULL;
     585             : #else
     586             :     m_aNPWindow.window = (void*)pEnvData->hWnd;
     587             : #endif
     588           0 :     com::sun::star::awt::Rectangle aPosSize = getPosSize();
     589             : 
     590           0 :     for( int i = 0; i < m_nArgs; i++ )
     591             :     {
     592           0 :         OString aName( m_pArgn[i] );
     593           0 :         if( aName.equalsIgnoreAsciiCase( "width" ) )
     594             :         {
     595           0 :             OString aValue( m_pArgv[i] );
     596           0 :             aPosSize.Width = aValue.toInt32();
     597             :         }
     598           0 :         else if( aName.equalsIgnoreAsciiCase( "height" ) )
     599             :         {
     600           0 :             OString aValue( m_pArgv[i] );
     601           0 :             aPosSize.Height = aValue.toInt32();
     602             :         }
     603           0 :     }
     604             : 
     605           0 :     m_aNPWindow.clipRect.top        = 0;
     606           0 :     m_aNPWindow.clipRect.left       = 0;
     607           0 :     m_aNPWindow.clipRect.bottom     = ::sal::static_int_cast< uint16_t, sal_Int32 >( aPosSize.Height );
     608           0 :     m_aNPWindow.clipRect.right      = ::sal::static_int_cast< uint16_t, sal_Int32 >( aPosSize.Width );
     609           0 :     m_aNPWindow.type = NPWindowTypeWindow;
     610             : 
     611           0 :     m_aNPWindow.x       = 0;
     612           0 :     m_aNPWindow.y       = 0;
     613           0 :     m_aNPWindow.width   = aPosSize.Width ? aPosSize.Width : 600;
     614           0 :     m_aNPWindow.height  = aPosSize.Height ? aPosSize.Height : 600;
     615             : 
     616           0 :     getPluginComm()->NPP_SetWindow( this );
     617             : }
     618             : 
     619           0 : void XPlugin_Impl::destroyStreams()
     620             : {
     621           0 :     Guard< Mutex > aGuard( m_aMutex );
     622             : 
     623             :     // streams remove themselves from this list when deleted
     624           0 :     while( m_aOutputStreams.size() )
     625           0 :         delete *m_aOutputStreams.begin();
     626             : 
     627             :     // input streams are XOutputStreams, they cannot be simply deleted
     628           0 :     std::list<PluginInputStream*> aLocalList( m_aInputStreams );
     629           0 :     for( std::list<PluginInputStream*>::iterator it = aLocalList.begin();
     630           0 :          it != aLocalList.end(); ++it )
     631           0 :         (*it)->setMode( -1 );
     632           0 : }
     633             : 
     634           0 : PluginStream* XPlugin_Impl::getStreamFromNPStream( NPStream* stream )
     635             : {
     636           0 :     Guard< Mutex > aGuard( m_aMutex );
     637             : 
     638           0 :     std::list<PluginInputStream*>::iterator iter;
     639           0 :     for( iter = m_aInputStreams.begin(); iter != m_aInputStreams.end(); ++iter )
     640           0 :         if( &(*iter)->getStream() == stream )
     641           0 :             return *iter;
     642             : 
     643           0 :     std::list<PluginOutputStream*>::iterator iter2;
     644           0 :     for( iter2 = m_aOutputStreams.begin(); iter2 != m_aOutputStreams.end(); ++iter2 )
     645           0 :         if( &(*iter2)->getStream() == stream )
     646           0 :             return *iter2;
     647             : 
     648           0 :     return NULL;
     649             : }
     650             : 
     651           0 : sal_Bool XPlugin_Impl::provideNewStream(const OUString& mimetype,
     652             :                                         const uno::Reference< com::sun::star::io::XActiveDataSource > & stream,
     653             :                                         const OUString& url, sal_Int32 length,
     654             :                                         sal_Int32 lastmodified, sal_Bool isfile) throw(std::exception)
     655             : 
     656             : {
     657           0 :     Guard< Mutex > aGuard( m_aMutex );
     658           0 :     bool bRet = false;
     659             : 
     660           0 :     if( m_nProvidingState != PROVIDING_NONE )
     661             :     {
     662           0 :         m_nProvidingState = PROVIDING_NOW;
     663           0 :         Any aAny;
     664           0 :         aAny <<= url;
     665           0 :         uno::Reference< com::sun::star::beans::XPropertySet >  xPS( m_xModel, UNO_QUERY );
     666           0 :         if( xPS.is() )
     667             :         {
     668             :             try
     669             :             {
     670           0 :                 xPS->setPropertyValue("URL", aAny );
     671           0 :                 aAny <<= mimetype;
     672           0 :                 xPS->setPropertyValue("TYPE", aAny );
     673             :             }
     674           0 :             catch(...)
     675             :             {
     676             :             }
     677           0 :         }
     678             :     }
     679           0 :     m_nProvidingState = PROVIDING_NOW;
     680             : 
     681           0 :     OString aMIME;
     682           0 :     if( !mimetype.isEmpty() )
     683           0 :         aMIME = OUStringToOString( mimetype, m_aEncoding );
     684             :     else
     685           0 :         aMIME = OUStringToOString( m_aDescription.Mimetype, m_aEncoding );
     686             : 
     687           0 :     OString aURL  = OUStringToOString( url, m_aEncoding );
     688             : 
     689             :     // check whether there is a notifylistener for this stream
     690             :     // this means that the strema is created from the plugin
     691             :     // via NPN_GetURLNotify or NPN_PostURLNotify
     692           0 :     std::list<PluginEventListener*>::iterator iter;
     693           0 :     for( iter = m_aPEventListeners.begin();
     694           0 :          iter != m_aPEventListeners.end();
     695             :          ++iter )
     696             :     {
     697           0 :         if( (*iter)->getNormalizedURL() == aURL )
     698             :         {
     699           0 :             aURL = (*iter)->getURL();
     700           0 :             break;
     701             :         }
     702             :     }
     703             : 
     704           0 :     if( ! m_pPluginComm )
     705             :     {
     706           0 :         loadPlugin();
     707           0 :         if( !m_aLastGetUrl.isEmpty() && m_aLastGetUrl == aURL )
     708             :         {
     709             :             // plugin is pulling data, don't push the same stream;
     710             :             // this complicated method could have been avoided if
     711             :             // all plugins respected the SRC parameter; but e.g.
     712             :             // acrobat reader plugin does not
     713           0 :             m_nProvidingState = PROVIDING_NONE;
     714           0 :             return sal_True;
     715             :         }
     716             :     }
     717           0 :      if( ! m_pPluginComm )
     718           0 :         return sal_False;
     719             : 
     720           0 :      if(  url.isEmpty() )
     721             :          // this is valid if the plugin is supposed to
     722             :          // pull data (via e.g. NPN_GetURL)
     723           0 :          return sal_True;
     724             : 
     725             :      // set mimetype on model
     726             :      {
     727           0 :          uno::Reference< com::sun::star::beans::XPropertySet >  xPS( m_xModel, UNO_QUERY );
     728           0 :          if( xPS.is() )
     729             :          {
     730             :              try
     731             :              {
     732           0 :                  Any aAny;
     733           0 :                  aAny <<= m_aDescription.Mimetype;
     734           0 :                  xPS->setPropertyValue("TYPE", aAny );
     735             :              }
     736           0 :              catch(...)
     737             :              {
     738             :              }
     739           0 :          }
     740             :      }
     741             : 
     742             :      // there may be plugins that can use the file length information,
     743             :      // but currently none are known. Since this file opening/seeking/closing
     744             :      // is rather costly, it is not implemented. If there are plugins known to
     745             :      // make use of the file length, simply put it in
     746             : 
     747             :      PluginInputStream* pStream = new PluginInputStream( this, aURL.getStr(),
     748           0 :                                                         length, lastmodified );
     749           0 :      uno::Reference< com::sun::star::io::XOutputStream > xNewStream( pStream );
     750             : 
     751           0 :      if( iter != m_aPEventListeners.end() )
     752           0 :          pStream->getStream().notifyData = (*iter)->getNotifyData();
     753             : 
     754           0 :     uint16_t stype = 0;
     755             : 
     756             :     // special handling acrobat reader
     757             :     // presenting a seekable stream to it does not seem to work correctly
     758           0 :     if( aMIME.equals( "application/pdf" ) )
     759           0 :         isfile = sal_False;
     760             : 
     761             : #if OSL_DEBUG_LEVEL > 1
     762             :     fprintf( stderr,
     763             :              "new stream \"%s\" of MIMEType \"%s\"\n"
     764             :              "for plugin \"%s\"\n"
     765             :              "seekable = %s, length = %" SAL_PRIdINT32 "\n",
     766             :              aURL.getStr(), aMIME.getStr(), getPluginComm()->getLibName().getStr(),
     767             :              isfile ? "true" : "false", length );
     768             : 
     769             : #endif
     770           0 :     if( ! m_pPluginComm->NPP_NewStream( &m_aInstance,
     771           0 :                                         const_cast<char*>(aMIME.getStr()),
     772           0 :                                         &pStream->getStream(), isfile,
     773           0 :                                         &stype ) )
     774             :     {
     775             : #if OSL_DEBUG_LEVEL > 1
     776             :         const char* pType;
     777             :         switch( stype )
     778             :         {
     779             :             case NP_NORMAL:     pType = "NP_NORMAL";break;
     780             :             case NP_SEEK:       pType = "NP_SEEK";break;
     781             :             case NP_ASFILE:     pType = "NP_ASFILE";break;
     782             :             case NP_ASFILEONLY: pType = "NP_ASFILEONLY";break;
     783             :             default:            pType = "unknown!!!";
     784             :         }
     785             :         fprintf( stderr, "Plugin wants it in Mode %s\n", pType );
     786             : #endif
     787           0 :         if( isfile && stype == NP_ASFILEONLY )
     788             :         {
     789           0 :             OString aFileName;
     790           0 :             if( url.startsWith("file:") )
     791             :             {
     792           0 :                 OUString aSysName;
     793           0 :                 osl_getSystemPathFromFileURL( url.pData, &aSysName.pData );
     794           0 :                 aFileName = OUStringToOString( aSysName, m_aEncoding );
     795             :             }
     796             :             else
     797           0 :                 aFileName = OUStringToOString( url, m_aEncoding );
     798             :             m_pPluginComm->
     799             :                 NPP_StreamAsFile( &m_aInstance,
     800           0 :                                   &pStream->getStream(),
     801           0 :                                   aFileName.getStr() );
     802             :         }
     803             :         else
     804             :         {
     805           0 :             pStream->setMode( stype );
     806             : 
     807           0 :             if( ! stream.is() )
     808             :             {
     809             :                 // stream has to be loaded by PluginStream itself via UCB
     810           0 :                 pStream->load();
     811             :             }
     812             :             else
     813             :             {
     814           0 :                 uno::Reference< com::sun::star::io::XConnectable > xConnectable( stream, UNO_QUERY );
     815           0 :                 pStream->setPredecessor( xConnectable );
     816           0 :                 if( xConnectable.is() )
     817             :                 {
     818           0 :                     xConnectable->setSuccessor( static_cast< com::sun::star::io::XConnectable* >(pStream) );
     819           0 :                     while( xConnectable->getPredecessor().is() )
     820           0 :                         xConnectable = xConnectable->getPredecessor();
     821             :                 }
     822           0 :                 stream->setOutputStream( xNewStream );
     823           0 :                 pStream->setSource( stream );
     824           0 :                 uno::Reference< com::sun::star::io::XActiveDataControl > xController;
     825           0 :                 if( xConnectable.is() )
     826           0 :                     xController = uno::Reference< com::sun::star::io::XActiveDataControl >( xConnectable, UNO_QUERY );
     827             :                 else
     828           0 :                     xController = uno::Reference< com::sun::star::io::XActiveDataControl >( stream, UNO_QUERY );
     829             : 
     830           0 :                 if( xController.is() )
     831           0 :                     xController->start();
     832             :             }
     833             :         }
     834           0 :         bRet = true;
     835             :     }
     836             : 
     837           0 :     m_nProvidingState = PROVIDING_NONE;
     838             : 
     839           0 :     return bRet;
     840             : }
     841             : 
     842           0 : void XPlugin_Impl::disposing( const com::sun::star::lang::EventObject& /*rSource*/ ) throw(std::exception)
     843             : {
     844           0 : }
     845             : 
     846           0 : void XPlugin_Impl::propertyChange(const com::sun::star::beans::PropertyChangeEvent& rEvent)
     847             :     throw (css::uno::RuntimeException, std::exception)
     848             : {
     849           0 :     Guard< Mutex > aGuard( m_aMutex );
     850             : 
     851           0 :     if( rEvent.PropertyName == "URL" )
     852             :     {
     853           0 :         OUString aStr;
     854           0 :         rEvent.NewValue >>= aStr;
     855           0 :         if( m_nProvidingState == PROVIDING_NONE )
     856             :         {
     857           0 :             if( aStr != m_aURL )
     858             :             {
     859           0 :                 m_aURL = aStr;
     860           0 :                 modelChanged();
     861             :             }
     862           0 :         }
     863           0 :     }
     864           0 : }
     865             : 
     866           0 : void XPlugin_Impl::setPluginContext( const uno::Reference< XPluginContext > & rContext )
     867             : {
     868           0 :     m_rBrowserContext = rContext;
     869           0 : }
     870             : 
     871           0 : void XPlugin_Impl::setPosSize( sal_Int32 nX_, sal_Int32 nY_, sal_Int32 nWidth_, sal_Int32 nHeight_, sal_Int16 nFlags )
     872             :         throw( RuntimeException, std::exception )
     873             : {
     874           0 :     Guard< Mutex > aGuard( m_aMutex );
     875             : 
     876             : #if OSL_DEBUG_LEVEL > 1
     877             :     fprintf( stderr, "XPlugin_Impl::setPosSize( %" SAL_PRIdINT32 ", %" SAL_PRIdINT32 ", %" SAL_PRIdINT32 ", %" SAL_PRIdINT32 ", %d )\n",
     878             :              nX_, nY_, nWidth_, nHeight_, nFlags );
     879             : #endif
     880             : 
     881           0 :     PluginControl_Impl::setPosSize(nX_, nY_, nWidth_, nHeight_, nFlags);
     882             : 
     883           0 :     m_aNPWindow.x                   = 0;
     884           0 :     m_aNPWindow.y                   = 0;
     885           0 :     m_aNPWindow.width               = nWidth_;
     886           0 :     m_aNPWindow.height              = nHeight_;
     887           0 :     m_aNPWindow.clipRect.top        = 0;
     888           0 :     m_aNPWindow.clipRect.left       = 0;
     889           0 :     m_aNPWindow.clipRect.right      = ::sal::static_int_cast< uint16_t, sal_Int32 >( nWidth_ );
     890           0 :     m_aNPWindow.clipRect.bottom     = ::sal::static_int_cast< uint16_t, sal_Int32 >( nHeight_ );
     891             : 
     892           0 :     if( getPluginComm() )
     893           0 :         getPluginComm()->NPP_SetWindow( this );
     894           0 : }
     895             : 
     896           0 : PluginDescription XPlugin_Impl::fitDescription( const OUString& rURL )
     897             : {
     898           0 :     uno::Reference< XPluginManager >  xPMgr( plugin::PluginManager::create(comphelper::getComponentContext(m_xSMgr)) );
     899             : 
     900           0 :     Sequence< PluginDescription > aDescrs = xPMgr->getPluginDescriptions();
     901           0 :     const PluginDescription* pDescrs = aDescrs.getConstArray();
     902             : 
     903           0 :     for( int nArg = 0; nArg < m_nArgs; nArg++ )
     904             :     {
     905           0 :         if( strncmp( m_pArgn[nArg], "TYPE", 4 ) == 0 &&
     906           0 :             m_pArgn[nArg][4] == 0 )
     907             :         {
     908           0 :             for( int i = 0; i < aDescrs.getLength(); i++ )
     909             :             {
     910           0 :                 if( pDescrs[i].Mimetype.equalsAscii( m_pArgv[nArg] ) )
     911           0 :                     return pDescrs[i];
     912             :             }
     913             :         }
     914             :     }
     915             : 
     916           0 :     int nPos = rURL.lastIndexOf( (sal_Unicode)'.' );
     917           0 :     if( nPos != -1 )
     918             :     {
     919           0 :         OUString const aExt = rURL.copy( nPos ).toAsciiLowerCase();
     920           0 :         for( int i = 0; i < aDescrs.getLength(); i++ )
     921             :         {
     922           0 :             OUString aThisExt = pDescrs[ i ].Extension.toAsciiLowerCase();
     923           0 :             if( aThisExt.indexOf( aExt ) != -1 )
     924             :             {
     925           0 :                 return pDescrs[i];
     926             :             }
     927           0 :         }
     928             :     }
     929           0 :     return PluginDescription();
     930             : }
     931             : 
     932             : 
     933           0 : PluginStream::PluginStream( XPlugin_Impl* pPlugin,
     934             :                             const char* url, sal_uInt32 len, sal_uInt32 lastmod)
     935           0 :     : m_wPlugin(static_cast< ::cppu::OWeakObject* >(pPlugin))
     936           0 :     , m_pPlugin(pPlugin)
     937             : 
     938             : {
     939           0 :     memset( &m_aNPStream, 0, sizeof( m_aNPStream ) );
     940           0 :     m_aNPStream.url             = strdup( url );
     941           0 :     m_aNPStream.end             = len;
     942           0 :     m_aNPStream.lastmodified    = lastmod;
     943           0 : }
     944             : 
     945           0 : PluginStream::~PluginStream()
     946             : {
     947           0 :     uno::Reference<uno::XInterface> const xPlugin(m_wPlugin);
     948           0 :     XPlugin_Impl *const pPlugin(m_pPlugin);
     949           0 :     if (xPlugin.is() && pPlugin)
     950             :     {
     951           0 :         Guard< Mutex > aGuard( pPlugin->getMutex() );
     952             : 
     953           0 :         if( m_pPlugin && m_pPlugin->getPluginComm() )
     954             :         {
     955           0 :             m_pPlugin->getPluginComm()->NPP_DestroyStream( &m_pPlugin->getNPPInstance(),
     956           0 :                                                            &m_aNPStream, NPRES_DONE );
     957           0 :             m_pPlugin->checkListeners( m_aNPStream.url );
     958           0 :             m_pPlugin->getPluginComm()->NPP_SetWindow( m_pPlugin );
     959           0 :         }
     960             :     }
     961           0 :     ::free( const_cast<char *>(m_aNPStream.url) );
     962           0 : }
     963             : 
     964           0 : PluginInputStream::PluginInputStream( XPlugin_Impl* pPlugin,
     965             :                                       const char* url,
     966             :                                       sal_uInt32 len,
     967             :                                       sal_uInt32 lastmod ) :
     968             :         PluginStream( pPlugin, url, len, lastmod ),
     969             :         m_pContent( NULL ),
     970             :         m_nMode( NP_NORMAL ),
     971           0 :         m_nWritePos( 0 )
     972             : {
     973             :     assert(m_pPlugin);
     974           0 :     Guard< Mutex > aGuard( m_pPlugin->getMutex() );
     975             : 
     976           0 :     m_pPlugin->getInputStreams().push_back( this );
     977           0 :     OUString aTmpFile;
     978           0 :     osl::FileBase::createTempFile( 0, 0, &aTmpFile );
     979             : 
     980             :     // set correct extension, some plugins need that
     981           0 :     OUString aName( m_aNPStream.url, strlen( m_aNPStream.url ), m_pPlugin->getTextEncoding() );
     982           0 :     OUString aExtension;
     983           0 :     sal_Int32 nSepInd = aName.lastIndexOf('.');
     984           0 :     if( nSepInd != -1 )
     985             :     {
     986           0 :        aExtension = aName.copy( nSepInd + 1, aName.getLength() - nSepInd - 1 );
     987             :     }
     988           0 :     if( !aExtension.isEmpty() )
     989             :     {
     990           0 :         aTmpFile += aExtension;
     991             :     }
     992           0 :     m_aFileStream.Open( aTmpFile, StreamMode::READ | StreamMode::WRITE );
     993           0 :     if( ! m_aFileStream.IsOpen() )
     994             :     {
     995             :         // might be that the extension scrambled the whole filename
     996           0 :         osl::FileBase::createTempFile( 0, 0, &aTmpFile );
     997           0 :         m_aFileStream.Open( aTmpFile, StreamMode::READ | StreamMode::WRITE );
     998           0 :     }
     999           0 : }
    1000             : 
    1001           0 : PluginInputStream::~PluginInputStream()
    1002             : {
    1003           0 :     OUString aFile( m_aFileStream.GetFileName() );
    1004             : 
    1005           0 :     m_aFileStream.Close();
    1006             : 
    1007           0 :     uno::Reference<uno::XInterface> const xPlugin(m_wPlugin);
    1008           0 :     XPlugin_Impl *const pPlugin(m_pPlugin);
    1009           0 :     if (xPlugin.is() && pPlugin)
    1010             :     {
    1011           0 :         Guard< Mutex > aGuard( pPlugin->getMutex() );
    1012             : 
    1013           0 :         pPlugin->getInputStreams().remove( this );
    1014             : 
    1015           0 :         if( m_pPlugin )
    1016             :         {
    1017           0 :             OString aFileName(OUStringToOString(aFile, m_pPlugin->getTextEncoding()));
    1018           0 :             if( m_pPlugin->getPluginComm() && m_nMode != -1 )
    1019             :                 // mode -1 means either an error occurred,
    1020             :                 // or the plugin is already disposing
    1021             :             {
    1022           0 :                 m_pPlugin->getPluginComm()->addFileToDelete( aFile );
    1023           0 :                 if( m_nMode == NP_ASFILE )
    1024             :                 {
    1025           0 :                     m_pPlugin->getPluginComm()->
    1026           0 :                         NPP_StreamAsFile( &m_pPlugin->getNPPInstance(),
    1027             :                                           &m_aNPStream,
    1028           0 :                                           aFileName.getStr() );
    1029             :                 }
    1030           0 :                 m_pPlugin->getPluginComm()->NPP_SetWindow( m_pPlugin );
    1031           0 :                 m_pPlugin->getInputStreams().remove( this );
    1032             :             }
    1033             :             else
    1034           0 :                 osl::File::remove( aFile );
    1035             :         }
    1036             :         else
    1037           0 :             osl::File::remove( aFile );
    1038             :     }
    1039             :     else
    1040           0 :         osl::File::remove( aFile );
    1041           0 :     if( m_pContent )
    1042           0 :         delete m_pContent;
    1043           0 : }
    1044             : 
    1045           0 : PluginStreamType PluginInputStream::getStreamType()
    1046             : {
    1047           0 :     return InputStream;
    1048             : }
    1049             : 
    1050           0 : void PluginInputStream::load()
    1051             : {
    1052           0 :     Guard< Mutex > aGuard( m_pPlugin->getMutex() );
    1053             : 
    1054           0 :     INetURLObject aUrl;
    1055           0 :     aUrl.SetSmartProtocol( INetProtocol::File );
    1056             :     aUrl.SetSmartURL(
    1057           0 :         OUString( getStream().url,
    1058           0 :                   strlen( getStream().url ),
    1059             :                 RTL_TEXTENCODING_MS_1252
    1060           0 :             ) );
    1061             :     try
    1062             :     {
    1063             :         m_pContent =
    1064             :             new ::ucbhelper::Content(
    1065             :                                aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI),
    1066             :                                uno::Reference< com::sun::star::ucb::XCommandEnvironment >(),
    1067             :                                comphelper::getProcessComponentContext()
    1068           0 :                                );
    1069           0 :         m_pContent->openStream( static_cast< XOutputStream* >( this ) );
    1070             :     }
    1071           0 :     catch(const com::sun::star::uno::Exception &)
    1072             :     {
    1073           0 :     }
    1074           0 : }
    1075             : 
    1076           0 : void PluginInputStream::setMode( sal_Int32 nMode )
    1077             : {
    1078             :     assert(m_pPlugin); // this is currently only called from two places...
    1079           0 :     Guard< Mutex > aGuard( m_pPlugin->getMutex() );
    1080             : 
    1081           0 :     m_nMode = nMode;
    1082             : 
    1083             :     // invalidation by plugin
    1084           0 :     if (m_nMode == -1)
    1085             :     {
    1086           0 :         m_pPlugin->getInputStreams().remove( this );
    1087           0 :         m_pPlugin = NULL;
    1088           0 :         m_wPlugin.clear();
    1089           0 :     }
    1090           0 : }
    1091             : 
    1092           0 : void PluginInputStream::writeBytes( const Sequence<sal_Int8>& Buffer ) throw(std::exception)
    1093             : {
    1094           0 :     uno::Reference<uno::XInterface> const xPlugin(m_wPlugin);
    1095           0 :     XPlugin_Impl *const pPlugin(m_pPlugin);
    1096           0 :     if (!xPlugin.is() || !pPlugin)
    1097           0 :         return;
    1098             : 
    1099           0 :     Guard< Mutex > aGuard( pPlugin->getMutex() );
    1100             : 
    1101           0 :     m_aFileStream.Seek( STREAM_SEEK_TO_END );
    1102           0 :     m_aFileStream.Write( Buffer.getConstArray(), Buffer.getLength() );
    1103             : 
    1104           0 :     if( m_nMode == NP_SEEK )
    1105             :         // hold reference, streem gets destroyed in NPN_DestroyStream
    1106           0 :         m_xSelf = this;
    1107             : 
    1108           0 :     if( m_nMode == -1 || !m_pPlugin->getPluginComm() )
    1109           0 :         return;
    1110             : 
    1111           0 :     sal_Size nPos = m_aFileStream.Tell();
    1112           0 :     sal_Size nBytes = 0;
    1113           0 :     while( m_nMode != NP_ASFILEONLY &&
    1114           0 :            m_nWritePos < nPos &&
    1115           0 :            (nBytes = m_pPlugin->getPluginComm()-> NPP_WriteReady(
    1116           0 :                &m_pPlugin->getNPPInstance(), &m_aNPStream )) > 0 )
    1117             :     {
    1118           0 :         nBytes = (nBytes > nPos - m_nWritePos) ? nPos - m_nWritePos : nBytes;
    1119             : 
    1120           0 :         boost::scoped_array<char> pBuffer(new char[ nBytes ]);
    1121           0 :         m_aFileStream.Seek( m_nWritePos );
    1122           0 :         nBytes = m_aFileStream.Read( pBuffer.get(), nBytes );
    1123             : 
    1124           0 :         int32_t nBytesRead = 0;
    1125             :         try
    1126             :         {
    1127           0 :             nBytesRead = m_pPlugin->getPluginComm()->NPP_Write(
    1128           0 :                 &m_pPlugin->getNPPInstance(), &m_aNPStream, m_nWritePos, nBytes, pBuffer.get() );
    1129             :         }
    1130           0 :         catch( ... )
    1131             :         {
    1132           0 :             nBytesRead = 0;
    1133             :         }
    1134             : 
    1135           0 :         if( nBytesRead < 0 )
    1136             :         {
    1137           0 :             m_nMode = -1;
    1138           0 :             return;
    1139             :         }
    1140             : 
    1141           0 :         m_nWritePos += nBytesRead;
    1142           0 :     }
    1143             : }
    1144             : 
    1145           0 : void PluginInputStream::closeOutput() throw(std::exception)
    1146             : {
    1147           0 :     uno::Reference<uno::XInterface> const xPlugin(m_wPlugin);
    1148           0 :     XPlugin_Impl *const pPlugin(m_pPlugin);
    1149           0 :     if (!xPlugin.is() || !pPlugin)
    1150           0 :         return;
    1151             : 
    1152           0 :     Guard< Mutex > aGuard( pPlugin->getMutex() );
    1153             : 
    1154           0 :     flush();
    1155           0 :     m_xSource = uno::Reference< com::sun::star::io::XActiveDataSource >();
    1156             : }
    1157             : 
    1158           0 : sal_uInt32 PluginInputStream::read( sal_uInt32 offset, sal_Int8* buffer, sal_uInt32 size )
    1159             : {
    1160           0 :     uno::Reference<uno::XInterface> const xPlugin(m_wPlugin);
    1161           0 :     XPlugin_Impl *const pPlugin(m_pPlugin);
    1162           0 :     if (!xPlugin.is() || !pPlugin)
    1163           0 :         return 0;
    1164             : 
    1165           0 :     Guard< Mutex > aGuard( pPlugin->getMutex() );
    1166             : 
    1167           0 :     if( m_nMode != NP_SEEK )
    1168           0 :         return 0;
    1169             : 
    1170           0 :     m_aFileStream.Seek( offset );
    1171           0 :     return m_aFileStream.Read( buffer, size );
    1172             : }
    1173             : 
    1174           0 : void PluginInputStream::flush() throw(std::exception)
    1175             : {
    1176           0 : }
    1177             : 
    1178           0 : PluginOutputStream::PluginOutputStream( XPlugin_Impl* pPlugin,
    1179             :                                         const char* url,
    1180             :                                         sal_uInt32 len,
    1181             :                                         sal_uInt32 lastmod ) :
    1182             :         PluginStream( pPlugin, url, len, lastmod ),
    1183           0 :         m_xStream( pPlugin->getServiceManager()->createInstance("com.sun.star.io.DataOutputStream"), UNO_QUERY )
    1184             : {
    1185           0 :     Guard< Mutex > aGuard( m_pPlugin->getMutex() );
    1186             : 
    1187           0 :     m_pPlugin->getOutputStreams().push_back( this );
    1188           0 : }
    1189             : 
    1190           0 : PluginOutputStream::~PluginOutputStream()
    1191             : {
    1192           0 :     Guard< Mutex > aGuard( m_pPlugin->getMutex() );
    1193             : 
    1194           0 :     m_pPlugin->getOutputStreams().remove( this );
    1195           0 : }
    1196             : 
    1197           0 : PluginStreamType PluginOutputStream::getStreamType()
    1198             : {
    1199           0 :     return OutputStream;
    1200             : }
    1201             : 
    1202             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11