diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianSymbolLib/Plugins/SLPluginSymbol/Reader/SymbolFileSegmentReader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianSymbolLib/Plugins/SLPluginSymbol/Reader/SymbolFileSegmentReader.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,243 @@ +/* +* 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 System.ComponentModel; +using SymbianUtils; +using SymbianUtils.Tracer; +using SymbianUtils.FileTypes; +using SymbianUtils.TextUtilities.Readers.Types.Array; +using SymbianStructuresLib.Debug.Symbols; +using SymbianStructuresLib.Debug.Symbols.Utilities; +using SymbianSymbolLib.SourceManagement.Source; +using SymbianSymbolLib.SourceManagement.Provisioning; +using SLPluginSymbol.Data; +using SLPluginSymbol.Source; + +namespace SLPluginSymbol.Reader +{ + internal class SymbolFileSegmentReader : DisposableObject + { + #region Delegates & events + public delegate void ProgressHandler( SymbolFileSegmentReader aReader, long aTotalNumberOfLines, long aNumberProcessed ); + public event ProgressHandler Progress; + + public delegate void OperationHandler( SymbolFileSegmentReader aReader ); + public event OperationHandler OperationStarted; + public event OperationHandler OperationCompleted; + #endregion + + #region Constructors + public SymbolFileSegmentReader( SymbolFileSegment aSegment ) + { + iSegment = aSegment; + } + #endregion + + #region API + public void Read( TSynchronicity aSynchronicity ) + { + switch ( aSynchronicity ) + { + default: + case TSynchronicity.EAsynchronous: + ThreadPool.QueueUserWorkItem( new WaitCallback( InitiateReadAsync ) ); + break; + case TSynchronicity.ESynchronous: + InitiateRead(); + break; + } + } + #endregion + + #region Properties + public SymbolSource Source + { + get { return iSegment.Source; } + } + + public SymbolFileSegment FileSegment + { + get { return iSegment; } + } + #endregion + + #region Internal methods + private void InitiateReadAsync( object aNotUsed ) + { + InitiateRead(); + } + + private void InitiateRead() + { + if ( OperationStarted != null ) + { + OperationStarted( this ); + } + // + int count = iSegment.Count; + for ( int i = count - 1; i >= 0; i-- ) + { + SymbolCollectionSegment segment = iSegment[ i ]; + // + ReadLines( segment ); + } + // + if ( OperationCompleted != null ) + { + OperationCompleted( this ); + } + } + + private void ReadLines( SymbolCollectionSegment aSegment ) + { + long count = 0; + + // Make a new collection to which we'll add symbols + SymbolCollection collection = aSegment.Collection; + collection.TransactionBegin(); + + // We'll use this to filter out bad symbols + try + { + using ( SymbolCollectionHarmoniser harmoniser = new SymbolCollectionHarmoniser( collection, SymbolCollectionHarmoniser.TCollectionType.EPossiblyXIP ) ) + { + // Then create symbols + SymbolCreator creator = new SymbolCreator(); + foreach ( string line in aSegment ) + { + Symbol symbol = creator.Parse( line, collection ); + if ( symbol != null ) + { + harmoniser.Add( symbol ); + } + // + ++count; + } + } + } + finally + { + collection.TransactionEnd(); + + // Collection is now complete - run final validation in + // background thread + ValidateAndSaveCollection( collection ); + } + + ReportProgress( count ); + +#if INSPECT_SYMBOL_DATA + using ( StreamWriter writer = new StreamWriter( @"C:\Temp\NewSymbols\" + Path.GetFileName( collection.FileName.FileNameInHost ) + ".symbol" ) ) + { + WriteToStream( collection, writer ); + } +#endif + } + + private void ValidateAndSaveCollection( SymbolCollection aCollection ) + { + // We don't save empty collections since they have no size + bool isEmpty = aCollection.IsEmptyApartFromDefaultSymbol; + if ( !isEmpty ) + { + // Make sure that the collection contains at least one entry with a valid size + bool save = false; + + int count = aCollection.Count; + for ( int i = 0; i < count; i++ ) + { + Symbol sym = aCollection[ i ]; + if ( sym.Size > 0 ) + { + save = true; + break; + } + } + + if ( save ) + { + try + { + // If the source does not accept the collection then just continue to the next + // entry in the file. + aCollection.SortAsync(); + Source.Add( aCollection ); + } + catch + { + } + } + } + } + + private void ReportProgress( long aChunkSize ) + { + if ( Progress != null ) + { + Progress( this, iSegment.NumberOfLines, aChunkSize ); + } + } + +#if INSPECT_SYMBOL_DATA + private void WriteToStream( SymbolCollection aCollection, StreamWriter aWriter ) + { + // First write the binary name + aWriter.WriteLine( string.Empty ); + aWriter.WriteLine( "From " + aCollection.FileName.FileNameInHost ); + aWriter.WriteLine( string.Empty ); + + foreach ( Symbol symbol in aCollection ) + { + StringBuilder ret = new StringBuilder(); + // + ret.Append( symbol.Address.ToString( "x8" ) ); + ret.Append( " " ); + ret.Append( symbol.Size.ToString( "x4" ) ); + ret.Append( " " ); + ret.Append( symbol.Name.PadRight( 40, ' ' ) ); + ret.Append( " " ); + ret.Append( symbol.Object ); + // + aWriter.WriteLine( ret.ToString() ); + } + } +#endif + #endregion + + #region From DisposableObject + protected override void CleanupManagedResources() + { + try + { + base.CleanupManagedResources(); + } + finally + { + } + } + #endregion + + #region Data members + private readonly SymbolFileSegment iSegment; + #endregion + } +}