crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianSymbolLib/Plugins/SLPluginSymbol/Program.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianSymbolLib/Plugins/SLPluginSymbol/Program.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,311 @@
+/*
+* 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.IO;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using SymbianUtils.Range;
+
+namespace SymbianSymbolLibTest
+{
+    class Program
+    {
+        class Binary
+        {
+            public string iFileName = string.Empty;
+            public byte[] iData = null;
+            public long iDataStart = 0;
+            public long iDataEnd = 0;
+        }
+        
+        class Binary2
+        {
+            public string iFileName = string.Empty;
+            public List<string> iData = new List<string>();
+        }
+
+        class Store
+        {
+            public Store()
+            {
+            }
+
+            public void Add( string aFileName, Binary2 aData )
+            {
+                lock ( iEntries )
+                {
+                    if ( !iEntries.ContainsKey( aFileName ) )
+                    {
+                        iEntries.Add( aFileName, aData );
+                    }
+                }
+            }
+
+            public int Count
+            {
+                get { return iEntries.Count; }
+            }
+
+            public void Dump()
+            {
+            }
+
+            private Dictionary<string, Binary2> iEntries = new Dictionary<string, Binary2>();
+        }
+
+        class ThreadReader
+        {
+            public delegate void CompletionHandler( ThreadReader aReader );
+            public event CompletionHandler Completed = null;
+
+            public ThreadReader( byte[] aData, int aStart, int aCount, Store aStore )
+            {
+                iData = aData;
+                iStart = aStart;
+                iCount = aCount;
+                iStore = aStore;
+            }
+
+            public void Read()
+            {
+                //System.Console.WriteLine( string.Format( "Reading starting - pos: 0x{0}, len: {1:d8}", iStart, iCount ) );
+                DateTime timeStamp = DateTime.Now;
+                
+                Binary2 currentBinary = null;
+
+                long binaryCount = 0;
+                long lineCount = 0;
+                using ( StreamReader reader = new StreamReader( new MemoryStream( iData, iStart, iCount ) ) )
+                {
+                    string line = reader.ReadLine();
+                    while ( line != null )
+                    {
+                        ++lineCount;
+                        if ( line.StartsWith( "From    " ) )
+                        {
+                            currentBinary = new Binary2();
+                            currentBinary.iFileName = line.Substring( 8 );
+                            //
+                            ++binaryCount;
+                            iStore.Add( currentBinary.iFileName, currentBinary );
+                        }
+                        else if ( currentBinary != null )
+                        {
+                            currentBinary.iData.Add( line );
+                        }
+
+                        line = reader.ReadLine();
+                    }
+                }
+
+                DateTime endTime = DateTime.Now;
+                TimeSpan span = ( endTime - timeStamp );
+                //System.Console.WriteLine( string.Format( "Reading complete - {0} time, {1} lines, {2} binaries", span, lineCount, binaryCount ) );
+
+                if ( Completed != null )
+                {
+                    Completed( this );
+                }
+            }
+
+            private readonly byte[] iData;
+            private readonly int iStart;
+            private readonly int iCount;
+            private readonly Store iStore;
+        }
+
+        class SymbolFile
+        {
+            #region Constructors
+            public SymbolFile( FileInfo aFile )
+            {
+                iFile = aFile;
+            }
+            #endregion
+
+            #region API
+            public void Read()
+            {
+                Partition();
+                //
+                iWaiter = new AutoResetEvent( false );
+                for( int i=iReaders.Count-1; i>=0; i-- )
+                {
+                    ThreadReader reader = iReaders[ i ];
+                    reader.Completed += new ThreadReader.CompletionHandler( Reader_Completed );
+                    ThreadPool.QueueUserWorkItem( new WaitCallback(StartReader ), reader );
+                }
+                
+                // Now wait
+                using ( iWaiter )
+                {
+                    iWaiter.WaitOne();
+                }
+                iWaiter = null;
+            }
+            #endregion
+
+            #region Properties
+            public int Count
+            {
+                get { return iStore.Count; }
+            }
+            #endregion
+
+            #region Event handlers
+            private void Reader_Completed( ThreadReader aReader )
+            {
+                iCompleted.Add( aReader );
+                iReaders.Remove( aReader );
+                //
+                if ( iReaders.Count == 0 )
+                {
+                    iWaiter.Set();
+                }
+            }
+            #endregion
+
+            #region Internal methods
+            private static void StartReader( object aThreadReader )
+            {
+                ThreadReader reader = (ThreadReader) aThreadReader;
+                reader.Read();
+            }
+
+            private void Partition()
+            {
+                // Read entire file into buffer
+                byte[] data = new byte[ iFile.Length ];
+                using ( Stream reader = new FileStream( iFile.FullName, FileMode.Open ) )
+                {
+                    reader.Read( data, 0, data.Length );
+                }
+
+                // This is the pattern we are searching for:
+                byte[] pattern = new byte[] { (byte) 'F', (byte) 'r', (byte) 'o', (byte) 'm', (byte) ' ', (byte) ' ', (byte) ' ', (byte) ' ' };
+
+                int threadCount = System.Environment.ProcessorCount;
+                int chunkSize = (int) iFile.Length / threadCount;
+
+                //
+                int blockPosStart = 0;
+                for ( int i = 0; i < threadCount; i++ )
+                {
+                    int pos = 0;
+                    int blockPosEnd = Math.Min( data.Length - 1, blockPosStart + chunkSize );
+                    while ( pos >= 0 )
+                    {
+                        pos = Array.IndexOf( data, pattern[ 0 ], blockPosEnd );
+                        if ( pos > 0 )
+                        {
+                            if ( pos + 8 >= data.Length )
+                            {
+                                break;
+                            }
+                            else if ( pos + 8 < data.Length && data[ pos + 7 ] == pattern[ 7 ] )
+                            {
+                                bool isMatch = CompareByteArrays( pattern, data, pos );
+                                if ( isMatch )
+                                {
+                                    int length = pos - blockPosStart;
+                                    System.Console.WriteLine( string.Format( "Block {0:d2} @ 0x{1:x8}, length: {2:d8}", i, blockPosStart, length ) );
+                                    //
+                                    ThreadReader reader = new ThreadReader( data, blockPosStart, length, iStore );
+                                    iReaders.Add( reader );
+
+                                    blockPosStart = pos;
+                                    break;
+                                }
+                            }
+                            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.
+                            int length2 = data.Length - blockPosStart;
+                            System.Console.WriteLine( string.Format( "Block {0:d2} @ 0x{1:x8}, length: {2:d8}", i, blockPosStart, length2 ) );
+                            //
+                            ThreadReader reader2 = new ThreadReader( data, blockPosStart, length2, iStore );
+                            iReaders.Add( reader2 );
+                            break;
+                        }
+                    }
+                }
+            }
+
+            private static bool CompareByteArrays( byte[] aSearchFor, byte[] aSearchIn, int aStartPos )
+            {
+                bool areEqual = true;
+                //
+                for ( int i = aStartPos; i < aSearchFor.Length; i++ )
+                {
+                    byte b = aSearchIn[ i ];
+                    byte c = aSearchFor[ i - aStartPos ];
+                    if ( b != c )
+                    {
+                        areEqual = false;
+                        break;
+                    }
+                }
+                //
+                return areEqual;
+            }
+            #endregion
+
+            #region Data members
+            private readonly FileInfo iFile;
+            private AutoResetEvent iWaiter = null;
+            private Store iStore = new Store();
+            private List<ThreadReader> iCompleted = new List<ThreadReader>();
+            private List<ThreadReader> iReaders = new List<ThreadReader>();
+            #endregion
+        }
+
+        static void Main( string[] args )
+        {
+            string path = @"C:\Tool Demo Files\2. Crash Data\File43\CoreImage"; // C:\Tool Demo Files\2. Crash Data\File28\";
+            DirectoryInfo dir = new DirectoryInfo( path );
+            FileInfo[] files = dir.GetFiles( "*.symbol" );
+            //
+            //
+            foreach ( FileInfo file in files )
+            {
+                //
+                DateTime timeStamp = DateTime.Now;
+                System.Console.WriteLine( string.Format( "[{0}] - Reading starting...", file.Name ) );
+
+                SymbolFile symbolFile = new SymbolFile( file );
+                symbolFile.Read();
+
+                DateTime endTime = DateTime.Now;
+                TimeSpan span = ( endTime - timeStamp );
+
+                System.Console.WriteLine( string.Format( "[{0}] - Reading complete - {1} time, {2} binaries", file.Name, span, symbolFile.Count ) );
+                System.Console.WriteLine( " " );
+                System.Console.WriteLine( " " );
+                System.Console.WriteLine( " " );
+                System.Console.ReadKey();
+            }
+        }
+    }
+}