Update ooo320-m1
[ooovba.git] / svtools / source / misc / flbytes.cxx
blobbb8c783b0a19a707e81f16896a93b86bc129b703
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: flbytes.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <vcl/svapp.hxx>
34 #include <flbytes.hxx>
36 #ifndef _SVSTDARR_ULONGS_DECL
37 #define _SVSTDARR_ULONGS
38 #include <svtools/svstdarr.hxx>
39 #undef _SVSTDARR_ULONGS
40 #endif
42 namespace unnamed_svtools_flbytes {} using namespace unnamed_svtools_flbytes;
43 // unnamed namespaces don't work well yet
45 //============================================================================
46 namespace unnamed_svtools_flbytes {
48 inline ULONG MyMin( long a, long b )
50 return Max( long( Min( a , b ) ), 0L );
55 //============================================================================
57 // SvFillLockBytes
59 //============================================================================
61 TYPEINIT1(SvFillLockBytes, SvLockBytes);
63 //============================================================================
64 SvFillLockBytes::SvFillLockBytes( SvLockBytes* pLockBytes )
65 : xLockBytes( pLockBytes ),
66 nFilledSize( 0 ),
67 bTerminated( FALSE )
71 //============================================================================
72 ErrCode SvFillLockBytes::ReadAt( ULONG nPos, void* pBuffer, ULONG nCount,
73 ULONG *pRead ) const
75 if( bTerminated )
76 return xLockBytes->ReadAt( nPos, pBuffer, nCount, pRead );
77 else
79 ULONG nWanted = nPos + nCount;
80 if( IsSynchronMode() )
82 while( nWanted > nFilledSize && !bTerminated )
83 Application::Yield();
84 return xLockBytes->ReadAt( nPos, pBuffer, nCount, pRead );
86 else
88 ULONG nRead = MyMin( nCount, long( nFilledSize ) - nPos );
89 ULONG nErr = xLockBytes->ReadAt( nPos, pBuffer, nRead, pRead );
90 return ( !nCount || nRead == nCount || nErr ) ?
91 nErr : ERRCODE_IO_PENDING;
96 //============================================================================
97 ErrCode SvFillLockBytes::WriteAt( ULONG nPos, const void* pBuffer,
98 ULONG nCount, ULONG *pWritten )
100 if( bTerminated )
101 return xLockBytes->WriteAt( nPos, pBuffer, nCount, pWritten );
102 else
104 ULONG nWanted = nPos + nCount;
105 if( IsSynchronMode() )
107 while( nWanted > nFilledSize && !bTerminated )
108 Application::Yield();
109 return xLockBytes->WriteAt( nPos, pBuffer, nCount, pWritten );
111 else
113 ULONG nRead = MyMin( nCount, long( nFilledSize ) - nPos );
114 ULONG nErr = xLockBytes->WriteAt( nPos, pBuffer, nRead, pWritten );
115 return ( !nCount || nRead == nCount || nErr ) ?
116 nErr : ERRCODE_IO_PENDING;
121 //============================================================================
122 ErrCode SvFillLockBytes::Flush() const
124 return xLockBytes->Flush( );
127 //============================================================================
128 ErrCode SvFillLockBytes::SetSize( ULONG nSize )
130 return xLockBytes->SetSize( nSize );
133 //============================================================================
134 ErrCode SvFillLockBytes::LockRegion( ULONG nPos, ULONG nCount, LockType eType)
136 return xLockBytes->LockRegion( nPos, nCount, eType );
139 //============================================================================
140 ErrCode SvFillLockBytes::UnlockRegion(
141 ULONG nPos, ULONG nCount, LockType eType)
143 return xLockBytes->UnlockRegion( nPos, nCount, eType );
146 //============================================================================
147 ErrCode SvFillLockBytes::Stat(
148 SvLockBytesStat* pStat, SvLockBytesStatFlag eFlag) const
150 return xLockBytes->Stat( pStat, eFlag );
153 //============================================================================
154 ErrCode SvFillLockBytes::FillAppend( const void* pBuffer, ULONG nCount, ULONG *pWritten )
156 ErrCode nRet = xLockBytes->WriteAt(
157 nFilledSize, pBuffer, nCount, pWritten );
158 nFilledSize += *pWritten;
159 return nRet;
162 //============================================================================
163 void SvFillLockBytes::Terminate()
165 bTerminated = TRUE;
168 //============================================================================
169 SV_DECL_IMPL_REF_LIST( SvLockBytes, SvLockBytes* )
171 //============================================================================
173 // SvSyncLockBytes
175 //============================================================================
177 TYPEINIT1(SvSyncLockBytes, SvOpenLockBytes);
179 //============================================================================
180 // virtual
181 ErrCode SvSyncLockBytes::ReadAt(ULONG nPos, void * pBuffer, ULONG nCount,
182 ULONG * pRead) const
184 for (ULONG nReadTotal = 0;;)
186 ULONG nReadCount = 0;
187 ErrCode nError = m_xAsyncLockBytes->ReadAt(nPos, pBuffer, nCount,
188 &nReadCount);
189 nReadTotal += nReadCount;
190 if (nError != ERRCODE_IO_PENDING || !IsSynchronMode())
192 if (pRead)
193 *pRead = nReadTotal;
194 return nError;
196 nPos += nReadCount;
197 pBuffer = static_cast< sal_Char * >(pBuffer) + nReadCount;
198 nCount -= nReadCount;
199 Application::Yield();
203 //============================================================================
204 // virtual
205 ErrCode SvSyncLockBytes::WriteAt(ULONG nPos, const void * pBuffer,
206 ULONG nCount, ULONG * pWritten)
208 for (ULONG nWrittenTotal = 0;;)
210 ULONG nWrittenCount = 0;
211 ErrCode nError = m_xAsyncLockBytes->WriteAt(nPos, pBuffer, nCount,
212 &nWrittenCount);
213 nWrittenTotal += nWrittenCount;
214 if (nError != ERRCODE_IO_PENDING || !IsSynchronMode())
216 if (pWritten)
217 *pWritten = nWrittenTotal;
218 return nError;
220 nPos += nWrittenCount;
221 pBuffer = static_cast< sal_Char const * >(pBuffer) + nWrittenCount;
222 nCount -= nWrittenCount;
223 Application::Yield();
227 //============================================================================
229 // SvCompositeLockBytes
231 //============================================================================
233 struct SvCompositeLockBytes_Impl
235 SvLockBytesMemberList aLockBytes;
236 SvULongs aPositions;
237 SvULongs aOffsets;
238 BOOL bPending;
239 ULONG RelativeOffset( ULONG nPos ) const;
240 ErrCode ReadWrite_Impl(
241 ULONG nPos, void* pBuffer, ULONG nCount, ULONG* pProcessed,
242 BOOL bRead );
243 SvCompositeLockBytes_Impl() : bPending( FALSE ){}
246 //============================================================================
247 ULONG SvCompositeLockBytes_Impl::RelativeOffset( ULONG nPos ) const
249 const SvULongs& rPositions = aPositions;
250 const SvULongs& rOffsets = aOffsets;
252 USHORT nMinPos = 0;
253 USHORT nListCount = rPositions.Count();
255 // Erster Lockbytes, der bearbeitet werden muss
256 while( nMinPos + 1 < nListCount && rPositions[ nMinPos + 1 ] <= nPos )
257 nMinPos ++;
258 ULONG nSectionStart = rPositions[ nMinPos ];
259 if( nSectionStart > nPos )
260 return ULONG_MAX;
261 return rOffsets[ nMinPos ] + nPos - nSectionStart;
264 //============================================================================
265 ErrCode SvCompositeLockBytes_Impl::ReadWrite_Impl(
266 ULONG nPos, void* pBuffer, ULONG nCount, ULONG* pProcessed,
267 BOOL bRead )
269 ErrCode nErr = ERRCODE_NONE;
270 SvULongs& rPositions = aPositions;
271 SvULongs& rOffsets = aOffsets;
272 SvLockBytesMemberList& rLockBytes = aLockBytes;
274 ULONG nBytes = nCount;
275 USHORT nListCount = rPositions.Count();
276 USHORT nMinPos = 0;
278 // Erster Lockbytes, der bearbeitet werden muss
279 while( nMinPos + 1 < nListCount && rPositions[ nMinPos + 1 ] <= nPos )
280 nMinPos ++;
281 ULONG nSectionStart = rPositions[ nMinPos ];
283 if( nSectionStart > nPos )
285 // Es wird aus fuehrendem Leerbereich gearbeitet
286 *pProcessed = 0;
287 return ERRCODE_IO_CANTREAD;
290 ULONG nDone;
291 while( nMinPos < nListCount )
293 ULONG nToProcess;
294 ULONG nSectionStop;
295 if( nMinPos + 1 < nListCount )
297 nSectionStop = rPositions[ nMinPos + 1 ];
298 nToProcess = MyMin( long( nSectionStop ) - nPos, nBytes );
300 else
302 nToProcess = nBytes;
303 nSectionStop = 0;
305 ULONG nAbsPos = nPos - nSectionStart + rOffsets[ nMinPos ];
306 SvLockBytes* pLB = rLockBytes.GetObject( nMinPos );
307 if( bRead )
308 nErr = pLB->ReadAt( nAbsPos, pBuffer, nToProcess, &nDone );
309 else
310 nErr = pLB->WriteAt( nAbsPos, pBuffer, nToProcess, &nDone );
311 nBytes -= nDone;
312 if( nErr || nDone < nToProcess || !nBytes )
314 *pProcessed = nCount - nBytes;
315 // Wenn aus dem letzten LockBytes nichts mehr gelesen wurde und
316 // bPending gesetzt ist, Pending zurueck
317 if( !nDone && nMinPos == nListCount - 1 )
318 return bPending ? ERRCODE_IO_PENDING : nErr;
319 else return nErr;
321 pBuffer = static_cast< sal_Char * >(pBuffer) + nDone;
322 nPos += nDone;
323 nSectionStart = nSectionStop;
324 nMinPos++;
326 return nErr;
329 //============================================================================
330 TYPEINIT1(SvCompositeLockBytes, SvLockBytes);
332 //============================================================================
333 SvCompositeLockBytes::SvCompositeLockBytes()
334 : pImpl( new SvCompositeLockBytes_Impl )
338 //============================================================================
339 SvCompositeLockBytes::~SvCompositeLockBytes()
341 delete pImpl;
344 //============================================================================
345 void SvCompositeLockBytes::SetIsPending( BOOL bSet )
347 pImpl->bPending = bSet;
350 //============================================================================
351 ULONG SvCompositeLockBytes::RelativeOffset( ULONG nPos ) const
353 return pImpl->RelativeOffset( nPos );
356 //============================================================================
357 ErrCode SvCompositeLockBytes::ReadAt(
358 ULONG nPos, void* pBuffer, ULONG nCount, ULONG* pRead ) const
360 return pImpl->ReadWrite_Impl( nPos, pBuffer, nCount, pRead, TRUE );
363 //============================================================================
364 ErrCode SvCompositeLockBytes::WriteAt(
365 ULONG nPos, const void* pBuffer, ULONG nCount, ULONG* pWritten )
367 return pImpl->ReadWrite_Impl(
368 nPos, const_cast< void * >(pBuffer), nCount, pWritten, FALSE );
371 //============================================================================
372 ErrCode SvCompositeLockBytes::Flush() const
374 SvLockBytesMemberList& rLockBytes = pImpl->aLockBytes;
375 ErrCode nErr = ERRCODE_NONE;
376 for( USHORT nCount = (USHORT)rLockBytes.Count(); !nErr && nCount--; )
377 nErr = rLockBytes.GetObject( nCount )->Flush();
378 return nErr;
381 //============================================================================
382 ErrCode SvCompositeLockBytes::SetSize( ULONG )
384 DBG_ERROR( "not implemented" );
385 return ERRCODE_IO_NOTSUPPORTED;
388 //============================================================================
389 ErrCode SvCompositeLockBytes::LockRegion( ULONG, ULONG, LockType )
391 DBG_ERROR( "not implemented" );
392 return ERRCODE_IO_NOTSUPPORTED;
395 //============================================================================
396 ErrCode SvCompositeLockBytes::UnlockRegion(
397 ULONG, ULONG, LockType )
399 DBG_ERROR( "not implemented" );
400 return ERRCODE_IO_NOTSUPPORTED;
403 //============================================================================
404 ErrCode SvCompositeLockBytes::Stat(
405 SvLockBytesStat* pStat, SvLockBytesStatFlag eFlag) const
407 USHORT nMax = pImpl->aPositions.Count() - 1;
409 SvLockBytesStat aStat;
410 ErrCode nErr = pImpl->aLockBytes.GetObject( nMax )->Stat( &aStat, eFlag );
411 pStat->nSize = pImpl->aPositions[ nMax ] + aStat.nSize;
413 return nErr;
416 //============================================================================
417 void SvCompositeLockBytes::Append(
418 SvLockBytes* pLockBytes, ULONG nPos, ULONG nOffset )
420 USHORT nCount = pImpl->aOffsets.Count();
421 pImpl->aLockBytes.Insert( pLockBytes, nCount );
422 pImpl->aPositions.Insert( nPos, nCount );
423 pImpl->aOffsets.Insert( nOffset, nCount );
426 //============================================================================
427 SvLockBytes* SvCompositeLockBytes::GetLastLockBytes() const
429 return pImpl->aLockBytes.Count() ?
430 pImpl->aLockBytes.GetObject( pImpl->aLockBytes.Count() - 1 ) : 0;