secureswitools/swisistools/source/rscparser/barscimpl.cpp
changeset 33 8110bf1194d1
parent 25 98b66e4fb0be
--- a/secureswitools/swisistools/source/rscparser/barscimpl.cpp	Mon May 03 12:38:03 2010 +0300
+++ b/secureswitools/swisistools/source/rscparser/barscimpl.cpp	Fri May 14 15:58:48 2010 +0300
@@ -25,25 +25,71 @@
 #include <sstream>
 #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<type>(exp))
+#define CONST_CAST(type,exp) (const_cast<type>(exp))
+#define STATIC_CAST(type,exp) (static_cast<type>(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<RDictionaryCompressionBitStream> RDictComprBitStream;
+	RDictComprBitStream* array = static_cast <RDictComprBitStream*> (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(const TInt& aRscIdx) const
+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)
@@ -52,19 +98,19 @@
 		}
 	
 	TInt index = aRscIdx/8;
-	
-	return (iBitArrayOfResourcesContainingCompressedUnicode)[index]&(1<<(aRscIdx%8));
-	}
+	assert(index < iBitArrayOfResourcesContainingCompressedUnicode->GetLength());
+	return (*iBitArrayOfResourcesContainingCompressedUnicode)[index]&(1<<(aRscIdx%8));
+}
 
 
 RResourceFileImpl::RResourceFileImpl() :
 	iResourceContents(NULL),
 	iSizeOfLargestResourceWhenCompletelyUncompressed(0),
-	iIndex(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
@@ -75,7 +121,7 @@
 
 	//Fixed "iOffset" position - because of the BC reasons.
 	assert(offsetof(RResourceFileImpl, iOffset)==12);
-	}
+}
 
 
 RResourceFileImpl::~RResourceFileImpl()
@@ -101,7 +147,15 @@
 	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, 
@@ -156,29 +210,49 @@
 }
 
 
-Ptr8* RResourceFileImpl::GetDecompressedResourceDataL(
-													const TInt& aResourceIndex,			
-													const TUint32& aFlags) 
-	{
-	const TInt positionOfResourceData= iIndex[aResourceIndex];
-	const TInt numberOfBytes= iIndex[aResourceIndex+1]-positionOfResourceData;
-	
-	assert(numberOfBytes >= 0);
-	
-	Ptr8* outputResourceData=new Ptr8(numberOfBytes);
-	ReadL(aFlags, positionOfResourceData, outputResourceData->GetPtr(), numberOfBytes);
-	outputResourceData->UpdateLength(numberOfBytes);
-	
-	return outputResourceData;
-	}
+/** 
+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:";
@@ -186,44 +260,105 @@
 		errDispStream<<" is not present in the RSC file";
 		
 		throw CResourceFileException(errDispStream.str());
-		}
+	}
 	
 	//"-1" because the first resource has ID 0x*****001 (not 0x*****000)
 	TInt resourceIndex= (aResourceId & EIdBits)-1; 
-	assert(resourceIndex>=0);
 	
-	Ptr8* decompressedResourceData= 
-		GetDecompressedResourceDataL(
-								resourceIndex,
-								iFlagsAndNumberOfResources & static_cast<TUint32>(EAllFlags));
-	
-	// Return the resource data if its not unicode compressed.
-	if (!iExtra->ContainsCompressedUnicode(resourceIndex))
+	if (iFlagsAndNumberOfResources & EFlagGenerate_RSS_SIGNATURE_ForFirstUserResource)
+	{
+		assert(iFlagsAndNumberOfResources & EFlagDictionaryCompressed);
+		assert(iFlagsAndNumberOfResources & EFlagThirdUidIsOffset);
+		
+		if (resourceIndex>0)
+		{
+			--resourceIndex;
+		}
+		else
 		{
-		return decompressedResourceData;
+			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;
 		}
+	}
 	
-	// Get the decompressed unicode data.
-	Ptr8* finalResourceData= DecompressUnicodeL(decompressedResourceData);	
+
+	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; 
+	}
 	
-	delete decompressedResourceData;	
-	return finalResourceData;	
+	assert(resourceIndex>=0);
+
+	Ptr8* const dictionaryDecompressedResourceData = DictionaryDecompressedResourceDataL(resourceIndex,
+						iFlagsAndNumberOfResources & static_cast<TUint>(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);
 		
 		TInt runLength=input[index];
@@ -233,63 +368,59 @@
 		// with the most significant bit of the first byte set to non-zero 
 		//to indicate that the run-length occupies two bytes.
 		if (runLength & 0x80)
-			{
+		{
 			++index;
 			if (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<unsigned char *>(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.
-@panic Some BAFL panic codes, if the file is corrupted.
-@leave KErrCorrupt The file is corrupted.
-Some other error codes are possible too.
-The method could panic or leave depending on the state of
-iAssertObj member of RResourceFileImpl::TExtra class. */
+@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);
@@ -312,19 +443,13 @@
 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(), AllocReadLC() or ReadL().
