crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Parsers/State/StateFactory.cs
author Matti Laitinen <matti.t.laitinen@nokia.com>
Thu, 11 Feb 2010 15:50:58 +0200
changeset 0 818e61de6cd1
permissions -rw-r--r--
Add initial version of Crash Analyser cmdline under EPL

/*
* 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<TState, TStateMapplet> 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<TState, TStateMapplet> iDictionary = new Dictionary<TState, TStateMapplet>();
        #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
}