diff options
Diffstat (limited to 'svtools/source/misc/flbytes.cxx')
-rw-r--r-- | svtools/source/misc/flbytes.cxx | 466 |
1 files changed, 466 insertions, 0 deletions
diff --git a/svtools/source/misc/flbytes.cxx b/svtools/source/misc/flbytes.cxx new file mode 100644 index 000000000000..98e4583b7004 --- /dev/null +++ b/svtools/source/misc/flbytes.cxx @@ -0,0 +1,466 @@ +/************************************************************************* + * + * $RCSfile: flbytes.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:59:02 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif + +#ifndef _FLBYTES_HXX +#include <flbytes.hxx> +#endif + +#ifndef _SVSTDARR_ULONGS_DECL +#define _SVSTDARR_ULONGS +#include <svstdarr.hxx> +#undef _SVSTDARR_ULONGS +#endif + +namespace unnamed_svtools_flbytes {} using namespace unnamed_svtools_flbytes; + // unnamed namespaces don't work well yet + +//============================================================================ +namespace unnamed_svtools_flbytes { + +inline ULONG MyMin( long a, long b ) +{ + return Max( long( Min( a , b ) ), 0L ); +} + +} + +//============================================================================ +// +// SvFillLockBytes +// +//============================================================================ + +TYPEINIT1(SvFillLockBytes, SvLockBytes); + +//============================================================================ +SvFillLockBytes::SvFillLockBytes( SvLockBytes* pLockBytes ) + : xLockBytes( pLockBytes ), + nFilledSize( 0 ), + bTerminated( FALSE ) +{ +} + +//============================================================================ +ErrCode SvFillLockBytes::ReadAt( ULONG nPos, void* pBuffer, ULONG nCount, + ULONG *pRead ) const +{ + if( bTerminated ) + return xLockBytes->ReadAt( nPos, pBuffer, nCount, pRead ); + else + { + ULONG nWanted = nPos + nCount; + if( IsSynchronMode() ) + { + while( nWanted > nFilledSize && !bTerminated ) + Application::Yield(); + return xLockBytes->ReadAt( nPos, pBuffer, nCount, pRead ); + } + else + { + ULONG nRead = MyMin( nCount, long( nFilledSize ) - nPos ); + ULONG nErr = xLockBytes->ReadAt( nPos, pBuffer, nRead, pRead ); + return ( !nCount || nRead == nCount || nErr ) ? + nErr : ERRCODE_IO_PENDING; + } + } +} + +//============================================================================ +ErrCode SvFillLockBytes::WriteAt( ULONG nPos, const void* pBuffer, + ULONG nCount, ULONG *pWritten ) +{ + if( bTerminated ) + return xLockBytes->WriteAt( nPos, pBuffer, nCount, pWritten ); + else + { + ULONG nWanted = nPos + nCount; + if( IsSynchronMode() ) + { + while( nWanted > nFilledSize && !bTerminated ) + Application::Yield(); + return xLockBytes->WriteAt( nPos, pBuffer, nCount, pWritten ); + } + else + { + ULONG nRead = MyMin( nCount, long( nFilledSize ) - nPos ); + ULONG nErr = xLockBytes->WriteAt( nPos, pBuffer, nRead, pWritten ); + return ( !nCount || nRead == nCount || nErr ) ? + nErr : ERRCODE_IO_PENDING; + } + } +} + +//============================================================================ +ErrCode SvFillLockBytes::Flush() const +{ + return xLockBytes->Flush( ); +} + +//============================================================================ +ErrCode SvFillLockBytes::SetSize( ULONG nSize ) +{ + return xLockBytes->SetSize( nSize ); +} + +//============================================================================ +ErrCode SvFillLockBytes::LockRegion( ULONG nPos, ULONG nCount, LockType eType) +{ + return xLockBytes->LockRegion( nPos, nCount, eType ); +} + +//============================================================================ +ErrCode SvFillLockBytes::UnlockRegion( + ULONG nPos, ULONG nCount, LockType eType) +{ + return xLockBytes->UnlockRegion( nPos, nCount, eType ); +} + +//============================================================================ +ErrCode SvFillLockBytes::Stat( + SvLockBytesStat* pStat, SvLockBytesStatFlag eFlag) const +{ + return xLockBytes->Stat( pStat, eFlag ); +} + +//============================================================================ +ErrCode SvFillLockBytes::FillAppend( const void* pBuffer, ULONG nCount, ULONG *pWritten ) +{ + ErrCode nRet = xLockBytes->WriteAt( + nFilledSize, pBuffer, nCount, pWritten ); + nFilledSize += *pWritten; + return nRet; +} + +//============================================================================ +void SvFillLockBytes::Terminate() +{ + bTerminated = TRUE; +} + +//============================================================================ +SV_DECL_IMPL_REF_LIST( SvLockBytes, SvLockBytes* ) + +//============================================================================ +// +// SvSyncLockBytes +// +//============================================================================ + +TYPEINIT1(SvSyncLockBytes, SvOpenLockBytes); + +//============================================================================ +// virtual +ErrCode SvSyncLockBytes::ReadAt(ULONG nPos, void * pBuffer, ULONG nCount, + ULONG * pRead) const +{ + for (ULONG nReadTotal = 0;;) + { + ULONG nReadCount = 0; + ErrCode nError = m_xAsyncLockBytes->ReadAt(nPos, pBuffer, nCount, + &nReadCount); + nReadTotal += nReadCount; + if (nError != ERRCODE_IO_PENDING || !IsSynchronMode()) + { + if (pRead) + *pRead = nReadTotal; + return nError; + } + nPos += nReadCount; + pBuffer = static_cast< sal_Char * >(pBuffer) + nReadCount; + nCount -= nReadCount; + Application::Yield(); + } +} + +//============================================================================ +// virtual +ErrCode SvSyncLockBytes::WriteAt(ULONG nPos, const void * pBuffer, + ULONG nCount, ULONG * pWritten) +{ + for (ULONG nWrittenTotal = 0;;) + { + ULONG nWrittenCount = 0; + ErrCode nError = m_xAsyncLockBytes->WriteAt(nPos, pBuffer, nCount, + &nWrittenCount); + nWrittenTotal += nWrittenCount; + if (nError != ERRCODE_IO_PENDING || !IsSynchronMode()) + { + if (pWritten) + *pWritten = nWrittenTotal; + return nError; + } + nPos += nWrittenCount; + pBuffer = static_cast< sal_Char const * >(pBuffer) + nWrittenCount; + nCount -= nWrittenCount; + Application::Yield(); + } +} + +//============================================================================ +// +// SvCompositeLockBytes +// +//============================================================================ + +struct SvCompositeLockBytes_Impl +{ + SvLockBytesMemberList aLockBytes; + SvULongs aPositions; + SvULongs aOffsets; + BOOL bPending; + ULONG RelativeOffset( ULONG nPos ) const; + ErrCode ReadWrite_Impl( + ULONG nPos, void* pBuffer, ULONG nCount, ULONG* pProcessed, + BOOL bRead ); + SvCompositeLockBytes_Impl() : bPending( FALSE ){} +}; + +//============================================================================ +ULONG SvCompositeLockBytes_Impl::RelativeOffset( ULONG nPos ) const +{ + const SvULongs& rPositions = aPositions; + const SvULongs& rOffsets = aOffsets; + + USHORT nMinPos = 0; + USHORT nListCount = rPositions.Count(); + + // Erster Lockbytes, der bearbeitet werden muss + while( nMinPos + 1 < nListCount && rPositions[ nMinPos + 1 ] <= nPos ) + nMinPos ++; + ULONG nSectionStart = rPositions[ nMinPos ]; + if( nSectionStart > nPos ) + return ULONG_MAX; + return rOffsets[ nMinPos ] + nPos - nSectionStart; +} + +//============================================================================ +ErrCode SvCompositeLockBytes_Impl::ReadWrite_Impl( + ULONG nPos, void* pBuffer, ULONG nCount, ULONG* pProcessed, + BOOL bRead ) +{ + ErrCode nErr = ERRCODE_NONE; + SvULongs& rPositions = aPositions; + SvULongs& rOffsets = aOffsets; + SvLockBytesMemberList& rLockBytes = aLockBytes; + + ULONG nBytes = nCount; + USHORT nListCount = rPositions.Count(); + USHORT nMinPos = 0; + + // Erster Lockbytes, der bearbeitet werden muss + while( nMinPos + 1 < nListCount && rPositions[ nMinPos + 1 ] <= nPos ) + nMinPos ++; + ULONG nSectionStart = rPositions[ nMinPos ]; + + if( nSectionStart > nPos ) + { + // Es wird aus fuehrendem Leerbereich gearbeitet + *pProcessed = 0; + return ERRCODE_IO_CANTREAD; + } + + ULONG nDone; + while( nMinPos < nListCount ) + { + ULONG nToProcess; + ULONG nSectionStop; + if( nMinPos + 1 < nListCount ) + { + nSectionStop = rPositions[ nMinPos + 1 ]; + nToProcess = MyMin( long( nSectionStop ) - nPos, nBytes ); + } + else + { + nToProcess = nBytes; + nSectionStop = 0; + } + ULONG nAbsPos = nPos - nSectionStart + rOffsets[ nMinPos ]; + SvLockBytes* pLB = rLockBytes.GetObject( nMinPos ); + if( bRead ) + nErr = pLB->ReadAt( nAbsPos, pBuffer, nToProcess, &nDone ); + else + nErr = pLB->WriteAt( nAbsPos, pBuffer, nToProcess, &nDone ); + nBytes -= nDone; + if( nErr || nDone < nToProcess || !nBytes ) + { + *pProcessed = nCount - nBytes; + // Wenn aus dem letzten LockBytes nichts mehr gelesen wurde und + // bPending gesetzt ist, Pending zurueck + if( !nDone && nMinPos == nListCount - 1 ) + return bPending ? ERRCODE_IO_PENDING : nErr; + else return nErr; + } + pBuffer = static_cast< sal_Char * >(pBuffer) + nDone; + nPos += nDone; + nSectionStart = nSectionStop; + nMinPos++; + } + return nErr; +} + +//============================================================================ +TYPEINIT1(SvCompositeLockBytes, SvLockBytes); + +//============================================================================ +SvCompositeLockBytes::SvCompositeLockBytes() + : pImpl( new SvCompositeLockBytes_Impl ) +{ +} + +//============================================================================ +SvCompositeLockBytes::~SvCompositeLockBytes() +{ + delete pImpl; +} + +//============================================================================ +void SvCompositeLockBytes::SetIsPending( BOOL bSet ) +{ + pImpl->bPending = bSet; +} + +//============================================================================ +ULONG SvCompositeLockBytes::RelativeOffset( ULONG nPos ) const +{ + return pImpl->RelativeOffset( nPos ); +} + +//============================================================================ +ErrCode SvCompositeLockBytes::ReadAt( + ULONG nPos, void* pBuffer, ULONG nCount, ULONG* pRead ) const +{ + return pImpl->ReadWrite_Impl( nPos, pBuffer, nCount, pRead, TRUE ); +} + +//============================================================================ +ErrCode SvCompositeLockBytes::WriteAt( + ULONG nPos, const void* pBuffer, ULONG nCount, ULONG* pWritten ) +{ + return pImpl->ReadWrite_Impl( + nPos, const_cast< void * >(pBuffer), nCount, pWritten, FALSE ); +} + +//============================================================================ +ErrCode SvCompositeLockBytes::Flush() const +{ + SvLockBytesMemberList& rLockBytes = pImpl->aLockBytes; + ErrCode nErr = ERRCODE_NONE; + for( USHORT nCount = (USHORT)rLockBytes.Count(); !nErr && nCount--; ) + nErr = rLockBytes.GetObject( nCount )->Flush(); + return nErr; +} + +//============================================================================ +ErrCode SvCompositeLockBytes::SetSize( ULONG nSize ) +{ + DBG_ERROR( "not implemented" ); + return ERRCODE_IO_NOTSUPPORTED; +} + +//============================================================================ +ErrCode SvCompositeLockBytes::LockRegion( ULONG nPos, ULONG nCount, LockType ) +{ + DBG_ERROR( "not implemented" ); + return ERRCODE_IO_NOTSUPPORTED; +} + +//============================================================================ +ErrCode SvCompositeLockBytes::UnlockRegion( + ULONG nPos, ULONG nCount, LockType ) +{ + DBG_ERROR( "not implemented" ); + return ERRCODE_IO_NOTSUPPORTED; +} + +//============================================================================ +ErrCode SvCompositeLockBytes::Stat( + SvLockBytesStat* pStat, SvLockBytesStatFlag eFlag) const +{ + USHORT nMax = pImpl->aPositions.Count() - 1; + + SvLockBytesStat aStat; + ErrCode nErr = pImpl->aLockBytes.GetObject( nMax )->Stat( &aStat, eFlag ); + pStat->nSize = pImpl->aPositions[ nMax ] + aStat.nSize; + + return nErr; +} + +//============================================================================ +void SvCompositeLockBytes::Append( + SvLockBytes* pLockBytes, ULONG nPos, ULONG nOffset ) +{ + USHORT nCount = pImpl->aOffsets.Count(); + pImpl->aLockBytes.Insert( pLockBytes, nCount ); + pImpl->aPositions.Insert( nPos, nCount ); + pImpl->aOffsets.Insert( nOffset, nCount ); +} + +//============================================================================ +SvLockBytes* SvCompositeLockBytes::GetLastLockBytes() const +{ + return pImpl->aLockBytes.Count() ? + pImpl->aLockBytes.GetObject( pImpl->aLockBytes.Count() - 1 ) : 0; +} + |