1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #include "precompiled_sw.hxx" 24 #include <retrievedinputstreamdata.hxx> 25 #include <retrieveinputstreamconsumer.hxx> 26 #include <vcl/svapp.hxx> 27 28 /** implementation of class <SwRetrievedInputStreamDataManager> 29 30 OD 2007-01-30 #i73788# 31 */ 32 SwRetrievedInputStreamDataManager* SwRetrievedInputStreamDataManager::mpManager = 0; 33 SwRetrievedInputStreamDataManager::tDataKey SwRetrievedInputStreamDataManager::mnNextKeyValue = 1; 34 osl::Mutex SwRetrievedInputStreamDataManager::maGetManagerMutex; 35 36 SwRetrievedInputStreamDataManager& SwRetrievedInputStreamDataManager::GetManager() 37 { 38 osl::MutexGuard aGuard(maGetManagerMutex); 39 40 if ( mpManager == 0 ) 41 { 42 mpManager = new SwRetrievedInputStreamDataManager(); 43 } 44 45 return *mpManager; 46 } 47 48 SwRetrievedInputStreamDataManager::tDataKey SwRetrievedInputStreamDataManager::ReserveData( 49 boost::weak_ptr< SwAsyncRetrieveInputStreamThreadConsumer > pThreadConsumer ) 50 { 51 osl::MutexGuard aGuard(maMutex); 52 53 // create empty data container for given thread Consumer 54 tDataKey nDataKey( mnNextKeyValue ); 55 tData aNewEntry( pThreadConsumer ); 56 maInputStreamData[ nDataKey ] = aNewEntry; 57 58 // prepare next data key value 59 if ( mnNextKeyValue < SAL_MAX_UINT64 ) 60 { 61 ++mnNextKeyValue; 62 } 63 else 64 { 65 mnNextKeyValue = 1; 66 } 67 68 return nDataKey; 69 } 70 71 void SwRetrievedInputStreamDataManager::PushData( 72 const tDataKey nDataKey, 73 com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xInputStream, 74 const sal_Bool bIsStreamReadOnly ) 75 { 76 osl::MutexGuard aGuard(maMutex); 77 78 std::map< tDataKey, tData >::iterator aIter = maInputStreamData.find( nDataKey ); 79 80 if ( aIter != maInputStreamData.end() ) 81 { 82 // Fill data container. 83 (*aIter).second.mxInputStream = xInputStream; 84 (*aIter).second.mbIsStreamReadOnly = bIsStreamReadOnly; 85 86 // post user event to process the retrieved input stream data 87 if ( GetpApp() ) 88 { 89 90 tDataKey* pDataKey = new tDataKey; 91 *pDataKey = nDataKey; 92 GetpApp()->PostUserEvent( LINK( this, SwRetrievedInputStreamDataManager, LinkedInputStreamReady ), pDataKey ); 93 } 94 else 95 { 96 // no application available -> discard data 97 maInputStreamData.erase( aIter ); 98 } 99 } 100 } 101 102 bool SwRetrievedInputStreamDataManager::PopData( const tDataKey nDataKey, 103 tData& rData ) 104 { 105 osl::MutexGuard aGuard(maMutex); 106 107 bool bDataProvided( false ); 108 109 std::map< tDataKey, tData >::iterator aIter = maInputStreamData.find( nDataKey ); 110 111 if ( aIter != maInputStreamData.end() ) 112 { 113 rData.mpThreadConsumer = (*aIter).second.mpThreadConsumer; 114 rData.mxInputStream = (*aIter).second.mxInputStream; 115 rData.mbIsStreamReadOnly = (*aIter).second.mbIsStreamReadOnly; 116 117 maInputStreamData.erase( aIter ); 118 119 bDataProvided = true; 120 } 121 122 return bDataProvided; 123 } 124 125 /** callback function, which is triggered by input stream data manager on 126 filling of the data container to provide retrieved input stream to the 127 thread Consumer using <Application::PostUserEvent(..)> 128 129 OD 2007-01-29 #i73788# 130 Note: This method has to be run in the main thread. 131 132 @author OD 133 */ 134 IMPL_LINK( SwRetrievedInputStreamDataManager, 135 LinkedInputStreamReady, 136 SwRetrievedInputStreamDataManager::tDataKey*, 137 pDataKey ) 138 { 139 if ( !pDataKey ) 140 { 141 return 0; 142 } 143 144 osl::MutexGuard aGuard(maMutex); 145 146 SwRetrievedInputStreamDataManager& rDataManager = 147 SwRetrievedInputStreamDataManager::GetManager(); 148 SwRetrievedInputStreamDataManager::tData aInputStreamData; 149 if ( rDataManager.PopData( *pDataKey, aInputStreamData ) ) 150 { 151 boost::shared_ptr< SwAsyncRetrieveInputStreamThreadConsumer > pThreadConsumer = 152 aInputStreamData.mpThreadConsumer.lock(); 153 if ( pThreadConsumer ) 154 { 155 pThreadConsumer->ApplyInputStream( aInputStreamData.mxInputStream, 156 aInputStreamData.mbIsStreamReadOnly ); 157 } 158 } 159 delete pDataKey; 160 161 return 0; 162 } 163 164