xref: /aoo42x/main/ucb/source/sorter/sortresult.cxx (revision 421ed02e)
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 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sorter.hxx"
26 
27 #include <vector>
28 #include <sortresult.hxx>
29 #include <cppuhelper/interfacecontainer.hxx>
30 #include <com/sun/star/sdbc/DataType.hpp>
31 #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
32 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
33 #include <com/sun/star/ucb/ListActionType.hpp>
34 #include <com/sun/star/ucb/XAnyCompare.hpp>
35 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
36 #include <osl/diagnose.h>
37 
38 //-----------------------------------------------------------------------------
39 using namespace com::sun::star::beans;
40 using namespace com::sun::star::container;
41 using namespace com::sun::star::io;
42 using namespace com::sun::star::lang;
43 using namespace com::sun::star::sdbc;
44 using namespace com::sun::star::ucb;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::util;
47 using namespace cppu;
48 using namespace rtl;
49 
50 //=========================================================================
51 
52 //  The mutex to synchronize access to containers.
getContainerMutex()53 static osl::Mutex& getContainerMutex()
54 {
55     static osl::Mutex* pMutex = NULL;
56     if( !pMutex )
57     {
58         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
59         if( !pMutex )
60         {
61             static osl::Mutex aMutex;
62             pMutex = &aMutex;
63         }
64     }
65 
66     return *pMutex;
67 }
68 
69 //==========================================================================
70 
71 struct SortInfo
72 {
73     sal_Bool    mbUseOwnCompare;
74     sal_Bool    mbAscending;
75     sal_Bool    mbCaseSensitive;
76     sal_Int32   mnColumn;
77     sal_Int32   mnType;
78     SortInfo*   mpNext;
79     Reference < XAnyCompare >   mxCompareFunction;
80 };
81 
82 //-----------------------------------------------------------------------------
83 
84 struct SortListData
85 {
86     sal_Bool    mbModified;
87     long        mnCurPos;
88     long        mnOldPos;
89 
90                 SortListData( long nPos, sal_Bool bModified = sal_False );
91 };
92 
93 //============================================================================
94 //
95 // class SRSPropertySetInfo.
96 //
97 //============================================================================
98 
99 class SRSPropertySetInfo :
100                 public OWeakObject,
101                 public XTypeProvider,
102                 public XPropertySetInfo
103 {
104     Property    maProps[2];
105 
106 private:
107 
108 public:
109                 SRSPropertySetInfo();
110     virtual     ~SRSPropertySetInfo();
111 
112     // XInterface
113     XINTERFACE_DECL()
114 
115     // XTypeProvider
116     XTYPEPROVIDER_DECL()
117 
118     // XPropertySetInfo
119     virtual Sequence< Property > SAL_CALL getProperties()
120         throw( RuntimeException );
121     virtual Property SAL_CALL getPropertyByName( const OUString& aName )
122         throw( UnknownPropertyException, RuntimeException );
123     virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
124         throw( RuntimeException );
125 };
126 
127 //=========================================================================
128 //
129 // PropertyChangeListenerContainer_Impl.
130 //
131 //=========================================================================
132 
133 struct equalStr_Impl
134 {
operator ()equalStr_Impl135     bool operator()( const OUString& s1, const OUString& s2 ) const
136     {
137         return !!( s1 == s2 );
138     }
139 };
140 
141 struct hashStr_Impl
142 {
operator ()hashStr_Impl143     size_t operator()( const OUString& rName ) const
144     {
145         return rName.hashCode();
146     }
147 };
148 
149 typedef OMultiTypeInterfaceContainerHelperVar
150 <
151     OUString,
152     hashStr_Impl,
153     equalStr_Impl
154 > PropertyChangeListenerContainer_Impl;
155 
156 //=========================================================================
157 //
158 // class PropertyChangeListeners_Impl
159 //
160 //=========================================================================
161 
162 class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl
163 {
164 public:
PropertyChangeListeners_Impl()165     PropertyChangeListeners_Impl()
166     : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {}
167 };
168 
169 //==========================================================================
SortedResultSet(Reference<XResultSet> aResult)170 SortedResultSet::SortedResultSet( Reference< XResultSet > aResult )
171 {
172     mpDisposeEventListeners = NULL;
173     mpPropChangeListeners   = NULL;
174     mpVetoChangeListeners   = NULL;
175     mpPropSetInfo           = NULL;
176 
177     mxOriginal  = aResult;
178     mpSortInfo  = NULL;
179     mnLastSort  = 0;
180     mnCurEntry  = 0;
181     mnCount     = 0;
182     mbIsCopy    = sal_False;
183 }
184 
185 //--------------------------------------------------------------------------
~SortedResultSet()186 SortedResultSet::~SortedResultSet()
187 {
188     mxOriginal.clear();
189     mxOther.clear();
190 
191     if ( !mbIsCopy )
192     {
193         SortInfo *pInfo = mpSortInfo;
194         while ( pInfo )
195         {
196             mpSortInfo = pInfo->mpNext;
197             delete pInfo;
198             pInfo = mpSortInfo;
199         }
200     }
201 
202     mpSortInfo = NULL;
203 
204     if ( mpPropSetInfo )
205         mpPropSetInfo->release();
206 
207     delete mpPropChangeListeners;
208     delete mpVetoChangeListeners;
209 }
210 
211 //--------------------------------------------------------------------------
212 // XInterface methods.
213 //--------------------------------------------------------------------------
214 
215 XINTERFACE_IMPL_9( SortedResultSet,
216                    XTypeProvider,
217                    XServiceInfo,
218                    XComponent,
219                    XContentAccess,
220                    XResultSet,
221                    XRow,
222                    XCloseable,
223                    XResultSetMetaDataSupplier,
224                    XPropertySet );
225 
226 //--------------------------------------------------------------------------
227 // XTypeProvider methods.
228 //--------------------------------------------------------------------------
229 
230 XTYPEPROVIDER_IMPL_9( SortedResultSet,
231                       XTypeProvider,
232                       XServiceInfo,
233                       XComponent,
234                       XContentAccess,
235                       XResultSet,
236                       XRow,
237                       XCloseable,
238                       XResultSetMetaDataSupplier,
239                       XPropertySet );
240 
241 //--------------------------------------------------------------------------
242 // XServiceInfo methods.
243 //--------------------------------------------------------------------------
244 
245 XSERVICEINFO_NOFACTORY_IMPL_1( SortedResultSet,
246                                OUString::createFromAscii(
247                                 "com.sun.star.comp.ucb.SortedResultSet" ),
248                                OUString::createFromAscii(
249                                 RESULTSET_SERVICE_NAME ) );
250 
251 //--------------------------------------------------------------------------
252 // XComponent methods.
253 //--------------------------------------------------------------------------
dispose()254 void SAL_CALL SortedResultSet::dispose()
255     throw( RuntimeException )
256 {
257     osl::Guard< osl::Mutex > aGuard( maMutex );
258 
259     if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
260     {
261         EventObject aEvt;
262         aEvt.Source = static_cast< XComponent * >( this );
263         mpDisposeEventListeners->disposeAndClear( aEvt );
264     }
265 
266     if ( mpPropChangeListeners )
267     {
268         EventObject aEvt;
269         aEvt.Source = static_cast< XPropertySet * >( this );
270         mpPropChangeListeners->disposeAndClear( aEvt );
271     }
272 
273     if ( mpVetoChangeListeners )
274     {
275         EventObject aEvt;
276         aEvt.Source = static_cast< XPropertySet * >( this );
277         mpVetoChangeListeners->disposeAndClear( aEvt );
278     }
279 
280     mxOriginal.clear();
281     mxOther.clear();
282 }
283 
284 //--------------------------------------------------------------------------
addEventListener(const Reference<XEventListener> & Listener)285 void SAL_CALL SortedResultSet::addEventListener(
286                             const Reference< XEventListener >& Listener )
287     throw( RuntimeException )
288 {
289     osl::Guard< osl::Mutex > aGuard( maMutex );
290 
291     if ( !mpDisposeEventListeners )
292         mpDisposeEventListeners =
293                     new OInterfaceContainerHelper( getContainerMutex() );
294 
295     mpDisposeEventListeners->addInterface( Listener );
296 }
297 
298 //--------------------------------------------------------------------------
removeEventListener(const Reference<XEventListener> & Listener)299 void SAL_CALL SortedResultSet::removeEventListener(
300                             const Reference< XEventListener >& Listener )
301     throw( RuntimeException )
302 {
303     osl::Guard< osl::Mutex > aGuard( maMutex );
304 
305     if ( mpDisposeEventListeners )
306         mpDisposeEventListeners->removeInterface( Listener );
307 }
308 
309 //--------------------------------------------------------------------------
310 // XContentAccess methods.
311 //--------------------------------------------------------------------------
312 
313 OUString SAL_CALL
queryContentIdentifierString()314 SortedResultSet::queryContentIdentifierString()
315     throw( RuntimeException )
316 {
317     osl::Guard< osl::Mutex > aGuard( maMutex );
318     return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
319 }
320 
321 //--------------------------------------------------------------------------
322 Reference< XContentIdentifier > SAL_CALL
queryContentIdentifier()323 SortedResultSet::queryContentIdentifier()
324     throw( RuntimeException )
325 {
326     osl::Guard< osl::Mutex > aGuard( maMutex );
327     return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
328 }
329 
330 //--------------------------------------------------------------------------
331 Reference< XContent > SAL_CALL
queryContent()332 SortedResultSet::queryContent()
333     throw( RuntimeException )
334 {
335     osl::Guard< osl::Mutex > aGuard( maMutex );
336     return Reference< XContentAccess >::query(mxOriginal)->queryContent();
337 }
338 
339 
340 //--------------------------------------------------------------------------
341 // XResultSet methods.
342 //--------------------------------------------------------------------------
next()343 sal_Bool SAL_CALL SortedResultSet::next()
344     throw ( SQLException, RuntimeException )
345 {
346     osl::Guard< osl::Mutex > aGuard( maMutex );
347 
348     mnCurEntry++;
349 
350     if ( mnCurEntry > 0 )
351     {
352         if ( mnCurEntry <= mnCount )
353         {
354             sal_Int32 nIndex = maS2O[ mnCurEntry ];
355             return mxOriginal->absolute( nIndex );
356         }
357         else
358         {
359             mnCurEntry = mnCount + 1;
360         }
361     }
362     return sal_False;
363 }
364 
365 //-------------------------------------------------------------------------
isBeforeFirst()366 sal_Bool SAL_CALL SortedResultSet::isBeforeFirst()
367     throw ( SQLException, RuntimeException )
368 {
369     if ( mnCurEntry )
370         return sal_False;
371     else
372         return sal_True;
373 }
374 
375 //-------------------------------------------------------------------------
isAfterLast()376 sal_Bool SAL_CALL SortedResultSet::isAfterLast()
377     throw ( SQLException, RuntimeException )
378 {
379     if ( mnCurEntry > mnCount )
380         return sal_True;
381     else
382         return sal_False;
383 }
384 
385 //-------------------------------------------------------------------------
isFirst()386 sal_Bool SAL_CALL SortedResultSet::isFirst()
387     throw ( SQLException, RuntimeException )
388 {
389     if ( mnCurEntry == 1 )
390         return sal_True;
391     else
392         return sal_False;
393 }
394 
395 //-------------------------------------------------------------------------
isLast()396 sal_Bool SAL_CALL SortedResultSet::isLast()
397     throw ( SQLException, RuntimeException )
398 {
399     if ( mnCurEntry == mnCount )
400         return sal_True;
401     else
402         return sal_False;
403 }
404 
405 //-------------------------------------------------------------------------
beforeFirst()406 void SAL_CALL SortedResultSet::beforeFirst()
407     throw ( SQLException, RuntimeException )
408 {
409     osl::Guard< osl::Mutex > aGuard( maMutex );
410     mnCurEntry = 0;
411     mxOriginal->beforeFirst();
412 }
413 
414 //-------------------------------------------------------------------------
afterLast()415 void SAL_CALL SortedResultSet::afterLast()
416     throw ( SQLException, RuntimeException )
417 {
418     osl::Guard< osl::Mutex > aGuard( maMutex );
419     mnCurEntry = mnCount+1;
420     mxOriginal->afterLast();
421 }
422 
423 //-------------------------------------------------------------------------
first()424 sal_Bool SAL_CALL SortedResultSet::first()
425     throw ( SQLException, RuntimeException )
426 {
427     osl::Guard< osl::Mutex > aGuard( maMutex );
428 
429     if ( mnCount )
430     {
431         mnCurEntry = 1;
432         sal_Int32 nIndex = maS2O[ mnCurEntry ];
433         return mxOriginal->absolute( nIndex );
434     }
435     else
436     {
437         mnCurEntry = 0;
438         return sal_False;
439     }
440 }
441 
442 //-------------------------------------------------------------------------
last()443 sal_Bool SAL_CALL SortedResultSet::last()
444     throw ( SQLException, RuntimeException )
445 {
446     osl::Guard< osl::Mutex > aGuard( maMutex );
447 
448     if ( mnCount )
449     {
450         mnCurEntry = mnCount;
451         sal_Int32 nIndex = maS2O[ mnCurEntry ];
452         return mxOriginal->absolute( nIndex );
453     }
454     else
455     {
456         mnCurEntry = 0;
457         return sal_False;
458     }
459 }
460 
461 //-------------------------------------------------------------------------
getRow()462 sal_Int32 SAL_CALL SortedResultSet::getRow()
463     throw ( SQLException, RuntimeException )
464 {
465     return mnCurEntry;
466 }
467 
468 //-------------------------------------------------------------------------
469 /**
470  moves the cursor to the given row number in the result set.
471  <p>If the row number is positive, the cursor moves to the given row
472  number with respect to the beginning of the result set. The first
473  row is row 1, the second is row 2, and so on.
474  <p>If the given row number is negative, the cursor moves to an
475  absolute row position with respect to the end of the result set.
476  For example, calling <code>moveToPosition(-1)</code> positions the
477  cursor on the last row, <code>moveToPosition(-2)</code> indicates the
478  next-to-last row, and so on.
479  <p>An attempt to position the cursor beyond the first/last row in the
480  result set leaves the cursor before/after the first/last row,
481  respectively.
482  <p>Note: Calling <code>moveToPosition(1)</code> is the same
483  as calling <code>moveToFirst()</code>. Calling
484  <code>moveToPosition(-1)</code> is the same as calling
485  <code>moveToLast()</code>.
486  @param row
487     is the number of rows to move. Could be negative.
488  @returns
489     <TRUE/> if the cursor is on a row; <FALSE/> otherwise
490  @throws SQLException
491     if a database access error occurs or if row is 0, or the result set
492     type is FORWARD_ONLY.
493  */
absolute(sal_Int32 row)494 sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
495     throw ( SQLException, RuntimeException )
496 {
497     osl::Guard< osl::Mutex > aGuard( maMutex );
498 
499     sal_Int32 nIndex;
500 
501     if ( row > 0 )
502     {
503         if ( row <= mnCount )
504         {
505             mnCurEntry = row;
506             nIndex = maS2O[ mnCurEntry ];
507             return mxOriginal->absolute( nIndex );
508         }
509         else
510         {
511             mnCurEntry = mnCount + 1;
512             return sal_False;
513         }
514     }
515     else if ( row == 0 )
516     {
517         throw SQLException();
518     }
519     else
520     {
521         if ( mnCount + row + 1 > 0 )
522         {
523             mnCurEntry = mnCount + row + 1;
524             nIndex = maS2O[ mnCurEntry ];
525             return mxOriginal->absolute( nIndex );
526         }
527         else
528         {
529             mnCurEntry = 0;
530             return sal_False;
531         }
532     }
533 }
534 
535 //-------------------------------------------------------------------------
536 /**
537  moves the cursor a relative number of rows, either positive or negative.
538  <p>
539  Attempting to move beyond the first/last row in the result set positions
540  the cursor before/after the first/last row. Calling
541  <code>moveRelative(0)</code> is valid, but does not change the cursor
542  position.
543  <p>Note: Calling <code>moveRelative(1)</code> is different from calling
544  <code>moveNext()</code> because is makes sense to call
545  <code>moveNext()</code> when there is no current row, for example,
546  when the cursor is positioned before the first row or after the last
547  row of the result set.
548  @param rows
549     is the number of rows to move. Could be negative.
550  @returns
551     <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
552     the result set.
553  @throws SQLException
554     if a database access error occurs or if there is no
555     current row, or the result set type is FORWARD_ONLY.
556  */
relative(sal_Int32 rows)557 sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
558     throw ( SQLException, RuntimeException )
559 {
560     osl::Guard< osl::Mutex > aGuard( maMutex );
561 
562     if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
563     {
564         throw SQLException();
565     }
566 
567     if ( rows == 0 )
568         return sal_True;
569 
570     sal_Int32 nTmp = mnCurEntry + rows;
571 
572     if ( nTmp <= 0 )
573     {
574         mnCurEntry = 0;
575         return sal_False;
576     }
577     else if ( nTmp > mnCount )
578     {
579         mnCurEntry = mnCount + 1;
580         return sal_False;
581     }
582     else
583     {
584         mnCurEntry = nTmp;
585         nTmp = maS2O[ mnCurEntry ];
586         return mxOriginal->absolute( nTmp );
587     }
588 }
589 
590 //-------------------------------------------------------------------------
591 /**
592  moves the cursor to the previous row in the result set.
593  <p>Note: <code>previous()</code> is not the same as
594  <code>relative(-1)</code> because it makes sense to call
595  <code>previous()</code> when there is no current row.
596  @returns <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
597     the result set.
598  @throws SQLException
599     if a database access error occurs or the result set type
600     is FORWARD_ONLY.
601  */
previous()602 sal_Bool SAL_CALL SortedResultSet::previous()
603     throw ( SQLException, RuntimeException )
604 {
605     osl::Guard< osl::Mutex > aGuard( maMutex );
606 
607     mnCurEntry -= 1;
608 
609     if ( mnCurEntry > 0 )
610     {
611         if ( mnCurEntry <= mnCount )
612         {
613             sal_Int32 nIndex = maS2O[ mnCurEntry ];
614             return mxOriginal->absolute( nIndex );
615         }
616     }
617     else
618         mnCurEntry = 0;
619 
620     return sal_False;
621 }
622 
623 //-------------------------------------------------------------------------
refreshRow()624 void SAL_CALL SortedResultSet::refreshRow()
625     throw ( SQLException, RuntimeException )
626 {
627     osl::Guard< osl::Mutex > aGuard( maMutex );
628 
629     if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
630     {
631         throw SQLException();
632     }
633 
634     mxOriginal->refreshRow();
635 }
636 
637 //-------------------------------------------------------------------------
rowUpdated()638 sal_Bool SAL_CALL SortedResultSet::rowUpdated()
639     throw ( SQLException, RuntimeException )
640 {
641     osl::Guard< osl::Mutex > aGuard( maMutex );
642 
643     if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
644     {
645         throw SQLException();
646     }
647 
648     return mxOriginal->rowUpdated();
649 }
650 
651 //-------------------------------------------------------------------------
rowInserted()652 sal_Bool SAL_CALL SortedResultSet::rowInserted()
653     throw ( SQLException, RuntimeException )
654 {
655     osl::Guard< osl::Mutex > aGuard( maMutex );
656 
657     if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
658     {
659         throw SQLException();
660     }
661 
662     return mxOriginal->rowInserted();
663 }
664 
665 //-------------------------------------------------------------------------
rowDeleted()666 sal_Bool SAL_CALL SortedResultSet::rowDeleted()
667     throw ( SQLException, RuntimeException )
668 {
669     osl::Guard< osl::Mutex > aGuard( maMutex );
670 
671     if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
672     {
673         throw SQLException();
674     }
675 
676     return mxOriginal->rowDeleted();
677 }
678 
679 //-------------------------------------------------------------------------
getStatement()680 Reference< XInterface > SAL_CALL SortedResultSet::getStatement()
681     throw ( SQLException, RuntimeException )
682 {
683     osl::Guard< osl::Mutex > aGuard( maMutex );
684 
685     if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
686     {
687         throw SQLException();
688     }
689 
690     return mxOriginal->getStatement();
691 }
692 
693 //--------------------------------------------------------------------------
694 // XRow methods.
695 //--------------------------------------------------------------------------
696 
wasNull()697 sal_Bool SAL_CALL SortedResultSet::wasNull()
698     throw( SQLException, RuntimeException )
699 {
700     osl::Guard< osl::Mutex > aGuard( maMutex );
701     return Reference< XRow >::query(mxOriginal)->wasNull();
702 }
703 
704 //-------------------------------------------------------------------------
getString(sal_Int32 columnIndex)705 OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
706     throw( SQLException, RuntimeException )
707 {
708     osl::Guard< osl::Mutex > aGuard( maMutex );
709     return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
710 }
711 
712 //-------------------------------------------------------------------------
getBoolean(sal_Int32 columnIndex)713 sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
714     throw( SQLException, RuntimeException )
715 {
716     osl::Guard< osl::Mutex > aGuard( maMutex );
717     return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
718 }
719 
720 //-------------------------------------------------------------------------
getByte(sal_Int32 columnIndex)721 sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
722     throw( SQLException, RuntimeException )
723 {
724     osl::Guard< osl::Mutex > aGuard( maMutex );
725     return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
726 }
727 
728 //-------------------------------------------------------------------------
getShort(sal_Int32 columnIndex)729 sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
730     throw( SQLException, RuntimeException )
731 {
732     osl::Guard< osl::Mutex > aGuard( maMutex );
733     return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
734 }
735 
736 //-------------------------------------------------------------------------
getInt(sal_Int32 columnIndex)737 sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
738     throw( SQLException, RuntimeException )
739 {
740     osl::Guard< osl::Mutex > aGuard( maMutex );
741     return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
742 }
743 //-------------------------------------------------------------------------
getLong(sal_Int32 columnIndex)744 sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
745     throw( SQLException, RuntimeException )
746 {
747     osl::Guard< osl::Mutex > aGuard( maMutex );
748     return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
749 }
750 
751 //-------------------------------------------------------------------------
getFloat(sal_Int32 columnIndex)752 float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
753     throw( SQLException, RuntimeException )
754 {
755     osl::Guard< osl::Mutex > aGuard( maMutex );
756     return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
757 }
758 
759 //-------------------------------------------------------------------------
getDouble(sal_Int32 columnIndex)760 double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
761     throw( SQLException, RuntimeException )
762 {
763     osl::Guard< osl::Mutex > aGuard( maMutex );
764     return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
765 }
766 
767 //-------------------------------------------------------------------------
getBytes(sal_Int32 columnIndex)768 Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
769     throw( SQLException, RuntimeException )
770 {
771     osl::Guard< osl::Mutex > aGuard( maMutex );
772     return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
773 }
774 
775 //-------------------------------------------------------------------------
getDate(sal_Int32 columnIndex)776 Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
777     throw( SQLException, RuntimeException )
778 {
779     osl::Guard< osl::Mutex > aGuard( maMutex );
780     return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
781 }
782 
783 //-------------------------------------------------------------------------
getTime(sal_Int32 columnIndex)784 Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
785     throw( SQLException, RuntimeException )
786 {
787     osl::Guard< osl::Mutex > aGuard( maMutex );
788     return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
789 }
790 
791 //-------------------------------------------------------------------------
getTimestamp(sal_Int32 columnIndex)792 DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
793     throw( SQLException, RuntimeException )
794 {
795     osl::Guard< osl::Mutex > aGuard( maMutex );
796     return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
797 }
798 
799 //-------------------------------------------------------------------------
800 Reference< XInputStream > SAL_CALL
getBinaryStream(sal_Int32 columnIndex)801 SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
802     throw( SQLException, RuntimeException )
803 {
804     osl::Guard< osl::Mutex > aGuard( maMutex );
805     return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
806 }
807 
808 //-------------------------------------------------------------------------
809 Reference< XInputStream > SAL_CALL
getCharacterStream(sal_Int32 columnIndex)810 SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
811     throw( SQLException, RuntimeException )
812 {
813     osl::Guard< osl::Mutex > aGuard( maMutex );
814     return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
815 }
816 
817 //-------------------------------------------------------------------------
getObject(sal_Int32 columnIndex,const Reference<XNameAccess> & typeMap)818 Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
819                        const Reference< XNameAccess >& typeMap )
820     throw( SQLException, RuntimeException )
821 {
822     osl::Guard< osl::Mutex > aGuard( maMutex );
823     return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
824                                                             typeMap);
825 }
826 
827 //-------------------------------------------------------------------------
getRef(sal_Int32 columnIndex)828 Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
829     throw( SQLException, RuntimeException )
830 {
831     osl::Guard< osl::Mutex > aGuard( maMutex );
832     return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
833 }
834 
835 //-------------------------------------------------------------------------
getBlob(sal_Int32 columnIndex)836 Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
837     throw( SQLException, RuntimeException )
838 {
839     osl::Guard< osl::Mutex > aGuard( maMutex );
840     return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
841 }
842 
843 //-------------------------------------------------------------------------
getClob(sal_Int32 columnIndex)844 Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
845     throw( SQLException, RuntimeException )
846 {
847     osl::Guard< osl::Mutex > aGuard( maMutex );
848     return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
849 }
850 
851 //-------------------------------------------------------------------------
getArray(sal_Int32 columnIndex)852 Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
853     throw( SQLException, RuntimeException )
854 {
855     osl::Guard< osl::Mutex > aGuard( maMutex );
856     return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
857 }
858 
859 
860 //--------------------------------------------------------------------------
861 // XCloseable methods.
862 //--------------------------------------------------------------------------
863 
close()864 void SAL_CALL SortedResultSet::close()
865     throw( SQLException, RuntimeException )
866 {
867     osl::Guard< osl::Mutex > aGuard( maMutex );
868     Reference< XCloseable >::query(mxOriginal)->close();
869 }
870 
871 //--------------------------------------------------------------------------
872 // XResultSetMetaDataSupplier methods.
873 //--------------------------------------------------------------------------
874 
getMetaData()875 Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData()
876     throw( SQLException, RuntimeException )
877 {
878     osl::Guard< osl::Mutex > aGuard( maMutex );
879     return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
880 }
881 
882 
883 //--------------------------------------------------------------------------
884 // XPropertySet methods.
885 //--------------------------------------------------------------------------
886 
887 Reference< XPropertySetInfo > SAL_CALL
getPropertySetInfo()888 SortedResultSet::getPropertySetInfo() throw( RuntimeException )
889 {
890     osl::Guard< osl::Mutex > aGuard( maMutex );
891 
892     if ( !mpPropSetInfo )
893     {
894         mpPropSetInfo = new SRSPropertySetInfo();
895         mpPropSetInfo->acquire();
896     }
897 
898     return Reference< XPropertySetInfo >( mpPropSetInfo );
899 }
900 
901 //--------------------------------------------------------------------------
setPropertyValue(const OUString & PropertyName,const Any &)902 void SAL_CALL SortedResultSet::setPropertyValue(
903                         const OUString& PropertyName,
904                         const Any& )
905     throw( UnknownPropertyException,
906            PropertyVetoException,
907            IllegalArgumentException,
908            WrappedTargetException,
909            RuntimeException )
910 {
911     osl::Guard< osl::Mutex > aGuard( maMutex );
912 
913     if ( ( PropertyName.compareToAscii( "RowCount" ) == 0 ) ||
914          ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 ) )
915         throw IllegalArgumentException();
916     else
917         throw UnknownPropertyException();
918 }
919 
920 //--------------------------------------------------------------------------
getPropertyValue(const OUString & PropertyName)921 Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
922     throw( UnknownPropertyException,
923            WrappedTargetException,
924            RuntimeException )
925 {
926     osl::Guard< osl::Mutex > aGuard( maMutex );
927 
928     Any aRet;
929 
930     if ( PropertyName.compareToAscii( "RowCount" ) == 0 )
931     {
932         aRet <<= maS2O.Count();
933     }
934     else if ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 )
935     {
936         sal_uInt32  nOrgCount = 0;
937         sal_Bool    bOrgFinal = false;
938         Any         aOrgRet;
939 
940         aRet <<= (sal_Bool) sal_False;
941 
942         aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
943                         getPropertyValue( PropertyName );
944         aOrgRet >>= bOrgFinal;
945 
946         if ( bOrgFinal )
947         {
948             aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
949                 getPropertyValue( OUString::createFromAscii( "RowCount" ) );
950             aOrgRet >>= nOrgCount;
951             if ( nOrgCount == maS2O.Count() )
952                 aRet <<= (sal_Bool) sal_True;
953         }
954     }
955     else
956         throw UnknownPropertyException();
957 
958     return aRet;
959 }
960 
961 //--------------------------------------------------------------------------
addPropertyChangeListener(const OUString & PropertyName,const Reference<XPropertyChangeListener> & Listener)962 void SAL_CALL SortedResultSet::addPropertyChangeListener(
963                         const OUString& PropertyName,
964                         const Reference< XPropertyChangeListener >& Listener )
965     throw( UnknownPropertyException,
966            WrappedTargetException,
967            RuntimeException )
968 {
969     osl::Guard< osl::Mutex > aGuard( maMutex );
970 
971     if ( !mpPropChangeListeners )
972         mpPropChangeListeners =
973                     new PropertyChangeListeners_Impl();
974 
975     mpPropChangeListeners->addInterface( PropertyName, Listener );
976 }
977 
978 //--------------------------------------------------------------------------
removePropertyChangeListener(const OUString & PropertyName,const Reference<XPropertyChangeListener> & Listener)979 void SAL_CALL SortedResultSet::removePropertyChangeListener(
980                         const OUString& PropertyName,
981                         const Reference< XPropertyChangeListener >& Listener )
982     throw( UnknownPropertyException,
983            WrappedTargetException,
984            RuntimeException )
985 {
986     osl::Guard< osl::Mutex > aGuard( maMutex );
987 
988     if ( mpPropChangeListeners )
989         mpPropChangeListeners->removeInterface( PropertyName, Listener );
990 }
991 
992 //--------------------------------------------------------------------------
addVetoableChangeListener(const OUString & PropertyName,const Reference<XVetoableChangeListener> & Listener)993 void SAL_CALL SortedResultSet::addVetoableChangeListener(
994                         const OUString& PropertyName,
995                         const Reference< XVetoableChangeListener >& Listener )
996     throw( UnknownPropertyException,
997            WrappedTargetException,
998            RuntimeException )
999 {
1000     osl::Guard< osl::Mutex > aGuard( maMutex );
1001 
1002     if ( !mpVetoChangeListeners )
1003         mpVetoChangeListeners =
1004                     new PropertyChangeListeners_Impl();
1005 
1006     mpVetoChangeListeners->addInterface( PropertyName, Listener );
1007 }
1008 
1009 //--------------------------------------------------------------------------
removeVetoableChangeListener(const OUString & PropertyName,const Reference<XVetoableChangeListener> & Listener)1010 void SAL_CALL SortedResultSet::removeVetoableChangeListener(
1011                         const OUString& PropertyName,
1012                         const Reference< XVetoableChangeListener >& Listener )
1013     throw( UnknownPropertyException,
1014            WrappedTargetException,
1015            RuntimeException )
1016 {
1017     osl::Guard< osl::Mutex > aGuard( maMutex );
1018 
1019     if ( mpVetoChangeListeners )
1020         mpVetoChangeListeners->removeInterface( PropertyName, Listener );
1021 }
1022 
1023 //--------------------------------------------------------------------------
1024 // private methods
1025 //--------------------------------------------------------------------------
CompareImpl(Reference<XResultSet> xResultOne,Reference<XResultSet> xResultTwo,long nIndexOne,long nIndexTwo,SortInfo * pSortInfo)1026 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1027                                    Reference < XResultSet > xResultTwo,
1028                                    long nIndexOne, long nIndexTwo,
1029                                    SortInfo* pSortInfo )
1030 
1031     throw( SQLException, RuntimeException )
1032 {
1033     Reference < XRow > xRowOne = Reference< XRow >::query( xResultOne );
1034     Reference < XRow > xRowTwo = Reference< XRow >::query( xResultTwo );
1035 
1036     long nCompare = 0;
1037     long nColumn = pSortInfo->mnColumn;
1038 
1039     switch ( pSortInfo->mnType )
1040     {
1041         case DataType::BIT :
1042         case DataType::TINYINT :
1043         case DataType::SMALLINT :
1044         case DataType::INTEGER :
1045             {
1046                 sal_Int32 aOne = 0;
1047 				sal_Int32 aTwo = 0;
1048 
1049                 if ( xResultOne->absolute( nIndexOne ) )
1050                     aOne = xRowOne->getInt( nColumn );
1051                 if ( xResultTwo->absolute( nIndexTwo ) )
1052                     aTwo = xRowTwo->getInt( nColumn );
1053 
1054                 if ( aOne < aTwo )
1055                     nCompare = -1;
1056                 else if ( aOne == aTwo )
1057                     nCompare = 0;
1058                 else
1059                     nCompare = 1;
1060 
1061                 break;
1062             }
1063         case DataType::BIGINT :
1064             {
1065                 sal_Int64 aOne = 0;
1066 				sal_Int64 aTwo = 0;
1067 
1068                 if ( xResultOne->absolute( nIndexOne ) )
1069                     aOne = xRowOne->getLong( nColumn );
1070                 if ( xResultTwo->absolute( nIndexTwo ) )
1071                     aTwo = xRowTwo->getLong( nColumn );
1072 
1073                 if ( aOne < aTwo )
1074                     nCompare = -1;
1075                 else if ( aOne == aTwo )
1076                     nCompare = 0;
1077                 else
1078                     nCompare = 1;
1079 
1080                 break;
1081             }
1082         case DataType::CHAR :
1083         case DataType::VARCHAR :
1084         case DataType::LONGVARCHAR :
1085             {
1086                 OUString aOne, aTwo;
1087 
1088                 if ( xResultOne->absolute( nIndexOne ) )
1089                     aOne = xRowOne->getString( nColumn );
1090                 if ( xResultTwo->absolute( nIndexTwo ) )
1091                     aTwo = xRowTwo->getString( nColumn );
1092 
1093                 if ( ! pSortInfo->mbCaseSensitive )
1094                 {
1095                     aOne = aOne.toAsciiLowerCase();
1096                     aTwo = aTwo.toAsciiLowerCase();
1097                 }
1098 
1099                 nCompare = aOne.compareTo( aTwo );
1100                 break;
1101             }
1102         case DataType::DATE :
1103             {
1104                 Date aOne, aTwo;
1105                 sal_Int32   nTmp;
1106 
1107                 if ( xResultOne->absolute( nIndexOne ) )
1108                     aOne = xRowOne->getDate( nColumn );
1109                 if ( xResultTwo->absolute( nIndexTwo ) )
1110                     aTwo = xRowTwo->getDate( nColumn );
1111 
1112                 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1113                 if ( !nTmp ) {
1114                     nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1115                 if ( !nTmp )
1116                     nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1117                 }
1118 
1119                 if ( nTmp < 0 )
1120                     nCompare = -1;
1121                 else if ( nTmp == 0 )
1122                     nCompare = 0;
1123                 else
1124                     nCompare = 1;
1125 
1126                 break;
1127             }
1128         case DataType::TIME :
1129             {
1130                 Time aOne, aTwo;
1131                 sal_Int32   nTmp;
1132 
1133                 if ( xResultOne->absolute( nIndexOne ) )
1134                     aOne = xRowOne->getTime( nColumn );
1135                 if ( xResultTwo->absolute( nIndexTwo ) )
1136                     aTwo = xRowTwo->getTime( nColumn );
1137 
1138                 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1139                 if ( !nTmp ) {
1140                     nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1141                 if ( !nTmp ) {
1142                     nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1143                 if ( !nTmp )
1144                     nTmp = (sal_Int32) aTwo.HundredthSeconds
1145                                     - (sal_Int32) aOne.HundredthSeconds;
1146                 }}
1147 
1148                 if ( nTmp < 0 )
1149                     nCompare = -1;
1150                 else if ( nTmp == 0 )
1151                     nCompare = 0;
1152                 else
1153                     nCompare = 1;
1154 
1155                 break;
1156             }
1157         case DataType::TIMESTAMP :
1158             {
1159                 DateTime aOne, aTwo;
1160                 sal_Int32   nTmp;
1161 
1162                 if ( xResultOne->absolute( nIndexOne ) )
1163                     aOne = xRowOne->getTimestamp( nColumn );
1164                 if ( xResultTwo->absolute( nIndexTwo ) )
1165                     aTwo = xRowTwo->getTimestamp( nColumn );
1166 
1167                 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1168                 if ( !nTmp ) {
1169                     nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1170                 if ( !nTmp ) {
1171                     nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1172                 if ( !nTmp ) {
1173                     nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1174                 if ( !nTmp ) {
1175                     nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1176                 if ( !nTmp ) {
1177                     nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1178                 if ( !nTmp )
1179                     nTmp = (sal_Int32) aTwo.HundredthSeconds
1180                                     - (sal_Int32) aOne.HundredthSeconds;
1181                 }}}}}
1182 
1183                 if ( nTmp < 0 )
1184                     nCompare = -1;
1185                 else if ( nTmp == 0 )
1186                     nCompare = 0;
1187                 else
1188                     nCompare = 1;
1189 
1190                 break;
1191             }
1192         case DataType::REAL :
1193             {
1194                 float aOne = 0;
1195 				float aTwo = 0;
1196 
1197                 if ( xResultOne->absolute( nIndexOne ) )
1198                     aOne = xRowOne->getFloat( nColumn );
1199                 if ( xResultTwo->absolute( nIndexTwo ) )
1200                     aTwo = xRowTwo->getFloat( nColumn );
1201 
1202                 if ( aOne < aTwo )
1203                     nCompare = -1;
1204                 else if ( aOne == aTwo )
1205                     nCompare = 0;
1206                 else
1207                     nCompare = 1;
1208 
1209                 break;
1210             }
1211         case DataType::FLOAT :
1212         case DataType::DOUBLE :
1213             {
1214                 double aOne = 0;
1215 				double aTwo = 0;
1216 
1217                 if ( xResultOne->absolute( nIndexOne ) )
1218                     aOne = xRowOne->getDouble( nColumn );
1219                 if ( xResultTwo->absolute( nIndexTwo ) )
1220                     aTwo = xRowTwo->getDouble( nColumn );
1221 
1222                 if ( aOne < aTwo )
1223                     nCompare = -1;
1224                 else if ( aOne == aTwo )
1225                     nCompare = 0;
1226                 else
1227                     nCompare = 1;
1228 
1229                 break;
1230             }
1231         default:
1232             {
1233                 OSL_ENSURE( sal_False, "DataType not supported for compare!" );
1234             }
1235     }
1236 
1237     return nCompare;
1238 }
1239 
1240 //--------------------------------------------------------------------------
CompareImpl(Reference<XResultSet> xResultOne,Reference<XResultSet> xResultTwo,long nIndexOne,long nIndexTwo)1241 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1242                                    Reference < XResultSet > xResultTwo,
1243                                    long nIndexOne, long nIndexTwo )
1244     throw( SQLException, RuntimeException )
1245 {
1246     long        nCompare = 0;
1247     SortInfo*   pInfo = mpSortInfo;
1248 
1249     while ( !nCompare && pInfo )
1250     {
1251         if ( pInfo->mbUseOwnCompare )
1252         {
1253             nCompare = CompareImpl( xResultOne, xResultTwo,
1254                                     nIndexOne, nIndexTwo, pInfo );
1255         }
1256         else
1257         {
1258             Any aOne, aTwo;
1259 
1260             Reference < XRow > xRowOne =
1261                             Reference< XRow >::query( xResultOne );
1262             Reference < XRow > xRowTwo =
1263                             Reference< XRow >::query( xResultTwo );
1264 
1265             if ( xResultOne->absolute( nIndexOne ) )
1266                 aOne = xRowOne->getObject( pInfo->mnColumn, NULL );
1267             if ( xResultTwo->absolute( nIndexTwo ) )
1268                 aTwo = xRowTwo->getObject( pInfo->mnColumn, NULL );
1269 
1270             nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
1271         }
1272 
1273         if ( ! pInfo->mbAscending )
1274             nCompare = - nCompare;
1275 
1276         pInfo = pInfo->mpNext;
1277     }
1278 
1279     return nCompare;
1280 }
1281 
1282 //--------------------------------------------------------------------------
Compare(SortListData * pOne,SortListData * pTwo)1283 long SortedResultSet::Compare( SortListData *pOne,
1284                                SortListData *pTwo )
1285     throw( SQLException, RuntimeException )
1286 {
1287     long nIndexOne;
1288     long nIndexTwo;
1289 
1290     Reference < XResultSet > xResultOne;
1291     Reference < XResultSet > xResultTwo;
1292 
1293     if ( pOne->mbModified )
1294     {
1295         xResultOne = mxOther;
1296         nIndexOne = pOne->mnOldPos;
1297     }
1298     else
1299     {
1300         xResultOne = mxOriginal;
1301         nIndexOne = pOne->mnCurPos;
1302     }
1303 
1304     if ( pTwo->mbModified )
1305     {
1306         xResultTwo = mxOther;
1307         nIndexTwo = pTwo->mnOldPos;
1308     }
1309     else
1310     {
1311         xResultTwo = mxOriginal;
1312         nIndexTwo = pTwo->mnCurPos;
1313     }
1314 
1315     long nCompare;
1316     nCompare = CompareImpl( xResultOne, xResultTwo,
1317                             nIndexOne, nIndexTwo );
1318     return nCompare;
1319 }
1320 
1321 //--------------------------------------------------------------------------
FindPos(SortListData * pEntry,long _nStart,long _nEnd)1322 long SortedResultSet::FindPos( SortListData *pEntry,
1323                                long _nStart, long _nEnd )
1324     throw( SQLException, RuntimeException )
1325 {
1326     if ( _nStart > _nEnd )
1327         return _nStart + 1;
1328 
1329     long nStart = _nStart;
1330     long nEnd   = _nEnd;
1331     long nMid = 0, nCompare = 0;
1332 
1333     SortListData    *pMid;
1334 
1335     while ( nStart <= nEnd )
1336     {
1337         nMid = ( nEnd - nStart ) / 2 + nStart;
1338         pMid = maS2O.GetData( nMid );
1339         nCompare = Compare( pEntry, pMid );
1340 
1341         if ( !nCompare )
1342             nCompare = ((long) pEntry ) - ( (long) pMid );
1343 
1344         if ( nCompare < 0 ) // pEntry < pMid
1345             nEnd = nMid - 1;
1346         else
1347             nStart = nMid + 1;
1348     }
1349 
1350     if ( nCompare < 0 )     // pEntry < pMid
1351         return nMid;
1352     else
1353         return nMid+1;
1354 }
1355 
1356 //--------------------------------------------------------------------------
PropertyChanged(const PropertyChangeEvent & rEvt)1357 void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
1358 {
1359     osl::Guard< osl::Mutex > aGuard( maMutex );
1360 
1361     if ( !mpPropChangeListeners )
1362         return;
1363 
1364     // Notify listeners interested especially in the changed property.
1365     OInterfaceContainerHelper* pPropsContainer =
1366             mpPropChangeListeners->getContainer( rEvt.PropertyName );
1367     if ( pPropsContainer )
1368     {
1369         OInterfaceIteratorHelper aIter( *pPropsContainer );
1370         while ( aIter.hasMoreElements() )
1371         {
1372             Reference< XPropertyChangeListener > xListener(
1373                                                     aIter.next(), UNO_QUERY );
1374             if ( xListener.is() )
1375                 xListener->propertyChange( rEvt );
1376         }
1377     }
1378 
1379     // Notify listeners interested in all properties.
1380     pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
1381     if ( pPropsContainer )
1382     {
1383         OInterfaceIteratorHelper aIter( *pPropsContainer );
1384         while ( aIter.hasMoreElements() )
1385         {
1386             Reference< XPropertyChangeListener > xListener(
1387                                                     aIter.next(), UNO_QUERY );
1388             if ( xListener.is() )
1389                 xListener->propertyChange( rEvt );
1390         }
1391     }
1392 }
1393 
1394 //-------------------------------------------------------------------------
1395 
1396 //--------------------------------------------------------------------------
1397 // public methods
1398 //--------------------------------------------------------------------------
1399 
CopyData(SortedResultSet * pSource)1400 void SortedResultSet::CopyData( SortedResultSet *pSource )
1401 {
1402     const SortedEntryList *pSrcS2O = pSource->GetS2OList();
1403     const SimpleList      *pSrcO2S = pSource->GetO2SList();
1404 
1405     long i, nCount;
1406 
1407     maS2O.Clear();
1408     maO2S.Clear();
1409     maModList.Clear();
1410 
1411     maS2O.Insert( NULL, 0 );
1412     maO2S.Insert( 0, (sal_uInt32) 0 );  // value, pos
1413 
1414     nCount = pSrcS2O->Count();
1415 
1416     for ( i=1; i<nCount; i++ )
1417     {
1418         maS2O.Insert( new SortListData( (*pSrcS2O)[ i ] ), i );
1419         maO2S.Insert( pSrcO2S->GetObject( i ), (sal_uInt32) i );
1420     }
1421 
1422     mnLastSort = maS2O.Count();
1423     mxOther = pSource->GetResultSet();
1424 
1425     if ( !mpSortInfo )
1426     {
1427         mpSortInfo = pSource->GetSortInfo();
1428         mbIsCopy = sal_True;
1429     }
1430 }
1431 
1432 //--------------------------------------------------------------------------
Initialize(const Sequence<NumberedSortingInfo> & xSortInfo,const Reference<XAnyCompareFactory> & xCompFactory)1433 void SortedResultSet::Initialize(
1434                 const Sequence < NumberedSortingInfo > &xSortInfo,
1435                 const Reference< XAnyCompareFactory > &xCompFactory )
1436 {
1437     BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
1438     // Insert dummy at pos 0
1439     SortListData *pData = new SortListData( 0 );
1440     maS2O.Insert( pData, 0 );
1441 
1442     long nIndex = 1;
1443 
1444     // now fetch all the elements from the original result set,
1445     // get there new position in the sorted result set and insert
1446     // an entry in the sorted to original mapping list
1447     try {
1448         while ( mxOriginal->absolute( nIndex ) )
1449         {
1450             pData       = new SortListData( nIndex );
1451             long nPos   = FindPos( pData, 1, nIndex-1 );
1452 
1453             maS2O.Insert( pData, nPos );
1454 
1455             nIndex++;
1456         }
1457     }
1458     catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::Initialize() : Got unexpected SQLException" ); }
1459 
1460     // when we have fetched all the elements, we can create the
1461     // original to sorted mapping list from the s2o list
1462     maO2S.Clear();
1463     maO2S.Insert( NULL, (sal_uInt32) 0 );
1464 
1465     // insert some dummy entries first and replace then
1466     // the entries with the right ones
1467     sal_uInt32 i;
1468 
1469     for ( i=1; i<maS2O.Count(); i++ )
1470         maO2S.Insert( (void*) 0, i );   // Insert( data, pos )
1471     for ( i=1; i<maS2O.Count(); i++ )
1472         maO2S.Replace( (void*) i, maS2O[ i ] ); // Insert( data, pos )
1473 
1474     mnCount = maS2O.Count() - 1;
1475 }
1476 
1477 //--------------------------------------------------------------------------
CheckProperties(long nOldCount,sal_Bool bWasFinal)1478 void SortedResultSet::CheckProperties( long nOldCount, sal_Bool bWasFinal )
1479 {
1480     osl::Guard< osl::Mutex > aGuard( maMutex );
1481 
1482     if ( !mpPropChangeListeners )
1483         return;
1484 
1485     try {
1486         // check for propertyChangeEvents
1487         if ( nOldCount != GetCount() )
1488         {
1489             sal_Bool bIsFinal = sal_False;
1490             PropertyChangeEvent aEvt;
1491 
1492             aEvt.PropertyName = OUString::createFromAscii( "RowCount" );
1493             aEvt.Further = sal_False;
1494             aEvt.PropertyHandle = -1;
1495             aEvt.OldValue <<= nOldCount;
1496             aEvt.NewValue <<= GetCount();
1497 
1498             PropertyChanged( aEvt );
1499 
1500             OUString aName = OUString::createFromAscii( "IsRowCountFinal" );
1501             Any aRet = getPropertyValue( aName );
1502             if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
1503             {
1504                 aEvt.PropertyName = aName;
1505                 aEvt.Further = sal_False;
1506                 aEvt.PropertyHandle = -1;
1507                 aEvt.OldValue <<= (sal_Bool) bWasFinal;
1508                 aEvt.NewValue <<= (sal_Bool) bIsFinal;
1509                 PropertyChanged( aEvt );
1510             }
1511         }
1512     }
1513     catch ( UnknownPropertyException ) {}
1514     catch ( WrappedTargetException ) {}
1515 }
1516 
1517 //-------------------------------------------------------------------------
InsertNew(long nPos,long nCount)1518 void SortedResultSet::InsertNew( long nPos, long nCount )
1519 {
1520     // in der maS2O Liste alle Eintr�ge, die >= nPos sind, um nCount
1521     // erh�hen
1522     SortListData    *pData;
1523     long            i, nEnd;
1524 
1525     nEnd = maS2O.Count();
1526     for ( i=1; i<=nEnd; i++ )
1527     {
1528         pData = maS2O.GetData( i );
1529         if ( pData->mnCurPos >= nPos )
1530         {
1531             pData->mnCurPos += nCount;
1532         }
1533     }
1534 
1535     // und die neuen eintr�ge hinten an die maS2O Liste anh�ngen bzw
1536     // an der Position nPos in der maO2S Liste einf�gen
1537     for ( i=0; i<nCount; i++ )
1538     {
1539         nEnd += 1;
1540         pData = new SortListData( nEnd );
1541 
1542         maS2O.Insert( pData, nEnd );    // Insert( Wert, Position )
1543         maO2S.Insert( (void*)nEnd, (sal_uInt32)(nPos+i) );  // Insert( Wert, Position )
1544     }
1545 
1546     mnCount += nCount;
1547 }
1548 
1549 //-------------------------------------------------------------------------
Remove(long nPos,long nCount,EventList * pEvents)1550 void SortedResultSet::Remove( long nPos, long nCount, EventList *pEvents )
1551 {
1552     sal_uInt32  i, j;
1553     long        nOldLastSort;
1554 
1555     // correct mnLastSort first
1556     nOldLastSort = mnLastSort;
1557     if ( nPos <= mnLastSort )
1558     {
1559         if ( nPos + nCount - 1 <= mnLastSort )
1560             mnLastSort -= nCount;
1561         else
1562             mnLastSort = nPos - 1;
1563     }
1564 
1565     // remove the entries from the lists and correct the positions
1566     // in the original2sorted list
1567     for ( i=0; i < (sal_uInt32) nCount; i++ )
1568     {
1569         long nSortPos = (long) maO2S.GetObject( nPos );
1570         maO2S.Remove( (sal_uInt32) nPos );
1571 
1572         for ( j=1; j<=maO2S.Count(); j++ )
1573         {
1574             long nVal = (long) maO2S.GetObject( j );
1575             if ( nVal > nSortPos )
1576             {
1577                 --nVal;
1578                 maO2S.Replace( (void*) nVal, j );
1579             }
1580         }
1581 
1582         SortListData *pData = maS2O.Remove( nSortPos );
1583         if ( pData->mbModified )
1584             maModList.Remove( (void*) pData );
1585         delete pData;
1586 
1587         // generate remove Event, but not for new entries
1588         if ( nSortPos <= nOldLastSort )
1589             pEvents->AddEvent( ListActionType::REMOVED, nSortPos, 1 );
1590     }
1591 
1592     // correct the positions in the sorted list
1593     for ( i=1; i<= maS2O.Count(); i++ )
1594     {
1595         SortListData *pData = maS2O.GetData( i );
1596         if ( pData->mnCurPos > nPos )
1597             pData->mnCurPos -= nCount;
1598     }
1599 
1600     mnCount -= nCount;
1601 }
1602 
1603 //-------------------------------------------------------------------------
Move(long nPos,long nCount,long nOffset)1604 void SortedResultSet::Move( long nPos, long nCount, long nOffset )
1605 {
1606     if ( !nOffset )
1607         return;
1608 
1609     long i, nSortPos, nTo;
1610     SortListData *pData;
1611 
1612     for ( i=0; i<nCount; i++ )
1613     {
1614         nSortPos = (long) maO2S.GetObject( nPos+i );
1615         pData = maS2O.GetData( nSortPos );
1616         pData->mnCurPos += nOffset;
1617     }
1618 
1619     if ( nOffset < 0 )
1620     {
1621         for ( i=nPos+nOffset; i<nPos; i++ )
1622         {
1623             nSortPos = (long) maO2S.GetObject( i );
1624             pData = maS2O.GetData( nSortPos );
1625             pData->mnCurPos += nCount;
1626         }
1627     }
1628     else
1629     {
1630         long nStart = nPos + nCount;
1631         long nEnd = nStart + nOffset;
1632         for ( i=nStart; i<nEnd; i++ )
1633         {
1634             nSortPos = (long) maO2S.GetObject( i );
1635             pData = maS2O.GetData( nSortPos );
1636             pData->mnCurPos -= nCount;
1637         }
1638     }
1639 
1640     // remember the to be moved entries
1641     long *pTmpArr = new long[ nCount ];
1642     for ( i=0; i<nCount; i++ )
1643         pTmpArr[i] = (long)maO2S.GetObject( (sal_uInt32)( nPos+i ) );
1644 
1645     // now move the entries, which are in the way
1646     if ( nOffset < 0 )
1647     {
1648         // be carefully here, because nOffset is negative here, so an
1649         // addition is a subtraction
1650         long nFrom = nPos - 1;
1651         nTo = nPos + nCount - 1;
1652 
1653         // same for i here
1654         for ( i=0; i>nOffset; i-- )
1655         {
1656             long nVal = (long) maO2S.GetObject( (sal_uInt32)( nFrom+i ) );
1657             maO2S.Replace( (void*) nVal, (sal_uInt32)( nTo+i ) );
1658         }
1659 
1660     }
1661     else
1662     {
1663         long nStart = nPos + nCount;
1664         for ( i=0; i<nOffset; i++ )
1665         {
1666             long nVal = (long) maO2S.GetObject( (sal_uInt32)( nStart+i ) );
1667             maO2S.Replace( (void*) nVal, (sal_uInt32)( nPos+i ) );
1668         }
1669     }
1670 
1671     // finally put the remembered entries at there new location
1672     nTo = nPos + nOffset;
1673     for ( i=0; i<nCount; i++ )
1674     {
1675         maO2S.Replace( (void*)pTmpArr[ i ], (sal_uInt32)( nTo+i ) );
1676     }
1677 
1678     delete [] pTmpArr;
1679 }
1680 
1681 //--------------------------------------------------------------------------
BuildSortInfo(Reference<XResultSet> aResult,const Sequence<NumberedSortingInfo> & xSortInfo,const Reference<XAnyCompareFactory> & xCompFactory)1682 void SortedResultSet::BuildSortInfo(
1683                 Reference< XResultSet > aResult,
1684                 const Sequence < NumberedSortingInfo > &xSortInfo,
1685                 const Reference< XAnyCompareFactory > &xCompFactory )
1686 {
1687     Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
1688 
1689     if ( ! xMeta.is() )
1690     {
1691         OSL_ENSURE( sal_False, "No MetaData, No Sorting!" );
1692         return;
1693     }
1694 
1695     Reference < XResultSetMetaData > xData = xMeta->getMetaData();
1696     const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
1697 
1698     sal_Int32   nColumn;
1699     OUString    aPropName;
1700     SortInfo    *pInfo;
1701 
1702     for ( long i=xSortInfo.getLength(); i > 0; )
1703     {
1704         --i;
1705         nColumn = pSortInfo[ i ].ColumnIndex;
1706         aPropName = xData->getColumnName( nColumn );
1707         pInfo = new SortInfo;
1708 
1709         if ( xCompFactory.is() )
1710             pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
1711                                             aPropName );
1712 
1713         if ( pInfo->mxCompareFunction.is() )
1714         {
1715             pInfo->mbUseOwnCompare = sal_False;
1716             pInfo->mnType = 0;
1717         }
1718         else
1719         {
1720             pInfo->mbUseOwnCompare = sal_True;
1721             pInfo->mnType = xData->getColumnType( nColumn );
1722         }
1723 
1724         pInfo->mnColumn = nColumn;
1725         pInfo->mbAscending = pSortInfo[ i ].Ascending;
1726         pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
1727         pInfo->mpNext = mpSortInfo;
1728         mpSortInfo = pInfo;
1729     }
1730 }
1731 
1732 //-------------------------------------------------------------------------
SetChanged(long nPos,long nCount)1733 void SortedResultSet::SetChanged( long nPos, long nCount )
1734 {
1735     for ( long i=0; i<nCount; i++ )
1736     {
1737         long nSortPos = (long) maO2S.GetObject( nPos );
1738         if ( nSortPos < mnLastSort )
1739         {
1740             SortListData *pData = maS2O.GetData( nSortPos );
1741             if ( ! pData->mbModified )
1742             {
1743                 pData->mbModified = sal_True;
1744                 maModList.Append( pData );
1745             }
1746         }
1747         nPos += 1;
1748     }
1749 }
1750 
1751 //-------------------------------------------------------------------------
ResortModified(EventList * pList)1752 void SortedResultSet::ResortModified( EventList* pList )
1753 {
1754     sal_uInt32 i, j;
1755     long nCompare, nCurPos, nNewPos;
1756     long nStart, nEnd, nOffset, nVal;
1757     SortListData *pData;
1758     ListAction *pAction;
1759 
1760     try {
1761         for ( i=0; i<maModList.Count(); i++ )
1762         {
1763             pData = (SortListData*) maModList.GetObject( i );
1764             nCompare = CompareImpl( mxOther, mxOriginal,
1765                                     pData->mnOldPos, pData->mnCurPos );
1766             pData->mbModified = sal_False;
1767             if ( nCompare != 0 )
1768             {
1769                 nCurPos = (long) maO2S.GetObject( (sal_uInt32) pData->mnCurPos );
1770                 if ( nCompare < 0 )
1771                 {
1772                     nNewPos = FindPos( pData, 1, nCurPos-1 );
1773                     nStart = nNewPos;
1774                     nEnd = nCurPos;
1775                     nOffset = 1;
1776                 }
1777                 else
1778                 {
1779                     nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
1780                     nStart = nCurPos;
1781                     nEnd = mnLastSort;
1782                     nOffset = -1;
1783                 }
1784 
1785                 if ( nNewPos != nCurPos )
1786                 {
1787                     // correct the lists!
1788                     maS2O.Remove( (sal_uInt32) nCurPos );
1789                     maS2O.Insert( pData, nNewPos );
1790                         for ( j=1; j<maO2S.Count(); j++ )
1791                     {
1792                         nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
1793                         if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
1794                         {
1795                             nVal += nOffset;
1796                             maO2S.Replace( (void*) (nVal), (sal_uInt32)( j ) );
1797                         }
1798                     }
1799 
1800                     maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1801 
1802                     pAction = new ListAction;
1803                     pAction->Position = nCurPos;
1804                     pAction->Count = 1;
1805                     pAction->ListActionType = ListActionType::MOVED;
1806                     pAction->ActionInfo <<= nNewPos-nCurPos;
1807                     pList->Insert( pAction );
1808                 }
1809                 pList->AddEvent( ListActionType::PROPERTIES_CHANGED,
1810                                  nNewPos, 1 );
1811             }
1812         }
1813     }
1814     catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortModified() : Got unexpected SQLException" ); }
1815 
1816     maModList.Clear();
1817 }
1818 
1819 //-------------------------------------------------------------------------
ResortNew(EventList * pList)1820 void SortedResultSet::ResortNew( EventList* pList )
1821 {
1822     long            i, j, nNewPos, nVal;
1823     SortListData    *pData;
1824 
1825     try {
1826         for ( i = mnLastSort; i<(long)maS2O.Count(); i++ )
1827         {
1828             pData = (SortListData*) maModList.GetObject( i );
1829             nNewPos = FindPos( pData, 1, mnLastSort );
1830             if ( nNewPos != i )
1831             {
1832                 maS2O.Remove( (sal_uInt32) i );
1833                 maS2O.Insert( pData, nNewPos );
1834                 // maO2S liste korigieren
1835                 for ( j=1; j<(long)maO2S.Count(); j++ )
1836                 {
1837                     nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
1838                     if ( nVal >= nNewPos )
1839                         maO2S.Replace( (void*) (nVal+1), (sal_uInt32)( j ) );
1840                 }
1841                 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1842             }
1843             mnLastSort++;
1844             pList->AddEvent( ListActionType::INSERTED, nNewPos, 1 );
1845         }
1846     }
1847     catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortNew() : Got unexpected SQLException" ); }
1848 }
1849 
1850 //-------------------------------------------------------------------------
1851 //
1852 // SortListData
1853 //
1854 //-------------------------------------------------------------------------
SortListData(long nPos,sal_Bool bModified)1855 SortListData::SortListData( long nPos, sal_Bool bModified )
1856 {
1857     mbModified = bModified;
1858     mnCurPos = nPos;
1859     mnOldPos = nPos;
1860 };
1861 
1862 
1863 //=========================================================================
Clear()1864 void SortedEntryList::Clear()
1865 {
1866     for ( std::deque< LISTACTION* >::size_type i = 0;
1867           i < maData.size(); ++i )
1868     {
1869         delete maData[i];
1870     }
1871 
1872     maData.clear();
1873 }
1874 
1875 //-------------------------------------------------------------------------
Insert(SortListData * pEntry,long nPos)1876 void SortedEntryList::Insert( SortListData *pEntry, long nPos )
1877 {
1878     if ( nPos < (long) maData.size() )
1879         maData.insert( maData.begin() + nPos, pEntry );
1880     else
1881         maData.push_back( pEntry );
1882 }
1883 
1884 //-------------------------------------------------------------------------
Remove(long nPos)1885 SortListData* SortedEntryList::Remove( long nPos )
1886 {
1887     SortListData *pData;
1888 
1889     if ( nPos < (long) maData.size() )
1890     {
1891         pData = maData[ nPos ];
1892         maData.erase( maData.begin() + nPos );
1893     }
1894     else
1895         pData = NULL;
1896 
1897     return pData;
1898 }
1899 
1900 //-------------------------------------------------------------------------
GetData(long nPos)1901 SortListData* SortedEntryList::GetData( long nPos )
1902 {
1903     SortListData *pData;
1904 
1905     if ( nPos < (long) maData.size() )
1906         pData = maData[ nPos ];
1907     else
1908         pData = NULL;
1909 
1910     return pData;
1911 }
1912 
1913 //-------------------------------------------------------------------------
operator [](long nPos) const1914 long SortedEntryList::operator [] ( long nPos ) const
1915 {
1916     SortListData *pData;
1917 
1918     if ( nPos < (long) maData.size() )
1919         pData = maData[ nPos ];
1920     else
1921         pData = NULL;
1922 
1923     if ( pData )
1924         if ( ! pData->mbModified )
1925             return pData->mnCurPos;
1926         else
1927         {
1928             OSL_ENSURE( sal_False, "SortedEntryList: Can't get value for modified entry!");
1929             return 0;
1930         }
1931     else
1932     {
1933         OSL_ENSURE( sal_False, "SortedEntryList: invalid pos!");
1934         return 0;
1935     }
1936 }
1937 
1938 //-------------------------------------------------------------------------
1939 //-------------------------------------------------------------------------
1940 //-------------------------------------------------------------------------
Remove(sal_uInt32 nPos)1941 void SimpleList::Remove( sal_uInt32 nPos )
1942 {
1943     if ( nPos < (sal_uInt32) maData.size() )
1944     {
1945         maData.erase( maData.begin() + nPos );
1946     }
1947 }
1948 
1949 //-------------------------------------------------------------------------
Remove(void * pData)1950 void SimpleList::Remove( void* pData )
1951 {
1952     sal_Bool    bFound = sal_False;
1953     sal_uInt32  i;
1954 
1955     for ( i = 0; i < (sal_uInt32) maData.size(); i++ )
1956     {
1957         if ( maData[ i ] == pData )
1958         {
1959             bFound = sal_True;
1960             break;
1961         }
1962     }
1963 
1964     if ( bFound )
1965         maData.erase( maData.begin() + i );
1966 }
1967 
1968 //-------------------------------------------------------------------------
Insert(void * pData,sal_uInt32 nPos)1969 void SimpleList::Insert( void* pData, sal_uInt32 nPos )
1970 {
1971     if ( nPos < (sal_uInt32) maData.size() )
1972         maData.insert( maData.begin() + nPos, pData );
1973     else
1974         maData.push_back( pData );
1975 }
1976 
1977 //-------------------------------------------------------------------------
GetObject(sal_uInt32 nPos) const1978 void* SimpleList::GetObject( sal_uInt32 nPos ) const
1979 {
1980     if ( nPos < (sal_uInt32) maData.size() )
1981         return maData[ nPos ];
1982     else
1983         return NULL;
1984 }
1985 
1986 //-------------------------------------------------------------------------
Replace(void * pData,sal_uInt32 nPos)1987 void SimpleList::Replace( void* pData, sal_uInt32 nPos )
1988 {
1989     if ( nPos < (sal_uInt32) maData.size() )
1990         maData[ nPos ] = pData;
1991 }
1992 
1993 //-------------------------------------------------------------------------
1994 //
1995 // class SRSPropertySetInfo.
1996 //
1997 //-------------------------------------------------------------------------
1998 
SRSPropertySetInfo()1999 SRSPropertySetInfo::SRSPropertySetInfo()
2000 {
2001     maProps[0].Name = OUString::createFromAscii( "RowCount" );
2002     maProps[0].Handle = -1;
2003     maProps[0].Type = ::getCppuType( (const OUString*) NULL );
2004     maProps[0].Attributes = -1;
2005 
2006     maProps[1].Name = OUString::createFromAscii( "IsRowCountFinal" );
2007     maProps[1].Handle = -1;
2008     maProps[1].Type = ::getBooleanCppuType();
2009     maProps[1].Attributes = -1;
2010 }
2011 
2012 //-------------------------------------------------------------------------
~SRSPropertySetInfo()2013 SRSPropertySetInfo::~SRSPropertySetInfo()
2014 {}
2015 
2016 //-------------------------------------------------------------------------
2017 // XInterface methods.
2018 //-------------------------------------------------------------------------
2019 
2020 XINTERFACE_IMPL_2( SRSPropertySetInfo,
2021                    XTypeProvider,
2022                    XPropertySetInfo );
2023 
2024 //-------------------------------------------------------------------------
2025 // XTypeProvider methods.
2026 //-------------------------------------------------------------------------
2027 
2028 XTYPEPROVIDER_IMPL_2( SRSPropertySetInfo,
2029                       XTypeProvider,
2030                       XPropertySetInfo );
2031 
2032 //-------------------------------------------------------------------------
2033 // XPropertySetInfo methods.
2034 //-------------------------------------------------------------------------
2035 Sequence< Property > SAL_CALL
getProperties()2036 SRSPropertySetInfo::getProperties() throw( RuntimeException )
2037 {
2038     return Sequence < Property > ( maProps, 2 );
2039 }
2040 
2041 //-------------------------------------------------------------------------
2042 Property SAL_CALL
getPropertyByName(const OUString & Name)2043 SRSPropertySetInfo::getPropertyByName( const OUString& Name )
2044     throw( UnknownPropertyException, RuntimeException )
2045 {
2046     if ( Name.compareToAscii( "RowCount" ) == 0 )
2047         return maProps[0];
2048     else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
2049         return maProps[1];
2050     else
2051         throw UnknownPropertyException();
2052 }
2053 
2054 //-------------------------------------------------------------------------
2055 sal_Bool SAL_CALL
hasPropertyByName(const OUString & Name)2056 SRSPropertySetInfo::hasPropertyByName( const OUString& Name )
2057     throw( RuntimeException )
2058 {
2059     if ( Name.compareToAscii( "RowCount" ) == 0 )
2060         return sal_True;
2061     else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
2062         return sal_True;
2063     else
2064         return sal_False;
2065 }
2066 
2067