diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Parsers/State/StateFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Parsers/State/StateFactory.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,209 @@ +/* +* 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.Collections.Generic; +using System.Text; +using System.Reflection; +using SymbianParserLib.Engine; +using CrashDebuggerLib.Structures.Fault; +using SymbianParserLib.Elements; +using CrashDebuggerLib.Parsers.State.Implementation; + +namespace CrashDebuggerLib.Parsers.State +{ + internal static class StateFactory + { + #region API + public static State Create( TState aState, CrashDebuggerParser aParser ) + { + CreateDictionary(); + // + State ret = null; + if ( iDictionary.ContainsKey( aState ) ) + { + ret = CreateState( aState, aParser ); + if ( ret != null ) + { + ret.Prepare(); + } + } + // + return ret; + } + + public static void RegisterCommands( ParserEngine aEngine ) + { + CreateDictionary(); + // + foreach ( KeyValuePair keyVP in iDictionary ) + { + string[] commandIds = keyVP.Value.CommandIdentifiers; + foreach ( string commandId in commandIds ) + { + // Create paragraph and associate the state type with the tag so that + // we know what type of object to create later on when the line fires. + ParserParagraph command = new ParserParagraph( commandId ); + command.Tag = keyVP.Key; + + // Create line to match + ParserLine line = ParserLine.New( commandId ); + + // Make sure that the paragraph and line don't disable themselves whenever + // they see a matching line. Some of these objects are needed more than once! + command.DisableWhenComplete = false; + line.DisableWhenComplete = false; + // + command.Add( line ); + aEngine.Add( command ); + } + } + } + #endregion + + #region Properties + #endregion + + #region Internal methods + private static void CreateDictionary() + { + if ( iDictionary.Count == 0 ) + { + // State table + iDictionary.Add( TState.EStateInfoFault, + new TStateMapplet( "*** CMD: Fault_Info", typeof( StateInfoFault ) ) ); + iDictionary.Add( TState.EStateInfoCpu, + new TStateMapplet( "*** CMD: Cpu_Info", typeof( StateInfoCpu ) ) ); + iDictionary.Add( TState.EStateInfoDebugMask, + new TStateMapplet( "*** CMD: Debug_Mask_Info", typeof( StateInfoDebugMask ) ) ); + iDictionary.Add( TState.EStateInfoScheduler, + new TStateMapplet( "*** CMD: Scheduler_Info", typeof( StateInfoScheduler ) ) ); + + // For compatibility reasons catch either of these entries + iDictionary.Add( TState.EStateInfoUserContextTable, + new TStateMapplet( typeof( StateInfoUserContextTable ), + "*** CMD: UserContextTable_Info", + "*** CMD: UserContextTables" ) ); + + // Other entries... + iDictionary.Add( TState.EStateTheCurrentProcess, + new TStateMapplet( "*** CMD: The_Current_Process", typeof( StateTheCurrentProcess ) ) ); + iDictionary.Add( TState.EStateTheCurrentThread, + new TStateMapplet( "*** CMD: The_Current_Thread", typeof( StateTheCurrentThread ) ) ); + iDictionary.Add( TState.EStateContainerCodeSegs, + new TStateMapplet( "*** CMD: container[CODESEG]", typeof( StateContainerCodeSegs ) ) ); + iDictionary.Add( TState.EStateContainerThread, + new TStateMapplet( "*** CMD: container[THREAD]", typeof( StateContainerThreads ) ) ); + iDictionary.Add( TState.EStateContainerProcess, + new TStateMapplet( "*** CMD: container[PROCESS]", typeof( StateContainerProcesses ) ) ); + iDictionary.Add( TState.EStateContainerChunk, + new TStateMapplet( "*** CMD: container[CHUNK]", typeof( StateContainerChunks ) ) ); + iDictionary.Add( TState.EStateContainerLibrary, + new TStateMapplet( "*** CMD: container[LIBRARY]", typeof( StateContainerLibraries ) ) ); + iDictionary.Add( TState.EStateContainerSemaphore, + new TStateMapplet( "*** CMD: container[SEMAPHORE]", typeof( StateContainerSemaphores ) ) ); + iDictionary.Add( TState.EStateContainerMutex, + new TStateMapplet( "*** CMD: container[MUTEX]", typeof( StateContainerMutexes ) ) ); + iDictionary.Add( TState.EStateContainerTimer, + new TStateMapplet( "*** CMD: container[TIMER]", typeof( StateContainerTimers ) ) ); + iDictionary.Add( TState.EStateContainerServer, + new TStateMapplet( "*** CMD: container[SERVER]", typeof( StateContainerServers ) ) ); + iDictionary.Add( TState.EStateContainerSession, + new TStateMapplet( "*** CMD: container[SESSION]", typeof( StateContainerSessions ) ) ); + iDictionary.Add( TState.EStateContainerLogicalDevice, + new TStateMapplet( "*** CMD: container[LOGICAL DEVICE]", typeof( StateContainerLogicalDevices ) ) ); + iDictionary.Add( TState.EStateContainerPhysicalDevice, + new TStateMapplet( "*** CMD: container[PHYSICAL DEVICE]", typeof( StateContainerPhysicalDevices ) ) ); + iDictionary.Add( TState.EStateContainerLogicalChannel, + new TStateMapplet( "*** CMD: container[LOGICAL CHANNEL]", typeof( StateContainerLogicalChannels ) ) ); + iDictionary.Add( TState.EStateContainerChangeNotifier, + new TStateMapplet( "*** CMD: container[CHANGE NOTIFIER]", typeof( StateContainerChangeNotifiers ) ) ); + iDictionary.Add( TState.EStateContainerUndertaker, + new TStateMapplet( "*** CMD: container[UNDERTAKER]", typeof( StateContainerUndertakers ) ) ); + iDictionary.Add( TState.EStateContainerMessageQueue, + new TStateMapplet( "*** CMD: container[MESSAGE QUEUE]", typeof( StateContainerMessageQueues ) ) ); + iDictionary.Add( TState.EStateContainerPropertyRef, + new TStateMapplet( "*** CMD: container[PROPERTY REF]", typeof( StateContainerPropertyRefs ) ) ); + iDictionary.Add( TState.EStateContainerConditionalVariable, + new TStateMapplet( "*** CMD: container[CONDITION VARIABLE]", typeof( StateContainerConditionalVariables ) ) ); + iDictionary.Add( TState.EStateThreadStacks, + new TStateMapplet( "*** CMD: Stack_Data[", typeof( StateThreadStacks ) ) ); + } + } + + private static State CreateState( TState aState, CrashDebuggerParser aParser ) + { + TStateMapplet maplet = iDictionary[ aState ]; + State ret = maplet.CreateInstance( aParser ); + return ret; + } + #endregion + + #region Data members + private static Dictionary iDictionary = new Dictionary(); + #endregion + } + + #region Internal structure + internal class TStateMapplet + { + #region Constructors + public TStateMapplet( Type aType, params string[] aCommandIdentifiers ) + { + iCommandIdentifiers = aCommandIdentifiers; + iType = aType; + } + + public TStateMapplet( string aCommandIdentifier, Type aType ) + { + iCommandIdentifiers = new string[] { aCommandIdentifier }; + iType = aType; + } + #endregion + + #region API + public State CreateInstance( CrashDebuggerParser aParser ) + { + State state = null; + // + Binder binder = null; + BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance; + object[] args = { aParser }; + object ret = iType.InvokeMember( string.Empty, bindingFlags, binder, null, args ); + if ( ret != null ) + { + state = (State) ret; + } + // + return state; + } + #endregion + + #region Properties + public string[] CommandIdentifiers + { + get { return iCommandIdentifiers; } + } + #endregion + + #region Data members + private readonly string[] iCommandIdentifiers; + private readonly Type iType; + #endregion + } + #endregion +}