1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #include "precompiled_sw.hxx"
28 #include <retrievedinputstreamdata.hxx>
29 #include <retrieveinputstreamconsumer.hxx>
30 #include <vcl/svapp.hxx>
31 
32 /** implementation of class <SwRetrievedInputStreamDataManager>
33 
34     OD 2007-01-30 #i73788#
35 */
36 SwRetrievedInputStreamDataManager* SwRetrievedInputStreamDataManager::mpManager = 0;
37 SwRetrievedInputStreamDataManager::tDataKey SwRetrievedInputStreamDataManager::mnNextKeyValue = 1;
38 osl::Mutex SwRetrievedInputStreamDataManager::maGetManagerMutex;
39 
40 SwRetrievedInputStreamDataManager& SwRetrievedInputStreamDataManager::GetManager()
41 {
42     osl::MutexGuard aGuard(maGetManagerMutex);
43 
44     if ( mpManager == 0 )
45     {
46         mpManager = new SwRetrievedInputStreamDataManager();
47     }
48 
49     return *mpManager;
50 }
51 
52 SwRetrievedInputStreamDataManager::tDataKey SwRetrievedInputStreamDataManager::ReserveData(
53                         boost::weak_ptr< SwAsyncRetrieveInputStreamThreadConsumer > pThreadConsumer )
54 {
55     osl::MutexGuard aGuard(maMutex);
56 
57     // create empty data container for given thread Consumer
58     tDataKey nDataKey( mnNextKeyValue );
59     tData aNewEntry( pThreadConsumer );
60     maInputStreamData[ nDataKey ] = aNewEntry;
61 
62     // prepare next data key value
63     if ( mnNextKeyValue < SAL_MAX_UINT64 )
64     {
65         ++mnNextKeyValue;
66     }
67     else
68     {
69         mnNextKeyValue = 1;
70     }
71 
72     return nDataKey;
73 }
74 
75 void SwRetrievedInputStreamDataManager::PushData(
76         const tDataKey nDataKey,
77         com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xInputStream,
78         const sal_Bool bIsStreamReadOnly )
79 {
80     osl::MutexGuard aGuard(maMutex);
81 
82     std::map< tDataKey, tData >::iterator aIter = maInputStreamData.find( nDataKey );
83 
84     if ( aIter != maInputStreamData.end() )
85     {
86         // Fill data container.
87         (*aIter).second.mxInputStream = xInputStream;
88         (*aIter).second.mbIsStreamReadOnly = bIsStreamReadOnly;
89 
90         // post user event to process the retrieved input stream data
91         if ( GetpApp() )
92         {
93 
94             tDataKey* pDataKey = new tDataKey;
95             *pDataKey = nDataKey;
96             GetpApp()->PostUserEvent( LINK( this, SwRetrievedInputStreamDataManager, LinkedInputStreamReady ), pDataKey );
97         }
98         else
99         {
100             // no application available -> discard data
101             maInputStreamData.erase( aIter );
102         }
103     }
104 }
105 
106 bool SwRetrievedInputStreamDataManager::PopData( const tDataKey nDataKey,
107                                                  tData& rData )
108 {
109     osl::MutexGuard aGuard(maMutex);
110 
111     bool bDataProvided( false );
112 
113     std::map< tDataKey, tData >::iterator aIter = maInputStreamData.find( nDataKey );
114 
115     if ( aIter != maInputStreamData.end() )
116     {
117         rData.mpThreadConsumer = (*aIter).second.mpThreadConsumer;
118         rData.mxInputStream = (*aIter).second.mxInputStream;
119         rData.mbIsStreamReadOnly = (*aIter).second.mbIsStreamReadOnly;
120 
121         maInputStreamData.erase( aIter );
122 
123         bDataProvided = true;
124     }
125 
126     return bDataProvided;
127 }
128 
129 /** callback function, which is triggered by input stream data manager on
130     filling of the data container to provide retrieved input stream to the
131     thread Consumer using <Application::PostUserEvent(..)>
132 
133     OD 2007-01-29 #i73788#
134     Note: This method has to be run in the main thread.
135 
136     @author OD
137 */
138 IMPL_LINK( SwRetrievedInputStreamDataManager,
139            LinkedInputStreamReady,
140            SwRetrievedInputStreamDataManager::tDataKey*,
141            pDataKey )
142 {
143     if ( !pDataKey )
144     {
145         return 0;
146     }
147 
148     osl::MutexGuard aGuard(maMutex);
149 
150     SwRetrievedInputStreamDataManager& rDataManager =
151                             SwRetrievedInputStreamDataManager::GetManager();
152     SwRetrievedInputStreamDataManager::tData aInputStreamData;
153     if ( rDataManager.PopData( *pDataKey, aInputStreamData ) )
154     {
155         boost::shared_ptr< SwAsyncRetrieveInputStreamThreadConsumer > pThreadConsumer =
156                                     aInputStreamData.mpThreadConsumer.lock();
157         if ( pThreadConsumer )
158         {
159             pThreadConsumer->ApplyInputStream( aInputStreamData.mxInputStream,
160                                                aInputStreamData.mbIsStreamReadOnly );
161         }
162     }
163     delete pDataKey;
164 
165     return 0;
166 }
167 
168