imgtools/romtools/rofsbuild/r_coreimage.cpp
changeset 590 360bd6b35136
parent 0 044383f39525
--- a/imgtools/romtools/rofsbuild/r_coreimage.cpp	Wed Jun 16 16:51:40 2010 +0300
+++ b/imgtools/romtools/rofsbuild/r_coreimage.cpp	Wed Jun 23 16:56:47 2010 +0800
@@ -1,699 +1,614 @@
-/*
-* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "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 <string.h>
-#include "h_utl.h"
-
-#include <e32std.h>
-#include <e32std_private.h>
-#include "rofs.h"
-
-#include "r_obey.h"
-#include "r_coreimage.h"
-
-// -----------------------------------------------------------
-//  RCoreImageReader
-// -----------------------------------------------------------
-
-/**
-Constructs reader for the specified file.
-
-@param aFilename Filename for core image file
-*/
-	RCoreImageReader::RCoreImageReader(char* aFilename) : 
-			iImageType(E_UNKNOWN), iCoreImage(0), iFilename(aFilename)
-	{
-	}
-
-/**
-Closes the core image file if it was opened.
-*/
-RCoreImageReader::~RCoreImageReader() 
-	{
-	if (iCoreImage)
-		fclose(iCoreImage);
-	iCoreImage = 0;
-	}
-
-/**
-Opens the image file that was specified at construction.
-
-@return ETrue if file was opened successfully otherwise returns EFalse
-*/
-TBool RCoreImageReader::Open()
-	{
-	iCoreImage = fopen(iFilename, "rb");
-	if (!iCoreImage)
-		{
-		Print(EError, "Cannot open image file %s\n", iFilename);
-		return EFalse;
-		}
-	return ETrue;
-	}
-
-/**
-Reads the image type from the core image file. It reads the value from the
-file and then translates it into the internal enum used for processing 
-the images. 
-
-@return Image type
-*/
-RCoreImageReader::TImageType RCoreImageReader::ReadImageType() 
-	{
-	iImageType = E_UNKNOWN;
-	if ( ReadIdentifier() == KErrNone)
-		{
-		if (iIdentifier[0] == 'R' &&
-				iIdentifier[1] == 'O' &&
-				iIdentifier[2] == 'F')
-			{
-			if (iIdentifier[3] == 'S')
-				iImageType = E_ROFS;
-			else if (iIdentifier[3] == 'x')
-				iImageType = E_ROFX;
-			}
-		}
-	return iImageType;
-	}
-
-/** 
-Reads the 4 byte image type identifier from the core image file.
-
-@return KErrNone for successful read or error number if failed 
-*/
-TInt RCoreImageReader::ReadIdentifier()
-	{
-	int itemsRead = fread(&iIdentifier, sizeof(TUint8), K_ID_SIZE, iCoreImage);
-	TInt result = ImageError(itemsRead,  K_ID_SIZE, "Read Identifier");
-	if (result != KErrNone)
-		{
-		iIdentifier[0] = 0;
-		}
-	return result;
-	}
-
-/**
-Reads the core header from the image file.
-
-@param aHeader space for the header read from the file. Only valid if KErrNone is returned.
-@return KErrNone for successful read or error number if failed 
-*/
-TInt RCoreImageReader::ReadCoreHeader(TRofsHeader& aHeader) 
-	{
-	int itemsRead = fread (&aHeader.iHeaderSize, 
-			(sizeof(TRofsHeader)) - K_ID_SIZE*sizeof(TUint8), 1, iCoreImage);
-	TInt result = ImageError(itemsRead, 1, "Read Core Header");
-	if (result == KErrNone)
-		{
-		// copy the previously read identifier into the header
-		for (int i=0; i<K_ID_SIZE; i++)
-			aHeader.iIdentifier[i] = iIdentifier[i];
-		}
-	return result;
-	}
-
-/**
-Reads the extension header from the image file.
-
-@param aHeader space for the header read from the file. Only valid if KErrNone is returned.
-@return KErrNone for successful read or error number if failed 
-*/
-TInt RCoreImageReader::ReadExtensionHeader(TExtensionRofsHeader& aHeader)
-	{
-	int itemsRead = fread (&aHeader.iHeaderSize, 
-			(sizeof(TExtensionRofsHeader)) - K_ID_SIZE*sizeof(TUint8), 1, iCoreImage);
-	TInt result = ImageError(itemsRead, 1, "Read Extension Header");
-	if (result == KErrNone)
-		{
-		// copy the previously read identifier into the header
-		for (int i=0; i<K_ID_SIZE; i++)
-			aHeader.iIdentifier[i] = iIdentifier[i];
-		}
-	return result;
-	}
-
-/**
-Moves the actual file position to the specified location.
-
-@param aFilePos Desired location for the new position
-*/
-void RCoreImageReader::SetFilePosition(long aFilePos)
-	{
-	fseek(iCoreImage, aFilePos, 0);
-	}
-
-/**
-Validates whether the supplied file position exists in the core image file. 
-It is not sufficient to just move to the required position in the file, 
-but a read needs to be performed as well to ensure that the position exists.
-The method preserves the current file position.
-
-@param aFilePos Desired File Position
-@return ETrue if desired file position exists in file else EFalse
-*/
-TBool RCoreImageReader::IsValidPosition(long aFilePos)
-	{
-	TBool valid = EFalse;
-	long currentPos = ftell(iCoreImage); // save current position
-	
-	int result = fseek(iCoreImage, aFilePos, 0);
-	if (result == 0)
-		{
-		int dummy;
-		int itemsRead = fread(&dummy, sizeof(dummy), 1, iCoreImage);
-
-		if (!ferror(iCoreImage) && !feof(iCoreImage) && result==0 && itemsRead == 1)
-			valid = ETrue;
-		}
-	fseek(iCoreImage, currentPos, 0); // return to previous position
-	return valid;
-	}
-
-/**
-Reads a directory entry from the current position in the core image file. This
-method does not read the variable length TRofsEntry part of the directory entry.
-TRofsEntry does not exist for all directory entries. This is read later by 
-other methods
-
-@param aDir memory where the directory entry is read from the file. This is only valid if KErrNone is returned.
-@return KErrNone for successful read or error number if failed 
-*/
-TInt RCoreImageReader::ReadDirEntry(TRofsDir& aDir)
-	{
-	// read directory without the associated TRofsEntry. The TRofsEntry 
-	// is read later when handling subdirectories
-	int bytesRead = sizeof(TRofsDir) - sizeof(TRofsEntry);
-	int itemsRead = fread (&aDir, bytesRead , 1, iCoreImage);
-	if (ImageError(itemsRead, 1, "Read Dir") == KErrNone)
-		return bytesRead;
-	else
-		return 0;
-	}
-
-/**
-Reads a directory entry from the specified position in the core image file.
-This method moves the position of the file to the specified value and then
-uses the other ReadDirEntry method to read the directory entry
-
-@param aDir memory where the directory entry is read from the file. This is only valid if KErrNone is returned.
-@param aFilePos position in the core image file where the directory
-entry is located
-@return KErrNone for successful read or error number if failed 
-@see RCoreImageReader::ReadDirEntry(TRofsDir* aDir)
-*/
-TInt RCoreImageReader::ReadDirEntry(TRofsDir& aDir, long aFilePos)
-	{
-	SetFilePosition(aFilePos);
-	return ReadDirEntry(aDir);
-	}
-
-/**
-Reads a TRofsEntry from the current file position within the core image.
-
-@param aEntry memory to be used for reading the data from the file. This is only valid if the size returned is greater than zero
-@return size of the entry read
-*/
-TInt RCoreImageReader::ReadRofEntry(TRofsEntry& aEntry)
-	{
-	// need to work out how big entry needs to be from the Struct Size
-	// in TRofsEntry
-	int itemsRead = fread(&aEntry.iStructSize, sizeof(TUint16), 1, iCoreImage);
-	int result = ImageError(itemsRead, 1, "Read Entry Size");
-	if (result == KErrNone)
-		{
-		// read rest of entry excluding the iStructSize
-		itemsRead = fread(&aEntry.iUids[0], sizeof(TRofsEntry) -sizeof(TUint16), 
-				          1, iCoreImage);
-		result = ImageError(itemsRead, 1, "Rest of Entry");
-		// return length read - this include includes iStructSize and first char of name
-		if (result == KErrNone)
-			return sizeof(TRofsEntry);	
-		}
-	return 0;
-	}
-
-/**
-Reads a TRofsEntry from the specified position within the core image
-
-@param aEntry memory to be used for reading the data from the file. This is only valid if the size returned is greater than zero
-@param aFilePos position in the core image file where the entry is located
-@return size of the entry read
-*/
-TInt RCoreImageReader::ReadRofEntry(TRofsEntry& aEntry, long aFilePos)
-	{
-	fseek(iCoreImage, aFilePos, 0);
-	return ReadRofEntry(aEntry);
-	}
-
-/**
-Reads a name of the specified length from the core image file.
-
-@param aName memory for the name read from the file. Only valid if KErrNone is returned
-@param aLength length of name to be read
-@return KErrNone for successful read or error number if failed 
-*/
-TInt RCoreImageReader::ReadRofEntryName(TUint16* aName, int aLength)
-	{
-	int itemsRead = fread(aName, sizeof(TUint16), aLength, iCoreImage);
-	return ImageError(itemsRead, aLength, "Rof Entry Name");
-	}
-
-/**
-Provides the current file position in the core image file.
-
-@return Current file position
-*/
-long  RCoreImageReader::FilePosition()
-	{
-	return ftell(iCoreImage);
-	}
-
-/** 
-Provides the name of the core image file being read.
-
-@return Core image Filename
-*/
-TText* RCoreImageReader::Filename()
-	{
-	return (TText *)iFilename;
-	}
-
-/**
-Determines whether the last read from the file was valid or not.
-It checks that the number of items read where the same number as expected,
-that there are no file errors and that the end of file was not reached. If an
-error is found than a message is printed and the appropriate error number is 
-returned.
-
-@param aItemsRead Number of items read
-@param aExpected Number of items expected to have been read
-@param aInfo Used by the caller to identify where the error occurred.
-@return Error number. KErrNone is returned if there are no errors.
-*/
-TInt RCoreImageReader::ImageError(int aItemsRead, int aExpected, char *aInfo)
-	{
-	if (aItemsRead != aExpected)
-		{
-		Print(EError, "Read From Core Image Failed (%s) \n", aInfo);
-		return KErrCorrupt;
-		}
-	if (int errnum = ferror(iCoreImage))
-		{
-		Print(EError, "Core Image File Error (%s) : %d\n", aInfo, errnum);
-		return KErrCorrupt;
-		}
-	if (feof(iCoreImage))
-		{
-		Print(EError, "Premature End of File Detected (%s)\n", aInfo);
-		return KErrEof;
-		}
-	return KErrNone;
-	}
-
-// -----------------------------------------------------------
-//  CCoreImage 
-// -----------------------------------------------------------
-
-/**
-Initialises the reader to be used for accessing the core image file
-
-@param aReader Reader to be used for accessing the core image file
-*/
-CCoreImage::CCoreImage(RCoreImageReader* aReader) : iReader(aReader),
-	iRootDirectory(0), iFileEntries(0), iDirTreeOffset(0),
-	iDirTreeSize(0), iDirFileEntriesOffset(0),
-iDirFileEntriesSize(0), iRomFileName(0), iImageSize(0)
-	{
-	}
-
-/**
-Deletes the directory tree that was created from the core image.
-*/
-CCoreImage::~CCoreImage()
-	{
-	delete iRootDirectory;
-	iRootDirectory=0;
-	}
-
-
-/**
-Creates the node to be used as the root directory of the directory tree.
-
-@return KErrNone for successful read or error number if failed 
-*/
-TInt CCoreImage::CreateRootDir()
-	{
-	iRootDirectory = new TRomNode((TText*)"");
-	if (iRootDirectory == 0 )
-		return KErrNoMemory;
-	return KErrNone;
-	}
-
-/**
-Processes the core image file to produce a directory tree.
-
-@return KErrNone for successful read or error number if failed 
-*/
-TInt CCoreImage::ProcessImage()
-	{
-	iRomFileName = iReader->Filename();
-	int result = CreateRootDir();
-	if (result == KErrNone)
-		{
-		if (iReader->Open())
-			{
-			RCoreImageReader::TImageType imageType = iReader->ReadImageType();
-			if (imageType == RCoreImageReader::E_ROFS)
-				{
-				TRofsHeader header;
-				result = iReader->ReadCoreHeader(header);
-				if (result == KErrNone)
-					{
-					SaveDirInfo(header);
-					result = ProcessDirectory(0);
-					}
-				}
-			else
-				result = KErrNotSupported;
-			}
-		else
-			result = KErrGeneral;
-		}
-	return result;
-	}
-
-/**
-Processes the directory in the core image file.
-
-@param aAdjustment The difference between offsets in the core image directory and
-@return KErrNone for successful read or error number if failed 
-*/
-TInt CCoreImage::ProcessDirectory(long aAdjustment)
-	{
-	long filePos = iDirTreeOffset - aAdjustment;
-	TDirectoryEntry *firstDir = new TDirectoryEntry(filePos, iReader, iRootDirectory);
-	if (firstDir == 0)
-		return KErrNoMemory;
-	TInt result = firstDir->Process(aAdjustment);
-	delete firstDir;
-	return result;
-	}
-
-/**
-Saves directory information from core image header for later usage.
-
-@param aHeader Header containing information to be saved
-*/
-void CCoreImage::SaveDirInfo(TRofsHeader& aHeader)
-	{
-	iDirTreeOffset = aHeader.iDirTreeOffset;
-	iDirTreeSize = aHeader.iDirTreeSize;
-	iDirFileEntriesOffset = aHeader.iDirFileEntriesOffset;
-	iDirFileEntriesSize = aHeader.iDirFileEntriesSize;
-	iImageSize = aHeader.iMaxImageSize;
-	}
-
-/**
-Saves directory information from extension image header for later usage.
-
-@param aHeader Header containing information to be saved
-*/
-void CCoreImage::SaveDirInfo(TExtensionRofsHeader& aHeader)
-	{
-	iDirTreeOffset = aHeader.iDirTreeOffset;
-	iDirTreeSize = aHeader.iDirTreeSize;
-	iDirFileEntriesOffset = aHeader.iDirFileEntriesOffset;
-	iDirFileEntriesSize = aHeader.iDirFileEntriesSize;
-	iImageSize = aHeader.iMaxImageSize;
-	}
-
-/**
-Displays the directory tree. This is used for debug purposes only.
-*/
-void CCoreImage::Display(ostream* aOut)
-	{
-	iRootDirectory->DisplayStructure(aOut);
-	}
-
-/**
-Reads offset where directory tree starts in core image.
-
-@return offset of directory tree in image
-*/
-long CCoreImage::DirTreeOffset()
-	{
-	return iDirTreeOffset;
-	}
-
-TRomNode* CCoreImage::CopyDirectory(TRomNode*& aSourceDirectory)
-	{
-	return iRootDirectory->CopyDirectory(aSourceDirectory);
-	}
-
-TRomNode* CCoreImage::RootDirectory()
-	{
-	return iRootDirectory;
-	}
-
-void CCoreImage::SetRootDirectory(TRomNode* aDir)
-	{
-	iRootDirectory = aDir;
-	}
-
-TText* CCoreImage::RomFileName()
-	{
-	return iRomFileName;
-	}
-
-TInt CCoreImage::Size()
-	{
-	return iImageSize;
-	}
-
-// -----------------------------------------------------------
-//  TDirectoryEntry 
-// -----------------------------------------------------------
-
-/**
-Initialises the directory entry
-
-@param aFilePos Position within file where the directory entry is located
-@param aReader Handle used to access the file;
-@param aDir The TRomNode associated with this directory
-*/
-TDirectoryEntry::TDirectoryEntry(long aFilePos, RCoreImageReader* aReader, 
-		TRomNode* aDir) :
-			iReader(aReader),  iCurrentDir(aDir),iFilePos(aFilePos),
-			iAdjustment(0) 
-	{
-	}
-
-/**
-Empty destructor.
-*/
-TDirectoryEntry::~TDirectoryEntry()
-	{
-	}
-
-/**
-Processes the current directory entry. If the directory has any files it will 
-create the appropriate file entries in the directory tree. If the directory 
-has any subdirectories it will create nodes in the directory tree and will 
-create an TDirectoryEntry and then use that to process the subdirectory
-
-@param aAdjustment The difference between offsets in the core image directory and
-the actual position in the file
-*/
-TInt TDirectoryEntry::Process(long aAdjustment)
-	{
-	TRofsDir dir;
-	iAdjustment = aAdjustment;
-	long dirStartPos = iFilePos;
-	int result = KErrNone;
-	int dirSize = iReader->ReadDirEntry(dir, iFilePos);
-	if (dirSize != 0)
-		{
-		if (dir.iFileBlockAddress != 0)
-			{
-			// directory has files in it
-			result = AddFiles(dir.iFileBlockAddress-iAdjustment, dir.iFileBlockSize);
-			}
-		if (result == KErrNone && dir.iStructSize > dirSize)
-			{
-			// directory has subdirectories
-			result = AddSubDirs(dirStartPos + dir.iStructSize);
-			}
-		}
-	else 
-		result = KErrGeneral;
-
-	return result;
-	}
-
-/**
-Processes the subdirectories in the current directory. For each subdirectory
-a TDirectoryEntry is created and is then used to process the directory
-
-@param aEndDirPos Position where the directory block finishes. This is to determine when all subdirectories have been processed
-*/
-TInt TDirectoryEntry::AddSubDirs(long aEndDirPos)
-	{
-	TRofsEntry entry;
-	iFilePos = iReader->FilePosition();
-	TInt result = KErrNone;
-	while (iFilePos < aEndDirPos && result == KErrNone)
-		{
-		TInt size = iReader->ReadRofEntry(entry, iFilePos);
-		if (size >0)
-			{
-			TText* nameStr = GetName(entry.iName[0], entry.iNameLength);
-			if (nameStr !=0)
-				{
-				TRomNode *dir = iCurrentDir->NewSubDir(nameStr);
-				TDirectoryEntry *subDir = new TDirectoryEntry(
-						entry.iFileAddress-iAdjustment, iReader, dir);
-				if (subDir != 0)
-					{
-					// now process the subdirectory
-					subDir->Process(iAdjustment);
-					iFilePos += entry.iStructSize;
-					// round to nearest word boundary
-					iFilePos += (4-entry.iStructSize) & 3;
-					}
-				else
-					result = KErrNoMemory;
-
-                if (subDir)
-                {
-                    delete subDir;
-                }
-				}
-			else
-				result = KErrNoMemory;
-			if(nameStr != 0)
-				delete [] nameStr;
-			}
-		else
-			{
-			result = KErrGeneral;
-			}
-		}
-	return result;
-	}
-
-/**
-Processes a file entries block in the directory and creates the appropriate 
-nodes for each file in the block
-
-@param aStartPosition start for file block in the core image file
-@param aSize size of the file entries block
-*/
-TInt TDirectoryEntry::AddFiles(long aStartPosition, int aSize )
-	{
-	long savedPosition = iReader->FilePosition();
-	long currentPos = aStartPosition;
-	iReader->SetFilePosition(aStartPosition);
-	long endPos = aStartPosition+aSize;
-	TRofsEntry entry;
-	TInt result = KErrNone;
-	while (currentPos < endPos && result == KErrNone)	
-		{
-		TInt size = iReader->ReadRofEntry(entry, currentPos);
-		if (size > 0)
-			{
-			TText *nameStr = GetName(entry.iName[0], entry.iNameLength);
-			if (nameStr != 0)
-				{
-				result = CreateFileEntry(nameStr, entry);
-				currentPos += entry.iStructSize;
-				}
-			else
-				result = KErrNoMemory;
-			if(nameStr != 0)
-			    delete [] nameStr;
-			}
-		else
-			{
-			result = KErrGeneral;
-			}
-		}
-	iReader->SetFilePosition(savedPosition);
-	return result;
-	}
-
-/** 
-Creates a new node for a file entry and the associated TRomBuilderEntry.
-
-@param aNameStr Name of the file entry to be created
-@param aFileAddress Address of file in the core image
-@param aFileSize Size of the file
-*/
-TInt TDirectoryEntry::CreateFileEntry(TText* aNameStr, TRofsEntry& aRofsEntry)
-	{
-	TRomBuilderEntry *fileEntry = new TRomBuilderEntry(0,aNameStr);
-	if (fileEntry == 0)
-		return KErrNoMemory;
-
-	memcpy(&fileEntry->iUids[0], &aRofsEntry.iUids[0], sizeof(fileEntry->iUids));
-	fileEntry->iFileOffset = aRofsEntry.iFileAddress;
-	fileEntry->SetRealFileSize(aRofsEntry.iFileSize);
-	TRomNode *file = new TRomNode(aNameStr, fileEntry);
-	file->iSize = aRofsEntry.iFileSize;
-	if (file == 0)
-		{
-		delete fileEntry;
-		return KErrNoMemory;
-		}
-	file->iAtt = aRofsEntry.iAtt;
-	file->iAttExtra = aRofsEntry.iAttExtra;
-	iCurrentDir->AddFile(file);
-	return KErrNone;
-	}
-
-/**
-Gets the name of a file or directory from the core image. The first character
-of the name has already been read.
-
-@param aFirstChar first character of name (already read by TRofsEntry)
-@param aLength Length of name to be read (including the first character)
-*/
-TText* TDirectoryEntry::GetName(TUint16 aFirstChar, TInt aLength)
-	{
-	TText *nameStr = 0;
-	TUint16* name = new TUint16[aLength];
-	if (name !=0)
-		{
-		name[0] = aFirstChar;
-		TInt result = iReader->ReadRofEntryName(&name[1], aLength-1);
-		if (result == KErrNone)
-			{
-			nameStr = new TText[aLength+1];
-			if (nameStr != 0)
-				{
-				for (int i=0; i< aLength; i++)
-					{
-					nameStr[i] = (TText) name[i];
-					}
-				nameStr[aLength]=0;
-				}
-			}
-		delete [] name;
-		}
-	return nameStr;
-	}
-
+/*
+* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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 <string.h>
+#include "h_utl.h"
+
+#include <e32std.h>
+#include <e32std_private.h>
+#include "rofs.h"
+
+#include "r_obey.h"
+#include "r_coreimage.h"
+#include "utf16string.h"
+// -----------------------------------------------------------
+//  RCoreImageReader
+// -----------------------------------------------------------
+
+/**
+Constructs reader for the specified file.
+
+@param aFilename Filename for core image file
+*/
+RCoreImageReader::RCoreImageReader(const char* aFilename) : 
+iImageType(E_UNKNOWN),  iFilename(aFilename) {
+}
+
+/**
+Closes the core image file if it was opened.
+*/
+RCoreImageReader::~RCoreImageReader()  {
+	if (iCoreImage.is_open())
+		iCoreImage.close(); 
+}
+
+/**
+Opens the image file that was specified at construction.
+
+@return ETrue if file was opened successfully otherwise returns EFalse
+*/
+TBool RCoreImageReader::Open() {
+	if(iCoreImage.is_open()) {
+		iCoreImage.seekg(0,ios_base::beg);
+	}else{
+		iCoreImage.open(iFilename.c_str(), ios_base::in + ios_base::binary);
+		if (!iCoreImage.is_open()) {
+			Print(EError, "Cannot open image file %s\n", iFilename.c_str());
+			return EFalse;
+		}
+	}
+
+	return ETrue;
+}
+
+/**
+Reads the image type from the core image file. It reads the value from the
+file and then translates it into the internal enum used for processing 
+the images. 
+
+@return Image type
+*/
+RCoreImageReader::TImageType RCoreImageReader::ReadImageType()  {
+	iImageType = E_UNKNOWN;
+	iCoreImage.seekg(0,ios_base::beg);
+	if ( ReadIdentifier() == KErrNone) {
+		if (iIdentifier[0] == 'R' &&
+			iIdentifier[1] == 'O' &&
+			iIdentifier[2] == 'F') {
+			if (iIdentifier[3] == 'S')
+				iImageType = E_ROFS;
+			else if (iIdentifier[3] == 'x')
+				iImageType = E_ROFX;
+		}
+	}
+	return iImageType;
+}
+
+/** 
+Reads the 4 byte image type identifier from the core image file.
+
+@return KErrNone for successful read or error number if failed 
+*/
+TInt RCoreImageReader::ReadIdentifier() {
+
+	iCoreImage.read(reinterpret_cast<char*>(&iIdentifier[0]),K_ID_SIZE);
+	TInt result = ImageError(iCoreImage.gcount(),  K_ID_SIZE, "Read Identifier");
+	if (result != KErrNone) {
+		iIdentifier[0] = 0;
+	}
+	return result;
+}
+
+/**
+Reads the core header from the image file.
+
+@param aHeader space for the header read from the file. Only valid if KErrNone is returned.
+@return KErrNone for successful read or error number if failed 
+*/
+TInt RCoreImageReader::ReadCoreHeader(TRofsHeader& aHeader)  {
+	int bytesRead  =  sizeof(TRofsHeader) - K_ID_SIZE; 
+	iCoreImage.read(reinterpret_cast<char*>(&aHeader.iHeaderSize),bytesRead ); 
+	TInt result = ImageError(iCoreImage.gcount(),bytesRead, "Read Core Header");
+	if (result == KErrNone) {
+		// copy the previously read identifier into the header
+		for (int i=0; i<K_ID_SIZE; i++)
+			aHeader.iIdentifier[i] = iIdentifier[i];
+	}
+	return result;
+}
+
+/**
+Reads the extension header from the image file.
+
+@param aHeader space for the header read from the file. Only valid if KErrNone is returned.
+@return KErrNone for successful read or error number if failed 
+*/
+TInt RCoreImageReader::ReadExtensionHeader(TExtensionRofsHeader& aHeader) {
+	int bytesRead =  sizeof(TExtensionRofsHeader) - K_ID_SIZE; 
+	iCoreImage.read(reinterpret_cast<char*>(&aHeader.iHeaderSize),bytesRead); 
+	TInt result = ImageError(iCoreImage.gcount(),bytesRead,  "Read Extension Header");
+	if (result == KErrNone) {
+		// copy the previously read identifier into the header
+		for (int i=0; i<K_ID_SIZE; i++)
+			aHeader.iIdentifier[i] = iIdentifier[i];
+	}
+	return result;
+}
+
+/**
+Moves the actual file position to the specified location.
+
+@param aFilePos Desired location for the new position
+*/
+void RCoreImageReader::SetFilePosition(size_t aFilePos) {
+	iCoreImage.seekg(aFilePos, ios_base::beg);
+}
+
+/**
+Validates whether the supplied file position exists in the core image file. 
+It is not sufficient to just move to the required position in the file, 
+but a read needs to be performed as well to ensure that the position exists.
+The method preserves the current file position.
+
+@param aFilePos Desired File Position
+@return ETrue if desired file position exists in file else EFalse
+*/
+TBool RCoreImageReader::IsValidPosition(size_t aFilePos) {
+	TBool valid = EFalse;
+	size_t currentPos = iCoreImage.tellg(); // save current position	
+	iCoreImage.seekg(aFilePos, ios_base::beg);
+	if (!iCoreImage.fail() && !iCoreImage.eof() ) {
+		int dummy;
+		iCoreImage.read(reinterpret_cast<char*>(&dummy), sizeof(dummy));
+		int bytesRead = iCoreImage.gcount();
+		if(bytesRead == sizeof(dummy) && !iCoreImage.fail() || !iCoreImage.eof())
+			valid = ETrue;
+	}
+	iCoreImage.seekg(currentPos, ios_base::beg); // return to previous position
+	return valid;
+}
+
+/**
+Reads a directory entry from the current position in the core image file. This
+method does not read the variable length TRofsEntry part of the directory entry.
+TRofsEntry does not exist for all directory entries. This is read later by 
+other methods
+
+@param aDir memory where the directory entry is read from the file. This is only valid if KErrNone is returned.
+@return KErrNone for successful read or error number if failed 
+*/
+TInt RCoreImageReader::ReadDirEntry(TRofsDir& aDir) {
+	// read directory without the associated TRofsEntry. The TRofsEntry 
+	// is read later when handling subdirectories
+	int bytesRead = sizeof(TRofsDir) - sizeof(TRofsEntry);
+	iCoreImage.read(reinterpret_cast<char*>(&aDir), bytesRead);
+	if (ImageError(iCoreImage.gcount(), bytesRead, "Read Dir") == KErrNone)
+		return bytesRead;
+	else
+		return 0;
+}
+
+/**
+Reads a directory entry from the specified position in the core image file.
+This method moves the position of the file to the specified value and then
+uses the other ReadDirEntry method to read the directory entry
+
+@param aDir memory where the directory entry is read from the file. This is only valid if KErrNone is returned.
+@param aFilePos position in the core image file where the directory
+entry is located
+@return KErrNone for successful read or error number if failed 
+@see RCoreImageReader::ReadDirEntry(TRofsDir* aDir)
+*/
+TInt RCoreImageReader::ReadDirEntry(TRofsDir& aDir, size_t aFilePos) {
+	SetFilePosition(aFilePos);
+	return ReadDirEntry(aDir);
+}
+
+/**
+Reads a TRofsEntry from the current file position within the core image.
+
+@param aEntry memory to be used for reading the data from the file. This is only valid if the size returned is greater than zero
+@return size of the entry read
+*/
+TInt RCoreImageReader::ReadRofEntry(TRofsEntry& aEntry) {
+	// need to work out how big entry needs to be from the Struct Size
+	// in TRofsEntry
+	iCoreImage.read(reinterpret_cast<char*>(&aEntry.iStructSize), sizeof(TUint16));
+	int result = ImageError(iCoreImage.gcount(), sizeof(TUint16), "Read Entry Size");
+	if (result == KErrNone) {
+		// read rest of entry excluding the iStructSize
+		int bytesRead = sizeof(TRofsEntry) -sizeof(TUint16);
+		iCoreImage.read(reinterpret_cast<char*>(&aEntry.iUids[0]),bytesRead);
+		result = ImageError(iCoreImage.gcount(), bytesRead, "Rest of Entry");
+		// return length read - this include includes iStructSize and first char of name
+		if (result == KErrNone)
+			return sizeof(TRofsEntry);	
+	}
+	return 0;
+}
+
+/**
+Reads a TRofsEntry from the specified position within the core image
+
+@param aEntry memory to be used for reading the data from the file. This is only valid if the size returned is greater than zero
+@param aFilePos position in the core image file where the entry is located
+@return size of the entry read
+*/
+TInt RCoreImageReader::ReadRofEntry(TRofsEntry& aEntry, size_t aFilePos) {
+	SetFilePosition(aFilePos);
+	return ReadRofEntry(aEntry);
+}
+
+/**
+Reads a name of the specified length from the core image file.
+
+@param aName memory for the name read from the file. Only valid if KErrNone is returned
+@param aLength length of name to be read
+@return KErrNone for successful read or error number if failed 
+*/
+TInt RCoreImageReader::ReadRofEntryName(TUint16* aName, int aLength) {
+	int bytesRead = aLength << 1;	
+	iCoreImage.read(reinterpret_cast<char*>(aName), bytesRead);
+	return ImageError(iCoreImage.gcount(), bytesRead, "Rof Entry Name");
+}
+
+/**
+Provides the current file position in the core image file.
+
+@return Current file position
+*/
+size_t  RCoreImageReader::FilePosition() {
+	return iCoreImage.tellg();
+}
+
+/** 
+Provides the name of the core image file being read.
+
+@return Core image Filename
+*/
+const char* RCoreImageReader::Filename() const {
+	return iFilename.c_str();
+}
+
+/**
+Determines whether the last read from the file was valid or not.
+It checks that the number of items read where the same number as expected,
+that there are no file errors and that the end of file was not reached. If an
+error is found than a message is printed and the appropriate error number is 
+returned.
+
+@param aItemsRead Number of items read
+@param aExpected Number of items expected to have been read
+@param aInfo Used by the caller to identify where the error occurred.
+@return Error number. KErrNone is returned if there are no errors.
+*/
+TInt RCoreImageReader::ImageError(int aItemsRead, int aExpected, char *aInfo) {
+	if (aItemsRead != aExpected) {
+		Print(EError, "Read From Core Image Failed (%s) \n", aInfo);
+		return KErrCorrupt;
+	} 
+	if (iCoreImage.eof()) {
+		Print(EError, "Premature End of File Detected (%s)\n", aInfo);
+		return KErrEof;
+	}
+	return KErrNone;
+}
+
+// -----------------------------------------------------------
+//  CCoreImage 
+// -----------------------------------------------------------
+
+/**
+Initialises the reader to be used for accessing the core image file
+
+@param aReader Reader to be used for accessing the core image file
+*/
+CCoreImage::CCoreImage(RCoreImageReader* aReader) : iReader(aReader),
+iRootDirectory(0), iFileEntries(0), iDirTreeOffset(0),
+iDirTreeSize(0), iDirFileEntriesOffset(0),
+iDirFileEntriesSize(0), iImageSize(0) {
+}
+
+/**
+Deletes the directory tree that was created from the core image.
+*/
+CCoreImage::~CCoreImage() {
+	if(iRootDirectory){
+		iRootDirectory->Destroy() ;
+		iRootDirectory = 0 ;
+	} 
+}
+
+
+/**
+Creates the node to be used as the root directory of the directory tree.
+
+@return KErrNone for successful read or error number if failed 
+*/
+TInt CCoreImage::CreateRootDir() {
+	iRootDirectory = new TRomNode("");
+	if (iRootDirectory == 0 )
+		return KErrNoMemory;
+	return KErrNone;
+}
+
+/**
+Processes the core image file to produce a directory tree.
+
+@return KErrNone for successful read or error number if failed 
+*/
+TInt CCoreImage::ProcessImage() {
+	iRomFileName = iReader->Filename();
+	int result = CreateRootDir();
+	if (result == KErrNone) {
+		if (iReader->Open()) {
+			RCoreImageReader::TImageType imageType = iReader->ReadImageType();
+			if (imageType == RCoreImageReader::E_ROFS) {
+				TRofsHeader header;
+				result = iReader->ReadCoreHeader(header);
+				if (result == KErrNone) {
+					SaveDirInfo(header);
+					result = ProcessDirectory(0);
+				}
+			}
+			else
+				result = KErrNotSupported;
+		}
+		else
+			result = KErrGeneral;
+	}
+	return result;
+}
+
+/**
+Processes the directory in the core image file.
+
+@param aAdjustment The difference between offsets in the core image directory and
+@return KErrNone for successful read or error number if failed 
+*/
+TInt CCoreImage::ProcessDirectory(long aAdjustment) {
+	long filePos = iDirTreeOffset - aAdjustment;
+	TDirectoryEntry *firstDir = new TDirectoryEntry(filePos, iReader, iRootDirectory);
+	if (firstDir == 0)
+		return KErrNoMemory;
+	TInt result = firstDir->Process(aAdjustment);
+	delete firstDir;
+	return result;
+}
+
+/**
+Saves directory information from core image header for later usage.
+
+@param aHeader Header containing information to be saved
+*/
+void CCoreImage::SaveDirInfo(TRofsHeader& aHeader) {
+	iDirTreeOffset = aHeader.iDirTreeOffset;
+	iDirTreeSize = aHeader.iDirTreeSize;
+	iDirFileEntriesOffset = aHeader.iDirFileEntriesOffset;
+	iDirFileEntriesSize = aHeader.iDirFileEntriesSize;
+	iImageSize = aHeader.iMaxImageSize;
+}
+
+/**
+Saves directory information from extension image header for later usage.
+
+@param aHeader Header containing information to be saved
+*/
+void CCoreImage::SaveDirInfo(TExtensionRofsHeader& aHeader) {
+	iDirTreeOffset = aHeader.iDirTreeOffset;
+	iDirTreeSize = aHeader.iDirTreeSize;
+	iDirFileEntriesOffset = aHeader.iDirFileEntriesOffset;
+	iDirFileEntriesSize = aHeader.iDirFileEntriesSize;
+	iImageSize = aHeader.iMaxImageSize;
+}
+
+/**
+Displays the directory tree. This is used for debug purposes only.
+*/
+void CCoreImage::Display(ostream* aOut) {
+	iRootDirectory->DisplayStructure(aOut);
+}
+
+/**
+Reads offset where directory tree starts in core image.
+
+@return offset of directory tree in image
+*/
+long CCoreImage::DirTreeOffset() {
+	return iDirTreeOffset;
+}
+
+TRomNode* CCoreImage::CopyDirectory(TRomNode*& aSourceDirectory) {
+	return iRootDirectory->CopyDirectory(aSourceDirectory);
+}
+
+TRomNode* CCoreImage::RootDirectory() {
+	return iRootDirectory;
+}
+
+void CCoreImage::SetRootDirectory(TRomNode* aDir) {
+	iRootDirectory = aDir;
+}
+
+const char* CCoreImage::RomFileName() const {
+	return iRomFileName.c_str();
+}
+
+TInt CCoreImage::Size() const {
+	return iImageSize;
+}
+
+// -----------------------------------------------------------
+//  TDirectoryEntry 
+// -----------------------------------------------------------
+
+/**
+Initialises the directory entry
+
+@param aFilePos Position within file where the directory entry is located
+@param aReader Handle used to access the file;
+@param aDir The TRomNode associated with this directory
+*/
+TDirectoryEntry::TDirectoryEntry(long filePos, RCoreImageReader* aReader,  TRomNode* aDir) :
+iReader(aReader),  iCurrentDir(aDir),iFilePos(filePos),
+iAdjustment(0)  {
+}
+
+/**
+Empty destructor.
+*/
+TDirectoryEntry::~TDirectoryEntry() {
+}
+
+/**
+Processes the current directory entry. If the directory has any files it will 
+create the appropriate file entries in the directory tree. If the directory 
+has any subdirectories it will create nodes in the directory tree and will 
+create an TDirectoryEntry and then use that to process the subdirectory
+
+@param aAdjustment The difference between offsets in the core image directory and
+the actual position in the file
+*/
+TInt TDirectoryEntry::Process(long aAdjustment) {
+	TRofsDir dir;
+	iAdjustment = aAdjustment;
+	long dirStartPos = iFilePos;
+	int result = KErrNone;
+	int dirSize = iReader->ReadDirEntry(dir, iFilePos);
+	if (dirSize != 0) {
+		if (dir.iFileBlockAddress != 0) {
+			// directory has files in it
+			result = AddFiles(dir.iFileBlockAddress-iAdjustment, dir.iFileBlockSize);
+		}
+		if (result == KErrNone && dir.iStructSize > dirSize) {
+			// directory has subdirectories
+			result = AddSubDirs(dirStartPos + dir.iStructSize);
+		}
+	}
+	else 
+		result = KErrGeneral;
+
+	return result;
+}
+
+/**
+Processes the subdirectories in the current directory. For each subdirectory
+a TDirectoryEntry is created and is then used to process the directory
+
+@param aEndDirPos Position where the directory block finishes. This is to determine when all subdirectories have been processed
+*/
+TInt TDirectoryEntry::AddSubDirs(long aEndDirPos) {
+	TRofsEntry entry;
+	iFilePos = iReader->FilePosition();
+	TInt result = KErrNone;
+	string name ;
+	while (iFilePos < aEndDirPos && result == KErrNone) {
+		TInt size = iReader->ReadRofEntry(entry, iFilePos);
+		UTF16String uniName ;
+		if (size >0) {
+			TUint16* nameBuf = uniName.Alloc(entry.iNameLength);
+			*nameBuf = entry.iName[0];
+			result = iReader->ReadRofEntryName(&nameBuf[1],entry.iNameLength - 1);
+			if(result != KErrNone){ 
+				return result ;
+			} 
+			if (uniName.ToUTF8(name)) { 
+				TRomNode *dir = iCurrentDir->NewSubDir(name.c_str());
+				TDirectoryEntry *subDir = new TDirectoryEntry(
+					entry.iFileAddress-iAdjustment, iReader, dir);
+				if (subDir != 0) {
+					// now process the subdirectory
+					subDir->Process(iAdjustment);
+					iFilePos += entry.iStructSize;
+					// round to nearest word boundary
+					iFilePos += (4-entry.iStructSize) & 3;
+				}
+				else
+					result = KErrNoMemory;
+
+				if (subDir) {
+					delete subDir;
+				}
+			}
+			else
+				result = KErrNoMemory;
+		}
+		else {
+			result = KErrGeneral;
+		}
+	}
+	return result;
+}
+
+/**
+Processes a file entries block in the directory and creates the appropriate 
+nodes for each file in the block
+
+@param aStartPosition start for file block in the core image file
+@param aSize size of the file entries block
+*/
+TInt TDirectoryEntry::AddFiles(long aStartPosition, int aSize ) {
+	long savedPosition = iReader->FilePosition();
+	long currentPos = aStartPosition;
+	iReader->SetFilePosition(aStartPosition);
+	long endPos = aStartPosition+aSize;
+	TRofsEntry entry;
+	TInt result = KErrNone;
+	string name ;
+	UTF16String uniName;
+	while (currentPos < endPos && result == KErrNone)	 {
+		TInt size = iReader->ReadRofEntry(entry, currentPos);
+		if (size > 0) {
+			TUint16* nameBuf = uniName.Alloc(entry.iNameLength);
+			*nameBuf = entry.iName[0] ;			
+			result = iReader->ReadRofEntryName(&nameBuf[1],entry.iNameLength - 1);
+			if(result != KErrNone){ 
+				return result ;
+			}  
+			if (uniName.ToUTF8(name)) {
+				result = CreateFileEntry(name.c_str(), entry);
+				currentPos += entry.iStructSize;
+			}
+			else
+				result = KErrNoMemory;
+		}
+		else {
+			result = KErrGeneral;
+		}
+	}
+	iReader->SetFilePosition(savedPosition);
+	return result;
+}
+
+/** 
+Creates a new node for a file entry and the associated TRomBuilderEntry.
+
+@param aNameStr Name of the file entry to be created
+@param aFileAddress Address of file in the core image
+@param aFileSize Size of the file
+*/
+TInt TDirectoryEntry::CreateFileEntry(const char* aNameStr, TRofsEntry& aRofsEntry) {
+	TRomBuilderEntry *fileEntry = new TRomBuilderEntry(0,aNameStr);
+	if (fileEntry == 0)
+		return KErrNoMemory;
+
+	memcpy(&fileEntry->iUids[0], &aRofsEntry.iUids[0], sizeof(fileEntry->iUids));
+	fileEntry->iFileOffset = aRofsEntry.iFileAddress;
+	fileEntry->SetRealFileSize(aRofsEntry.iFileSize);
+	TRomNode *file = new TRomNode(aNameStr, fileEntry);
+	file->iSize = aRofsEntry.iFileSize;
+	if (file == 0) {
+		delete fileEntry;
+		return KErrNoMemory;
+	}
+	file->iAtt = aRofsEntry.iAtt;
+	file->iAttExtra = aRofsEntry.iAttExtra;
+	iCurrentDir->AddFile(file);
+	return KErrNone;
+}
+