summaryrefslogtreecommitdiff
path: root/svtools/source/misc/flbytes.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/misc/flbytes.cxx')
-rw-r--r--svtools/source/misc/flbytes.cxx466
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;
+}
+