diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/Range/AddressRange.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/Range/AddressRange.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,328 @@ +/* +* 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; + +namespace SymbianUtils.Range +{ + public class AddressRange : IComparable + { + #region Delegates & events + public delegate void ChangeHandler( AddressRange aAddressRange ); + public event ChangeHandler RangeChanged; + #endregion + + #region Constructors + public AddressRange() + { + } + + public AddressRange( string aSpecifier ) + { + this.Parse( aSpecifier ); + } + + public AddressRange( uint aMin, uint aMax ) + { + iMin = aMin; + iMax = aMax; + } + + public AddressRange( long aMin, long aMax ) + : this( (uint) aMin, (uint) aMax ) + { + } + + public AddressRange( AddressRange aCopy ) + : this( aCopy.Min, aCopy.Max ) + { + } + #endregion + + #region API + public void Set( uint aMin, uint aMax ) + { + iMax = aMax; + iMin = aMin; + } + + public bool Contains( uint aAddress ) + { + bool ret = ( aAddress >= iMin && aAddress <= iMax ); + return ret; + } + + public bool Contains( long aAddress ) + { + bool ret = Contains( (uint) aAddress ); + return ret; + } + + public bool Contains( AddressRange aRange ) + { + bool ret = Contains( aRange.Min ) && Contains( aRange.Max ); + return ret; + } + + public void Reset() + { + iMin = uint.MaxValue; + iMax = uint.MinValue; + // + OnChanging(); + } + + public void Update( AddressRange aRange ) + { + AddressRange transaction = TransactionBegin(); + // + UpdateMin( aRange.Min ); + UpdateMax( aRange.Max ); + // + TransactionEnd( transaction ); + } + + public void UpdateMin( uint aProposedMin ) + { + uint old = iMin; + iMin = Math.Min( iMin, aProposedMin ); + // + if ( old != iMin ) + { + OnChanging(); + } + } + + public void UpdateMax( uint aProposedMax ) + { + uint old = iMax; + iMax = Math.Max( iMax, aProposedMax ); + // + if ( old != iMax ) + { + OnChanging(); + } + } + + public void UpdateMin( long aProposedMin ) + { + UpdateMin( (uint) aProposedMin ); + } + + public void UpdateMax( long aProposedMax ) + { + UpdateMax( (uint) aProposedMax ); + } + + public void Parse( string aValue ) + { + Match m = KRegEx.Match( aValue ); + if ( m.Success ) + { + string min = m.Groups[ "Min" ].Value.Replace( "0x", string.Empty ); + string max = m.Groups[ "Max" ].Value.Replace( "0x", string.Empty ); + + // Also need to know if they are hex or decimal specifiers + int baseMin = ( m.Groups[ 0 ].Value == "0x" ? 16 : 10 ); + int baseMax = ( m.Groups[ 1 ].Value == "0x" ? 16 : 10 ); + + // Now convert + uint valueMin = System.Convert.ToUInt32( min, baseMin ); + uint valueMax = System.Convert.ToUInt32( max, baseMax ); + + // Make range... + AddressRange transaction = TransactionBegin(); + // + UpdateMin( valueMin ); + UpdateMin( valueMax ); + // + TransactionEnd( transaction ); + } + else + { + throw new ArgumentException( "Invalid range format - expected [0x]AAA - [0x]BBB" ); + } + } + #endregion + + #region Properties + public uint Min + { + get { return iMin; } + set + { + if ( iMin != value ) + { + iMin = value; + OnChanging(); + } + } + } + + public uint Max + { + get { return iMax; } + set + { + if ( iMax != value ) + { + iMax = value; + OnChanging(); + } + } + } + + public uint Size + { + get + { + uint ret = Max - Min + 1; + return ret; + } + } + + public bool IsValid + { + get + { + bool goodMin = ( iMin != uint.MaxValue ); + bool goodMax = ( iMax != uint.MinValue ); + // + return ( goodMin && goodMax ); + } + } + #endregion + + #region From System.Object + public override string ToString() + { + StringBuilder ret = new StringBuilder(); + ret.AppendFormat( "{0:x8}-{1:x8}", Min, Max ); + return ret.ToString(); + } + + public override int GetHashCode() + { + return (int) ( Min ^ Max ); + } + + public override bool Equals( object aObject ) + { + bool ret = false; + // + if ( aObject != null ) + { + if ( aObject is AddressRange ) + { + AddressRange other = (AddressRange) aObject; + // + int compareMin = other.Min.CompareTo( this.Min ); + int compareMax = other.Max.CompareTo( this.Max ); + // + ret = ( compareMin == 0 && compareMax == 0 ); + } + else + { + ret = base.Equals( aObject ); + } + } + // + return ret; + } + #endregion + + #region Operators + public static implicit operator AddressRange( string aSpecifier ) + { + AddressRange ret = new AddressRange( aSpecifier ); + return ret; + } + #endregion + + #region Internal regular expressions + private static readonly Regex KRegEx = new Regex( + "(?(?((0x))0x[A-Fa-f0-9]{1,8}|[0-9]{1,8}))\\s*\\-\\s*(?<"+ + "Max>(?((0x))0x[A-Fa-f0-9]{1,8}|[0-9]{1,8}))", + RegexOptions.CultureInvariant + | RegexOptions.Compiled + ); + #endregion + + #region From IComparable + public int CompareTo( AddressRange aOther ) + { + int ret = 1; + // + if ( aOther != null ) + { + ret = this.Min.CompareTo( aOther.Min ); + } + // + return ret; + } + #endregion + + #region Internal methods + private void OnChanging() + { + if ( !InTransaction ) + { + OnChanged(); + } + } + + protected virtual void OnChanged() + { + if ( RangeChanged != null ) + { + RangeChanged( this ); + } + } + + private bool InTransaction + { + get { return iTransactionCount > 0; } + } + + private AddressRange TransactionBegin() + { + ++iTransactionCount; + // + AddressRange ret = new AddressRange( this.Min, this.Min ); + return ret; + } + + private void TransactionEnd( AddressRange aTransaction ) + { + System.Diagnostics.Debug.Assert( iTransactionCount > 0 ); + --iTransactionCount; + // + if ( aTransaction.CompareTo( this ) != 0 ) + { + OnChanging(); + } + } + #endregion + + #region Data members + private uint iMin = uint.MaxValue; + private uint iMax = uint.MinValue; + private int iTransactionCount = 0; + #endregion + } +}