crashanalysercmd/Libraries/Engine/CrashItemLib/Crash/Registers/CIRegisterListCollection.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) 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.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using CrashItemLib.Crash;
using CrashItemLib.Crash.Base;
using CrashItemLib.Crash.Container;
using CrashItemLib.Crash.Stacks;
using CrashItemLib.Crash.ExitInfo;
using CrashItemLib.Crash.Processes;
using CrashItemLib.Crash.Registers;
using SymbianStructuresLib.Uids;
using SymbianStructuresLib.Arm.Registers;

namespace CrashItemLib.Crash.Registers
{
	public class CIRegisterListCollection : CIElement, IEnumerable<CIRegisterList>
	{
		#region Constructors
        [CIElementAttributeMandatory()]
        public CIRegisterListCollection( CIContainer aContainer )
            : this( aContainer, null )
		{
        }
        
        internal CIRegisterListCollection( CIContainer aContainer, CIElement aParent )
            : base( aContainer, aParent )
        {
        }
        #endregion

        #region API
        public void Add( TArmRegisterBank aType )
        {
            this[ aType ] = new CIRegisterList( Container, aType );
        }

        public void Add( CIRegisterList aCollection )
        {
            // Make sure the dictionary doesn't already contain this bank type!
            bool exists = Contains( aCollection.Bank );
            if ( exists )
            {
                throw new Exception( aCollection.BankName + " already exists within collection" );
            }
            else
            {
                iRegisters.Add( aCollection.Bank, aCollection );

                // Register as child also
                base.AddChild( aCollection );
            }
        }

        public void Add( params TArmRegisterBank[] aTypes )
        {
            foreach ( TArmRegisterBank type in aTypes )
            {
                Add( type );
            }
        }

        public bool Contains( TArmRegisterBank aType )
        {
            return iRegisters.ContainsKey( aType );
        }

        public override void Clear()
        {
            iRegisters.Clear();
            base.Clear();
        }
        #endregion

        #region Properties
        public virtual uint CPSR
        {
            get
            {
                uint ret = 0;
                //
                CIRegisterList list = CurrentProcessorModeRegisters;
                if ( list != null )
                {
                    ret = list[ TArmRegisterType.EArmReg_CPSR ].Value;
                }
                else
                {
                    // CPSR is not yet defined
                }
                //
                return ret;
            }
            set
            {
                TArmRegisterBank bank = ArmRegisterBankUtils.ExtractBank( value );
                
                // Remove CPSR from current register list
                CIRegisterList list = CurrentProcessorModeRegisters;
                if ( list != null )
                {
                    list.Remove( TArmRegisterType.EArmReg_CPSR );
                }

                // Now we can add it without fear of creating a duplicate
                CIRegisterList cpsrRegList = this[ bank ];
                if ( cpsrRegList != null )
                {
                    cpsrRegList.Add( TArmRegisterType.EArmReg_CPSR, value );
                }
            }
        }

        public virtual CIRegisterList CurrentProcessorModeRegisters
        {
            get
            {
                // Try to find the bank that contains CPSR (if any) and
                // return that.
                CIRegisterList ret = null;
                //
                foreach ( CIRegisterList col in this )
                {
                    if ( col.Contains( TArmRegisterType.EArmReg_CPSR ) )
                    {
                        // Get CPSR value
                        ArmRegister cpsr = col[ TArmRegisterType.EArmReg_CPSR ];
                        TArmRegisterBank cpsrBank = ArmRegisterBankUtils.ExtractBank( cpsr );

                        // Try to get the corresponding bank (should be the same as col...)
                        if ( Contains( cpsrBank ) )
                        {
                            CIRegisterList list = this[ cpsrBank ];
                            System.Diagnostics.Debug.Assert( list is CIRegisterList );
                            ret = (CIRegisterList) list;
                        }
                        break;
                    }
                }
                //
                return ret;
            }
        }

        public CIRegisterList this[ TArmRegisterBank aType ]
        {
            get { return iRegisters[ aType ]; }
            set
            {
                if ( iRegisters.ContainsKey( aType ) )
                {
                    iRegisters[ aType ] = value;
                }
                else
                {
                    Add( value );
                }
            }
        }
        #endregion

        #region Internal methods
        #endregion

        #region From IEnumerable<CIRegisterCollection>
        public new IEnumerator<CIRegisterList> GetEnumerator()
        {
            foreach ( KeyValuePair<TArmRegisterBank, CIRegisterList> kvp in iRegisters )
            {
                yield return kvp.Value;
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            foreach ( KeyValuePair<TArmRegisterBank, CIRegisterList> kvp in iRegisters )
            {
                yield return kvp.Value;
            }
        }
        #endregion

        #region Data members
        private Dictionary<TArmRegisterBank, CIRegisterList> iRegisters = new Dictionary<TArmRegisterBank, CIRegisterList>();
        #endregion
    }
}