+calling Offset(), AllocReadL() or ReadL().
 
-@see Offset()
-@see AllocReadL()
-@see AllocReadLC() 
-@see ReadL()
 @internalComponent
 @pre OpenL() is called.
-@panic Some BAFL panic codes, if the file is corrupted.
-@leave KErrCorrupt The file is corrupted.
+@leave if the file is corrupted.
 Some other error codes are possible too.
-The method could panic or leave depending on the state of
-iAssertObj member of RResourceFileImpl::TExtra class. */
+*/
 void RResourceFileImpl::ConfirmSignatureL()
 {
 	// Added to support reading of rel 6.x resource files.
@@ -340,23 +465,33 @@
 	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)
 	{
-	
-	if (aLengthOfCompressedUnicode>0)
-		{
 		TUint8* startOfDecompressedUnicode= aBuffer->GetPtr() + aBuffer->GetLength();
 		
 		if (reinterpret_cast<TUint32>(startOfDecompressedUnicode) & 0x01)
-			{			
+		{			
 			TUint8 padChar = 0xab;
 			memcpy(startOfDecompressedUnicode,&padChar,1);
 			++startOfDecompressedUnicode;
 			aBuffer->UpdateLength(1);
-			}
+		}
 		
 		const TInt maximumOutputLength= (
 			iSizeOfLargestResourceWhenCompletelyUncompressed - (aBuffer->GetLength()))/2; 
@@ -379,15 +514,28 @@
 		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))
 //		{
@@ -396,17 +544,27 @@
 	
 	const TInt resourceIndex=(aResourceId & EIdBits)-1;
 	TInt numberOfResources=(iFlagsAndNumberOfResources & ~EAllFlags);
-	
-	return (resourceIndex >= 0) && (resourceIndex < numberOfResources);
+	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);
+}
 
-void RResourceFileImpl::ReadL(
+TInt RResourceFileImpl::ReadL(
 							const TUint32& aFlags, 
 							TInt aPos,
 							TUint8* aData,
 							const TInt& aLength) 
-	{
+{
 	aPos += iExtra->iFileOffset;
 	
 	assert(aPos >= iExtra->iFileOffset);
@@ -415,125 +573,557 @@
 	
 	// Seek to the offset specified by "aPos"
 	iResourceContents->seekg(aPos, std::ios_base::beg);
-	iResourceContents->read((char*)aData, aLength);		
-	}
+	iResourceContents->read((char*)aData, aLength);	
+	return iResourceContents->gcount();
+}
 
 
-void RResourceFileImpl::ReadL(TInt aPos, TUint8* aData, const TInt& aLength) 
-	{
-	ReadL(iFlagsAndNumberOfResources & static_cast<TUint32>(EAllFlags),aPos,aData,aLength);
-	}
+TInt RResourceFileImpl::ReadL(TInt aPos, TUint8* aData, const TInt& aLength) 
+{
+	return ReadL(iFlagsAndNumberOfResources & static_cast<TUint32>(EAllFlags),aPos,aData,aLength);
+}
 
 
 TInt RResourceFileImpl::LittleEndianTwoByteInteger(
-													TUint8* aBuffer,
-													const TInt& aIndexOfFirstByte) const
-	{
+													const TUint8* aBuffer,
+													const TInt& aIndexOfFirstByte, TInt aLength) const
+{
+	assert((aIndexOfFirstByte + 1) < aLength);
 	return aBuffer[aIndexOfFirstByte] | (aBuffer[aIndexOfFirstByte+1]<<8);
-	}
+}
 
 
-void RResourceFileImpl::ReadHeaderAndResourceIndexL()
-	{
+/** 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.
+*/
 	
-	// Unicode compressed RSC file will have 19 bytes header.
-	const TUint8 kHeaderSize= 19;
-	TUint8 header[kHeaderSize];
-			
-	sTUid uid;
-	
-	// Verify the header of the RSC file.
-	if(iExtra->iFileSize >= kHeaderSize)
-		{
+void RResourceFileImpl::ReadHeaderAndResourceIndexL()
+{
+	SDictionaryCompressionData dictionaryCompressionData;
 		
-		// Get the RSC header
-		ReadL(0,0,header,kHeaderSize);
-		// Get the first UID
-		memcpy((TUint8*)&uid.iUid1,header,4);
-		
-		// First uid of unicode compressed RSC is "0x101f4a6b"
-		TUint32 unicodeCompressedFirstUid = 0x101f4a6b;
-		
-		if (uid.iUid1 == unicodeCompressedFirstUid)
+	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<TUint>(EFlagIsRomFile)) == 0)
 			{
-			iFlagsAndNumberOfResources |= EFlagPotentiallyContainsCompressedUnicode;
-			iSizeOfLargestResourceWhenCompletelyUncompressed=	LittleEndianTwoByteInteger(header,16+1);
+				// 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<TUint>(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; 
 			}
-		else
+			if (firstByteAfterUids & 0x40)
+			{
+				// this flag is only set if the resource file is dictionary-compressed
+				iFlagsAndNumberOfResources |= EFlagGenerate_RSS_SIGNATURE_ForFirstUserResource; 
+			}
+			if (firstByteAfterUids & 0x20)
 			{
-				if (iResourceContents->is_open())
-						iResourceContents->close();
-			std::string errMsg="Failed : Unsupported RSC file type";
-			throw CResourceFileException(errMsg);
+				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<TUint>(EAllFlags),
+											dictionaryCompressionData,
+											nulldesc);
+				if(NULL != nulldesc)
+				{
+					delete nulldesc;
+				}
 			}
 		}
