diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianImageLib/ROFS/Structures/TRofsDir.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianImageLib/ROFS/Structures/TRofsDir.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,181 @@ +/* +* Copyright (c) 2009 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: +* +*/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using SymbianUtils.Tracer; +using SymbianUtils.Streams; +using SymbianStructuresLib.Uids; +using SymbianStructuresLib.Version; + +namespace SymbianImageLib.ROFS.Structures +{ + internal class TRofsDir : IEnumerable + { + #region Constructors + public TRofsDir( string aName, uint aFileAddress, SymbianStreamReaderLE aReader, ITracer aTracer ) + { + //aTracer.Trace( "[Dir ] @ 0x{0:x8} {1}", aFileAddress, aName ); + // + iName = aName; + // + aReader.Seek( aFileAddress, SeekOrigin.Begin ); + // + iStructSize = aReader.ReadUInt16(); + iPadding = aReader.ReadUInt8(); + iFirstEntryOffset = aReader.ReadUInt8(); + iFileBlockAddress = aReader.ReadUInt32(); + iFileBlockSize = aReader.ReadUInt32(); + // + if ( iFileBlockAddress != 0 ) + { + // Directory has files in it + AddFiles( aReader, aTracer, iFileBlockAddress, iFileBlockSize ); + } + if ( iStructSize > KMinimumDirectoryEntrySize ) + { + // Directory has subdirectories + AddSubDirs( aReader, aTracer, aFileAddress + iStructSize ); + } + } + #endregion + + #region API + #endregion + + #region Constants + // The minimum standard entry size, irrespective of whether the directory + // contains subdirs or files. + public const uint KMinimumDirectoryEntrySize = 2 + 1 + 1 + 4 + 4; + #endregion + + #region Properties + public uint Size + { + get { return iStructSize; } + } + + public string Name + { + get { return iName; } + } + + public uint FirstEntryOffset + { + get { return iFirstEntryOffset; } + } + + public uint FileBlockAddress + { + get { return iFileBlockAddress; } + } + + public uint FileBlockSize + { + get { return iFileBlockSize; } + } + + public TRofsDir[] SubDirectories + { + get + { + return iSubdirectories.ToArray(); + } + } + #endregion + + #region Internal methods + private void AddFiles( SymbianStreamReaderLE aReader, ITracer aTracer, long aStartPosition, uint aSize ) + { + long originalPosition = aReader.Position; + long endPos = aStartPosition + aSize; + // + long filePosition = aStartPosition; + while ( filePosition < endPos ) + { + // Seek to start of file and read it + aReader.Seek( filePosition, SeekOrigin.Begin ); + TRofsEntry entry = new TRofsEntry( aReader, aTracer ); + iFiles.Add( entry ); + //aTracer.Trace( "[File] @ 0x{0:x8} {1:d8} {2}", filePosition, entry.FileSize, entry.Name ); + + // Move to next file + filePosition += entry.Size; + } + + // Restore original position + aReader.Seek( originalPosition, SeekOrigin.Begin ); + } + + private void AddSubDirs( SymbianStreamReaderLE aReader, ITracer aTracer, long aEndDirPos ) + { + long originalPosition = aReader.Position; + // + long filePosition = aReader.BaseStream.Position; + while ( filePosition < aEndDirPos ) + { + // Seek to start of subdir and read basic properties + aReader.Seek( filePosition, SeekOrigin.Begin ); + TRofsEntry entry = new TRofsEntry( aReader, aTracer ); + + // Create a new subdirectory that we'll process recursively. + TRofsDir subdir = new TRofsDir( entry.Name, entry.FileAddress, aReader, aTracer ); + iSubdirectories.Add( subdir ); + + // Move to next subdir, rounding to 4 bytes + long nextSubDirOffset = entry.Size; + nextSubDirOffset += ( ( 4 - nextSubDirOffset ) & 0x3 ); + filePosition += nextSubDirOffset; + } + + // Restore original position + aReader.Seek( originalPosition, SeekOrigin.Begin ); + } + #endregion + + #region From IEnumerable + public IEnumerator GetEnumerator() + { + foreach ( TRofsEntry entry in iFiles ) + { + yield return entry; + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + foreach ( TRofsEntry entry in iFiles ) + { + yield return entry; + } + } + #endregion + + #region Data members + private readonly string iName; + private ushort iStructSize; // Total size of this directory block including padding + private byte iPadding; + private byte iFirstEntryOffset; // offset to first entry + private uint iFileBlockAddress; // address of associated file block + private uint iFileBlockSize; // size of associated file block + + private List iFiles = new List(); + private List iSubdirectories = new List(); + #endregion + } +}