diff -r 000000000000 -r f58d6ec98e88 reszip/src/resentry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/reszip/src/resentry.cpp Thu Dec 17 09:14:18 2009 +0200 @@ -0,0 +1,502 @@ +/* +* Copyright (c) 1997-1999 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: +* +*/ + + + +#include "resentry.h" +#include "resdict.h" +#include "rescomp.h" + +//TResComponent + +TInt TResComponent::Size(TInt aDictionaryBits) + { + if (iType == EResTypePlain) + { + if (iLength == 0) + return 0; + TInt bits = iLength * 8; + bits++; // data flag + if (iLength == 1) + bits ++; // first bit zero if 1 byte of data + else + { + bits++; // first bit 1 if >1 byte of data + if (iLength == 2) + { + bits ++; // second bit zero if 2 bytes of data + } + else + { + bits ++; // second bit 1 if >2 bytes of data + if (iLength < 11) + { + // write 4 bits of data + 1 zero bit flag + bits += 4; + } + else + { + // write 8 bits of data + 1 '1' bit flag + bits += 9; + } + } + } + +// console->Printf(_L("Type Plain: %d\n"), bits); + return bits; + } + if (iType == EResTypeToken) + { + return 1+aDictionaryBits; +// console->Printf(_L("Type Token: %d\n"), iToken); +// return 8; // dictionary entries are stored in 6 bits + } + return 0; + } + + +void TResComponent::WriteBitStreamL(TBitWriter& aWriter, TInt aDictionaryBits) + { + if (iType == EResTypePlain) + { + if (iLength == 0) + return; +// Debugging code +/* + RDebug::Print(_L("Data Length: %d"), iLength); + TBuf<100> b; + for (TInt xx=0; xx1 byte of data + if (iLength == 2) + { + aWriter.WriteL(0, 1); // second bit zero if 2 bytes of data + } + else + { + aWriter.WriteL(1, 1); // second bit 1 if >2 bytes of data + if (iLength < 11) + { + aWriter.WriteL(0, 1); + aWriter.WriteL(iLength-3, 3); + // write 4 bits of data + 1 zero bit flag + } + else + { + aWriter.WriteL(1, 1); + aWriter.WriteL(iLength, 8); + // write 8 bits of data + 1 '1' bit flag + if (iLength > 255) + { + User::Panic(_L("Entry too long"),0); + } + } + } + } + // Now write data to output + for (TInt ii=0; ii(4); + } + +CResEntry::~CResEntry() + { + delete iComponent; + } + + +void CResEntry::AddPlainDataL(TUint8* aData, TInt aLength) + { + TResComponent comp; + comp.iType = EResTypePlain; + comp.iData = aData; + comp.iLength = aLength; + iComponent->AppendL(comp); + } + +void CResEntry::InsertTokenL(TInt aPosition, TInt aToken) + { + TResComponent comp; + comp.iType = EResTypeToken; + comp.iToken = aToken; + comp.iLength=0; + iComponent->InsertL(aPosition,comp); + (*iDict)[aToken].iUses++; + } + +void CResEntry::SplitPlainDataWithZeroSpacedL(TInt aComponent, TInt aZeroSpacedStart, TInt aLength) + { + TResComponent comp = (*iComponent)[aComponent]; + + TResComponent newComp1; + newComp1.iType = EResTypePlain; + newComp1.iData = comp.iData; + newComp1.iLength = aZeroSpacedStart; + + TResComponent newComp2; + newComp2.iType = EResTypePlain; + newComp2.iData = comp.iData + aZeroSpacedStart + aLength; + newComp2.iLength = comp.iLength-(aZeroSpacedStart+aLength); + + TResComponent newComp3; + newComp3.iType = EResTypeZeroSpaced; + newComp3.iData = comp.iData + aZeroSpacedStart; + newComp3.iLength = aLength; + + + iComponent->Delete(aComponent); + TInt componentPos = aComponent; + if (newComp1.iLength != 0) + { + iComponent->InsertL(componentPos, newComp1); + componentPos++; + } + + iComponent->InsertL(componentPos, newComp3); + componentPos++; + + if (newComp2.iLength != 0) + { + iComponent->InsertL(componentPos, newComp2); + } + } + + +void CResEntry::SplitPlainDataWithTokenL(TInt aComponent, TInt aToken, TInt aPosition) + { + TResComponent comp = (*iComponent)[aComponent]; + TDesC8& dEntry = (*iDict)[aToken].Data(); + TInt dictLength = dEntry.Length(); + + TResComponent newComp1; + newComp1.iType = EResTypePlain; + newComp1.iData = comp.iData; + newComp1.iLength = aPosition; + + TResComponent newComp2; + newComp2.iType = EResTypePlain; + newComp2.iData = comp.iData + aPosition + dictLength; + newComp2.iLength = comp.iLength - dictLength - aPosition; + + iComponent->Delete(aComponent); + TInt componentPos = aComponent; + if (newComp1.iLength != 0) + { + iComponent->InsertL(componentPos, newComp1); + componentPos++; + } + InsertTokenL(componentPos, aToken); + componentPos++; + + if (newComp2.iLength != 0) + { + iComponent->InsertL(componentPos, newComp2); + } + + } + + +TInt CResEntry::Size(TInt aDictionaryBits) + { + TInt size = 0; + TInt count = iComponent->Count(); + for (TInt ii=0; iiAt(ii).Size(aDictionaryBits); + } + return size; + } + +void CResEntry::WriteBitStreamL(TBitWriter& aWriter, TInt aDictionaryBits) + { + TInt count = iComponent->Count(); + for (TInt ii=0; iiAt(ii).WriteBitStreamL(aWriter, aDictionaryBits); + } + } + + + +TBool CResEntry::DoMatchDictL(TResComponent& aComp, TInt aOffset, TInt aDictIndex) + { + TInt dCount = iDict->Count(); + TInt cSize = aComp.iLength; + for (TInt ii=0; iiPrintf(_L("Found %d Offset: %d\n"),ii, pos); + SplitPlainDataWithTokenL(aOffset, ii, pos); + return ETrue; + } + } + } + } + return EFalse; + } + + +void CResEntry::MatchDictL(TInt aDictIndex) + { + // Match plain text components against dictionary + TInt count = iComponent->Count(); + for (TInt ii=0; iiCount(); + ii--; + } + } + } + } + + +/* +void CResEntry::MatchZeroSpacedL() + { + // Find zero spaced data + TInt count = iComponent->Count(); + for (TInt ii=0; iiCount(); + ii--; + } + } + } + } + + +TBool CResEntry::DoMatchZeroSpacedL(TResComponent& aComp, TInt aOffset) + { + // Analyse data and see if there is a string of zero spaced data + // Data, followed by zero + TInt length = aComp.iLength; + TInt pos = 0; + TInt dataSize = 0; + for (TInt ii=0; ii 2) + { + SplitPlainDataWithZeroSpacedL(aOffset, pos, dataSize); + return ETrue; + } + dataSize = 0; + } + } + return EFalse; + } +*/ + + +void CResEntry::MatchSelfL(TInt aRes,CResComp* aResComp) + { + // Find duplicates within resource + TInt count = iComponent->Count(); + for (TInt ii=0; iiCount(); + ii--; + } + } + } + } + + + + +/* +TBool CResEntry::MatchPreviousComponent(TInt aCompIndex, TDesC8& aMatch) + { + TInt size = aMatch.Size(); + for (TInt ii=0; iiPrintf(_L("Matching: %d (Length: %d)\n"), aCompIndex, size); + if (comp.iLength <= size) + { + TPtrC8 buf(comp.iData, comp.iLength); + TInt found = buf.Find(aMatch); + if (found != KErrNotFound) + { + console->Printf(_L("Found\n")); + return ii; + } + } + } + } + + return KErrNotFound; + } +*/ + +TBool CResEntry::DoMatchSelfL(TResComponent& aComp, TInt aOffset, TInt aRes, CResComp* aResComp) + { + TInt cSize = aComp.iLength; + TInt matchSize = cSize/2; + if (matchSize > KMaxDictEntry) + matchSize = KMaxDictEntry; + + while (matchSize > 1) + { + TInt pos=matchSize; + TInt positions = (cSize-(matchSize*2))+1; + while (positions) + { + TPtr8 match(aComp.iData + pos, matchSize,matchSize); + TPtr8 left(aComp.iData, pos, pos); + TInt found = left.Find(match); + if (found != KErrNotFound) + { + TInt token = iDict->AddEntryL(match); + // Remove both matches and replace with token + SplitPlainDataWithTokenL(aOffset, token, pos); + SplitPlainDataWithTokenL(aOffset, token, found); + return ETrue; + } + else + { + // Find in all other resources + TInt find = aResComp->FindInResources(match, aRes); + if (find != KErrNotFound) + { + TInt token = iDict->AddEntryL(match); + SplitPlainDataWithTokenL(aOffset, token, pos); + return ETrue; + } + + } + positions--; + pos++; + } + matchSize--; + } + return EFalse; + } + + + TResType iType; + TUint8* iData; + TInt iLength; + TInt iToken; + + +void CResEntry::CheckForLongDataStringsL() + { + TInt components = iComponent->Count(); + for (TInt ii=0; ii 255) + { + TInt length = comp.iLength; + RDebug::Print(_L("Component Too Long!")); + TResComponent comp1; + comp1.iType = comp.iType; + comp1.iData = comp.iData; + comp1.iLength = 255; + comp1.iToken = comp.iToken; + + TResComponent comp2; + comp2.iType = comp.iType; + comp2.iData = comp.iData + 255; + comp2.iLength = length - 255; + comp2.iToken = comp.iToken; + + iComponent->Delete(ii); + iComponent->InsertL(ii, comp1); + iComponent->InsertL(ii+1, comp2); + + components = iComponent->Count(); + } + } + } +