diff options
Diffstat (limited to 'ucb/source/sorter/sortresult.cxx')
-rw-r--r-- | ucb/source/sorter/sortresult.cxx | 1778 |
1 files changed, 1778 insertions, 0 deletions
diff --git a/ucb/source/sorter/sortresult.cxx b/ucb/source/sorter/sortresult.cxx new file mode 100644 index 000000000..e5b7ce746 --- /dev/null +++ b/ucb/source/sorter/sortresult.cxx @@ -0,0 +1,1778 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "sortresult.hxx" +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/SQLException.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/ucb/ListActionType.hpp> +#include <com/sun/star/ucb/XAnyCompare.hpp> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <tools/diagnose_ex.h> +#include <memory> + +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace com::sun::star::io; +using namespace com::sun::star::lang; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; +using namespace com::sun::star::util; +using namespace comphelper; +using namespace cppu; + + +// The mutex to synchronize access to containers. +static osl::Mutex& getContainerMutex() +{ + static osl::Mutex ourMutex; + + return ourMutex; +} + + +struct SortInfo +{ + bool mbUseOwnCompare; + bool mbAscending; + bool mbCaseSensitive; + sal_Int32 mnColumn; + sal_Int32 mnType; + SortInfo* mpNext; + Reference < XAnyCompare > mxCompareFunction; +}; + + +struct SortListData +{ + bool mbModified; + sal_IntPtr mnCurPos; + sal_IntPtr mnOldPos; + + explicit SortListData( sal_IntPtr nPos ); +}; + + + + +class SRSPropertySetInfo : public cppu::WeakImplHelper < + XPropertySetInfo > +{ + Property maProps[2]; + +private: + +public: + SRSPropertySetInfo(); + + // XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties() override; + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) override; + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override; +}; + + +SortedResultSet::SortedResultSet( Reference< XResultSet > const & aResult ) +{ + mpDisposeEventListeners = nullptr; + mpPropChangeListeners = nullptr; + mpVetoChangeListeners = nullptr; + + mxOriginal = aResult; + mpSortInfo = nullptr; + mnLastSort = 0; + mnCurEntry = 0; + mnCount = 0; + mbIsCopy = false; +} + + +SortedResultSet::~SortedResultSet() +{ + mxOriginal.clear(); + mxOther.clear(); + + if ( !mbIsCopy ) + { + SortInfo *pInfo = mpSortInfo; + while ( pInfo ) + { + mpSortInfo = pInfo->mpNext; + delete pInfo; + pInfo = mpSortInfo; + } + } + + mpSortInfo = nullptr; + + mpPropSetInfo.clear(); +} + + +// XServiceInfo methods. + +OUString SAL_CALL SortedResultSet::getImplementationName() +{ + return "com.sun.star.comp.ucb.SortedResultSet"; +} + +sal_Bool SAL_CALL SortedResultSet::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +css::uno::Sequence< OUString > SAL_CALL SortedResultSet::getSupportedServiceNames() +{ + return { RESULTSET_SERVICE_NAME }; +} + + +// XComponent methods. + +void SAL_CALL SortedResultSet::dispose() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() ) + { + EventObject aEvt; + aEvt.Source = static_cast< XComponent * >( this ); + mpDisposeEventListeners->disposeAndClear( aEvt ); + } + + if ( mpPropChangeListeners ) + { + EventObject aEvt; + aEvt.Source = static_cast< XPropertySet * >( this ); + mpPropChangeListeners->disposeAndClear( aEvt ); + } + + if ( mpVetoChangeListeners ) + { + EventObject aEvt; + aEvt.Source = static_cast< XPropertySet * >( this ); + mpVetoChangeListeners->disposeAndClear( aEvt ); + } + + mxOriginal.clear(); + mxOther.clear(); +} + + +void SAL_CALL SortedResultSet::addEventListener( + const Reference< XEventListener >& Listener ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( !mpDisposeEventListeners ) + mpDisposeEventListeners = + new OInterfaceContainerHelper3<XEventListener>( getContainerMutex() ); + + mpDisposeEventListeners->addInterface( Listener ); +} + + +void SAL_CALL SortedResultSet::removeEventListener( + const Reference< XEventListener >& Listener ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( mpDisposeEventListeners ) + mpDisposeEventListeners->removeInterface( Listener ); +} + + +// XContentAccess methods. + + +OUString SAL_CALL +SortedResultSet::queryContentIdentifierString() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString(); +} + + +Reference< XContentIdentifier > SAL_CALL +SortedResultSet::queryContentIdentifier() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier(); +} + + +Reference< XContent > SAL_CALL +SortedResultSet::queryContent() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XContentAccess >::query(mxOriginal)->queryContent(); +} + + +// XResultSet methods. + +sal_Bool SAL_CALL SortedResultSet::next() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + mnCurEntry++; + + if ( mnCurEntry > 0 ) + { + if ( mnCurEntry <= mnCount ) + { + sal_Int32 nIndex = maS2O[ mnCurEntry ]; + return mxOriginal->absolute( nIndex ); + } + else + { + mnCurEntry = mnCount + 1; + } + } + return false; +} + + +sal_Bool SAL_CALL SortedResultSet::isBeforeFirst() +{ + if ( mnCurEntry ) + return false; + else + return true; +} + + +sal_Bool SAL_CALL SortedResultSet::isAfterLast() +{ + if ( mnCurEntry > mnCount ) + return true; + else + return false; +} + + +sal_Bool SAL_CALL SortedResultSet::isFirst() +{ + if ( mnCurEntry == 1 ) + return true; + else + return false; +} + + +sal_Bool SAL_CALL SortedResultSet::isLast() +{ + if ( mnCurEntry == mnCount ) + return true; + else + return false; +} + + +void SAL_CALL SortedResultSet::beforeFirst() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + mnCurEntry = 0; + mxOriginal->beforeFirst(); +} + + +void SAL_CALL SortedResultSet::afterLast() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + mnCurEntry = mnCount+1; + mxOriginal->afterLast(); +} + + +sal_Bool SAL_CALL SortedResultSet::first() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( mnCount ) + { + mnCurEntry = 1; + sal_Int32 nIndex = maS2O[ mnCurEntry ]; + return mxOriginal->absolute( nIndex ); + } + else + { + mnCurEntry = 0; + return false; + } +} + + +sal_Bool SAL_CALL SortedResultSet::last() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( mnCount ) + { + mnCurEntry = mnCount; + sal_Int32 nIndex = maS2O[ mnCurEntry ]; + return mxOriginal->absolute( nIndex ); + } + else + { + mnCurEntry = 0; + return false; + } +} + + +sal_Int32 SAL_CALL SortedResultSet::getRow() +{ + return mnCurEntry; +} + + +/** + moves the cursor to the given row number in the result set. + <p>If the row number is positive, the cursor moves to the given row + number with respect to the beginning of the result set. The first + row is row 1, the second is row 2, and so on. + <p>If the given row number is negative, the cursor moves to an + absolute row position with respect to the end of the result set. + For example, calling <code>moveToPosition(-1)</code> positions the + cursor on the last row, <code>moveToPosition(-2)</code> indicates the + next-to-last row, and so on. + <p>An attempt to position the cursor beyond the first/last row in the + result set leaves the cursor before/after the first/last row, + respectively. + <p>Note: Calling <code>moveToPosition(1)</code> is the same + as calling <code>moveToFirst()</code>. Calling + <code>moveToPosition(-1)</code> is the same as calling + <code>moveToLast()</code>. + @param row + is the number of rows to move. Could be negative. + @returns + <TRUE/> if the cursor is on a row; <FALSE/> otherwise + @throws SQLException + if a database access error occurs or if row is 0, or the result set + type is FORWARD_ONLY. + */ +sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + sal_Int32 nIndex; + + if ( row > 0 ) + { + if ( row <= mnCount ) + { + mnCurEntry = row; + nIndex = maS2O[ mnCurEntry ]; + return mxOriginal->absolute( nIndex ); + } + else + { + mnCurEntry = mnCount + 1; + return false; + } + } + else if ( row == 0 ) + { + throw SQLException(); + } + else + { + if ( mnCount + row + 1 > 0 ) + { + mnCurEntry = mnCount + row + 1; + nIndex = maS2O[ mnCurEntry ]; + return mxOriginal->absolute( nIndex ); + } + else + { + mnCurEntry = 0; + return false; + } + } +} + + +/** + moves the cursor a relative number of rows, either positive or negative. + <p> + Attempting to move beyond the first/last row in the result set positions + the cursor before/after the first/last row. Calling + <code>moveRelative(0)</code> is valid, but does not change the cursor + position. + <p>Note: Calling <code>moveRelative(1)</code> is different from calling + <code>moveNext()</code> because is makes sense to call + <code>moveNext()</code> when there is no current row, for example, + when the cursor is positioned before the first row or after the last + row of the result set. + @param rows + is the number of rows to move. Could be negative. + @returns + <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off + the result set. + @throws SQLException + if a database access error occurs or if there is no + current row, or the result set type is FORWARD_ONLY. + */ +sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) + { + throw SQLException(); + } + + if ( rows == 0 ) + return true; + + sal_Int32 nTmp = mnCurEntry + rows; + + if ( nTmp <= 0 ) + { + mnCurEntry = 0; + return false; + } + else if ( nTmp > mnCount ) + { + mnCurEntry = mnCount + 1; + return false; + } + else + { + mnCurEntry = nTmp; + nTmp = maS2O[ mnCurEntry ]; + return mxOriginal->absolute( nTmp ); + } +} + + +/** + moves the cursor to the previous row in the result set. + <p>Note: <code>previous()</code> is not the same as + <code>relative(-1)</code> because it makes sense to call + <code>previous()</code> when there is no current row. + @returns <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off + the result set. + @throws SQLException + if a database access error occurs or the result set type + is FORWARD_ONLY. + */ +sal_Bool SAL_CALL SortedResultSet::previous() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + mnCurEntry -= 1; + + if ( mnCurEntry > 0 ) + { + if ( mnCurEntry <= mnCount ) + { + sal_Int32 nIndex = maS2O[ mnCurEntry ]; + return mxOriginal->absolute( nIndex ); + } + } + else + mnCurEntry = 0; + + return false; +} + + +void SAL_CALL SortedResultSet::refreshRow() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) + { + throw SQLException(); + } + + mxOriginal->refreshRow(); +} + + +sal_Bool SAL_CALL SortedResultSet::rowUpdated() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) + { + throw SQLException(); + } + + return mxOriginal->rowUpdated(); +} + + +sal_Bool SAL_CALL SortedResultSet::rowInserted() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) + { + throw SQLException(); + } + + return mxOriginal->rowInserted(); +} + + +sal_Bool SAL_CALL SortedResultSet::rowDeleted() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) + { + throw SQLException(); + } + + return mxOriginal->rowDeleted(); +} + + +Reference< XInterface > SAL_CALL SortedResultSet::getStatement() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) + { + throw SQLException(); + } + + return mxOriginal->getStatement(); +} + + +// XRow methods. + + +sal_Bool SAL_CALL SortedResultSet::wasNull() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->wasNull(); +} + + +OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getString( columnIndex ); +} + + +sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex ); +} + + +sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getByte( columnIndex ); +} + + +sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getShort( columnIndex ); +} + + +sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getInt( columnIndex ); +} + +sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getLong( columnIndex ); +} + + +float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex ); +} + + +double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex ); +} + + +Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex ); +} + + +Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getDate( columnIndex ); +} + + +Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getTime( columnIndex ); +} + + +DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex ); +} + + +Reference< XInputStream > SAL_CALL +SortedResultSet::getBinaryStream( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex ); +} + + +Reference< XInputStream > SAL_CALL +SortedResultSet::getCharacterStream( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex ); +} + + +Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex, + const Reference< XNameAccess >& typeMap ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getObject( columnIndex, + typeMap); +} + + +Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getRef( columnIndex ); +} + + +Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex ); +} + + +Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getClob( columnIndex ); +} + + +Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XRow >::query(mxOriginal)->getArray( columnIndex ); +} + + +// XCloseable methods. + + +void SAL_CALL SortedResultSet::close() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + Reference< XCloseable >::query(mxOriginal)->close(); +} + + +// XResultSetMetaDataSupplier methods. + + +Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData(); +} + + +// XPropertySet methods. + + +Reference< XPropertySetInfo > SAL_CALL +SortedResultSet::getPropertySetInfo() +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( !mpPropSetInfo.is() ) + { + mpPropSetInfo = new SRSPropertySetInfo(); + } + + return mpPropSetInfo; +} + + +void SAL_CALL SortedResultSet::setPropertyValue( + const OUString& PropertyName, + const Any& ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( PropertyName == "RowCount" || PropertyName == "IsRowCountFinal" ) + throw IllegalArgumentException(); + else + throw UnknownPropertyException(PropertyName); +} + + +Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + Any aRet; + + if ( PropertyName == "RowCount" ) + { + aRet <<= maS2O.Count(); + } + else if ( PropertyName == "IsRowCountFinal" ) + { + bool bOrgFinal = false; + Any aOrgRet; + + aRet <<= false; + + aOrgRet = Reference< XPropertySet >::query(mxOriginal)-> + getPropertyValue( PropertyName ); + aOrgRet >>= bOrgFinal; + + if ( bOrgFinal ) + { + aOrgRet = Reference< XPropertySet >::query(mxOriginal)-> + getPropertyValue("RowCount"); + sal_uInt32 nOrgCount = 0; + aOrgRet >>= nOrgCount; + if ( nOrgCount == maS2O.Count() ) + aRet <<= true; + } + } + else + throw UnknownPropertyException(PropertyName); + + return aRet; +} + + +void SAL_CALL SortedResultSet::addPropertyChangeListener( + const OUString& PropertyName, + const Reference< XPropertyChangeListener >& Listener ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( !mpPropChangeListeners ) + mpPropChangeListeners.reset( + new comphelper::OMultiTypeInterfaceContainerHelperVar3<css::beans::XPropertyChangeListener, OUString>(getContainerMutex()) ); + + mpPropChangeListeners->addInterface( PropertyName, Listener ); +} + + +void SAL_CALL SortedResultSet::removePropertyChangeListener( + const OUString& PropertyName, + const Reference< XPropertyChangeListener >& Listener ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( mpPropChangeListeners ) + mpPropChangeListeners->removeInterface( PropertyName, Listener ); +} + + +void SAL_CALL SortedResultSet::addVetoableChangeListener( + const OUString& PropertyName, + const Reference< XVetoableChangeListener >& Listener ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( !mpVetoChangeListeners ) + mpVetoChangeListeners.reset( + new comphelper::OMultiTypeInterfaceContainerHelperVar3<css::beans::XVetoableChangeListener, OUString>(getContainerMutex()) ); + + mpVetoChangeListeners->addInterface( PropertyName, Listener ); +} + + +void SAL_CALL SortedResultSet::removeVetoableChangeListener( + const OUString& PropertyName, + const Reference< XVetoableChangeListener >& Listener ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( mpVetoChangeListeners ) + mpVetoChangeListeners->removeInterface( PropertyName, Listener ); +} + + +// private methods + +sal_Int32 SortedResultSet::CompareImpl( const Reference < XResultSet >& xResultOne, + const Reference < XResultSet >& xResultTwo, + sal_Int32 nIndexOne, sal_Int32 nIndexTwo, + SortInfo const * pSortInfo ) +{ + Reference < XRow > xRowOne( xResultOne, UNO_QUERY ); + Reference < XRow > xRowTwo( xResultTwo, UNO_QUERY ); + + sal_IntPtr nCompare = 0; + sal_Int32 nColumn = pSortInfo->mnColumn; + + switch ( pSortInfo->mnType ) + { + case DataType::BIT : + case DataType::TINYINT : + case DataType::SMALLINT : + case DataType::INTEGER : + { + sal_Int32 aOne = 0; + sal_Int32 aTwo = 0; + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getInt( nColumn ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getInt( nColumn ); + + if ( aOne < aTwo ) + nCompare = -1; + else if ( aOne == aTwo ) + nCompare = 0; + else + nCompare = 1; + + break; + } + case DataType::BIGINT : + { + sal_Int64 aOne = 0; + sal_Int64 aTwo = 0; + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getLong( nColumn ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getLong( nColumn ); + + if ( aOne < aTwo ) + nCompare = -1; + else if ( aOne == aTwo ) + nCompare = 0; + else + nCompare = 1; + + break; + } + case DataType::CHAR : + case DataType::VARCHAR : + case DataType::LONGVARCHAR : + { + OUString aOne, aTwo; + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getString( nColumn ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getString( nColumn ); + + if ( ! pSortInfo->mbCaseSensitive ) + { + aOne = aOne.toAsciiLowerCase(); + aTwo = aTwo.toAsciiLowerCase(); + } + + nCompare = aOne.compareTo( aTwo ); + break; + } + case DataType::DATE : + { + Date aOne, aTwo; + sal_Int32 nTmp; + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getDate( nColumn ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getDate( nColumn ); + + nTmp = static_cast<sal_Int32>(aTwo.Year) - static_cast<sal_Int32>(aOne.Year); + if ( !nTmp ) { + nTmp = static_cast<sal_Int32>(aTwo.Month) - static_cast<sal_Int32>(aOne.Month); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.Day) - static_cast<sal_Int32>(aOne.Day); + } + + if ( nTmp < 0 ) + nCompare = -1; + else if ( nTmp == 0 ) + nCompare = 0; + else + nCompare = 1; + + break; + } + case DataType::TIME : + { + Time aOne, aTwo; + sal_Int32 nTmp; + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getTime( nColumn ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getTime( nColumn ); + + nTmp = static_cast<sal_Int32>(aTwo.Hours) - static_cast<sal_Int32>(aOne.Hours); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.Minutes) - static_cast<sal_Int32>(aOne.Minutes); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.Seconds) - static_cast<sal_Int32>(aOne.Seconds); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.NanoSeconds) + - static_cast<sal_Int32>(aOne.NanoSeconds); + + if ( nTmp < 0 ) + nCompare = -1; + else if ( nTmp == 0 ) + nCompare = 0; + else + nCompare = 1; + + break; + } + case DataType::TIMESTAMP : + { + DateTime aOne, aTwo; + sal_Int32 nTmp; + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getTimestamp( nColumn ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getTimestamp( nColumn ); + + nTmp = static_cast<sal_Int32>(aTwo.Year) - static_cast<sal_Int32>(aOne.Year); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.Month) - static_cast<sal_Int32>(aOne.Month); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.Day) - static_cast<sal_Int32>(aOne.Day); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.Hours) - static_cast<sal_Int32>(aOne.Hours); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.Minutes) - static_cast<sal_Int32>(aOne.Minutes); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.Seconds) - static_cast<sal_Int32>(aOne.Seconds); + if ( !nTmp ) + nTmp = static_cast<sal_Int32>(aTwo.NanoSeconds) + - static_cast<sal_Int32>(aOne.NanoSeconds); + + if ( nTmp < 0 ) + nCompare = -1; + else if ( nTmp == 0 ) + nCompare = 0; + else + nCompare = 1; + + break; + } + case DataType::REAL : + { + float aOne = 0; + float aTwo = 0; + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getFloat( nColumn ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getFloat( nColumn ); + + if ( aOne < aTwo ) + nCompare = -1; + else if ( aOne == aTwo ) + nCompare = 0; + else + nCompare = 1; + + break; + } + case DataType::FLOAT : + case DataType::DOUBLE : + { + double aOne = 0; + double aTwo = 0; + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getDouble( nColumn ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getDouble( nColumn ); + + if ( aOne < aTwo ) + nCompare = -1; + else if ( aOne == aTwo ) + nCompare = 0; + else + nCompare = 1; + + break; + } + default: + { + OSL_FAIL( "DataType not supported for compare!" ); + } + } + + return nCompare; +} + + +sal_Int32 SortedResultSet::CompareImpl( const Reference < XResultSet >& xResultOne, + const Reference < XResultSet >& xResultTwo, + sal_Int32 nIndexOne, sal_Int32 nIndexTwo ) +{ + sal_IntPtr nCompare = 0; + SortInfo* pInfo = mpSortInfo; + + while ( !nCompare && pInfo ) + { + if ( pInfo->mbUseOwnCompare ) + { + nCompare = CompareImpl( xResultOne, xResultTwo, + nIndexOne, nIndexTwo, pInfo ); + } + else + { + Any aOne, aTwo; + + Reference < XRow > xRowOne = + Reference< XRow >::query( xResultOne ); + Reference < XRow > xRowTwo = + Reference< XRow >::query( xResultTwo ); + + if ( xResultOne->absolute( nIndexOne ) ) + aOne = xRowOne->getObject( pInfo->mnColumn, nullptr ); + if ( xResultTwo->absolute( nIndexTwo ) ) + aTwo = xRowTwo->getObject( pInfo->mnColumn, nullptr ); + + nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo ); + } + + if ( ! pInfo->mbAscending ) + nCompare = - nCompare; + + pInfo = pInfo->mpNext; + } + + return nCompare; +} + + +sal_Int32 SortedResultSet::Compare( SortListData const *pOne, + SortListData const *pTwo ) +{ + sal_IntPtr nIndexOne; + sal_IntPtr nIndexTwo; + + Reference < XResultSet > xResultOne; + Reference < XResultSet > xResultTwo; + + if ( pOne->mbModified ) + { + xResultOne = mxOther; + nIndexOne = pOne->mnOldPos; + } + else + { + xResultOne = mxOriginal; + nIndexOne = pOne->mnCurPos; + } + + if ( pTwo->mbModified ) + { + xResultTwo = mxOther; + nIndexTwo = pTwo->mnOldPos; + } + else + { + xResultTwo = mxOriginal; + nIndexTwo = pTwo->mnCurPos; + } + + sal_IntPtr nCompare; + nCompare = CompareImpl( xResultOne, xResultTwo, + nIndexOne, nIndexTwo ); + return nCompare; +} + + +sal_Int32 SortedResultSet::FindPos( SortListData const *pEntry, + sal_IntPtr _nStart, sal_IntPtr _nEnd ) +{ + if ( _nStart > _nEnd ) + return _nStart + 1; + + sal_IntPtr nStart = _nStart; + sal_IntPtr nEnd = _nEnd; + sal_IntPtr nMid = 0, nCompare = 0; + + + while ( nStart <= nEnd ) + { + nMid = ( nEnd - nStart ) / 2 + nStart; + SortListData *pMid = maS2O.GetData( nMid ); + nCompare = Compare( pEntry, pMid ); + + if ( !nCompare ) + nCompare = (pEntry != pMid) ? ((pEntry < pMid) ? -1 : 1) : 0; + + if ( nCompare < 0 ) // pEntry < pMid + nEnd = nMid - 1; + else + nStart = nMid + 1; + } + + if ( nCompare < 0 ) // pEntry < pMid + return nMid; + else + return nMid+1; +} + + +void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( !mpPropChangeListeners ) + return; + + // Notify listeners interested especially in the changed property. + OInterfaceContainerHelper3<XPropertyChangeListener>* pPropsContainer = + mpPropChangeListeners->getContainer( rEvt.PropertyName ); + if ( pPropsContainer ) + pPropsContainer->notifyEach( &XPropertyChangeListener::propertyChange, rEvt ); + + // Notify listeners interested in all properties. + pPropsContainer = mpPropChangeListeners->getContainer( OUString() ); + if ( pPropsContainer ) + pPropsContainer->notifyEach( &XPropertyChangeListener::propertyChange, rEvt ); +} + + +// public methods + + +void SortedResultSet::CopyData( SortedResultSet *pSource ) +{ + const SortedEntryList& rSrcS2O = pSource->maS2O; + + sal_IntPtr i, nCount; + + maS2O.Clear(); + m_O2S.clear(); + m_ModList.clear(); + + maS2O.Insert( nullptr, 0 ); + m_O2S.push_back(0); + + nCount = rSrcS2O.Count(); + + for ( i=1; i<nCount; i++ ) + { + maS2O.Insert( std::unique_ptr<SortListData>(new SortListData( rSrcS2O[ i ] )), i ); + m_O2S.push_back(pSource->m_O2S[i]); + } + + mnLastSort = maS2O.Count(); + mxOther = pSource->mxOriginal; + + if ( !mpSortInfo ) + { + mpSortInfo = pSource->mpSortInfo; + mbIsCopy = true; + } +} + + +void SortedResultSet::Initialize( + const Sequence < NumberedSortingInfo > &xSortInfo, + const Reference< XAnyCompareFactory > &xCompFactory ) +{ + BuildSortInfo( mxOriginal, xSortInfo, xCompFactory ); + // Insert dummy at pos 0 + maS2O.Insert( std::unique_ptr<SortListData>(new SortListData( 0 )), 0 ); + + sal_IntPtr nIndex = 1; + + // now fetch all the elements from the original result set, + // get there new position in the sorted result set and insert + // an entry in the sorted to original mapping list + try { + while ( mxOriginal->absolute( nIndex ) ) + { + std::unique_ptr<SortListData> pData(new SortListData( nIndex )); + sal_IntPtr nPos = FindPos( pData.get(), 1, nIndex-1 ); + + maS2O.Insert( std::move(pData), nPos ); + + nIndex++; + } + } + catch (const SQLException&) + { + TOOLS_WARN_EXCEPTION("ucb", ""); + } + + // when we have fetched all the elements, we can create the + // original to sorted mapping list from the s2o list + m_O2S.clear(); + m_O2S.push_back(0); + + // insert some dummy entries first and replace then + // the entries with the right ones + size_t i; + + for ( i=1; i<maS2O.Count(); i++ ) + m_O2S.push_back(0); + for ( i=1; i<maS2O.Count(); i++ ) + m_O2S[maS2O[i]] = i; + + mnCount = maS2O.Count() - 1; +} + + +void SortedResultSet::CheckProperties( sal_Int32 nOldCount, bool bWasFinal ) +{ + osl::Guard< osl::Mutex > aGuard( maMutex ); + + if ( !mpPropChangeListeners ) + return; + + try { + // check for propertyChangeEvents + if ( nOldCount != GetCount() ) + { + bool bIsFinal = false; + PropertyChangeEvent aEvt; + + aEvt.PropertyName = "RowCount"; + aEvt.Further = false; + aEvt.PropertyHandle = -1; + aEvt.OldValue <<= nOldCount; + aEvt.NewValue <<= GetCount(); + + PropertyChanged( aEvt ); + + OUString aName = "IsRowCountFinal"; + Any aRet = getPropertyValue( aName ); + if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal ) + { + aEvt.PropertyName = aName; + aEvt.Further = false; + aEvt.PropertyHandle = -1; + aEvt.OldValue <<= bWasFinal; + aEvt.NewValue <<= bIsFinal; + PropertyChanged( aEvt ); + } + } + } + catch (const UnknownPropertyException&) {} + catch (const WrappedTargetException&) {} +} + + +void SortedResultSet::InsertNew( sal_Int32 nPos, sal_Int32 nCount ) +{ + // for all entries in the msS20-list, which are >= nPos, increase by nCount + sal_IntPtr i, nEnd; + + nEnd = maS2O.Count(); + for ( i=1; i<=nEnd; i++ ) + { + SortListData *pData = maS2O.GetData( i ); + if ( pData->mnCurPos >= nPos ) + { + pData->mnCurPos += nCount; + } + } + + // and append the new entries at the end of the maS2O-list or insert at the + // position nPos in the maS2O-list + for ( i=0; i<nCount; i++ ) + { + nEnd += 1; + std::unique_ptr<SortListData> pData(new SortListData( nEnd )); + + maS2O.Insert( std::move(pData), nEnd ); // Insert( Value, Position ) + m_O2S.insert(m_O2S.begin() + nPos + i, nEnd); + } + + mnCount += nCount; +} + + +void SortedResultSet::Remove( sal_Int32 nPos, sal_Int32 nCount, EventList *pEvents ) +{ + sal_IntPtr nOldLastSort; + + // correct mnLastSort first + nOldLastSort = mnLastSort; + if ( nPos <= mnLastSort ) + { + if ( nPos + nCount - 1 <= mnLastSort ) + mnLastSort -= nCount; + else + mnLastSort = nPos - 1; + } + + // remove the entries from the lists and correct the positions + // in the original2sorted list + for ( sal_IntPtr i=0; i < nCount; i++ ) + { + sal_IntPtr nSortPos = m_O2S[nPos]; + m_O2S.erase(m_O2S.begin() + nPos); + + for (size_t j=1; j < m_O2S.size(); ++j) + { + sal_IntPtr nVal = m_O2S[j]; + if ( nVal > nSortPos ) + { + --nVal; + m_O2S[j] = nVal; + } + } + + std::unique_ptr<SortListData> pData = maS2O.Remove( nSortPos ); + if ( pData->mbModified ) + m_ModList.erase(std::find(m_ModList.begin(), m_ModList.end(), pData.get())); + + // generate remove Event, but not for new entries + if ( nSortPos <= nOldLastSort ) + pEvents->AddEvent( ListActionType::REMOVED, nSortPos ); + } + + // correct the positions in the sorted list + for ( sal_uInt32 i=1; i<= maS2O.Count(); i++ ) + { + SortListData *pData = maS2O.GetData( i ); + if ( pData->mnCurPos > nPos ) + pData->mnCurPos -= nCount; + } + + mnCount -= nCount; +} + + +void SortedResultSet::Move( sal_Int32 nPos, sal_Int32 nCount, sal_Int32 nOffset ) +{ + if ( !nOffset ) + return; + + sal_IntPtr i, nSortPos, nTo; + SortListData *pData; + + for ( i=0; i<nCount; i++ ) + { + nSortPos = m_O2S[nPos + i]; + pData = maS2O.GetData( nSortPos ); + pData->mnCurPos += nOffset; + } + + if ( nOffset < 0 ) + { + for ( i=nPos+nOffset; i<nPos; i++ ) + { + nSortPos = m_O2S[i]; + pData = maS2O.GetData( nSortPos ); + pData->mnCurPos += nCount; + } + } + else + { + sal_IntPtr nStart = nPos + nCount; + sal_IntPtr nEnd = nStart + nOffset; + for ( i=nStart; i<nEnd; i++ ) + { + nSortPos = m_O2S[i]; + pData = maS2O.GetData( nSortPos ); + pData->mnCurPos -= nCount; + } + } + + // remember the to be moved entries + std::unique_ptr<sal_IntPtr[]> pTmpArr(new sal_IntPtr[ nCount ]); + for ( i=0; i<nCount; i++ ) + pTmpArr[i] = m_O2S[nPos + i]; + + // now move the entries, which are in the way + if ( nOffset < 0 ) + { + // be carefully here, because nOffset is negative here, so an + // addition is a subtraction + sal_IntPtr nFrom = nPos - 1; + nTo = nPos + nCount - 1; + + // same for i here + for ( i=0; i>nOffset; i-- ) + { + sal_IntPtr const nVal = m_O2S[nFrom + i]; + m_O2S[nTo + i] = nVal; + } + + } + else + { + sal_IntPtr nStart = nPos + nCount; + for ( i=0; i<nOffset; i++ ) + { + sal_IntPtr const nVal = m_O2S[nStart + i]; + m_O2S[nPos + i] = nVal; + } + } + + // finally put the remembered entries at their new location + nTo = nPos + nOffset; + for ( i=0; i<nCount; i++ ) + { + m_O2S[nTo + i] = pTmpArr[i]; + } +} + + +void SortedResultSet::BuildSortInfo( + const Reference< XResultSet >& aResult, + const Sequence < NumberedSortingInfo > &xSortInfo, + const Reference< XAnyCompareFactory > &xCompFactory ) +{ + Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY ); + + if ( ! xMeta.is() ) + { + OSL_FAIL( "No MetaData, No Sorting!" ); + return; + } + + Reference < XResultSetMetaData > xData = xMeta->getMetaData(); + const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray(); + + sal_Int32 nColumn; + OUString aPropName; + SortInfo *pInfo; + + for ( sal_Int32 i=xSortInfo.getLength(); i > 0; ) + { + --i; + nColumn = pSortInfo[ i ].ColumnIndex; + aPropName = xData->getColumnName( nColumn ); + pInfo = new SortInfo; + + if ( xCompFactory.is() ) + pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName( + aPropName ); + + if ( pInfo->mxCompareFunction.is() ) + { + pInfo->mbUseOwnCompare = false; + pInfo->mnType = 0; + } + else + { + pInfo->mbUseOwnCompare = true; + pInfo->mnType = xData->getColumnType( nColumn ); + } + + pInfo->mnColumn = nColumn; + pInfo->mbAscending = pSortInfo[ i ].Ascending; + pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn ); + pInfo->mpNext = mpSortInfo; + mpSortInfo = pInfo; + } +} + + +void SortedResultSet::SetChanged( sal_Int32 nPos, sal_Int32 nCount ) +{ + for ( sal_IntPtr i=0; i<nCount; i++ ) + { + sal_IntPtr const nSortPos = m_O2S[nPos]; + if ( nSortPos < mnLastSort ) + { + SortListData *pData = maS2O.GetData( nSortPos ); + if ( ! pData->mbModified ) + { + pData->mbModified = true; + m_ModList.push_back(pData); + } + } + nPos += 1; + } +} + + +void SortedResultSet::ResortModified( EventList* pList ) +{ + sal_IntPtr nCompare, nCurPos, nNewPos; + sal_IntPtr nStart, nEnd, nOffset, nVal; + + try { + for (size_t i = 0; i < m_ModList.size(); ++i) + { + SortListData *const pData = m_ModList[i]; + nCompare = CompareImpl( mxOther, mxOriginal, + pData->mnOldPos, pData->mnCurPos ); + pData->mbModified = false; + if ( nCompare != 0 ) + { + nCurPos = m_O2S[pData->mnCurPos]; + if ( nCompare < 0 ) + { + nNewPos = FindPos( pData, 1, nCurPos-1 ); + nStart = nNewPos; + nEnd = nCurPos; + nOffset = 1; + } + else + { + nNewPos = FindPos( pData, nCurPos+1, mnLastSort ); + nStart = nCurPos; + nEnd = mnLastSort; + nOffset = -1; + } + + if ( nNewPos != nCurPos ) + { + // correct the lists! + maS2O.Move( static_cast<sal_uInt32>(nCurPos), nNewPos ); + for (size_t j = 1; j < m_O2S.size(); ++j) + { + nVal = m_O2S[j]; + if ( ( nStart <= nVal ) && ( nVal <= nEnd ) ) + { + nVal += nOffset; + m_O2S[j] = nVal; + } + } + + m_O2S[pData->mnCurPos] = nNewPos; + + ListAction aAction; + aAction.Position = nCurPos; + aAction.Count = 1; + aAction.ListActionType = ListActionType::MOVED; + aAction.ActionInfo <<= nNewPos-nCurPos; + pList->Insert( aAction ); + } + pList->AddEvent( ListActionType::PROPERTIES_CHANGED, nNewPos ); + } + } + } + catch (const SQLException&) + { + TOOLS_WARN_EXCEPTION("ucb", ""); + } + + m_ModList.clear(); +} + + +void SortedResultSet::ResortNew( EventList* pList ) +{ + sal_IntPtr i, nNewPos, nVal; + + try { + for ( i = mnLastSort; i<static_cast<sal_IntPtr>(maS2O.Count()); i++ ) + { + SortListData *const pData = m_ModList[i]; + nNewPos = FindPos( pData, 1, mnLastSort ); + if ( nNewPos != i ) + { + maS2O.Move( static_cast<sal_uInt32>(i), nNewPos ); + for (size_t j=1; j< m_O2S.size(); ++j) + { + nVal = m_O2S[j]; + if ( nVal >= nNewPos ) + m_O2S[j] = nVal + 1; + } + m_O2S[pData->mnCurPos] = nNewPos; + } + mnLastSort++; + pList->AddEvent( ListActionType::INSERTED, nNewPos ); + } + } + catch (const SQLException&) + { + TOOLS_WARN_EXCEPTION("ucb", ""); + } +} + + +// SortListData + + +SortListData::SortListData( sal_IntPtr nPos ) + : mbModified(false) + , mnCurPos(nPos) + , mnOldPos(nPos) +{ +}; + +SortedEntryList::SortedEntryList() +{ +} + +SortedEntryList::~SortedEntryList() +{ +} + +void SortedEntryList::Clear() +{ + maData.clear(); +} + + +void SortedEntryList::Insert( std::unique_ptr<SortListData> pEntry, sal_Int32 nPos ) +{ + if ( nPos < static_cast<sal_IntPtr>(maData.size()) ) + maData.insert( maData.begin() + nPos, std::move(pEntry) ); + else + maData.push_back( std::move(pEntry) ); +} + +void SortedEntryList::Move( sal_Int32 nOldPos, sal_Int32 nNewPos ) +{ + auto p = std::move(maData[nOldPos]); + maData.erase( maData.begin() + nOldPos ); + maData.insert(maData.begin() + nNewPos, std::move(p)); +} + +std::unique_ptr<SortListData> SortedEntryList::Remove( sal_Int32 nPos ) +{ + std::unique_ptr<SortListData> pData; + + if ( nPos < static_cast<sal_IntPtr>(maData.size()) ) + { + pData = std::move(maData[ nPos ]); + maData.erase( maData.begin() + nPos ); + } + + return pData; +} + + +SortListData* SortedEntryList::GetData( sal_Int32 nPos ) +{ + SortListData *pData; + + if ( nPos < static_cast<sal_IntPtr>(maData.size()) ) + pData = maData[ nPos ].get(); + else + pData = nullptr; + + return pData; +} + + +sal_Int32 SortedEntryList::operator [] ( sal_Int32 nPos ) const +{ + SortListData *pData; + + if ( nPos < static_cast<sal_IntPtr>(maData.size()) ) + pData = maData[ nPos ].get(); + else + pData = nullptr; + + if ( pData ) + if ( ! pData->mbModified ) + return pData->mnCurPos; + else + { + OSL_FAIL( "SortedEntryList: Can't get value for modified entry!"); + return 0; + } + else + { + OSL_FAIL( "SortedEntryList: invalid pos!"); + return 0; + } +} + + +SRSPropertySetInfo::SRSPropertySetInfo() +{ + maProps[0].Name = "RowCount"; + maProps[0].Handle = -1; + maProps[0].Type = cppu::UnoType<OUString>::get(); + maProps[0].Attributes = -1; + + maProps[1].Name = "IsRowCountFinal"; + maProps[1].Handle = -1; + maProps[1].Type = cppu::UnoType<bool>::get(); + maProps[1].Attributes = -1; +} + +// XPropertySetInfo methods. + +Sequence< Property > SAL_CALL +SRSPropertySetInfo::getProperties() +{ + return Sequence < Property > ( maProps, 2 ); +} + + +Property SAL_CALL +SRSPropertySetInfo::getPropertyByName( const OUString& Name ) +{ + if ( Name == "RowCount" ) + return maProps[0]; + else if ( Name == "IsRowCountFinal" ) + return maProps[1]; + else + throw UnknownPropertyException(Name); +} + + +sal_Bool SAL_CALL +SRSPropertySetInfo::hasPropertyByName( const OUString& Name ) +{ + if ( Name == "RowCount" ) + return true; + else if ( Name == "IsRowCountFinal" ) + return true; + else + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |