Fixed fzip's extracting of nested folders, added --logging-allocator option to leak.
authorTom Sutcliffe <thomas.sutcliffe@accenture.com>
Fri, 13 Aug 2010 13:09:59 +0100
changeset 31 d0e1c40de386
parent 30 35cb3fe43f60
child 32 50af04b02d7d
Fixed fzip's extracting of nested folders, added --logging-allocator option to leak.
commands/fzip/fzip.cpp
commands/leak/leak.cif
commands/leak/leak.cpp
commands/leak/leak.h
commands/leak/leak.mmp
--- a/commands/fzip/fzip.cpp	Thu Aug 12 16:38:42 2010 +0100
+++ b/commands/fzip/fzip.cpp	Fri Aug 13 13:09:59 2010 +0100
@@ -62,7 +62,7 @@
 				PrintWarning(_L("Ignoring \'-r\' recurse option."));
 				}
 			}
-		TRAPL(ExpandArchiveL(), _L("Couldn't expand archive"));
+		ExpandArchiveL();
 		}
 	else
 		{
@@ -323,7 +323,8 @@
 		{
 		Printf(_L("Opening\t\t\'%S\'\r\n"), &iArchive);
 		}
-	CZipFile* zip = CZipFile::NewL(Fs(), iArchive);
+	CZipFile* zip = NULL;
+	TRAPL(zip = CZipFile::NewL(Fs(), iArchive), _L("Couldn't create CZipFile for %S"), &iArchive);
 	CleanupStack::PushL(zip);
 	CZipFileMemberIterator* zipIterator = zip->GetMembersL();
 	CleanupStack::PushL(zipIterator);
@@ -344,10 +345,6 @@
 //
 void CCmdZip::ExtractZipFileL(CZipFile& aZip, const CZipFileMember& aMember)
 	{
-	// prep. the stream
-	RZipFileMemberReaderStream* readStream;
-	aZip.GetInputStreamL(&aMember, readStream);
-	CleanupStack::PushL(readStream);
 	// prep. the destination file. 
 	// note if iUnzipPath is not specified, it'll stuff the extracted file in the current directory from which fzip.exe runs
 	RFile newFile;
@@ -356,9 +353,16 @@
 	TInt err = Fs().MkDirAll(dest);
 	if ((err != KErrNone) && (err != KErrAlreadyExists))
 		{
-		User::Leave(err);
+		LeaveIfErr(err, _L("Couldn't create directory for file %S"), &dest);
 		}
-	User::LeaveIfError(newFile.Replace(Fs(), dest, EFileShareExclusive));
+	if (aMember.Name()->Right(1) == _L("\\")) return; // It's a directory entry, nothing more to be done
+
+	// prep. the stream
+	RZipFileMemberReaderStream* readStream;
+	aZip.GetInputStreamL(&aMember, readStream);
+	CleanupStack::PushL(readStream);
+
+	LeaveIfErr(newFile.Replace(Fs(), dest, EFileShareExclusive), _L("Couldn't create file %S"), &dest);
 	CleanupClosePushL(newFile);
 	if (iVerbose)
 		{
@@ -376,8 +380,8 @@
 	TPtr8 ptr = data->Des();
 	do
 		{
-		User::LeaveIfError(readStream->Read(ptr, length));
-		User::LeaveIfError(newFile.Write(ptr));
+		LeaveIfErr(readStream->Read(ptr, length), _L("Error reading from zip stream"));
+		LeaveIfErr(newFile.Write(ptr), _L("Error writing to file %S"), &dest);
 		bytesRead += length;
 		if ((aMember.UncompressedSize() - bytesRead) < KDefaultZipBufferLength)
 			{
--- a/commands/leak/leak.cif	Thu Aug 12 16:38:42 2010 +0100
+++ b/commands/leak/leak.cif	Fri Aug 13 13:09:59 2010 +0100
@@ -52,6 +52,10 @@
 
 If specified, when an allocation fails retry using a smaller increment amount.
 
+==option bool l logging-allocator
+
+If specified, install the logging allocator before starting to leak memory. Assumes the C<--heap> option.
+
 ==copyright
 
 Copyright (c) 2007-2010 Accenture. All rights reserved.
--- a/commands/leak/leak.cpp	Thu Aug 12 16:38:42 2010 +0100
+++ b/commands/leak/leak.cpp	Fri Aug 13 13:09:59 2010 +0100
@@ -12,6 +12,9 @@
 
 #include "leak.h"
 #include <fshell/common.mmh>
+#ifdef FSHELL_QR3_SUPPORT_LOGGINGALLOCATOR
+#include <fshell/loggingallocator.h>
+#endif
 
 const TInt KMinChunkSize = 4 * 1024;
 const TInt KMaxChunkSize = 512 * 1024 * 1024;
@@ -26,6 +29,12 @@
 
 CCmdLeak::~CCmdLeak()
 	{
+#ifdef FSHELL_QR3_SUPPORT_LOGGINGALLOCATOR
+	if (iLoggingAllocator)
+		{
+		// Hmm how do I clean up a logging allocator created with RLoggingAllocator::New()?
+		}
+#endif
 	iChunk.Close();
 	if (iChunkHeap)
 		{
@@ -67,10 +76,21 @@
 			}
 		}
 
+	if (iUseLoggingAllocator) iUseHeap = ETrue; // Using the logging allocator implies the --heap option
+
 	if (iUseHeap)
 		{
 		iChunkHeap = UserHeap::ChunkHeap(NULL, KMinChunkSize, 256*1024*1024);
 		if (!iChunkHeap) LeaveIfErr(KErrNoMemory, _L("Couldn't create chunk heap"));
+		iAllocatorToUse = iChunkHeap;
+
+#ifdef FSHELL_QR3_SUPPORT_LOGGINGALLOCATOR
+		if (iUseLoggingAllocator)
+			{
+			LeaveIfErr(RLoggingAllocator::New(0, iChunkHeap, iLoggingAllocator), _L("Couldn't create logging allocator"));
+			iAllocatorToUse = iLoggingAllocator;
+			}
+#endif
 		}
 	else
 		{
@@ -137,6 +157,11 @@
 
 	_LIT(KOptRetry, "retry");
 	aOptions.AppendBoolL(iRetry, KOptRetry);
+
+#ifdef FSHELL_QR3_SUPPORT_LOGGINGALLOCATOR
+	_LIT(KOptUseLoggingAllocator, "logging-allocator");
+	aOptions.AppendBoolL(iUseLoggingAllocator, KOptUseLoggingAllocator);
+#endif
 	}
 
 void CCmdLeak::ArgumentsL(RCommandArgumentList& aArguments)
@@ -153,9 +178,9 @@
 TInt CCmdLeak::LeakStep(TInt aAmount)
 	{
 	TInt err = KErrNone;
-	if (iChunkHeap)
+	if (iAllocatorToUse)
 		{
-		TAny* cell = iChunkHeap->Alloc(aAmount);
+		TAny* cell = iAllocatorToUse->Alloc(aAmount);
 		if (!cell) err = KErrNoMemory;
 		}
 	else
--- a/commands/leak/leak.h	Thu Aug 12 16:38:42 2010 +0100
+++ b/commands/leak/leak.h	Fri Aug 13 13:09:59 2010 +0100
@@ -12,6 +12,8 @@
 
 #include <fshell/ioutils.h>
 
+class RLoggingAllocator;
+
 using namespace IoUtils;
 
 class CCmdLeak : public CCommandBase
@@ -37,9 +39,12 @@
 	TUint iHeapAddr;
 	TBool iUseHeap;
 	TBool iRetry;
+	TBool iUseLoggingAllocator;
 
 	RChunk iChunk;
 	RAllocator* iChunkHeap;
+	RLoggingAllocator* iLoggingAllocator;
+	RAllocator* iAllocatorToUse;
 
 	TInt iCurrentLeak;
 	};
--- a/commands/leak/leak.mmp	Thu Aug 12 16:38:42 2010 +0100
+++ b/commands/leak/leak.mmp	Fri Aug 13 13:09:59 2010 +0100
@@ -30,4 +30,8 @@
 library         am-eikclient.lib
 #endif
 
+#ifdef FSHELL_QR3_SUPPORT_LOGGINGALLOCATOR
+library			loggingallocator.lib
+#endif
+
 macro           EXE_BUILD