-		
-		TInt numberOfResources= 0;
-		TUint8* bitArrayOfResourcesContainingCompressedUnicode= NULL;
-		
-		if (iFlagsAndNumberOfResources & EFlagPotentiallyContainsCompressedUnicode)
+	}
+	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)
 		{
-			// Cache the resource-index (in iIndex) to minimize disk access.		
-			const TInt KMaximumNumberOfBytesCached= 256;
-			TUint8 cache[KMaximumNumberOfBytesCached];
-			const TInt numberOfBytesCached=
-				((iExtra->iFileSize>KMaximumNumberOfBytesCached) ? KMaximumNumberOfBytesCached : iExtra->iFileSize);
-			
-			ReadL(iExtra->iFileSize-numberOfBytesCached, cache, 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;
+			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;
+			}
+		}
 			
-			if (numberOfBytesOfIndexStillToRetrieve<=0)
-				{
-				iIndex= new TUint16[numberOfBytesOfIndex/2];
-				memcpy(iIndex, cache+(numberOfBytesCached-numberOfBytesOfIndex), numberOfBytesOfIndex);
-				}
-			else
-				{
-				TUint16* index= new TUint16(numberOfBytesOfIndex/2);			
-				ReadL(positionOfStartOfIndex, reinterpret_cast<TUint8*>(index), numberOfBytesOfIndexStillToRetrieve);
-				memcpy((index+numberOfBytesOfIndexStillToRetrieve),cache,numberOfBytesCached); 		
-
-				iIndex=index;			
-				}
-
-			//"-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)
-				{
-				if (iResourceContents->is_open())
-						iResourceContents->close();
-				std::string errMsg="Failed : Invalid RSC file.";
+		//"-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);
-				}
-				
-			const TInt lengthOfBitArrayInBytes=(numberOfResources+7)/8;
-			bitArrayOfResourcesContainingCompressedUnicode=
-								new TUint8(lengthOfBitArrayInBytes);
-			
+			}
+			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,bitArrayOfResourcesContainingCompressedUnicode,lengthOfBitArrayInBytes); 
+			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<RDictionaryCompressionBitStream> 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;
 		
-		assert((numberOfResources & EAllFlags)==0);
-		assert((iFlagsAndNumberOfResources & ~EAllFlags)==0);
-		
-		iFlagsAndNumberOfResources |= (numberOfResources & ~EAllFlags);
-		iExtra->iUid = uid;
-		iExtra->iBitArrayOfResourcesContainingCompressedUnicode = bitArrayOfResourcesContainingCompressedUnicode;
+}
+	
+
+void RResourceFileImpl::AppendDictionaryCompressionBitStreamL(
+			std::vector<RDictionaryCompressionBitStream>& aStackOfDictionaryCompressionBitStreams,
+			TUint aFlags,
+			const SDictionaryCompressionData& aDictionaryCompressionData,
+			TInt aStartOfBitData,
+			TInt aStartOfIndex,
+			TInt aIndexEntry) const
+{
+	const TBool isRomFile=(aFlags & static_cast<TUint>(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
+	}
+}
+