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 
GetManager()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 
ReserveData(boost::weak_ptr<SwAsyncRetrieveInputStreamThreadConsumer> pThreadConsumer)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 
PushData(const tDataKey nDataKey,com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xInputStream,const sal_Bool bIsStreamReadOnly)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 
PopData(const tDataKey nDataKey,tData & rData)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 */
IMPL_LINK(SwRetrievedInputStreamDataManager,LinkedInputStreamReady,SwRetrievedInputStreamDataManager::tDataKey *,pDataKey)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