Branch data 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 : : #if defined( UNX )
22 : : #include <wchar.h>
23 : : #endif
24 : : #include <osl/mutex.hxx>
25 : : #include <osl/diagnose.h>
26 : : #include <comphelper/eventattachermgr.hxx>
27 : : #include <com/sun/star/beans/XIntrospection.hpp>
28 : : #include <com/sun/star/io/XObjectInputStream.hpp>
29 : : #include <com/sun/star/io/XPersistObject.hpp>
30 : : #include <com/sun/star/io/XObjectOutputStream.hpp>
31 : : #include <com/sun/star/io/XMarkableStream.hpp>
32 : : #include <com/sun/star/lang/XInitialization.hpp>
33 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 : : #include <com/sun/star/reflection/XIdlClass.hpp>
35 : : #include <com/sun/star/reflection/XIdlReflection.hpp>
36 : : #include <com/sun/star/reflection/XIdlMethod.hpp>
37 : : #include <com/sun/star/script/XTypeConverter.hpp>
38 : : #include <com/sun/star/script/XEngineListener.hpp>
39 : : #include <com/sun/star/script/XEventAttacher2.hpp>
40 : : #include <com/sun/star/script/XEventAttacherManager.hpp>
41 : : #include <com/sun/star/script/XScriptListener.hpp>
42 : : #include <cppuhelper/weak.hxx>
43 : : #include <cppuhelper/interfacecontainer.hxx>
44 : : #include <cppuhelper/implbase1.hxx>
45 : : #include <cppuhelper/implbase2.hxx>
46 : :
47 : : #include <deque>
48 : : #include <algorithm>
49 : : #include <functional>
50 : :
51 : : using namespace com::sun::star::uno;
52 : : using namespace com::sun::star::io;
53 : : using namespace com::sun::star::lang;
54 : : using namespace com::sun::star::beans;
55 : : using namespace com::sun::star::script;
56 : : using namespace com::sun::star::reflection;
57 : : using namespace cppu;
58 : : using namespace osl;
59 : :
60 : : using ::rtl::OUString;
61 : :
62 : : namespace comphelper
63 : : {
64 : :
65 : : //-----------------------------------------------------------------------------
66 [ + - ][ + - ]: 7132 : struct AttachedObject_Impl
[ + - ]
67 : : {
68 : : Reference< XInterface > xTarget;
69 : : Sequence< Reference< XEventListener > > aAttachedListenerSeq;
70 : : Any aHelper;
71 : :
72 : : bool operator<( const AttachedObject_Impl & ) const;
73 : : bool operator==( const AttachedObject_Impl & ) const;
74 : : };
75 : :
76 [ + - ][ + - ]: 6135 : struct AttacherIndex_Impl
[ + - ]
77 : : {
78 : : ::std::deque< ScriptEventDescriptor > aEventList;
79 : : ::std::deque< AttachedObject_Impl > aObjList;
80 : :
81 : : bool operator<( const AttacherIndex_Impl & ) const;
82 : : bool operator==( const AttacherIndex_Impl & ) const;
83 : : };
84 : :
85 : : //-----------------------------------------------------------------------------
86 : : class ImplEventAttacherManager
87 : : : public WeakImplHelper2< XEventAttacherManager, XPersistObject >
88 : : {
89 : : friend class AttacherAllListener_Impl;
90 : : ::std::deque< AttacherIndex_Impl > aIndex;
91 : : Mutex aLock;
92 : : // Container for the ScriptListener
93 : : OInterfaceContainerHelper aScriptListeners;
94 : : // Instance of EventAttacher
95 : : Reference< XEventAttacher2 > xAttacher;
96 : : Reference< XMultiServiceFactory > mxSMgr;
97 : : Reference< XIdlReflection > mxCoreReflection;
98 : : Reference< XIntrospection > mxIntrospection;
99 : : Reference< XTypeConverter > xConverter;
100 : : sal_Int16 nVersion;
101 : : public:
102 : : ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection,
103 : : const Reference< XMultiServiceFactory > rSMgr );
104 : : ~ImplEventAttacherManager();
105 : :
106 : : // Methods of XEventAttacherManager
107 : : virtual void SAL_CALL registerScriptEvent(sal_Int32 Index, const ScriptEventDescriptor& ScriptEvent)
108 : : throw( IllegalArgumentException, RuntimeException );
109 : : virtual void SAL_CALL registerScriptEvents(sal_Int32 Index, const Sequence< ScriptEventDescriptor >& ScriptEvents)
110 : : throw( IllegalArgumentException, RuntimeException );
111 : : virtual void SAL_CALL revokeScriptEvent(sal_Int32 Index, const OUString& ListenerType, const OUString& EventMethod, const OUString& removeListenerParam)
112 : : throw( IllegalArgumentException, RuntimeException );
113 : : virtual void SAL_CALL revokeScriptEvents(sal_Int32 Index)
114 : : throw( IllegalArgumentException, RuntimeException );
115 : : virtual void SAL_CALL insertEntry(sal_Int32 Index)
116 : : throw( IllegalArgumentException, RuntimeException );
117 : : virtual void SAL_CALL removeEntry(sal_Int32 Index)
118 : : throw( IllegalArgumentException, RuntimeException );
119 : : virtual Sequence< ScriptEventDescriptor > SAL_CALL getScriptEvents(sal_Int32 Index)
120 : : throw( IllegalArgumentException, RuntimeException );
121 : : virtual void SAL_CALL attach(sal_Int32 Index, const Reference< XInterface >& Object, const Any& Helper)
122 : : throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException );
123 : : virtual void SAL_CALL detach(sal_Int32 nIndex, const Reference< XInterface >& xObject)
124 : : throw( IllegalArgumentException, RuntimeException );
125 : : virtual void SAL_CALL addScriptListener(const Reference< XScriptListener >& aListener)
126 : : throw( IllegalArgumentException, RuntimeException );
127 : : virtual void SAL_CALL removeScriptListener(const Reference< XScriptListener >& Listener)
128 : : throw( IllegalArgumentException, RuntimeException );
129 : :
130 : : // Methods of XPersistObject
131 : : virtual OUString SAL_CALL getServiceName(void) throw( RuntimeException );
132 : : virtual void SAL_CALL write(const Reference< XObjectOutputStream >& OutStream) throw( IOException, RuntimeException );
133 : : virtual void SAL_CALL read(const Reference< XObjectInputStream >& InStream) throw( IOException, RuntimeException );
134 : :
135 : : private:
136 : : Reference< XIdlReflection > getReflection() throw( Exception );
137 : :
138 : : /** checks if <arg>_nIndex</arg> is a valid index, throws an <type>IllegalArgumentException</type> if not
139 : : @param _nIndex
140 : : the index to check
141 : : @return
142 : : the iterator pointing to the position indicated by the index
143 : : */
144 : : ::std::deque<AttacherIndex_Impl>::iterator implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) );
145 : : };
146 : :
147 : : //========================================================================
148 : : //========================================================================
149 : : //========================================================================
150 : :
151 : :
152 : : // Implementation of an EventAttacher-subclass 'AllListeners', which
153 : : // only passes individual events of the general AllListeners.
154 [ - + ]: 64 : class AttacherAllListener_Impl : public WeakImplHelper1< XAllListener >
155 : : {
156 : : ImplEventAttacherManager* mpManager;
157 : : Reference< XEventAttacherManager > xManager;
158 : : OUString aScriptType;
159 : : OUString aScriptCode;
160 : :
161 : : void convertToEventReturn( Any & rRet, const Type & rRetType )
162 : : throw( CannotConvertException );
163 : : public:
164 : : AttacherAllListener_Impl( ImplEventAttacherManager* pManager_, const OUString &rScriptType_,
165 : : const OUString & rScriptCode_ );
166 : :
167 : : // Methods of XAllListener
168 : : virtual void SAL_CALL firing(const AllEventObject& Event) throw( RuntimeException );
169 : : virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw( InvocationTargetException, RuntimeException );
170 : :
171 : : // Methods of XEventListener
172 : : virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException );
173 : : };
174 : :
175 : : //========================================================================
176 : 32 : AttacherAllListener_Impl::AttacherAllListener_Impl
177 : : (
178 : : ImplEventAttacherManager* pManager_,
179 : : const OUString & rScriptType_,
180 : : const OUString & rScriptCode_
181 : : )
182 : : : mpManager( pManager_ )
183 : : , xManager( pManager_ )
184 : : , aScriptType( rScriptType_ )
185 [ + - ][ + - ]: 32 : , aScriptCode( rScriptCode_ )
186 : : {
187 : 32 : }
188 : :
189 : :
190 : : //========================================================================
191 : : // Methods of XAllListener
192 : 2 : void SAL_CALL AttacherAllListener_Impl::firing(const AllEventObject& Event)
193 : : throw( RuntimeException )
194 : : {
195 [ + - ]: 2 : ScriptEvent aScriptEvent;
196 [ + - ]: 2 : aScriptEvent.Source = (OWeakObject *)mpManager; // get correct XInterface
197 : 2 : aScriptEvent.ListenerType = Event.ListenerType;
198 : 2 : aScriptEvent.MethodName = Event.MethodName;
199 [ + - ]: 2 : aScriptEvent.Arguments = Event.Arguments;
200 : 2 : aScriptEvent.Helper = Event.Helper;
201 : 2 : aScriptEvent.ScriptType = aScriptType;
202 : 2 : aScriptEvent.ScriptCode = aScriptCode;
203 : :
204 : : // Iterate over all listeners and pass events.
205 [ + - ]: 2 : OInterfaceIteratorHelper aIt( mpManager->aScriptListeners );
206 [ + + ]: 6 : while( aIt.hasMoreElements() )
207 [ + - ][ + - ]: 6 : ((XScriptListener *)aIt.next())->firing( aScriptEvent );
[ + - ][ + - ]
208 : 2 : }
209 : :
210 : : //========================================================================
211 : : // Convert to the standard event return
212 : 0 : void AttacherAllListener_Impl::convertToEventReturn( Any & rRet, const Type & rRetType )
213 : : throw( CannotConvertException )
214 : : {
215 : : // no return value? Set to the specified values
216 [ # # ]: 0 : if( rRet.getValueType().getTypeClass() == TypeClass_VOID )
217 : : {
218 [ # # # # : 0 : switch( rRetType.getTypeClass() )
# # # # #
# # ]
219 : : {
220 : : case TypeClass_INTERFACE:
221 : : {
222 [ # # ]: 0 : rRet <<= Reference< XInterface >();
223 : : }
224 : 0 : break;
225 : :
226 : : case TypeClass_BOOLEAN:
227 [ # # ]: 0 : rRet <<= sal_True;
228 : 0 : break;
229 : :
230 : : case TypeClass_STRING:
231 [ # # ]: 0 : rRet <<= OUString();
232 : 0 : break;
233 : :
234 [ # # ]: 0 : case TypeClass_FLOAT: rRet <<= float(0); break;
235 [ # # ]: 0 : case TypeClass_DOUBLE: rRet <<= double(0.0); break;
236 [ # # ]: 0 : case TypeClass_BYTE: rRet <<= sal_uInt8(0); break;
237 [ # # ]: 0 : case TypeClass_SHORT: rRet <<= sal_Int16( 0 ); break;
238 [ # # ]: 0 : case TypeClass_LONG: rRet <<= sal_Int32( 0 ); break;
239 [ # # ]: 0 : case TypeClass_UNSIGNED_SHORT: rRet <<= sal_uInt16( 0 ); break;
240 [ # # ]: 0 : case TypeClass_UNSIGNED_LONG: rRet <<= sal_uInt32( 0 ); break;
241 : :
242 : : default:
243 : : OSL_ASSERT(false);
244 : 0 : break;
245 : : }
246 : : }
247 [ # # ]: 0 : else if( !rRet.getValueType().equals( rRetType ) )
248 : : {
249 [ # # ]: 0 : if( mpManager->xConverter.is() )
250 : 0 : rRet = mpManager->xConverter->convertTo( rRet, rRetType );
251 : : else
252 [ # # ]: 0 : throw CannotConvertException();
253 : : }
254 : 0 : }
255 : :
256 : : //========================================================================
257 : : // Methods of XAllListener
258 : 0 : Any SAL_CALL AttacherAllListener_Impl::approveFiring( const AllEventObject& Event )
259 : : throw( InvocationTargetException, RuntimeException )
260 : : {
261 [ # # ]: 0 : ScriptEvent aScriptEvent;
262 [ # # ]: 0 : aScriptEvent.Source = (OWeakObject *)mpManager; // get correct XInterface
263 : 0 : aScriptEvent.ListenerType = Event.ListenerType;
264 : 0 : aScriptEvent.MethodName = Event.MethodName;
265 [ # # ]: 0 : aScriptEvent.Arguments = Event.Arguments;
266 : 0 : aScriptEvent.Helper = Event.Helper;
267 : 0 : aScriptEvent.ScriptType = aScriptType;
268 : 0 : aScriptEvent.ScriptCode = aScriptCode;
269 : :
270 : 0 : Any aRet;
271 : : // Iterate over all listeners and pass events.
272 [ # # ]: 0 : OInterfaceIteratorHelper aIt( mpManager->aScriptListeners );
273 [ # # ]: 0 : while( aIt.hasMoreElements() )
274 : : {
275 [ # # ][ # # ]: 0 : aRet = ((XScriptListener *)aIt.next())->approveFiring( aScriptEvent );
276 : : try
277 : : {
278 [ # # ][ # # ]: 0 : Reference< XIdlClass > xListenerType = mpManager->getReflection()->
279 [ # # ]: 0 : forName( Event.ListenerType.getTypeName() );
280 [ # # ][ # # ]: 0 : Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName );
281 [ # # ]: 0 : if( xMeth.is() )
282 : : {
283 [ # # ][ # # ]: 0 : Reference< XIdlClass > xRetType = xMeth->getReturnType();
284 [ # # ][ # # ]: 0 : Type aRetType(xRetType->getTypeClass(), xRetType->getName());
[ # # ][ # # ]
285 [ # # ]: 0 : convertToEventReturn( aRet, aRetType );
286 : : }
287 : :
288 [ # # # # : 0 : switch( aRet.getValueType().getTypeClass() )
# # # # #
# # ]
289 : : {
290 : : case TypeClass_INTERFACE:
291 : : {
292 : : // Interface not null, return
293 : 0 : Reference< XInterface > x;
294 [ # # ]: 0 : aRet >>= x;
295 [ # # ]: 0 : if( x.is() )
296 [ # # ]: 0 : return aRet;
297 : : }
298 : 0 : break;
299 : :
300 : : case TypeClass_BOOLEAN:
301 : : // FALSE -> Return
302 [ # # ]: 0 : if( !(*(sal_Bool*)aRet.getValue()) )
303 : : return aRet;
304 : 0 : break;
305 : :
306 : : case TypeClass_STRING:
307 : : // none empty string -> return
308 [ # # ]: 0 : if( !((OUString*)aRet.getValue())->isEmpty() )
309 : : return aRet;
310 : 0 : break;
311 : :
312 : : // none zero number -> return
313 [ # # ]: 0 : case TypeClass_FLOAT: if( *((float*)aRet.getValue()) ) return aRet; break;
314 [ # # ]: 0 : case TypeClass_DOUBLE: if( *((double*)aRet.getValue()) ) return aRet; break;
315 [ # # ]: 0 : case TypeClass_BYTE: if( *((sal_uInt8*)aRet.getValue()) ) return aRet; break;
316 [ # # ]: 0 : case TypeClass_SHORT: if( *((sal_Int16*)aRet.getValue()) ) return aRet; break;
317 [ # # ]: 0 : case TypeClass_LONG: if( *((sal_Int32*)aRet.getValue()) ) return aRet; break;
318 [ # # ]: 0 : case TypeClass_UNSIGNED_SHORT: if( *((sal_uInt16*)aRet.getValue()) ) return aRet; break;
319 [ # # ]: 0 : case TypeClass_UNSIGNED_LONG: if( *((sal_uInt32*)aRet.getValue()) ) return aRet; break;
320 : :
321 : : default:
322 : : OSL_ASSERT(false);
323 : 0 : break;
324 [ # # ][ # # ]: 0 : }
325 : : }
326 [ # # # # ]: 0 : catch( CannotConvertException& )
327 : : {
328 : : // silent ignore conversions errors from a script call
329 [ # # # # ]: 0 : Reference< XIdlClass > xListenerType = mpManager->getReflection()->
330 [ # # ]: 0 : forName( Event.ListenerType.getTypeName() );
331 [ # # # # ]: 0 : Reference< XIdlMethod > xMeth = xListenerType->getMethod( Event.MethodName );
332 [ # # ]: 0 : if( xMeth.is() )
333 : : {
334 [ # # # # ]: 0 : Reference< XIdlClass > xRetType = xMeth->getReturnType();
335 [ # # # # : 0 : Type aRetType(xRetType->getTypeClass(), xRetType->getName());
# # # # ]
336 : 0 : aRet.clear();
337 [ # # ]: 0 : convertToEventReturn( aRet, aRetType );
338 : 0 : }
339 : : }
340 : : }
341 [ # # ][ # # ]: 0 : return aRet;
342 : : }
343 : :
344 : : //========================================================================
345 : : // Methods of XEventListener
346 : 0 : void SAL_CALL AttacherAllListener_Impl::disposing(const EventObject& )
347 : : throw( RuntimeException )
348 : : {
349 : : // It is up to the container to release the object
350 : 0 : }
351 : :
352 : :
353 : : // Constructor method for EventAttacherManager
354 : 638 : Reference< XEventAttacherManager > createEventAttacherManager( const Reference< XMultiServiceFactory > & rSMgr )
355 : : throw( Exception )
356 : : {
357 [ + - ]: 638 : if ( rSMgr.is() )
358 : : {
359 [ + - ][ + - ]: 638 : Reference< XInterface > xIFace( rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" )) ) );
[ + - ]
360 [ + - ]: 638 : if ( xIFace.is() )
361 : : {
362 [ + - ]: 638 : Reference< XIntrospection > xIntrospection( xIFace, UNO_QUERY);
363 [ + - ][ + - ]: 638 : return new ImplEventAttacherManager( xIntrospection, rSMgr );
[ + - ]
364 [ - + ]: 638 : }
365 : : }
366 : :
367 : 638 : return Reference< XEventAttacherManager >();
368 : : }
369 : :
370 : : //-----------------------------------------------------------------------------
371 : 638 : ImplEventAttacherManager::ImplEventAttacherManager( const Reference< XIntrospection > & rIntrospection,
372 : : const Reference< XMultiServiceFactory > rSMgr )
373 : : : aScriptListeners( aLock )
374 : : , mxSMgr( rSMgr )
375 [ + - ][ + - ]: 638 : , mxIntrospection( rIntrospection )
[ + - ]
376 : : {
377 [ + - ]: 638 : if ( rSMgr.is() )
378 : : {
379 [ + - ][ + - ]: 638 : Reference< XInterface > xIFace( rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.EventAttacher" )) ) );
[ + - ]
380 [ + + ]: 638 : if ( xIFace.is() )
381 : : {
382 [ + - ][ + - ]: 566 : xAttacher = Reference< XEventAttacher2 >::query( xIFace );
383 : : }
384 [ + - ][ + - ]: 638 : xIFace = rSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" )) );
[ + - ][ + - ]
385 [ + - ]: 638 : if ( xIFace.is() )
386 : : {
387 [ + - ][ + - ]: 638 : xConverter = Reference< XTypeConverter >::query( xIFace );
388 : 638 : }
389 : : }
390 : :
391 [ + - ]: 638 : Reference< XInitialization > xInit( xAttacher, UNO_QUERY );
392 [ + + ]: 638 : if( xInit.is() )
393 : : {
394 [ + - ]: 566 : Sequence< Any > Arguments( 1 );
395 [ + - ][ + - ]: 566 : Arguments[0] <<= rIntrospection;
396 [ + - ][ + - ]: 566 : xInit->initialize( Arguments );
[ + - ]
397 : 638 : }
398 : 638 : }
399 : :
400 : : //-----------------------------------------------------------------------------
401 [ + - ][ + - ]: 616 : ImplEventAttacherManager::~ImplEventAttacherManager()
402 : : {
403 [ - + ]: 1232 : }
404 : :
405 : 0 : Reference< XIdlReflection > ImplEventAttacherManager::getReflection() throw( Exception )
406 : : {
407 [ # # ]: 0 : Guard< Mutex > aGuard( aLock );
408 : : // Do we already have a service? If not, create one.
409 [ # # ]: 0 : if( !mxCoreReflection.is() )
410 : : {
411 [ # # ][ # # ]: 0 : Reference< XInterface > xIFace( mxSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.CoreReflection" )) ) );
[ # # ]
412 [ # # ][ # # ]: 0 : mxCoreReflection = Reference< XIdlReflection >( xIFace, UNO_QUERY);
413 : : }
414 [ # # ]: 0 : return mxCoreReflection;
415 : : }
416 : :
417 : :
418 : : //-----------------------------------------------------------------------------
419 : 1430 : ::std::deque<AttacherIndex_Impl>::iterator ImplEventAttacherManager::implCheckIndex( sal_Int32 _nIndex ) SAL_THROW ( ( IllegalArgumentException ) )
420 : : {
421 [ - + ]: 1430 : if (_nIndex < 0)
422 [ # # ]: 0 : throw IllegalArgumentException();
423 : :
424 : 1430 : ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
425 [ + + ][ + - ]: 2902 : for ( sal_Int32 i = 0; (i < _nIndex) && (aIt != aIndex.end()); ++i, ++aIt )
[ + - ][ + + ]
[ + + # # ]
426 : : ;
427 : :
428 [ - + ]: 1430 : if( aIt == aIndex.end() )
429 [ # # ]: 0 : throw IllegalArgumentException();
430 : :
431 : 1430 : return aIt;
432 : : }
433 : :
434 : : namespace {
435 : :
436 : : class DetachObject : public std::unary_function<AttachedObject_Impl, void>
437 : : {
438 : : ImplEventAttacherManager& mrMgr;
439 : : sal_Int32 mnIdx;
440 : : public:
441 : 1382 : DetachObject(ImplEventAttacherManager& rMgr, sal_Int32 nIdx) :
442 : 1382 : mrMgr(rMgr), mnIdx(nIdx) {}
443 : :
444 : 520 : void operator() (AttachedObject_Impl& rObj)
445 : : {
446 : 520 : mrMgr.detach(mnIdx, rObj.xTarget);
447 : 520 : }
448 : : };
449 : :
450 : : class AttachObject : public std::unary_function<AttachedObject_Impl, void>
451 : : {
452 : : ImplEventAttacherManager& mrMgr;
453 : : sal_Int32 mnIdx;
454 : : public:
455 : 502 : AttachObject(ImplEventAttacherManager& rMgr, sal_Int32 nIdx) :
456 : 502 : mrMgr(rMgr), mnIdx(nIdx) {}
457 : :
458 : 490 : void operator() (AttachedObject_Impl& rObj)
459 : : {
460 : 490 : mrMgr.attach(mnIdx, rObj.xTarget, rObj.aHelper);
461 : 490 : }
462 : : };
463 : :
464 : : }
465 : :
466 : : //-----------------------------------------------------------------------------
467 : : // Methods of XEventAttacherManager
468 : 22 : void SAL_CALL ImplEventAttacherManager::registerScriptEvent
469 : : (
470 : : sal_Int32 nIndex,
471 : : const ScriptEventDescriptor& ScriptEvent
472 : : )
473 : : throw( IllegalArgumentException, RuntimeException )
474 : : {
475 [ + - ]: 22 : Guard< Mutex > aGuard( aLock );
476 : :
477 : : // Examine the index and apply the array
478 [ + - ]: 22 : ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
479 : :
480 [ + - ]: 22 : ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
481 : :
482 : 22 : ScriptEventDescriptor aEvt = ScriptEvent;
483 : 22 : const sal_Unicode* pLastDot = aEvt.ListenerType.getStr();
484 : 22 : pLastDot += rtl_ustr_lastIndexOfChar( pLastDot, '.' );
485 [ + - ]: 22 : if( pLastDot )
486 : 22 : aEvt.ListenerType = pLastDot +1;
487 [ + - ]: 22 : (*aIt).aEventList.push_back( aEvt );
488 : :
489 : : // register new new Event
490 : 22 : ::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.begin();
491 : 22 : ::std::deque< AttachedObject_Impl >::iterator aObjEnd = (*aIt).aObjList.end();
492 [ + - ][ + + ]: 24 : while( aObjIt != aObjEnd )
493 : : {
494 : : // resize
495 : 2 : sal_Int32 nPos = (*aObjIt).aAttachedListenerSeq.getLength();
496 [ + - ]: 2 : (*aObjIt).aAttachedListenerSeq.realloc( nPos + 1 );
497 [ + - ]: 2 : Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray();
498 : :
499 : : Reference< XAllListener > xAll =
500 [ + - ][ + - ]: 2 : new AttacherAllListener_Impl( this, ScriptEvent.ScriptType, ScriptEvent.ScriptCode );
[ + - ]
501 : : try
502 : : {
503 [ + - ]: 4 : pArray[nPos] = xAttacher->attachSingleEventListener( (*aObjIt).xTarget, xAll,
504 : 2 : (*aObjIt).aHelper, ScriptEvent.ListenerType,
505 [ + - ][ # # ]: 2 : ScriptEvent.AddListenerParam, ScriptEvent.EventMethod );
[ + - ]
506 : : }
507 [ # # ]: 0 : catch( Exception& )
508 : : {
509 : : }
510 : :
511 [ + - ]: 2 : ++aObjIt;
512 [ + - ]: 24 : }
513 : 22 : }
514 : :
515 : : //-----------------------------------------------------------------------------
516 : 494 : void SAL_CALL ImplEventAttacherManager::registerScriptEvents
517 : : (
518 : : sal_Int32 nIndex,
519 : : const Sequence< ScriptEventDescriptor >& ScriptEvents
520 : : )
521 : : throw( IllegalArgumentException, RuntimeException )
522 : : {
523 [ + - ]: 494 : Guard< Mutex > aGuard( aLock );
524 : :
525 : : // Examine the index and apply the array
526 [ + - ]: 494 : ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
527 : :
528 [ + - ]: 494 : ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
529 [ + - ]: 494 : ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex));
530 : :
531 : 494 : const ScriptEventDescriptor* pArray = ScriptEvents.getConstArray();
532 : 494 : sal_Int32 nLen = ScriptEvents.getLength();
533 [ + + ]: 512 : for( sal_Int32 i = 0 ; i < nLen ; i++ )
534 [ + - ]: 18 : registerScriptEvent( nIndex, pArray[ i ] );
535 : :
536 [ + - ][ + - ]: 494 : ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex));
537 : 494 : }
538 : :
539 : : //-----------------------------------------------------------------------------
540 : 2 : void SAL_CALL ImplEventAttacherManager::revokeScriptEvent
541 : : (
542 : : sal_Int32 nIndex,
543 : : const OUString& ListenerType,
544 : : const OUString& EventMethod,
545 : : const OUString& ToRemoveListenerParam
546 : : )
547 : : throw( IllegalArgumentException, RuntimeException )
548 : : {
549 [ + - ]: 2 : Guard< Mutex > aGuard( aLock );
550 : :
551 [ + - ]: 2 : ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
552 : :
553 [ + - ]: 2 : ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
554 [ + - ]: 2 : ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex));
555 : :
556 : 2 : OUString aLstType = ListenerType;
557 : 2 : const sal_Unicode * pLastDot = aLstType.getStr();
558 : 2 : pLastDot += rtl_ustr_lastIndexOfChar( pLastDot, '.' );
559 [ + - ]: 2 : if( pLastDot )
560 : 2 : aLstType = pLastDot +1;
561 : :
562 : 2 : ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = (*aIt).aEventList.begin();
563 : 2 : ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end();
564 [ + - ][ + - ]: 2 : while( aEvtIt != aEvtEnd )
565 : : {
566 [ + - + - : 6 : if( aLstType == (*aEvtIt).ListenerType
+ - ][ + - ]
567 : 2 : && EventMethod == (*aEvtIt).EventMethod
568 : 2 : && ToRemoveListenerParam == (*aEvtIt).AddListenerParam )
569 : : {
570 [ + - ]: 2 : (*aIt).aEventList.erase( aEvtIt );
571 : 2 : break;
572 : : }
573 : :
574 [ # # ]: 0 : ++aEvtIt;
575 : : }
576 [ + - ][ + - ]: 2 : ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex));
577 : 2 : }
578 : :
579 : : //-----------------------------------------------------------------------------
580 : 6 : void SAL_CALL ImplEventAttacherManager::revokeScriptEvents(sal_Int32 nIndex )
581 : : throw( IllegalArgumentException, RuntimeException )
582 : : {
583 [ + - ]: 6 : Guard< Mutex > aGuard( aLock );
584 [ + - ]: 6 : ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
585 : :
586 [ + - ]: 6 : ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
587 [ + - ]: 6 : ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex));
588 : 6 : (*aIt).aEventList.clear();
589 [ + - ][ + - ]: 6 : ::std::for_each(aList.begin(), aList.end(), AttachObject(*this, nIndex));
590 : 6 : }
591 : :
592 : : //-----------------------------------------------------------------------------
593 : 932 : void SAL_CALL ImplEventAttacherManager::insertEntry(sal_Int32 nIndex)
594 : : throw( IllegalArgumentException, RuntimeException )
595 : : {
596 [ + - ]: 932 : Guard< Mutex > aGuard( aLock );
597 [ - + ]: 932 : if( nIndex < 0 )
598 [ # # ]: 0 : throw IllegalArgumentException();
599 : :
600 [ + + ]: 932 : if ( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() )
601 [ + - ]: 568 : aIndex.resize(nIndex+1);
602 : :
603 [ + - ]: 932 : AttacherIndex_Impl aTmp;
604 [ + - ][ + - ]: 932 : aIndex.insert( aIndex.begin() + nIndex, aTmp );
[ + - ]
605 : 932 : }
606 : :
607 : : //-----------------------------------------------------------------------------
608 : 880 : void SAL_CALL ImplEventAttacherManager::removeEntry(sal_Int32 nIndex)
609 : : throw( IllegalArgumentException, RuntimeException )
610 : : {
611 [ + - ]: 880 : Guard< Mutex > aGuard( aLock );
612 [ + - ]: 880 : ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
613 : :
614 [ + - ]: 880 : ::std::deque< AttachedObject_Impl > aList = (*aIt).aObjList;
615 [ + - ]: 880 : ::std::for_each(aList.begin(), aList.end(), DetachObject(*this, nIndex));
616 [ + - ][ + - ]: 880 : aIndex.erase( aIt );
617 : 880 : }
618 : :
619 : : //-----------------------------------------------------------------------------
620 : 26 : Sequence< ScriptEventDescriptor > SAL_CALL ImplEventAttacherManager::getScriptEvents(sal_Int32 nIndex)
621 : : throw( IllegalArgumentException, RuntimeException )
622 : : {
623 [ + - ]: 26 : Guard< Mutex > aGuard( aLock );
624 [ + - ]: 26 : ::std::deque<AttacherIndex_Impl>::iterator aIt = implCheckIndex( nIndex );
625 : :
626 [ + - ]: 26 : Sequence< ScriptEventDescriptor > aSeq( (*aIt).aEventList.size() );
627 [ + - ]: 26 : ScriptEventDescriptor * pArray = aSeq.getArray();
628 : :
629 : 26 : ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = (*aIt).aEventList.begin();
630 : 26 : ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end();
631 : 26 : sal_Int32 i = 0;
632 [ + - ][ + + ]: 36 : while( aEvtIt != aEvtEnd )
633 : : {
634 : 10 : pArray[i++] = *aEvtIt;
635 [ + - ]: 10 : ++aEvtIt;
636 : : }
637 [ + - ]: 26 : return aSeq;
638 : : }
639 : :
640 : : //-----------------------------------------------------------------------------
641 : 1527 : void SAL_CALL ImplEventAttacherManager::attach(sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any & Helper)
642 : : throw( IllegalArgumentException, ServiceNotRegisteredException, RuntimeException )
643 : : {
644 [ + - ]: 1527 : Guard< Mutex > aGuard( aLock );
645 [ + - ][ - + ]: 1527 : if( nIndex < 0 || !xObject.is() )
[ - + ]
646 [ # # ]: 0 : throw IllegalArgumentException();
647 : :
648 [ - + ]: 1527 : if( static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() )
649 : : {
650 : : // read older files
651 [ # # ]: 0 : if( nVersion == 1 )
652 : : {
653 [ # # ]: 0 : insertEntry( nIndex );
654 [ # # ]: 0 : attach( nIndex, xObject, Helper );
655 : : return;
656 : : }
657 : : else
658 [ # # ]: 0 : throw IllegalArgumentException();
659 : : }
660 : :
661 [ + - ]: 1527 : ::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex;
662 : :
663 [ + - ]: 1527 : AttachedObject_Impl aTmp;
664 [ + - ]: 1527 : aTmp.xTarget = xObject;
665 : 1527 : aTmp.aHelper = Helper;
666 [ + - ]: 1527 : aCurrentPosition->aObjList.push_back( aTmp );
667 : :
668 : : //::std::deque< AttachedObject_Impl >::iterator aObjIt = (*aIt).aObjList.back();
669 [ + - ]: 1527 : AttachedObject_Impl & rCurObj = aCurrentPosition->aObjList.back();
670 [ + - ][ + - ]: 1527 : rCurObj.aAttachedListenerSeq = Sequence< Reference< XEventListener > >( aCurrentPosition->aEventList.size() );
[ + - ]
671 : :
672 [ + + ]: 1527 : if (aCurrentPosition->aEventList.empty())
673 : : return;
674 : :
675 [ + - ]: 30 : Sequence<com::sun::star::script::EventListener> aEvents(aCurrentPosition->aEventList.size());
676 : 30 : std::deque<ScriptEventDescriptor>::iterator itr = aCurrentPosition->aEventList.begin();
677 : 30 : std::deque<ScriptEventDescriptor>::iterator itrEnd = aCurrentPosition->aEventList.end();
678 [ + - ]: 30 : ::com::sun::star::script::EventListener* p = aEvents.getArray();
679 : 30 : size_t i = 0;
680 [ + - ][ + - ]: 60 : for (; itr != itrEnd; ++itr)
[ + + ]
681 : : {
682 [ + - ]: 30 : com::sun::star::script::EventListener aListener;
683 : : aListener.AllListener =
684 [ + - ][ + - ]: 30 : new AttacherAllListener_Impl(this, itr->ScriptType, itr->ScriptCode);
[ + - ]
685 : 30 : aListener.Helper = rCurObj.aHelper;
686 : 30 : aListener.ListenerType = itr->ListenerType;
687 : 30 : aListener.EventMethod = itr->EventMethod;
688 : 30 : aListener.AddListenerParam = itr->AddListenerParam;
689 [ + - ]: 30 : p[i++] = aListener;
690 [ + - ]: 30 : }
691 : :
692 : : try
693 : : {
694 : : rCurObj.aAttachedListenerSeq =
695 [ + - ][ + - ]: 30 : xAttacher->attachMultipleEventListeners(rCurObj.xTarget, aEvents);
[ + - ][ + - ]
[ # # ]
696 : : }
697 [ # # ]: 0 : catch (const Exception&)
698 : : {
699 : : // Fail gracefully.
700 [ + - ][ + - ]: 1527 : }
[ + + ][ + - ]
[ + + ]
701 : : }
702 : :
703 : : //-----------------------------------------------------------------------------
704 : 1501 : void SAL_CALL ImplEventAttacherManager::detach(sal_Int32 nIndex, const Reference< XInterface >& xObject)
705 : : throw( IllegalArgumentException, RuntimeException )
706 : : {
707 [ + - ]: 1501 : Guard< Mutex > aGuard( aLock );
708 : : //return;
709 [ + - ][ + - ]: 1501 : if( nIndex < 0 || static_cast< ::std::deque< AttacherIndex_Impl >::size_type>(nIndex) >= aIndex.size() || !xObject.is() )
[ - + ][ - + ]
710 [ # # ]: 0 : throw IllegalArgumentException();
711 : :
712 [ + - # # ]: 1501 : ::std::deque< AttacherIndex_Impl >::iterator aCurrentPosition = aIndex.begin() + nIndex;
713 : 1501 : ::std::deque< AttachedObject_Impl >::iterator aObjIt = aCurrentPosition->aObjList.begin();
714 : 1501 : ::std::deque< AttachedObject_Impl >::iterator aObjEnd = aCurrentPosition->aObjList.end();
715 [ + - ][ + + ]: 1634 : while( aObjIt != aObjEnd )
716 : : {
717 [ + - ][ + + ]: 1604 : if( (*aObjIt).xTarget == xObject )
718 : : {
719 [ + - ]: 1471 : Reference< XEventListener > * pArray = (*aObjIt).aAttachedListenerSeq.getArray();
720 : :
721 : 1471 : ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = aCurrentPosition->aEventList.begin();
722 : 1471 : ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = aCurrentPosition->aEventList.end();
723 : 1471 : sal_Int32 i = 0;
724 [ + - ][ + + ]: 1503 : while( aEvtIt != aEvtEnd )
725 : : {
726 [ + + ]: 32 : if( pArray[i].is() )
727 : : {
728 : : try
729 : : {
730 [ + - ]: 32 : xAttacher->removeListener( (*aObjIt).xTarget, (*aEvtIt).ListenerType,
731 [ + - ]: 32 : (*aEvtIt).AddListenerParam, pArray[i] );
732 : : }
733 [ # # ]: 0 : catch( Exception& )
734 : : {
735 : : }
736 : : }
737 : 32 : i++;
738 [ + - ]: 32 : ++aEvtIt;
739 : : }
740 [ + - ]: 1471 : aCurrentPosition->aObjList.erase( aObjIt );
741 : : break;
742 : : }
743 [ + - ]: 133 : ++aObjIt;
744 [ + - ]: 1501 : }
745 : 1501 : }
746 : :
747 : 1258 : void SAL_CALL ImplEventAttacherManager::addScriptListener(const Reference< XScriptListener >& aListener)
748 : : throw( IllegalArgumentException, RuntimeException )
749 : : {
750 [ + - ]: 1258 : Guard< Mutex > aGuard( aLock );
751 [ + - ][ + - ]: 1258 : aScriptListeners.addInterface( aListener );
752 : 1258 : }
753 : :
754 : 1226 : void SAL_CALL ImplEventAttacherManager::removeScriptListener(const Reference< XScriptListener >& aListener)
755 : : throw( IllegalArgumentException, RuntimeException )
756 : : {
757 [ + - ]: 1226 : Guard< Mutex > aGuard( aLock );
758 [ + - ][ + - ]: 1226 : aScriptListeners.removeInterface( aListener );
759 : 1226 : }
760 : :
761 : :
762 : : // Methods of XPersistObject
763 : 0 : OUString SAL_CALL ImplEventAttacherManager::getServiceName(void)
764 : : throw( RuntimeException )
765 : : {
766 : 0 : return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.script.EventAttacherManager") );
767 : : }
768 : :
769 : 2 : void SAL_CALL ImplEventAttacherManager::write(const Reference< XObjectOutputStream >& OutStream)
770 : : throw( IOException, RuntimeException )
771 : : {
772 [ + - ]: 2 : Guard< Mutex > aGuard( aLock );
773 : : // Don't run without XMarkableStream
774 [ + - ]: 2 : Reference< XMarkableStream > xMarkStream( OutStream, UNO_QUERY );
775 [ - + ]: 2 : if( !xMarkStream.is() )
776 : 2 : return;
777 : :
778 : : // Write out the version
779 [ + - ][ + - ]: 2 : OutStream->writeShort( 2 );
780 : :
781 : : // Remember position for length
782 [ + - ][ + - ]: 2 : sal_Int32 nObjLenMark = xMarkStream->createMark();
783 [ + - ][ + - ]: 2 : OutStream->writeLong( 0L );
784 : :
785 [ + - ][ + - ]: 2 : OutStream->writeLong( aIndex.size() );
786 : :
787 : : // Write out sequences
788 : 2 : ::std::deque<AttacherIndex_Impl>::iterator aIt = aIndex.begin();
789 : 2 : ::std::deque<AttacherIndex_Impl>::iterator aEnd = aIndex.end();
790 [ + - ][ + + ]: 8 : while( aIt != aEnd )
791 : : {
792 : : // Write out the length of the sequence and all descriptions
793 [ + - ][ + - ]: 6 : OutStream->writeLong( (*aIt).aEventList.size() );
794 : 6 : ::std::deque< ScriptEventDescriptor >::iterator aEvtIt = (*aIt).aEventList.begin();
795 : 6 : ::std::deque< ScriptEventDescriptor >::iterator aEvtEnd = (*aIt).aEventList.end();
796 [ + - ][ - + ]: 6 : while( aEvtIt != aEvtEnd )
797 : : {
798 : 0 : const ScriptEventDescriptor& rDesc = (*aEvtIt);
799 [ # # ][ # # ]: 0 : OutStream->writeUTF( rDesc.ListenerType );
800 [ # # ][ # # ]: 0 : OutStream->writeUTF( rDesc.EventMethod );
801 [ # # ][ # # ]: 0 : OutStream->writeUTF( rDesc.AddListenerParam );
802 [ # # ][ # # ]: 0 : OutStream->writeUTF( rDesc.ScriptType );
803 [ # # ][ # # ]: 0 : OutStream->writeUTF( rDesc.ScriptCode );
804 : :
805 [ # # ]: 0 : ++aEvtIt;
806 : : }
807 [ + - ]: 6 : ++aIt;
808 : : }
809 : :
810 : : // The length is now known
811 [ + - ][ + - ]: 2 : sal_Int32 nObjLen = xMarkStream->offsetToMark( nObjLenMark ) -4;
812 [ + - ][ + - ]: 2 : xMarkStream->jumpToMark( nObjLenMark );
813 [ + - ][ + - ]: 2 : OutStream->writeLong( nObjLen );
814 [ + - ][ + - ]: 2 : xMarkStream->jumpToFurthest();
815 [ + - ][ + - ]: 2 : xMarkStream->deleteMark( nObjLenMark );
[ - + ][ + - ]
[ + - ]
816 : : }
817 : :
818 : 2 : void SAL_CALL ImplEventAttacherManager::read(const Reference< XObjectInputStream >& InStream)
819 : : throw( IOException, RuntimeException )
820 : : {
821 [ + - ]: 2 : Guard< Mutex > aGuard( aLock );
822 : : // Don't run without XMarkableStream
823 [ + - ]: 2 : Reference< XMarkableStream > xMarkStream( InStream, UNO_QUERY );
824 [ - + ]: 2 : if( !xMarkStream.is() )
825 : 2 : return;
826 : :
827 : : // Read in the version
828 [ + - ][ + - ]: 2 : nVersion = InStream->readShort();
829 : :
830 : : // At first there's the data according to version 1 --
831 : : // this part needs to be kept in later versions.
832 [ + - ][ + - ]: 2 : sal_Int32 nLen = InStream->readLong();
833 : :
834 : : // Position for comparative purposes
835 [ + - ][ + - ]: 2 : sal_Int32 nObjLenMark = xMarkStream->createMark();
836 : :
837 : : // Number of read sequences
838 [ + - ][ + - ]: 2 : sal_Int32 nItemCount = InStream->readLong();
839 : :
840 [ + + ]: 8 : for( sal_Int32 i = 0 ; i < nItemCount ; i++ )
841 : : {
842 [ + - ]: 6 : insertEntry( i );
843 : : // Read the length of the sequence
844 [ + - ][ + - ]: 6 : sal_Int32 nSeqLen = InStream->readLong();
845 : :
846 : : // Display the sequences and read the descriptions
847 [ + - ]: 6 : Sequence< ScriptEventDescriptor > aSEDSeq( nSeqLen );
848 [ + - ]: 6 : ScriptEventDescriptor* pArray = aSEDSeq.getArray();
849 [ - + ]: 6 : for( sal_Int32 j = 0 ; j < nSeqLen ; j++ )
850 : : {
851 : 0 : ScriptEventDescriptor& rDesc = pArray[ j ];
852 [ # # ][ # # ]: 0 : rDesc.ListenerType = InStream->readUTF();
853 [ # # ][ # # ]: 0 : rDesc.EventMethod = InStream->readUTF();
854 [ # # ][ # # ]: 0 : rDesc.AddListenerParam = InStream->readUTF();
855 [ # # ][ # # ]: 0 : rDesc.ScriptType = InStream->readUTF();
856 [ # # ][ # # ]: 0 : rDesc.ScriptCode = InStream->readUTF();
857 : : }
858 [ + - ]: 6 : registerScriptEvents( i, aSEDSeq );
859 [ + - ]: 6 : }
860 : :
861 : : // Have we read the specified length?
862 [ + - ][ + - ]: 2 : sal_Int32 nRealLen = xMarkStream->offsetToMark( nObjLenMark );
863 [ - + ]: 2 : if( nRealLen != nLen )
864 : : {
865 : : // Only if the StreamVersion is > 1 and the date still follows, can
866 : : // this be true. Otherwise, something is completely gone.
867 [ # # ][ # # ]: 0 : if( nRealLen > nLen || nVersion == 1 )
868 : : {
869 : : OSL_FAIL( "ImplEventAttacherManager::read(): Fatal Error, wrong object length" );
870 : : }
871 : : else
872 : : { // TODO: Examine if caching the dates would be useful
873 : : // But for now, it's easier to skip it.
874 : 0 : sal_Int32 nSkipCount = nLen - nRealLen;
875 [ # # ][ # # ]: 0 : InStream->skipBytes( nSkipCount );
876 : : }
877 : : }
878 [ + - ][ + - ]: 2 : xMarkStream->jumpToFurthest();
879 [ + - ][ + - ]: 2 : xMarkStream->deleteMark( nObjLenMark );
[ - + ][ + - ]
[ + - ]
880 : : }
881 : :
882 : : } // namesapce comphelper
883 : :
884 : :
885 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|