--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videocollection/mpxmyvideoscollection/src/vcxmyvideosasyncfilecopy.cpp Wed Mar 31 21:34:36 2010 +0300
@@ -0,0 +1,294 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Asynchronous file copy, implemented with several small sync block copies.*
+*/
+
+
+
+
+// INCLUDE FILES
+#include <mpxlog.h>
+#include <bautils.h>
+#include "vcxmyvideosasyncfilecopy.h"
+
+/**
+* One block shouldn't take more than 1 second to copy to keep cancel
+* response fast enough. On the otherhand, the deleting the already
+* copied data may take several seconds.
+*
+* Copying speed tests (from massmemory to memorycard):
+*
+* Block size speed response time
+* 6MB -> 3.20 MB/s ~2sec (unacceptable response time, full speed)
+* 3MB -> 3.17 MB/s ~1sec (poor response time, almost full speed)
+* 1MB -> 3.16 MB/s ~0.3sec (good response time, almost full speed)
+* 0.5MB -> 2.60 MB/s ~0.19sec (good response time, some speed loss)
+*
+* -> 1MB is the best.
+*
+* * Copying speed tests (from memorycard to massmemory):
+*
+* Block size speed response time
+* 3MB -> 5.470 MB/s 0.548sec
+* 1MB -> 4.393 MB/s 0.228sec
+*
+* 1M gives slightly reduced speed, great response time. 3MB would be better than
+* 1M but can't use it since it gives 1sec response time in memorycard writing.
+*/
+const TInt KBigBufSize = 1024 * 1024; // 1MB
+const TInt KMediumBufSize = 512 * 1024; // 0.5MB
+const TInt KSmallBufSize = 100 * 1024; // 0.1MB
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosAsyncFileCopy* CVcxMyVideosAsyncFileCopy::NewL( RFs& aFs )
+ {
+ CVcxMyVideosAsyncFileCopy* self = new (ELeave) CVcxMyVideosAsyncFileCopy( aFs );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// Destructor.
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosAsyncFileCopy::~CVcxMyVideosAsyncFileCopy()
+ {
+ iSourceFile.Close();
+ iTargetFile.Close();
+ delete iFileBlockBuffer;
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor.
+// ----------------------------------------------------------------------------
+//
+CVcxMyVideosAsyncFileCopy::CVcxMyVideosAsyncFileCopy( RFs& aFs )
+: iFs( aFs )
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosAsyncFileCopy::ConstructL ()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosAsyncFileCopy::CopyL
+// ----------------------------------------------------------------------------
+//
+TBool CVcxMyVideosAsyncFileCopy::CopyL( const TDesC& aSourceFileName,
+ const TDesC& aTargetFileName )
+ {
+ MPX_DEBUG1("CVcxMyVideosAsyncFileCopy::CopyL() start");
+
+ if ( iIsCopying )
+ {
+ User::Leave( KErrNotReady );
+ }
+
+ TInt error = iSourceFile.Open( iFs, aSourceFileName, EFileRead | EFileShareReadersOnly );
+
+ User::LeaveIfError( error );
+
+ error = iTargetFile.Replace( iFs, aTargetFileName, EFileWrite | EFileWriteDirectIO
+ | EFileShareExclusive );
+
+ if ( error == KErrPathNotFound )
+ {
+ error = iFs.MkDirAll( aTargetFileName );
+ if ( error == KErrNone )
+ {
+ error = iTargetFile.Create( iFs, aTargetFileName, EFileWrite
+ | EFileWriteDirectIO | EFileShareExclusive );
+ }
+ }
+
+ User::LeaveIfError( error );
+ User::LeaveIfError( iSourceFile.Size( iDataRemaining ) );
+ User::LeaveIfError( iTargetFile.SetSize( iDataRemaining ) );
+
+ TInt suggestBlockSize;
+ if ( iDataRemaining > KBigBufSize )
+ {
+ suggestBlockSize = KBigBufSize;
+ }
+ else
+ {
+ suggestBlockSize = iDataRemaining;
+ }
+ AllocateFileBlockBufferL( suggestBlockSize );
+
+ iReadPos = 0;
+ iIsCopying = ETrue;
+
+#ifdef _DEBUG
+ iStartTime.UniversalTime();
+#endif
+
+ DoNextBlockCopy();
+
+ MPX_DEBUG1("CVcxMyVideosAsyncFileCopy::CopyL() exit");
+ return !iIsCopying;
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosAsyncFileCopy::CopyIsOngoing
+// ----------------------------------------------------------------------------
+//
+TBool CVcxMyVideosAsyncFileCopy::CopyIsOngoing()
+ {
+ return iIsCopying;
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosAsyncFileCopy::DoNextBlockCopy
+// ----------------------------------------------------------------------------
+//
+TInt CVcxMyVideosAsyncFileCopy::DoNextBlockCopy()
+ {
+ TInt err = KErrNone;
+ TPtr8 fileBufPtr = iFileBlockBuffer->Des();
+
+ TInt bytesToCopy = Min( iDataRemaining, fileBufPtr.MaxSize() );
+
+ err = iSourceFile.Read( iReadPos, fileBufPtr, bytesToCopy );
+ if ( err == KErrNone && fileBufPtr.Length() != bytesToCopy )
+ {
+ err = KErrCorrupt;
+ }
+ if ( err == KErrNone )
+ {
+ err = iTargetFile.Write( iReadPos, fileBufPtr, bytesToCopy );
+ }
+ if ( err != KErrNone )
+ {
+ EndCopy( ETrue /* remove target file */);
+ return err;
+ }
+
+ iReadPos += bytesToCopy;
+ iDataRemaining -= bytesToCopy;
+
+ if ( iDataRemaining == 0 )
+ {
+ EndCopy( EFalse /* keep target file */);
+ }
+
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosAsyncFileCopy::Cancel
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosAsyncFileCopy::Cancel()
+ {
+ MPX_DEBUG1("CVcxMyVideosAsyncFileCopy::Cancel() start");
+
+ if ( iIsCopying )
+ {
+ EndCopy( ETrue /* remove target file */ );
+ }
+ MPX_DEBUG1("CVcxMyVideosAsyncFileCopy::Cancel() exit");
+ }
+
+// ----------------------------------------------------------------------------
+// CVcxMyVideosAsyncFileCopy::AllocateFileBlockBufferL
+// ----------------------------------------------------------------------------
+//
+void CVcxMyVideosAsyncFileCopy::AllocateFileBlockBufferL( TInt aFileSize )
+ {
+ delete iFileBlockBuffer;
+ iFileBlockBuffer = NULL;
+
+ TInt big = Min( aFileSize, KBigBufSize );
+ iFileBlockBuffer = HBufC8::New( big );
+ if ( !iFileBlockBuffer )
+ {
+ iFileBlockBuffer = HBufC8::New( KMediumBufSize );
+ }
+ if ( !iFileBlockBuffer )
+ {
+ iFileBlockBuffer = HBufC8::NewL( KSmallBufSize );
+ }
+ }
+
+void CVcxMyVideosAsyncFileCopy::EndCopy( TBool aRemoveTargetFile )
+ {
+ MPX_DEBUG1("CVcxMyVideosAsyncFileCopy::EndCopy() start");
+
+ TTime modified;
+ iSourceFile.Modified( modified );
+ iTargetFile.SetModified( modified );
+
+#ifdef _DEBUG
+
+ TDateTime dT = modified.DateTime();
+ TBuf<200> buf;
+ buf.Format(_L("CVcxMyVideosAsyncFileCopy:: setting file modified date: %2d.%2d.%4d %2d:%2d:%2d"),
+ dT.Day()+1, dT.Month()+1, dT.Year(), dT.Hour(), dT.Minute(), dT.Second() );
+ MPX_DEBUG2("%S", &buf );
+
+ const TInt megaBytes = 0x100000;
+ const TInt kiloBytes = 1024;
+ TInt dataCopiedInMegaBytes = iReadPos / megaBytes;
+ TTime now;
+ now.UniversalTime();
+ TTimeIntervalSeconds interval;
+ now.SecondsFrom( iStartTime, interval );
+ TInt copyingSpeed = 0;
+ if ( interval.Int() > 0 )
+ {
+ copyingSpeed = (iReadPos / kiloBytes) / interval.Int();
+ }
+ MPX_DEBUG3("CVcxMyVideosAsyncFileCopy:: Data copied: %d (MB), %d kB/s", dataCopiedInMegaBytes, copyingSpeed);
+#endif
+
+ delete iFileBlockBuffer;
+ iFileBlockBuffer = NULL;
+ iReadPos = 0;
+ iDataRemaining = 0;
+ iSourceFile.Close();
+ iIsCopying = EFalse;
+
+ if ( aRemoveTargetFile )
+ {
+ TFileName fileName;
+ TInt err = iTargetFile.FullName( fileName );
+
+ iTargetFile.Close();
+
+ if ( err == KErrNone )
+ {
+ MPX_DEBUG2("CVcxMyVideosAsyncFileCopy:: removing file: %S", &fileName);
+ iFs.Delete( fileName );
+ }
+ }
+ else
+ {
+ iTargetFile.Close();
+ }
+
+ MPX_DEBUG1("CVcxMyVideosAsyncFileCopy::EndCopy() exit");
+ }