diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/SearchAndReplace/SymbolicSearchAndReplaceParser.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/SearchAndReplace/SymbolicSearchAndReplaceParser.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,193 @@ +/* +* 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; +using System.Collections.Specialized; +using System.Text.RegularExpressions; +using System.IO; +using System.Text; +using SymbianUtils; +using SymbolLib.Engines; +using SymbolLib.CodeSegDef; + +namespace SymbolLib.SearchAndReplace +{ + public class SymbolicSearchAndReplaceParser : AsyncTextFileReader + { + #region Constructors & destructor + public SymbolicSearchAndReplaceParser( SymbolManager aSymbolManager, string aSourceFile, string aDestinationFile ) + : this( aSymbolManager, aSourceFile, aDestinationFile, string.Empty ) + { + } + + public SymbolicSearchAndReplaceParser( SymbolManager aSymbolManager, string aSourceFile, string aDestinationFile, string aPrefix ) + : base( aSourceFile, new AsyncTextReaderPrefix( aPrefix ), true ) + { + iSymbolManager = aSymbolManager; + iWriter = new StreamWriter( aDestinationFile, false ); + } + #endregion + + #region API + public void SearchAndReplace() + { + base.AsyncRead(); + } + #endregion + + #region Properties + public SymbolManager SymbolManager + { + get { return iSymbolManager; } + } + #endregion + + #region From AsyncTextReaderBase + protected override void HandleFilteredLine( string aLine ) + { + const string KHexChars = "abcdefABCDEF1234567890"; + + int startPos = 0; + StringBuilder line = new StringBuilder(); + + CodeSegDefinition def = iSymbolManager.ROFSEngine.DefinitionParser.ParseAndResolveDefinition( aLine ); + if ( def != null ) + { + SymbolManager.LoadDynamicCodeSegment( def, TSynchronicity.ESynchronous ); + line.Append( aLine ); + } + else + { + // Look through the line looking for 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f in runs of 8 characters + MatchCollection collection = iAddressRegEx.Matches( aLine ); + if ( collection != null && collection.Count > 0 ) + { + foreach ( Match m in collection ) + { + // Now get the stack address + CaptureCollection captures = m.Captures; + foreach ( Capture capture in captures ) + { + string matchText = capture.Value.Trim(); + + // Take all the initial text + int capturePos = capture.Index; + + // Check whether it is a discrete word + bool checkForSymbolMatch = true; + if ( capturePos > 0 ) + { + // Check previous character wasn't a match from our group + char prevCharacter = aLine[ capturePos - 1 ]; + checkForSymbolMatch = ( KHexChars.IndexOf( prevCharacter ) < 0 ); + } + if ( checkForSymbolMatch && ( capturePos + matchText.Length < aLine.Length ) ) + { + // Check next character too + char nextCharacter = aLine[ capturePos + matchText.Length ]; + checkForSymbolMatch = ( KHexChars.IndexOf( nextCharacter ) < 0 ); + } + + // Take any preceeding text... + if ( capturePos > 0 ) + { + int length = capturePos - startPos; + line.Append( aLine.Substring( startPos, length ) ); + startPos = capturePos; + } + + // Always store the original text + line.Append( matchText ); + + // Decide if we can try to find a symbol... + if ( checkForSymbolMatch ) + { + // And now take the text as a symbol (if we have + // a match). + long address = SymbianUtils.NumberBaseUtils.TextToDecimalNumber( matchText, NumberBaseUtils.TNumberBase.EHex ); + Generics.GenericSymbol symbol = iSymbolManager.EntryByAddress( address ); + + if ( symbol != null ) + { + line.Append( " [ " + symbol.Symbol + " ]" ); + } + else if ( iSymbolManager.AddressInRange( address ) ) + { + line.Append( " [ #UNKNOWN# ]" ); + } + } + else + { + // Not a match, just take the original match text and move on... + } + + startPos += matchText.Length; + } + } + } + + // Remember to add anything that is left at the end... + string remainder = aLine.Substring( startPos ); + line.Append( remainder ); + } + + iWriter.WriteLine( line.ToString() ); + } + + protected override void HandleReadCompleted() + { + try + { + if ( iWriter != null ) + { + iWriter.Close(); + } + iWriter = null; + } + finally + { + base.HandleReadCompleted(); + } + } + #endregion + + #region From DisposableObject + protected override void CleanupManagedResources() + { + try + { + if ( iWriter != null ) + { + iWriter.Close(); + } + iWriter = null; + } + finally + { + base.CleanupManagedResources(); + } + } + #endregion + + #region Data members + private readonly SymbolManager iSymbolManager; + private static Regex iAddressRegEx = new Regex( @"[a-fA-F0-9]{8}", RegexOptions.IgnoreCase ); + private StreamWriter iWriter; + #endregion + } +} +