Changed the CCommandFactory logic that searches for commands.
* Changed the CCommandFactory logic that searches for commands; it now scans \resource\cif\fshell rather than \sys\bin. This means that the 'help' command now works on the emulator and on installs without all capabilities.
* Fixed wslog ciftest
// fzipup.cpp// // Copyright (c) 2008 - 2010 Accenture. All rights reserved.// This component and the accompanying materials are made available// under the terms of the "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:// Accenture - Initial contribution//#include <ezstream.h>#include <ezcompressor.h>#include <ezdecompressor.h>#include <ezfilebuffer.h>#include <f32file.h>#include "fzipup.h"const TInt KDefaultDiskNumber = 0;const TInt CZipEntry::iOffset = _FOFF(CZipEntry, iLink);const TUint16 KFZipVersion = 0x0014;TInt KWindowBits = -CEZCompressor::EMaxWBits; // negative value is an undocumented feature of our zlib implementation, ensuring we do not include the zlib header in the compressed data (which we must do for zip-file format support)const TInt KCompressedSizeRelativePosition = 18; // iCompressedSize is 18 bytes in from the current entry's LFH//// CBufferManager//CBufferManager *CBufferManager::NewLC(RFileReadStream& aInput, RFileWriteStream& aOutput, TInt aInputStreamBytes, TInt aBufferSize) { CBufferManager *bm = new (ELeave) CBufferManager(aInput, aOutput, aInputStreamBytes, aBufferSize); CleanupStack::PushL(bm); bm->ConstructL(); return bm; }CBufferManager::CBufferManager(RFileReadStream& aInput, RFileWriteStream& aOutput, TInt aInputStreamBytes, TInt aBufferSize):iInput(aInput), iOutput(aOutput), iInputStreamBytes(aInputStreamBytes), iBufferSize(aBufferSize), iInputDescriptor(NULL,0), iOutputDescriptor(NULL,0) { }CBufferManager::~CBufferManager() { delete[] iInputBuffer; delete[] iOutputBuffer; }void CBufferManager::ConstructL() { if (iInputStreamBytes < iBufferSize) iBufferSize = iInputStreamBytes; if (iBufferSize <=0) { User::Leave(KErrUnderflow); } iInputBuffer = new (ELeave) TUint8[iBufferSize]; iOutputBuffer = new (ELeave) TUint8[iBufferSize]; iInputDescriptor.Set(iInputBuffer,0,iBufferSize); iOutputDescriptor.Set(iOutputBuffer,0,iBufferSize); iReadLength = iBufferSize; }void CBufferManager::InitializeL(CEZZStream &aZStream) { ReadInputL(); aZStream.SetInput(iInputDescriptor); aZStream.SetOutput(iOutputDescriptor); }void CBufferManager::NeedInputL(CEZZStream &aZStream) { ReadInputL(); aZStream.SetInput(iInputDescriptor); }void CBufferManager::NeedOutputL(CEZZStream &aZStream) { WriteOutputL(aZStream); aZStream.SetOutput(iOutputDescriptor); }void CBufferManager::FinalizeL(CEZZStream &aZStream) { WriteOutputL(aZStream); }void CBufferManager::ReadInputL() { iInput.ReadL(iInputDescriptor, iReadLength); iInputStreamBytes -= iReadLength; if (iInputStreamBytes < iBufferSize) { iReadLength = iInputStreamBytes; } if (iReadLength < 0) { User::Leave(KErrOverflow); } }void CBufferManager::WriteOutputL(CEZZStream& aZStream) { TPtrC8 od = aZStream.OutputDescriptor(); iOutput.WriteL(od); iBytesWritten += od.Size(); }//// CZipEntry// CZipEntry* CZipEntry::NewLC(RFs& aFs, const TDesC& aFilename, const TInt aUid) { CZipEntry* self = new (ELeave) CZipEntry(aFs, aUid); CleanupStack::PushL(self); self->ConstructL(aFilename); return self; }CZipEntry::CZipEntry(RFs& aFs, const TInt aUid):iFs(aFs), iUid(aUid) { iLFH.iCRC32 = crc32(iLFH.iCRC32, NULL, 0); }CZipEntry::~CZipEntry() { if (iFileData) delete iFileData; if (iInput.SubSessionHandle() > 0) iInput.Close(); }void CZipEntry::ConstructL(const TDesC& aFilename) { User::LeaveIfError(iInput.Open(iFs, aFilename, EFileRead | EFileShareReadersOnly)); // ensure aFileName is stored in accordance with zip file-format specification TFileName2 file(aFilename); if (file.HasDriveLetter()) { file.Delete(0, 3); // remove '<drive>:\' } if (file.HasLeadingSlash()) { file.Delete(0, 1); // remove '\' } iAsciiName.Copy(file); TUint8* ptr = const_cast<TUint8*> (iAsciiName.Ptr()); TInt count = 0; do { if (*ptr == '\\') { *ptr = '/'; } ptr++; } while (count++ < iAsciiName.Length()); // config. local file header iLFH.iSignature = KLocalHeaderSignature; iLFH.iVersionNeeded = KFZipVersion; iLFH.iFlags = 0x0002; // best (-exx/-ex) compression was used iLFH.iCompressionMethod = EDeflated; TTime time; User::LeaveIfError(iInput.Modified(time)); TDateTime td = time.DateTime(); TUint16 param1 = td.Year() - 1980; TUint16 param2 = td.Month() + 1; TUint16 param3 = td.Day() + 1; iLFH.iLastModifiedFileDate = (param1 << 9) | (param2 << 5) | param3; param1 = td.Hour() + 1; param2 = td.Minute() + 1; param3 = td.Second() + 1; iLFH.iLastModifiedFileTime = (param1 << 11) | (param2 << 5) | (param3 >> 1); TInt uSize = 0; User::LeaveIfError(iInput.Size(uSize)); if (uSize <= 0) { User::Leave(KErrAbort); } iLFH.iUncompressedSize = uSize; iLFH.iCompressedSize = uSize; // note: to be adjusted later once the compression is performed CalcCRCL(); iLFH.iFileNameLength = iAsciiName.Size(); iLFH.iExtraFieldLength = 0; // config. file header iFH.iSignature = KCentralDirectoryHeaderSignature; iFH.iMadeBy = KFZipVersion; iFH.iRequired = KFZipVersion; iFH.iFlags = iLFH.iFlags; iFH.iCompressionMethod = iLFH.iCompressionMethod; iFH.iLastModifiedFileTime = iLFH.iLastModifiedFileTime; iFH.iLastModifiedFileDate = iLFH.iLastModifiedFileDate; iFH.iCRC32 = iLFH.iCRC32; iFH.iCompressedSize = iLFH.iCompressedSize; // note: to be adjusted later once the compression is performed iFH.iUncompressedSize = iLFH.iUncompressedSize; iFH.iFileNameLength = iLFH.iFileNameLength; iFH.iExtraFieldLength = iLFH.iExtraFieldLength; iFH.iFileCommentLength = 0x0000; iFH.iDiskNumberStart = KDefaultDiskNumber; iFH.iInternalFileAttributes = 0x0001; iFH.iExternalFileAttributes = 0x00000020; // hardcoded to 'Archive' iFH.iLocalHeaderOffset = 0x00000000; // to be adjusted later (if necessary) }void CZipEntry::SetOffset(TUint32 aOffset) { iFH.iLocalHeaderOffset = aOffset; }TUint32 CZipEntry::ReturnOffset() { TUint32 result = iFH.iLocalHeaderOffset; // start with the offset of the LFH result += KLocalHeaderFixedLength; // add the size of the LFH itself result += iAsciiName.Size(); // add the size of the filename result += iLFH.iCompressedSize; // add any compressed data return result; }TUint32 CZipEntry::FileHeaderSize() { TUint32 result = KCentralDirectoryHeaderFixedLength; result += iAsciiName.Size(); return result; }//// CZipEntry::CalcCRCL// mem. efficient means of calculating the crc on uncompressed data// we require a maximum of KDefaultZipBufferLength heap space regardless size of data//void CZipEntry::CalcCRCL() { ASSERT(iInput.SubSessionHandle() > 0); TInt bytesRead = 0; TInt length = KDefaultZipBufferLength; // 32Kb if (iLFH.iUncompressedSize < KDefaultZipBufferLength) { length = iLFH.iUncompressedSize; } iLFH.iCRC32 = crc32(0, NULL, 0); HBufC8* crc = HBufC8::NewLC(length); TPtr8 crcPtr = crc->Des(); User::LeaveIfError(iInput.Seek(ESeekStart, bytesRead)); do { User::LeaveIfError(iInput.Read(crcPtr, length)); iLFH.iCRC32 = crc32(iLFH.iCRC32, crcPtr.Ptr(), length); bytesRead += length; if ((iLFH.iUncompressedSize - bytesRead) < KDefaultZipBufferLength) { length = iLFH.iUncompressedSize - bytesRead; } } while (length > 0); CleanupStack::PopAndDestroy(1); // crc }//// CZipItUp// CZipItUp* CZipItUp::NewLC(RFs& aFs, TDesC& aArchive) { CZipItUp* self = new (ELeave) CZipItUp(aFs, aArchive); CleanupStack::PushL(self); self->ConstructL(); return self; } CZipItUp::CZipItUp(RFs& aFs, TDesC& aArchive):iFs(aFs), iFileName(aArchive), iZipMemberLinkedList(CZipEntry::iOffset), iZipMemberLinkedListIter(iZipMemberLinkedList) { }CZipItUp::~CZipItUp() { if (iFile.SubSessionHandle() > 0) { iFile.Close(); } while (!iZipMemberLinkedList.IsEmpty()) { CZipEntry* entry = iZipMemberLinkedList.First(); iZipMemberLinkedList.Remove(*entry); delete entry; } iZipMemberLinkedList.Reset(); }void CZipItUp::ConstructL() { User::LeaveIfError(iFile.Create(iFs, iFileName, EFileStream | EFileShareExclusive)); }//// CZipItUp::AddFileL//void CZipItUp::AddFileL(const TDesC& aFile) { if (!DuplicateEntryL(aFile)) { // spawn a new zip entry, compress the file, add it to the list of zip file contained in the archive CZipEntry* zipEntry = CZipEntry::NewLC(iFs, aFile, ++iEntryUid); AddEntryL(*zipEntry); CleanupStack::Pop(zipEntry); } }//// CZipItUp::DuplicateEntryL// run a check against the zip archive's current entries (if any!) for duplicate files// return ETrue if a duplicate is found//TBool CZipItUp::DuplicateEntryL(const TDesC& aFile) { if (iZipMemberLinkedList.IsEmpty()) { return EFalse; } // turn aFile into a zip-file format filename TFileName2 file(aFile); if (file.HasDriveLetter()) { file.Delete(0, 3); // remove '<drive>:\' } if (file.HasLeadingSlash()) { file.Delete(0, 1); // remove '\' } TBuf8<KMaxFileName> ascii; ascii.Copy(file); TUint8* ptr = const_cast<TUint8*> (ascii.Ptr()); TInt count = 0; do { if (*ptr == '\\') { *ptr = '/'; } ptr++; } while (count++ < ascii.Length()); // iterate through zip archive entries looking for a duplicate iZipMemberLinkedListIter.SetToFirst(); CZipEntry* entry = iZipMemberLinkedListIter++; while (entry != NULL) { if (entry->iAsciiName == ascii) { return ETrue; } entry = iZipMemberLinkedListIter++; } return EFalse; }//// CZipItUp::AddEntryL// Add an entry to the zip archive.//void CZipItUp::AddEntryL(CZipEntry& aEntry) { // append the new entry to the queue if (!iZipMemberLinkedList.IsEmpty()) { // prior entries in the list therefore need to adjust this entry's local file header offset CZipEntry* lastEntry = iZipMemberLinkedList.Last(); User::LeaveIfNull(lastEntry); } iZipMemberLinkedList.AddLast(aEntry); }//// CZipItUp::CreateZipL// Creates the actual file, including all the previously compressed zip files in the archive//void CZipItUp::CreateZipL() { ASSERT(iFile.SubSessionHandle() > 0); if (iZipMemberLinkedList.IsEmpty()) { User::Leave(KErrGeneral); } RFileWriteStream stream(iFile); stream.PushL(); // initialise central directory header iCDT.iSignature = CZipArchive::KCentralDirectorySignature; iCDT.iDiskNumber = KDefaultDiskNumber; iCDT.iStartDiskNumber = KDefaultDiskNumber; iCDT.iLocalEntryCount = 0; iCDT.iTotalEntryCount = 0; iCDT.iSize = 0; iCDT.iCommentLength = 0; // iterate through each zip entry, appending local file header (LFH), file data (FD) to file iZipMemberLinkedListIter.SetToFirst(); CZipEntry* entry = iZipMemberLinkedListIter++; CZipEntry* prior = NULL; User::LeaveIfNull(entry); do { if (prior) { // adjust file header local offset if necessary entry->SetOffset(prior->ReturnOffset()); } // insert entry's Local File Header AppendLocalFileHeaderL(stream, *entry); // insert entry's File Data AppendCompressedDataL(stream, *entry); // adjust cdt parameters iCDT.iLocalEntryCount++; iCDT.iTotalEntryCount++; iCDT.iSize += entry->FileHeaderSize(); // move onto the next entry prior = entry; entry = iZipMemberLinkedListIter++; } while (entry != NULL); // adjust cdt offset parameter iCDT.iOffset = iZipMemberLinkedList.Last()->ReturnOffset(); // iterate through each zip entry, appending the central directory File Headers to file (these must go after LFH, FD entries) iZipMemberLinkedListIter.SetToFirst(); entry = iZipMemberLinkedListIter++; do { // central directory File Header AppendCentralDirectoryFileHeaderL(stream, *entry); // move onto the next entry entry = iZipMemberLinkedListIter++; } while (entry != NULL); // append the central directory trailer AppendCentralDirectoryTrailerL(stream); // commit the transaction stream.CommitL(); stream.Pop(); stream.Close(); // go back through & adjust compressed size values for each zip entry post-mortem ASSERT(iFile.SubSessionHandle() == 0); User::LeaveIfError(iFile.Open(iFs, iFileName, EFileWrite | EFileShareExclusive)); TInt pos = 0; const TInt remainder = 8; // CZipArchive::KLocalHeaderFixedLength - KCompressedSizeRelativePosition User::LeaveIfError(iFile.Seek(ESeekStart, pos)); iZipMemberLinkedListIter.SetToFirst(); entry = iZipMemberLinkedListIter++; do { pos += KCompressedSizeRelativePosition; // step to iCompressedSize location in the current entry's LFH TUint32 cs = entry->iLFH.iCompressedSize; TUint32 KMyByte = 0x000000FF; TInt bytecount = 0; TBuf8<8> compSize; do { TUint32 csChar((cs & KMyByte)); compSize.Append(csChar); cs >>= 8; } while (++bytecount < 4); // zip-file format allows us 4 bytes only for the compressed size value User::LeaveIfError(iFile.Write(pos, compSize)); pos += bytecount; // the 4 bytes we just wrote // step over remaing bytes to the beginning of the next entry's LFH pos += remainder; pos += entry->iAsciiName.Size(); pos += entry->iLFH.iCompressedSize; // we're now positioned at the next entry's LFH entry = iZipMemberLinkedListIter++; } while (entry != NULL); }void CZipItUp::AppendLocalFileHeaderL(RFileWriteStream& aStream, CZipEntry& aZipEntry) { aStream.WriteUint32L(aZipEntry.iLFH.iSignature); aStream.WriteUint16L(aZipEntry.iLFH.iVersionNeeded); aStream.WriteUint16L(aZipEntry.iLFH.iFlags); aStream.WriteUint16L(aZipEntry.iLFH.iCompressionMethod); aStream.WriteUint16L(aZipEntry.iLFH.iLastModifiedFileTime); aStream.WriteUint16L(aZipEntry.iLFH.iLastModifiedFileDate); aStream.WriteUint32L(aZipEntry.iLFH.iCRC32); aStream.WriteUint32L(aZipEntry.iLFH.iCompressedSize); aStream.WriteUint32L(aZipEntry.iLFH.iUncompressedSize); aStream.WriteUint16L(aZipEntry.iLFH.iFileNameLength); aStream.WriteUint16L(aZipEntry.iLFH.iExtraFieldLength); aStream.WriteL(aZipEntry.iAsciiName); }void CZipItUp::AppendCompressedDataL(RFileWriteStream& aStream, CZipEntry& aZipEntry) { // compress data & stream it to the zip archive (aStream) RFileReadStream inStream; inStream.Attach(aZipEntry.iInput); // note takes ownership of iInput subsession handle CBufferManager* fb = CBufferManager::NewLC(inStream, aStream, aZipEntry.iLFH.iUncompressedSize, KDefaultZipBufferLength); CEZCompressor* compressor = CEZCompressor::NewLC(*fb, CEZCompressor::EBestCompression, KWindowBits, CEZCompressor::EDefMemLevel, CEZCompressor::EDefaultStrategy); while (compressor->DeflateL()){/* do nothing */} // update the entry's LocalFileHeader and FileHeader aZipEntry.iLFH.iCompressedSize = fb->TotalBytesOut(); aZipEntry.iFH.iCompressedSize = aZipEntry.iLFH.iCompressedSize; // cleanup CleanupStack::PopAndDestroy(2, fb); // compressor, fb inStream.Close(); }void CZipItUp::AppendCentralDirectoryFileHeaderL(RFileWriteStream& aStream, CZipEntry& aEntry) { aStream.WriteUint32L(aEntry.iFH.iSignature); aStream.WriteUint16L(aEntry.iFH.iMadeBy); aStream.WriteUint16L(aEntry.iFH.iRequired); aStream.WriteUint16L(aEntry.iFH.iFlags); aStream.WriteUint16L(aEntry.iFH.iCompressionMethod); aStream.WriteUint16L(aEntry.iFH.iLastModifiedFileTime); aStream.WriteUint16L(aEntry.iFH.iLastModifiedFileDate); aStream.WriteUint32L(aEntry.iFH.iCRC32); aStream.WriteUint32L(aEntry.iFH.iCompressedSize); aStream.WriteUint32L(aEntry.iFH.iUncompressedSize); aStream.WriteUint16L(aEntry.iFH.iFileNameLength); aStream.WriteUint16L(aEntry.iFH.iExtraFieldLength); aStream.WriteUint16L(aEntry.iFH.iFileCommentLength); aStream.WriteUint16L(aEntry.iFH.iDiskNumberStart); aStream.WriteUint16L(aEntry.iFH.iInternalFileAttributes); aStream.WriteUint32L(aEntry.iFH.iExternalFileAttributes); aStream.WriteUint32L(aEntry.iFH.iLocalHeaderOffset); aStream.WriteL(aEntry.iAsciiName); }void CZipItUp::AppendCentralDirectoryTrailerL(RFileWriteStream& aStream) { aStream.WriteUint32L(iCDT.iSignature); aStream.WriteUint16L(iCDT.iDiskNumber); aStream.WriteUint16L(iCDT.iStartDiskNumber); aStream.WriteUint16L(iCDT.iLocalEntryCount); aStream.WriteUint16L(iCDT.iTotalEntryCount); aStream.WriteUint32L(iCDT.iSize); aStream.WriteUint32L(iCDT.iOffset); aStream.WriteUint16L(iCDT.iCommentLength); }