diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianParserLib/Elements/ParserElementLine.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianParserLib/Elements/ParserElementLine.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,398 @@ +//#define SHOW_EACH_LINE +/* +* 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.Generic; +using System.Text; +using System.Text.RegularExpressions; +using System.Reflection; +using SymbianParserLib.Utilities; +using SymbianParserLib.RegExTranslators; +using SymbianParserLib.BaseStructures; +using SymbianParserLib.ValueStores; + +namespace SymbianParserLib.Elements +{ + public class ParserLine : ParserElementBaseWithValueStore, IEnumerable + { + #region Enumerations + public enum TLineType + { + ELineTypeSimpleStringMatch = 0, + ELineTypeSymbianFormatString, + ELineTypeRegEx + } + + [Flags] + internal enum TLineFlags + { + ELineFlagNone = 0, + ELineFlagDequeueIfComplete = 1, + ELineFlagNeverConsumesLine = 2 + } + #endregion + + #region Static constructors + public static ParserLine New( string aText ) + { + ParserLine self = new ParserLine( TLineType.ELineTypeSimpleStringMatch ); + self.OriginalValue = ParserUtils.RemoveLineEndings( aText ); + return self; + } + + public static ParserLine NewSymFormat( string aFormat ) + { + // First check with cache + ParserLine self = RegExTranslatorManager.PreCachedCompiledEntry( aFormat ); + if ( self == null ) + { + // Wasn't cached so we need to parse and create a new entry + self = new ParserLine( TLineType.ELineTypeSymbianFormatString ); + self.OriginalValue = aFormat; + // + RegExTranslatorManager.CompileToRegularExpression( self ); + } + // + return self; + } + + public static ParserLine NewRegEx( string aRegEx ) + { + throw new NotSupportedException(); + } + + internal static ParserLine NewCopy( ParserLine aLine ) + { + ParserLine ret = new ParserLine( aLine ); + return ret; + } + #endregion + + #region Constructors + private ParserLine( TLineType aLineType ) + { + iLineType = aLineType; + } + + private ParserLine( ParserLine aLine ) + { + iLineType = aLine.LineType; + iOriginalValue = aLine.OriginalValue; + iFinalValue = new StringBuilder( aLine.FinalValue ); + iFlags = aLine.iFlags; + + foreach ( ParserField templateField in aLine ) + { + ParserField copy = new ParserField( templateField ); + Add( copy ); + } + + CreateRegEx(); + } + #endregion + + #region API + public void Add( ParserField aField ) + { + aField.Parent = this; + aField.DisableWhenComplete = this.DisableWhenComplete; + iFields.Add( aField ); + } + + internal void Finalise() + { + if ( Count != 0 ) + { + FinalValue = OriginalValue; + + // Fixup the final string to be a new "dynamically" generated regular expression. Work + // backwards since we adjust the string by index and therefore we must not affect earlier + // indexes when forming the replacement. + for( int i=Count-1; i>=0; i-- ) + { + ParserField field = this[ i ]; + // + string regex = field.FormatSpecifier.RegularExpressionString; + int origPos = field.FormatSpecifier.OriginalLocation; + int origLen = field.FormatSpecifier.OriginalLength; + iFinalValue.Remove( origPos, origLen ); + iFinalValue.Insert( origPos, regex ); + } + + CreateRegEx(); + } + } + #endregion + + #region Properties + public int Count + { + get { return iFields.Count; } + } + + public ParserField this[ int aIndex ] + { + get { return iFields[ aIndex ]; } + } + + public ParserParagraph Paragraph + { + get + { + ParserParagraph ret = null; + // + if ( Parent != null && Parent is ParserParagraph ) + { + ret = Parent as ParserParagraph; + } + // + return ret; + } + } + + public bool DequeueIfComplete + { + get { return ( iFlags & TLineFlags.ELineFlagDequeueIfComplete ) == TLineFlags.ELineFlagDequeueIfComplete; } + set + { + if ( value ) + { + iFlags |= TLineFlags.ELineFlagDequeueIfComplete; + } + else + { + iFlags &= ~TLineFlags.ELineFlagDequeueIfComplete; + } + } + } + + public bool NeverConsumesLine + { + get { return ( iFlags & TLineFlags.ELineFlagNeverConsumesLine ) == TLineFlags.ELineFlagNeverConsumesLine; } + set + { + if ( value ) + { + iFlags |= TLineFlags.ELineFlagNeverConsumesLine; + } + else + { + iFlags &= ~TLineFlags.ELineFlagNeverConsumesLine; + } + } + } + + public string OriginalValue + { + get { return iOriginalValue; } + set { iOriginalValue = value; } + } + + public TLineType LineType + { + get { return iLineType; } + } + + internal string FinalValue + { + get { return FinalValueBuilder.ToString(); } + set { iFinalValue = new StringBuilder( value ); } + } + + internal StringBuilder FinalValueBuilder + { + get { return iFinalValue; } + set { iFinalValue = value; } + } + #endregion + + #region From ParserElementBase + internal override ParserResponse Offer( ref string aLine ) + { + ParserResponse ret = new ParserResponse(); + // + if ( iLineType == TLineType.ELineTypeSimpleStringMatch ) + { + bool match = ( aLine.Contains( OriginalValue ) ); + if ( match ) + { +#if SHOW_EACH_LINE + System.Diagnostics.Debug.WriteLine( aLine ); +#endif + ret = new ParserResponse( ParserResponse.TResponseType.EResponseTypeHandled ); + } + } + else if ( iLineType == TLineType.ELineTypeSymbianFormatString ) + { + if ( iFinalRegEx != null ) + { + Match m = iFinalRegEx.Match( aLine ); + bool match = m.Success; + if ( match ) + { +#if SHOW_EACH_LINE + System.Diagnostics.Debug.WriteLine( aLine ); +#endif + + GroupCollection groups = m.Groups; + ExtractValues( groups ); + + ret = new ParserResponse( ParserResponse.TResponseType.EResponseTypeHandled ); + } + } + } + + // Update completion - will trigger observers + IsComplete = ret.WasHandled; + + if ( IsComplete ) + { + // Dequeue the line from parent paragraph if it is + // complete and so adorned + if ( DequeueIfComplete ) + { + Paragraph.Remove( this ); + } + + // If this object never consumes the input string, then + // instead throw a nonconsuming exception, and the engine + // will re-offer it to all objects + if ( NeverConsumesLine ) + { + ret = new ParserResponse( ParserResponse.TResponseType.EResponseTypeHandledByRequiresReProcessing ); + } + } + + return ret; + } + + internal override void OnDisableWhenComplete() + { + base.OnDisableWhenComplete(); + // + foreach( ParserField f in iFields ) + { + f.DisableWhenComplete = this.DisableWhenComplete; + } + } + + internal override void OnNeverEnding() + { + base.OnNeverEnding(); + // + foreach ( ParserField f in iFields ) + { + f.IsNeverEnding = this.IsNeverEnding; + } + } + #endregion + + #region From ParserElementBaseWithValueStore + public override void SetTargetObject() + { + base.SetTargetObject(); + foreach ( ParserField field in this ) + { + field.SetTargetObject(); + } + } + + internal override void SetTargetProperty( object aPropertyObject, string aPropertyName, int aIndex ) + { + if ( aIndex == ParserElementBaseWithValueStore.KGloballyApplicable ) + { + // Applicable to all + iValueStore = new ValueStore(); + iValueStore.SetTargetProperty( aPropertyObject, aPropertyName ); + } + else + { + // Specific to a field + if ( aIndex < 0 || aIndex >= Count ) + { + throw new ArgumentOutOfRangeException( "aIndex" ); + } + + this[ aIndex ].SetTargetProperty( aPropertyObject, aPropertyName ); + } + } + #endregion + + #region Internal methods + private void CreateRegEx() + { + iFinalRegEx = new Regex( FinalValue, RegexOptions.Singleline ); + } + + private void ExtractValues( GroupCollection aGroups ) + { + for ( int i = 1; i < aGroups.Count; i++ ) + { + Group group = aGroups[ i ]; + if ( group.Success ) + { + int pos = group.Index; + string value = group.Value; + // + if ( i <= Count ) + { + ParserField field = this[ i - 1 ]; + field.ExtractValue( group ); + } + } + } + } + #endregion + + #region Internal constants + #endregion + + #region From System.Object + public override string ToString() + { + return base.ToString(); + } + #endregion + + #region From IEnumerable + public IEnumerator GetEnumerator() + { + foreach ( ParserField field in iFields ) + { + yield return field; + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + foreach ( ParserField field in iFields ) + { + yield return field; + } + } + #endregion + + #region Data members + private readonly TLineType iLineType; + private string iOriginalValue = string.Empty; + private StringBuilder iFinalValue = new StringBuilder(); + private Regex iFinalRegEx = null; + private TLineFlags iFlags = TLineFlags.ELineFlagNone; + private List iFields = new List(); + #endregion + } +}