diff -r 7333d7932ef7 -r 8b7f4e561641 secureswitools/swisistools/source/rscparser/barscimpl.cpp --- a/secureswitools/swisistools/source/rscparser/barscimpl.cpp Tue Aug 31 15:21:33 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1129 +0,0 @@ -// Copyright (c) 2009 - 2010 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: -// -/** -* @file BaRscImpl.cpp -* -* @internalComponent -* @released -*/ -#include -#include -#include -#include -#include -#include "barsc2.h" -#include "barscimpl.h" -#include "dictionarycompression.h" -#include "ucmp.h" -#include "util.h" -#include "parse.h" - -#define REINTERPRET_CAST(type,exp) (reinterpret_cast(exp)) -#define CONST_CAST(type,exp) (const_cast(exp)) -#define STATIC_CAST(type,exp) (static_cast(exp)) - -inline TUint8* MemCopy(TAny* aTrg, const TAny* aSrc, TInt aLength) -{ return (TUint8*)memmove(aTrg, aSrc, aLength) + aLength; } - - -/** Cleanup function. -@internalComponent -@param aArrayOfDictionaryCompressionBitStreams Pointer to an vector of -RDictionaryCompressionBitStream objects which have to be closed. */ -void CloseArrayOfDictionaryCompressionBitStreams(TAny* aArray) -{ - typedef std::vector RDictComprBitStream; - RDictComprBitStream* array = static_cast (aArray); - for (TInt i=array->size()-1;i>=0;--i) - { - array[i].clear(); - } - array->clear(); -} - -RResourceFileImpl::TExtra::TExtra(): - iBitArrayOfResourcesContainingCompressedUnicode(NULL), - iFileOffset(0), - iFileSize(0) -{ -} - - -RResourceFileImpl::TExtra::~TExtra() -{ - delete [] iDictionaryCompressionData.iCachedResourceBuffer; - iDictionaryCompressionData.iCachedResourceBuffer = NULL; - delete [] iDictionaryCompressionData.iCachedDictionaryIndex; - iDictionaryCompressionData.iCachedDictionaryIndex = 0; - - delete iBitArrayOfResourcesContainingCompressedUnicode; -} - - -TInt32 RResourceFileImpl::TExtra::ContainsCompressedUnicode(TInt& aRscIdx, TBool aFirstRscIsGen) const -{ - - if (aFirstRscIsGen) - { - // dictionary-compressed resource files can have an automatically generated - //resource which is the bit-array of resources containing compressed Unicode - //(this automatically generated resource does not have a corresponding bit - //for itself in the bit-array as it would be self-referring...) - --aRscIdx; - if (aRscIdx<0) - { - //aRscIdx is referring to the automatically generated resource - //(which is the bit-array of resources containing compressed Unicode) - return EFalse; - } - } - - assert(aRscIdx>=0); - - if (iBitArrayOfResourcesContainingCompressedUnicode==NULL) - { - return EFalse; - } - - TInt index = aRscIdx/8; - assert(index < iBitArrayOfResourcesContainingCompressedUnicode->GetLength()); - return (*iBitArrayOfResourcesContainingCompressedUnicode)[index]&(1<<(aRscIdx%8)); -} - - -RResourceFileImpl::RResourceFileImpl() : - iResourceContents(NULL), - iSizeOfLargestResourceWhenCompletelyUncompressed(0), - iIndex(NULL), - iOffset(0), - iExtra(NULL), - iFlagsAndNumberOfResources(0) -{ - // Fixed class size - because of the BC reasons. - // RResourceFileImpl size must be the same as CResourceFile size. - enum - { - KRscFileImplSize = 24 - }; - assert(sizeof(RResourceFileImpl) == KRscFileImplSize); - - //Fixed "iOffset" position - because of the BC reasons. - assert(offsetof(RResourceFileImpl, iOffset)==12); -} - - -RResourceFileImpl::~RResourceFileImpl() -{ - if(iResourceContents) - { - if (iResourceContents->is_open()) - { - iResourceContents->close(); - } - delete iResourceContents; - } - iSizeOfLargestResourceWhenCompletelyUncompressed=0; - delete iIndex; - iIndex=NULL; - if (iExtra) - { - delete iExtra; - iExtra=NULL; - } - - iFlagsAndNumberOfResources=0; - iOffset=0; -} - -/** Opens the resource file reader. -The resource file reader must be opened before reading resources or -checking the signature of the resource file. -@internalComponent -@param aName File to open as a resource file. -@param aFileOffset The resource file section offset from the beginning of the file. -@param aFileSize The resource file section size. -@leave - The file is corrupted. -*/ -void RResourceFileImpl::OpenL( - const std::string& aName, - TUint32 aFileOffset, - TInt aFileSize) -{ - iResourceContents= new std::ifstream(aName.c_str(), std::ios::in|std::ios::binary); - - if(!iResourceContents->good()) - { - std::string errMsg= "Unable to open RSC file. " + aName; - if (iResourceContents->is_open()) - iResourceContents->close(); - if(iResourceContents) - delete iResourceContents; - throw CResourceFileException(errMsg); - } - - iExtra=new TExtra(); - iExtra->iFileOffset = aFileOffset; - - TInt fileSize = 0; - if (aFileSize) - { - fileSize = aFileSize; - assert(fileSize > TInt(aFileOffset)); - } - else - { - // Get the resource file size - struct stat resourceFileStats; - - if (stat(aName.c_str(),&resourceFileStats) == 0) - { - // The size of the file in bytes is in - // resourceFileStats.st_size - fileSize=resourceFileStats.st_size; - assert(fileSize > 0); - } - else - { - if (iResourceContents->is_open()) - iResourceContents->close(); - std::string errMsg="Invalid RSC File"; - throw CResourceFileException(errMsg); - } - } - - iExtra->iFileSize = fileSize; - - // Verify the header of the RSC and get the resource index - ReadHeaderAndResourceIndexL(); -} - - -/** -Retrieve the UID tuple of the opened resource file. - -@internalComponent -@pre OpenL() has been called successfully. -@return The UIDs of the loaded resource file. -*/ -TUidType RResourceFileImpl::UidType() const -{ - assert(iExtra!=NULL); - return iExtra->iUidType; -} - -/** Reads a resource into a heap buffer, returns a pointer to that -buffer. - -A heap buffer of appropriate length is allocated for the resource. -Ownership of the heap buffer passes to the caller who must destroy -it. The search for the resource uses the following algorithm:A -resource id in the range 1 to 4095 is looked up in this resource file. -The function leaves if there is no matching resource.If the resource -id is greater than 4095, then the most significant 20 bits of the -resource id is treated as an offset and the least significant 12 bits -is treated as the real resource id. If the offset matches the offset -value defined for this file, then the resource is looked up in this -resource file using the real resource id (i.e. the least significant -12 bits). If the offset does not match, then the function leaves.Note, -do not call this function until a call to -ConfirmSignatureL() has completed successfully. - -@internalComponent -@pre OpenL() is called. -@param aResourceId The numeric id of the resource to be read. -@return Pointer to a heap buffer containing the resource. -@panic Some BAFL panic codes, if the file is corrupted. -@leave - The file is corrupted. -@leave - There is no resource with aResourceId in the file. -*/ -Ptr8* RResourceFileImpl::AllocReadL(const TInt& aResourceId) -{ - // Check if the resource id is present in the RSC file - if (!OwnsResourceId(aResourceId)) - { - std::ostringstream errDispStream; - - errDispStream<<"Resource ID:"; - errDispStream<0) - { - --resourceIndex; - } - else - { - assert(resourceIndex==0); - - Ptr8* resourceDataFor_RSS_SIGNATURE = new Ptr8(8); - if(NULL==resourceDataFor_RSS_SIGNATURE || NULL==resourceDataFor_RSS_SIGNATURE->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - - resourceDataFor_RSS_SIGNATURE->SetLength(8); - TUint* wordPointer=REINTERPRET_CAST(TUint*,CONST_CAST(TUint8*,resourceDataFor_RSS_SIGNATURE->GetPtr())); - - wordPointer[0]=4; - wordPointer[1]=((iExtra->iUidType[2].iUid << 12) | 1); - return resourceDataFor_RSS_SIGNATURE; - } - } - - - const TBool firstResourceIsGenerated= - (iFlagsAndNumberOfResources & - EFlagFirstResourceIsGeneratedBitArrayOfResourcesContainingCompressedUnicode); - if (firstResourceIsGenerated) - { - assert(iFlagsAndNumberOfResources & EFlagDictionaryCompressed); - //dictionary-compressed resource files can have an automatically generated - //resource which is the bit-array of resources containing compressed Unicode - //(this automatically generated resource does not have a corresponding bit for - //itself in the bit-array as it would be self-referring...) - ++resourceIndex; - } - - assert(resourceIndex>=0); - - Ptr8* const dictionaryDecompressedResourceData = DictionaryDecompressedResourceDataL(resourceIndex, - iFlagsAndNumberOfResources & static_cast(EAllFlags), - iExtra->iDictionaryCompressionData, - iIndex); - - // Return the resource data if its not unicode compressed. - if (!iExtra->ContainsCompressedUnicode(resourceIndex,firstResourceIsGenerated)) - { - return dictionaryDecompressedResourceData; - } - - Ptr8* const finalResourceData=DecompressUnicodeL(dictionaryDecompressedResourceData); - - delete dictionaryDecompressedResourceData; - return finalResourceData; - -} - -/** The method will decompress the unicode data (aInputResourceData argument), allocate enough -memory from the heap for the decompressed data, copy the data there and return a buffer -to the decompressed data. - -The method doesn't own the allocated heap memory for the decompressed data. It's a caller -responsibility to deallocate the allocated memory. - -@internalComponent -@param aInputResourceData Compressed data. -@pre OpenL() is called. -@leave - The file is corrupted. -@leave - There is not enough memory for the decompressed data. -*/ -Ptr8* RResourceFileImpl::DecompressUnicodeL(const Ptr8* aInputResourceData) const -{ - const TInt numberOfBytesInInput= aInputResourceData->GetLength(); - assert(iSizeOfLargestResourceWhenCompletelyUncompressed>0); - - Ptr8* outputResourceData= new Ptr8(iSizeOfLargestResourceWhenCompletelyUncompressed); - if(NULL==outputResourceData || NULL==outputResourceData->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - - const TUint8* input= aInputResourceData->GetPtr(); - TInt index=0; - - TBool decompressRun=ETrue; - while (1) - { - assert(index=numberOfBytesInInput) - { - std::string errMsg="Invalid Rsc File"; - throw CResourceFileException(errMsg); - } - runLength &= ~0x80; - runLength <<= 8; - runLength |= input[index]; - } - ++index; - if (runLength>0) - { - if (decompressRun) - { - AppendDecompressedUnicodeL( - outputResourceData, - const_cast(input+index), - runLength); - } - else - { - assert( - (outputResourceData->GetLength() + runLength) <= - iSizeOfLargestResourceWhenCompletelyUncompressed); - - memcpy((char*)(outputResourceData->GetPtr()+outputResourceData->GetLength()),(char*)(input+index),runLength); - outputResourceData->UpdateLength(runLength); - } - index+=runLength; - } - if (index>numberOfBytesInInput) - { - std::string errMsg="Invalid Rsc File"; - throw CResourceFileException(errMsg); - } - if (index>=numberOfBytesInInput) - { - break; - } - decompressRun=!decompressRun; - } - return outputResourceData; -} - - -/** @internalComponent -@return The first resource record. -@leave - The file is corrupted. -*/ -RResourceFileImpl::SSigRecord RResourceFileImpl::FirstRecordL() const -{ - // Added to support reading of rel 6.x resource files. - // rel 6.x files do not have signatures! - Ptr8* const firstResource=AllocReadL(1); - - // Basic check to test if the signature is of the correct size. - if (firstResource->GetLength()!= sizeof(SSigRecord)) - { - std::string errMsg="Invalid RSS Signature"; - throw CResourceFileException(errMsg); - } - SSigRecord sigRecord = *reinterpret_cast(firstResource->GetPtr()); - delete firstResource; - return sigRecord; -} - -/** Initialises the offset value from the first resource. - -The function tests to catch cases where the first resource is not an RSS_SIGNATURE. -It assumes that the first resource in the file consists of -two 32-bit integers. The first integer contains the version number and -the second is a self-referencing link whose value is the offset for -the resources in the file, plus 1.This function must be called before -calling Offset(), AllocReadL() or ReadL(). - -@internalComponent -@pre OpenL() is called. -@leave if the file is corrupted. -Some other error codes are possible too. -*/ -void RResourceFileImpl::ConfirmSignatureL() -{ - // Added to support reading of rel 6.x resource files. - SSigRecord firstRecord=FirstRecordL(); - - // If the resource offset does not correspond to the first resource - // this is not a resource signature. - if ((firstRecord.offset & EIdBits) != 1) - { - std::string errMsg="Failed : Invalid RSS Signature"; - throw CResourceFileException(errMsg); - } - iOffset=(firstRecord.offset & EOffsetBits); -} - -/** The method will decomress the unicode data (aCompressedUnicode argument) and append -the decompressed data to the end of aBuffer (aBuffer argument). - -@internalComponent -@pre OpenL() is called. -@param aBuffer Destination buffer. -@param aCompressedUnicode Compressed unicode buffer. -@leave - The file is corrupted. -*/ - -void RResourceFileImpl::AppendDecompressedUnicodeL( - Ptr8* aBuffer, - const TUint8* aCompressedUnicode, - const TInt& aLengthOfCompressedUnicode) const -{ - - if (aLengthOfCompressedUnicode>0) - { - TUint8* startOfDecompressedUnicode= aBuffer->GetPtr() + aBuffer->GetLength(); - - if (reinterpret_cast(startOfDecompressedUnicode) & 0x01) - { - TUint8 padChar = 0xab; - memcpy(startOfDecompressedUnicode,&padChar,1); - ++startOfDecompressedUnicode; - aBuffer->UpdateLength(1); - } - - const TInt maximumOutputLength= ( - iSizeOfLargestResourceWhenCompletelyUncompressed - (aBuffer->GetLength()))/2; - - TMemoryUnicodeSink decompressedUnicode(reinterpret_cast(startOfDecompressedUnicode)); - - TInt lengthOfDecompressedUnicode; - TInt numberOfInputBytesConsumed; - TUnicodeExpander unicodeExpander; - - unicodeExpander.ExpandL(decompressedUnicode, - aCompressedUnicode, - maximumOutputLength, - aLengthOfCompressedUnicode, - &lengthOfDecompressedUnicode, - &numberOfInputBytesConsumed); - TInt temp; - unicodeExpander.FlushL(decompressedUnicode,maximumOutputLength,temp); - lengthOfDecompressedUnicode+=temp; - aBuffer->UpdateLength(lengthOfDecompressedUnicode*2); - - assert(numberOfInputBytesConsumed == aLengthOfCompressedUnicode); - } -} - -/** Tests whether the resource file owns the specified resource id. - -The resource file owns the resource id if the most significant 20 bits -of the resource id are zero or match the offset value as returned from -a call to the Offset() member function or if the resource id is not out of range. - -@internalComponent -@pre OpenL() is called. -@param aResourceId The resource id to test. -@return True, if the resource file owns the id, false otherwise. -@leave - The file is corrupted. -*/ - -TBool RResourceFileImpl::OwnsResourceId(const TInt& aResourceId) const -{ - // Checks whether Rsc file owns the resource: - // does so if offset is 0, or matches that given, - // and id is in index. - - const TInt offset=(aResourceId & EOffsetBits); -// if ((offset!=0) && (offset!=iOffset)) -// { -// return EFalse; -// } - - const TInt resourceIndex=(aResourceId & EIdBits)-1; - TInt numberOfResources=(iFlagsAndNumberOfResources & ~EAllFlags); - if (iFlagsAndNumberOfResources & EFlagGenerate_RSS_SIGNATURE_ForFirstUserResource) - { - assert(iFlagsAndNumberOfResources & EFlagDictionaryCompressed); - assert(iFlagsAndNumberOfResources & EFlagThirdUidIsOffset); - ++numberOfResources; - } - if (iFlagsAndNumberOfResources & - EFlagFirstResourceIsGeneratedBitArrayOfResourcesContainingCompressedUnicode) - { - assert(iFlagsAndNumberOfResources & EFlagDictionaryCompressed); - --numberOfResources; - } - return (resourceIndex >= 0) && (resourceIndex < numberOfResources); -} - -TInt RResourceFileImpl::ReadL( - const TUint32& aFlags, - TInt aPos, - TUint8* aData, - const TInt& aLength) -{ - aPos += iExtra->iFileOffset; - - assert(aPos >= iExtra->iFileOffset); - assert(aLength >= 0); - assert((aPos + aLength) <= (iExtra->iFileOffset + iExtra->iFileSize)); - - // Seek to the offset specified by "aPos" - iResourceContents->seekg(aPos, std::ios_base::beg); - iResourceContents->read((char*)aData, aLength); - return iResourceContents->gcount(); -} - - -TInt RResourceFileImpl::ReadL(TInt aPos, TUint8* aData, const TInt& aLength) -{ - return ReadL(iFlagsAndNumberOfResources & static_cast(EAllFlags),aPos,aData,aLength); -} - - -TInt RResourceFileImpl::LittleEndianTwoByteInteger( - const TUint8* aBuffer, - const TInt& aIndexOfFirstByte, TInt aLength) const -{ - assert((aIndexOfFirstByte + 1) < aLength); - return aBuffer[aIndexOfFirstByte] | (aBuffer[aIndexOfFirstByte+1]<<8); -} - - -/** Function to retrieve the header information of the rsc file and all the - resource index information in the rsc file. This function is created to - handle the common functionality in the two OpenL() method. -@internalComponent -@pre OpenL() is called. -*/ - -void RResourceFileImpl::ReadHeaderAndResourceIndexL() -{ - SDictionaryCompressionData dictionaryCompressionData; - - TUidType uidType; - TInt length =0; - //dictionary-compressed resource files have a 21-byte header, - //16 bytes of checked UIDs followed by a 1-byte field and two 2-byte fields - TUint8 header[21]; - if(iExtra->iFileSize >= 16) - { - length = ReadL(0,header,Min((sizeof(header)/sizeof(header[0])),iExtra->iFileSize)); - uidType=TCheckedUid(header, 16).UidType(); - - if (uidType[0].iUid==0x101f4a6b) - { - iFlagsAndNumberOfResources |= EFlagPotentiallyContainsCompressedUnicode; - assert(length >= 18); - iSizeOfLargestResourceWhenCompletelyUncompressed = LittleEndianTwoByteInteger(header,16+1,length); - } - else if (uidType[0].iUid==0x101f5010) - { - iFlagsAndNumberOfResources |= - EFlagPotentiallyContainsCompressedUnicode | EFlagDictionaryCompressed; - assert(length >= 18); - iSizeOfLargestResourceWhenCompletelyUncompressed = LittleEndianTwoByteInteger(header,16+1,length); - } - else if (uidType[0]!=TUid::Null()) - { - std::string errMsg="Failed : Not Supported. Invalid Registration File."; - throw CResourceFileException(errMsg); - } - //the "signature" of Calypso's resource files - else if (LittleEndianTwoByteInteger(header,0,length)==4) - { - iFlagsAndNumberOfResources |= EFlagDictionaryCompressed | EFlagCalypsoFileFormat; - iSizeOfLargestResourceWhenCompletelyUncompressed = LittleEndianTwoByteInteger(header,8,length); - } - } - - //It seems that the following AssertDebL() call never fails, - //because LittleEndianTwoByteIntegerL always - //returns zero or positive value. - assert(iSizeOfLargestResourceWhenCompletelyUncompressed>=0); - TInt numberOfResources=0; - Ptr8* bitArrayOfResourcesContainingCompressedUnicode=NULL; - if (iFlagsAndNumberOfResources & EFlagDictionaryCompressed) - { - if (iFlagsAndNumberOfResources & EFlagCalypsoFileFormat) - { - assert(length > 10); - numberOfResources=LittleEndianTwoByteInteger(header,2,length); - const TInt numberOfBitsUsedForDictionaryTokens = header[10]; - const TInt numberOfDictionaryEntries = - (1 << numberOfBitsUsedForDictionaryTokens) - header[5]; - assert(numberOfDictionaryEntries >= 0); - // "+2" because the first entry in the dictionary-index in this file format - //is the number of bits from the start of the dictionary data to the start - //of the first dictionary entry which is always zero, and thus unnecessary - const TInt startOfDictionaryData=4+7+2; - // "+2" because the first entry in the resource-index in this file format is - //the number of bits from the start of the resource data to the start of the - //first resource which is always zero, and thus unnecessary - const TInt startOfResourceIndex=LittleEndianTwoByteInteger(header,6,length)+2; - assert(startOfResourceIndex >= 0); - dictionaryCompressionData.iStartOfDictionaryData= - startOfDictionaryData+(numberOfDictionaryEntries*2); - dictionaryCompressionData.iStartOfDictionaryIndex=startOfDictionaryData; - dictionaryCompressionData.iNumberOfDictionaryEntries=numberOfDictionaryEntries; - dictionaryCompressionData.iStartOfResourceData= - startOfResourceIndex+(numberOfResources*2); - dictionaryCompressionData.iStartOfResourceIndex=startOfResourceIndex; - dictionaryCompressionData.iNumberOfBitsUsedForDictionaryTokens= - numberOfBitsUsedForDictionaryTokens; - - if ((iFlagsAndNumberOfResources & static_cast(EFlagIsRomFile)) == 0) - { - // attempt to cache dictionary index - // allocate and populate the dictionary index buffer - dictionaryCompressionData.iCachedDictionaryIndex = new TUint16[numberOfDictionaryEntries]; - if (dictionaryCompressionData.iCachedDictionaryIndex != 0) - { - TInt len = numberOfDictionaryEntries * 2; - - Ptr8* ptr8 = new Ptr8(numberOfDictionaryEntries * 2); - if(NULL==ptr8 || NULL==ptr8->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - ptr8->UpdateLength(numberOfDictionaryEntries * 2); - ReadL( - iFlagsAndNumberOfResources & static_cast(EAllFlags), // aFlags - startOfDictionaryData, // aPos - (TUint8*)ptr8->GetPtr(), - len); // aLength - - memcpy((TUint8*)dictionaryCompressionData.iCachedDictionaryIndex, ptr8->GetPtr(), len); - if(NULL != ptr8) - { - delete ptr8; - } - } - } // if (iFlagsAndNumberOfResources & EFlagIsRomFile) - } - else - { - assert(length==16+1+2+2); - const TUint firstByteAfterUids=header[16]; - if (firstByteAfterUids & 0x80) - { - // this flag is only set if the resource file is dictionary-compressed - iFlagsAndNumberOfResources |= EFlagThirdUidIsOffset; - } - if (firstByteAfterUids & 0x40) - { - // this flag is only set if the resource file is dictionary-compressed - iFlagsAndNumberOfResources |= EFlagGenerate_RSS_SIGNATURE_ForFirstUserResource; - } - if (firstByteAfterUids & 0x20) - { - iFlagsAndNumberOfResources |= - EFlagFirstResourceIsGeneratedBitArrayOfResourcesContainingCompressedUnicode; - } - dictionaryCompressionData.iStartOfResourceData = LittleEndianTwoByteInteger(header,16+1+2,length); - TUint8 temp[2]; - length = ReadL((iExtra->iFileSize)-2,temp,2); - - const TInt numberOfBitsOfResourceData = LittleEndianTwoByteInteger(temp,0,length); - dictionaryCompressionData.iStartOfResourceIndex= - dictionaryCompressionData.iStartOfResourceData+ - ((numberOfBitsOfResourceData+7)/8); - numberOfResources=(iExtra->iFileSize-dictionaryCompressionData.iStartOfResourceIndex)/2; - dictionaryCompressionData.iStartOfDictionaryData=16+5; - if ((numberOfResources>0) && - !(iFlagsAndNumberOfResources & - EFlagFirstResourceIsGeneratedBitArrayOfResourcesContainingCompressedUnicode)) - { - const TInt lengthOfBitArrayInBytes=(numberOfResources+7)/8; - bitArrayOfResourcesContainingCompressedUnicode= new Ptr8(lengthOfBitArrayInBytes); - if(NULL==bitArrayOfResourcesContainingCompressedUnicode || NULL==bitArrayOfResourcesContainingCompressedUnicode->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - bitArrayOfResourcesContainingCompressedUnicode->UpdateLength(lengthOfBitArrayInBytes); - TUint8* asWritable = bitArrayOfResourcesContainingCompressedUnicode->GetPtr(); - ReadL(16+5,asWritable,lengthOfBitArrayInBytes); - dictionaryCompressionData.iStartOfDictionaryData+=lengthOfBitArrayInBytes; - } - length = ReadL(dictionaryCompressionData.iStartOfResourceData-2,temp,2); - const TInt numberOfBitsOfDictionaryData=LittleEndianTwoByteInteger(temp,0,length); - dictionaryCompressionData.iStartOfDictionaryIndex= - dictionaryCompressionData.iStartOfDictionaryData+ - ((numberOfBitsOfDictionaryData+7)/8); - dictionaryCompressionData.iNumberOfDictionaryEntries= - (dictionaryCompressionData.iStartOfResourceData- - dictionaryCompressionData.iStartOfDictionaryIndex)/2; - //the bottom 3 bits of firstByteAfterUids stores the number of bits used for - //dictionary tokens as an offset from 3, e.g. if 2 is stored in these three bits - //then the number of bits per dictionary token would be 3+2=5 - this allows a - //range of 3-11 bits per dictionary token (the maximum number of dictionary - //tokens therefore ranging from 8-2048) - the spec currently only supports 5-9 - //bits per dictionary token, however - dictionaryCompressionData.iNumberOfBitsUsedForDictionaryTokens= - 3 + (firstByteAfterUids & 0x07); - if ((numberOfResources>0) && - (iFlagsAndNumberOfResources & - EFlagFirstResourceIsGeneratedBitArrayOfResourcesContainingCompressedUnicode)) - { - Ptr16* nulldesc = new Ptr16(1); - if(NULL==nulldesc || NULL==nulldesc->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - *(nulldesc->GetPtr()) = 0; - nulldesc->UpdateLength(0); - - bitArrayOfResourcesContainingCompressedUnicode= - DictionaryDecompressedResourceDataL( - 0, - iFlagsAndNumberOfResources & static_cast(EAllFlags), - dictionaryCompressionData, - nulldesc); - if(NULL != nulldesc) - { - delete nulldesc; - } - } - } - } - else - { - assert((iExtra->iFileSize + iExtra->iFileOffset) > 2); - // This format of resource file is likely to be used for non-ROM resource files, - //so cache the resource-index (in iIndex) to minimize disk access. - // Ignore the flags in non-dictionary-compressed resource files - they are to - //be used only by a dictionary-compressing program. - const TInt KMaximumNumberOfBytesCached=256; - TUint8 cache[KMaximumNumberOfBytesCached]; - const TInt numberOfBytesCached=Min(iExtra->iFileSize,KMaximumNumberOfBytesCached); - TInt len = ReadL(iExtra->iFileSize-numberOfBytesCached,cache,numberOfBytesCached); - assert(len==numberOfBytesCached); - const TInt positionOfStartOfIndex= - ((cache[numberOfBytesCached-1]<<8) | cache[numberOfBytesCached-2]); - const TInt numberOfBytesOfIndex=iExtra->iFileSize-positionOfStartOfIndex; - assert(numberOfBytesOfIndex%2==0); - assert(numberOfBytesOfIndex>=0); - const TInt numberOfBytesOfIndexStillToRetrieve= - numberOfBytesOfIndex-numberOfBytesCached; - if (numberOfBytesOfIndexStillToRetrieve<=0) - { - Ptr8* indexAsBinaryBuffer = new Ptr8(numberOfBytesOfIndex); - if(NULL==indexAsBinaryBuffer || NULL==indexAsBinaryBuffer->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - - indexAsBinaryBuffer->UpdateLength(numberOfBytesOfIndex); - BufCpy8(indexAsBinaryBuffer->GetPtr(), cache+(numberOfBytesCached - numberOfBytesOfIndex) , numberOfBytesOfIndex); - - iIndex = new Ptr16(numberOfBytesOfIndex/2); - if(NULL==iIndex || NULL==iIndex->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - - MemCopy(CONST_CAST(TUint16*,(TUint16*)iIndex->GetPtr()),indexAsBinaryBuffer->GetPtr(),numberOfBytesOfIndex); - iIndex->UpdateLength(numberOfBytesOfIndex/2); - - if(NULL != indexAsBinaryBuffer) - { - delete indexAsBinaryBuffer; - } - } - else - { - Ptr16* const index=new Ptr16(numberOfBytesOfIndex/2); - if(NULL==index || NULL==index->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - index->UpdateLength(numberOfBytesOfIndex/2); - - Ptr8* indexAsWritableBinaryBuffer = new Ptr8(numberOfBytesOfIndex); - if(NULL==indexAsWritableBinaryBuffer || NULL==indexAsWritableBinaryBuffer->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - indexAsWritableBinaryBuffer->UpdateLength(numberOfBytesOfIndexStillToRetrieve); - - ReadL(positionOfStartOfIndex,indexAsWritableBinaryBuffer->GetPtr(), - numberOfBytesOfIndexStillToRetrieve); - assert(indexAsWritableBinaryBuffer->GetLength()==numberOfBytesOfIndexStillToRetrieve); - indexAsWritableBinaryBuffer->Append(cache, len); - indexAsWritableBinaryBuffer->UpdateLength(len); - assert(indexAsWritableBinaryBuffer->GetLength()==numberOfBytesOfIndex); - assert(indexAsWritableBinaryBuffer->GetLength()==index->GetLength()*2); - memcpy((TUint8*)index->GetPtr(), indexAsWritableBinaryBuffer->GetPtr() , numberOfBytesOfIndex); - - iIndex=index; - if(NULL != indexAsWritableBinaryBuffer) - { - delete indexAsWritableBinaryBuffer; - } - } - - //"-1" because the last thing in the index (which is in fact the last thing in the - //file itself) is the position of the start of the index which is therefore not - //pointing to a resource - numberOfResources=(numberOfBytesOfIndex/2) - 1; - if ((numberOfResources>0) && - (iFlagsAndNumberOfResources & EFlagPotentiallyContainsCompressedUnicode)) - { - const TInt lengthOfBitArrayInBytes=(numberOfResources+7)/8; - bitArrayOfResourcesContainingCompressedUnicode= new Ptr8(lengthOfBitArrayInBytes); - if(NULL==bitArrayOfResourcesContainingCompressedUnicode || NULL==bitArrayOfResourcesContainingCompressedUnicode->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - bitArrayOfResourcesContainingCompressedUnicode->UpdateLength(lengthOfBitArrayInBytes); - TUint8* bitArray = bitArrayOfResourcesContainingCompressedUnicode->GetPtr(); - //"16+1+2": 16 bytes of checked-UID + 1 byte of flags (these flags are for a - //dictionary-compressing program's use rather than directly for Bafl's use, - //so we ignore them) + 2 bytes containing the size of the largest resource when - //uncompressed - ReadL(16+1+2,bitArray,lengthOfBitArrayInBytes); - } - } - assert((numberOfResources & EAllFlags)==0); - assert((iFlagsAndNumberOfResources & ~EAllFlags)==0); - iFlagsAndNumberOfResources |= (numberOfResources & ~EAllFlags); - iExtra->iUidType = uidType; - iExtra->iBitArrayOfResourcesContainingCompressedUnicode = bitArrayOfResourcesContainingCompressedUnicode; - iExtra->iBitArrayOfResourcesContainingCompressedUnicode->SetLength(bitArrayOfResourcesContainingCompressedUnicode->GetLength()); - iExtra->iDictionaryCompressionData = dictionaryCompressionData; - //iOffset is set by calling ConfirmSignatureL - assert(iOffset==0); -} - - -/** @internalComponent -@pre OpenL() is called. -@leave KErrCorrupt The file is corrupted. -@leave KErrNoMemory There is not enough memory for the decompressed data. -Some other error codes are possible too. -*/ -Ptr8* RResourceFileImpl::DictionaryDecompressedResourceDataL( - TInt aResourceIndex, - TUint aFlags, - const SDictionaryCompressionData& aDictionaryCompressionData, - const Ptr16* aIndex) const -{ - if (aFlags & EFlagDictionaryCompressed) - { - assert(iSizeOfLargestResourceWhenCompletelyUncompressed>0); - Ptr8* const outputResourceData = new Ptr8(iSizeOfLargestResourceWhenCompletelyUncompressed); - if(NULL==outputResourceData || NULL==outputResourceData->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - - Ptr8* asWritable = outputResourceData; - std::vector stackOfDictionaryCompressionBitStreams; - AppendDictionaryCompressionBitStreamL( - stackOfDictionaryCompressionBitStreams, - aFlags, - aDictionaryCompressionData, - aDictionaryCompressionData.iStartOfResourceData, - aDictionaryCompressionData.iStartOfResourceIndex, - aResourceIndex); - const TBool calypsoFileFormat=(aFlags & EFlagCalypsoFileFormat); - while(1) - { - const TInt indexOfTopBitStream=stackOfDictionaryCompressionBitStreams.size()-1; - assert(indexOfTopBitStream>=-1); - if (indexOfTopBitStream<0) - { - break; - } - RDictionaryCompressionBitStream& dictionaryCompressionBitStream= - stackOfDictionaryCompressionBitStreams[indexOfTopBitStream]; - - while(1) - { - if (dictionaryCompressionBitStream.EndOfStreamL()) - { - dictionaryCompressionBitStream.Close(); - stackOfDictionaryCompressionBitStreams.erase(indexOfTopBitStream); - break; - } - const TInt indexOfDictionaryEntry= - dictionaryCompressionBitStream.IndexOfDictionaryEntryL(); - if (indexOfDictionaryEntry<0) - { - dictionaryCompressionBitStream.ReadL(asWritable,calypsoFileFormat); - } - else - { - AppendDictionaryCompressionBitStreamL( - stackOfDictionaryCompressionBitStreams, - aFlags, - aDictionaryCompressionData, - aDictionaryCompressionData.iStartOfDictionaryData, - aDictionaryCompressionData.iStartOfDictionaryIndex, - indexOfDictionaryEntry); - break; - } - } - } - stackOfDictionaryCompressionBitStreams.clear(); - return outputResourceData; - } - - assert(aResourceIndex < aIndex->GetLength()); - - const TInt positionOfResourceData=(*aIndex)[aResourceIndex]; - const TInt numberOfBytes=(*aIndex)[aResourceIndex+1]-positionOfResourceData; - - assert(numberOfBytes >= 0); - Ptr8* const outputResourceData= new Ptr8(numberOfBytes); - if(NULL==outputResourceData || NULL==outputResourceData->GetPtr()) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - - TUint8* asWritable = outputResourceData->GetPtr(); - ReadL(aFlags,positionOfResourceData,asWritable,numberOfBytes); - outputResourceData->UpdateLength(numberOfBytes); - - return outputResourceData; - -} - - -void RResourceFileImpl::AppendDictionaryCompressionBitStreamL( - std::vector& aStackOfDictionaryCompressionBitStreams, - TUint aFlags, - const SDictionaryCompressionData& aDictionaryCompressionData, - TInt aStartOfBitData, - TInt aStartOfIndex, - TInt aIndexEntry) const -{ - const TBool isRomFile=(aFlags & static_cast(EFlagIsRomFile)); - TUint8 temp[4]; - TInt length = 0; - assert(aIndexEntry>=0); - TInt offsetToFirstBit; - TInt offsetOnePastLastBit; - if ( aDictionaryCompressionData.iStartOfDictionaryIndex == aStartOfIndex - && aDictionaryCompressionData.iCachedDictionaryIndex != 0) - { - assert(!isRomFile); - // indices start at 1 - offsetToFirstBit = (aIndexEntry <= 0) - ? 0 - : aDictionaryCompressionData.iCachedDictionaryIndex[aIndexEntry-1]; - offsetOnePastLastBit = aDictionaryCompressionData.iCachedDictionaryIndex[aIndexEntry]; - } - else - { - TInt len = ReadL(aFlags,aStartOfIndex+((aIndexEntry-1)*2),temp,4); - offsetToFirstBit=(aIndexEntry > 0) ? LittleEndianTwoByteInteger(temp,0,len) : 0; - offsetOnePastLastBit=LittleEndianTwoByteInteger(temp,2,len); - } - TInt rsc_file_size = iExtra->iFileOffset + iExtra->iFileSize; - TInt offset_first = offsetToFirstBit / 8 + iExtra->iFileOffset; - assert(offset_first < rsc_file_size); - TInt offset_last = offsetOnePastLastBit / 8 + iExtra->iFileOffset; - assert(offset_last <= rsc_file_size); - TUint8* buffer = NULL; - TInt start_pos = 0; - if (isRomFile) - { - TInt startOfBitData = aStartOfBitData + iExtra->iFileOffset; - assert(startOfBitData < rsc_file_size); - buffer = startOfBitData; - } - else - { - const TInt offsetToByteContainingFirstBit=offsetToFirstBit/8; - const TInt offsetToOnePastByteContainingLastBit=((offsetOnePastLastBit-1)/8)+1; - const TInt numberOfBytesToLoad= - offsetToOnePastByteContainingLastBit-offsetToByteContainingFirstBit; - assert(numberOfBytesToLoad >= 0); - buffer=new TUint8[numberOfBytesToLoad]; - if(NULL==buffer) - { - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - - if( iExtra->iDictionaryCompressionData.iCachedResourceBuffer == 0) - { - iExtra->iDictionaryCompressionData.iCachedResourceBuffer=new TUint8[rsc_file_size]; // reserver buffer for whole file - if(NULL==iExtra->iDictionaryCompressionData.iCachedResourceBuffer) - { - delete buffer; // buffer deleted in RDictionaryCompressionBitStream::close - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - - Ptr8* JKasWritable = new Ptr8(rsc_file_size); - if(NULL==JKasWritable || NULL == JKasWritable->GetPtr()) - { - delete buffer; // buffer deleted in RDictionaryCompressionBitStream::close - std::string errMsg= "Failed : Error in Reading File. Memory Allocation Failed"; - throw CResourceFileException(errMsg); - } - JKasWritable->UpdateLength(rsc_file_size); - - try { - length = ReadL(0,(TUint8*)JKasWritable->GetPtr(), rsc_file_size); - } - catch(...) - { - delete buffer; // buffer deleted in RDictionaryCompressionBitStream::close - std::string errMsg= "Failed : Error in Reading File."; - throw CResourceFileException(errMsg); - } - - BufCpy8(iExtra->iDictionaryCompressionData.iCachedResourceBuffer, JKasWritable->GetPtr(), length); - if(NULL != JKasWritable) - { - delete JKasWritable; - } - } - start_pos = aStartOfBitData + offsetToByteContainingFirstBit + iExtra->iFileOffset; - assert(start_pos < rsc_file_size); - assert((start_pos + numberOfBytesToLoad) <= rsc_file_size); - const TInt numberOfBitsFromStartOfBitDataToFirstLoadedByte= - offsetToByteContainingFirstBit*8; - offsetToFirstBit-=numberOfBitsFromStartOfBitDataToFirstLoadedByte; - offsetOnePastLastBit-=numberOfBitsFromStartOfBitDataToFirstLoadedByte; - - MemCopy( buffer, iExtra->iDictionaryCompressionData.iCachedResourceBuffer + start_pos, numberOfBytesToLoad); - } - RDictionaryCompressionBitStream stream; - stream.OpenL( - aDictionaryCompressionData.iNumberOfBitsUsedForDictionaryTokens, - offsetToFirstBit, - offsetOnePastLastBit, - !isRomFile, - buffer); - try { - aStackOfDictionaryCompressionBitStreams.push_back(stream); - } - catch(...) - { - delete buffer; // buffer deleted in RDictionaryCompressionBitStream::close - std::string errMsg= "Failed : Error in Reading File."; - throw CResourceFileException(errMsg); - } - if (!isRomFile) - { - delete buffer; // buffer deleted in RDictionaryCompressionBitStream::close - } -} -