diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianSymbolLib/Plugins/SLPluginSymbol/Data/SymbolFileData.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianSymbolLib/Plugins/SLPluginSymbol/Data/SymbolFileData.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,244 @@ +/* +* Copyright (c) 2004-2008 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.IO; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using SymbianStructuresLib.Debug.Symbols; +using SymbianStructuresLib.Debug.Symbols.Interfaces; +using SymbianSymbolLib.SourceManagement.Source; +using SymbianSymbolLib.SourceManagement.Provisioning; +using SymbianUtils; +using SymbianUtils.Tracer; +using SymbianUtils.FileTypes; +using SymbianUtils.Threading; +using SLPluginSymbol.Source; + +namespace SLPluginSymbol.Data +{ + internal class SymbolFileData : DisposableObject, IEnumerable + { + #region Delegates & events + public delegate void DataPreparedHandler( SymbolFileData aData ); + public event DataPreparedHandler DataPrepared = delegate { }; + #endregion + + #region Constructors + public SymbolFileData( SymbolSource aSource ) + { + iSource = aSource; + iData = File.ReadAllBytes( aSource.URI ); + } + #endregion + + #region API + public void Split( int aSegmentCount ) + { + int chunkSize = (int) iData.Length / aSegmentCount; + int blockPosStart = 0; + int length = 0; + // + for ( int i = 0; i < aSegmentCount; i++ ) + { + int pos = 0; + int blockPosEnd = Math.Min( iData.Length - 1, blockPosStart + chunkSize ); + while ( pos >= 0 ) + { + pos = Array.IndexOf( iData, KPattern[ 0 ], blockPosEnd ); + if ( pos > 0 ) + { + if ( pos + 8 >= iData.Length ) + { + break; + } + else if ( pos + 8 < iData.Length && iData[ pos + 7 ] == KPattern[ 7 ] ) + { + bool isMatch = CompareByteArrays( KPattern, iData, pos ); + if ( isMatch ) + { + length = pos - blockPosStart; + //System.Diagnostics.Debug.WriteLine( string.Format( "Block {0:d2} @ 0x{1:x8}, length: {2:d8}", i, blockPosStart, length ) ); + // + iSegments.Add( new SymbolFileSegment( this, blockPosStart, length ) ); + blockPosStart = pos; + break; + } + else + { + // Didn't find a match, move forwards + blockPosEnd = pos + 1; + } + } + else + { + // Didn't find a match, move forwards + blockPosEnd = pos + 1; + } + } + else + { + // Searched to end of file and didn't find another block, so just create + // a new reader for everything that remains. + length = iData.Length - blockPosStart; + //System.Diagnostics.Debug.WriteLine( string.Format( "Block {0:d2} @ 0x{1:x8}, length: {2:d8}", i, blockPosStart, length ) ); + iSegments.Add( new SymbolFileSegment( this, blockPosStart, length ) ); + // + break; + } + } + } + + iCollectionIdentifier = new MultiThreadedProcessor( this ); + } + + public void FindCollections() + { + System.Diagnostics.Debug.Assert( iCollectionIdentifier != null ); + iCollectionIdentifier.ProcessItem += new MultiThreadedProcessor.ItemProcessor( CollectionIdentifier_ProcessItem ); + iCollectionIdentifier.EventHandler += new MultiThreadedProcessor.ProcessorEventHandler( CollectionIdentifier_EventHandler ); + iCollectionIdentifier.Start( TSynchronicity.EAsynchronous ); + } + #endregion + + #region Properties + public SymbolSource Source + { + get { return iSource; } + } + #endregion + + #region Operators + public static implicit operator byte[]( SymbolFileData aData ) + { + return aData.iData; + } + #endregion + + #region Internal constants + private static readonly byte[] KPattern = new byte[] { (byte) 'F', (byte) 'r', (byte) 'o', (byte) 'm', (byte) ' ', (byte) ' ', (byte) ' ', (byte) ' ' }; + #endregion + + #region Event handlers + private void CollectionIdentifier_EventHandler( MultiThreadedProcessor.TEvent aEvent ) + { + switch ( aEvent ) + { + default: + break; + case MultiThreadedProcessor.TEvent.EEventStarting: + break; + case MultiThreadedProcessor.TEvent.EEventCompleted: + iCollectionIdentifier.ProcessItem -= new MultiThreadedProcessor.ItemProcessor( CollectionIdentifier_ProcessItem ); + iCollectionIdentifier.EventHandler -= new MultiThreadedProcessor.ProcessorEventHandler( CollectionIdentifier_EventHandler ); + iCollectionIdentifier.Dispose(); + iCollectionIdentifier = null; + DataPrepared( this ); + break; + } + } + + private void CollectionIdentifier_ProcessItem( SymbolFileSegment aItem ) + { + aItem.PerformInitialCollectionIdentification(); + } + #endregion + + #region Internal methods + private static bool CompareByteArrays( byte[] aSearchFor, byte[] aSearchIn, int aStartPos ) + { + bool areEqual = true; + // + for ( int i = 0; i < aSearchFor.Length; i++ ) + { + byte c = aSearchFor[ i ]; + + int bigBufferIndex = aStartPos + i; + if ( bigBufferIndex > aSearchIn.Length ) + { + // We ran out of data + areEqual = false; + break; + } + else + { + byte b = aSearchIn[ bigBufferIndex ]; + if ( b != c ) + { + areEqual = false; + break; + } + } + } + // + return areEqual; + } + #endregion + + #region From IEnumerable + public IEnumerator GetEnumerator() + { + foreach( SymbolFileSegment segment in iSegments ) + { + yield return segment; + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + foreach ( SymbolFileSegment segment in iSegments ) + { + yield return segment; + } + } + #endregion + + #region From DisposableObject + protected override void CleanupManagedResources() + { + try + { + base.CleanupManagedResources(); + } + finally + { + foreach ( SymbolFileSegment seg in iSegments ) + { + seg.Dispose(); + } + // + if ( iCollectionIdentifier != null ) + { + iCollectionIdentifier.Dispose(); + iCollectionIdentifier = null; + } + // + iSegments.Clear(); + iData = null; + } + } + #endregion + + #region Data members + private readonly SymbolSource iSource; + private byte[] iData = null; + private List iSegments = new List(); + private MultiThreadedProcessor iCollectionIdentifier; + #endregion + } +}