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<ParserField>
+ {
+ #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<ParserField>
+ public IEnumerator<ParserField> 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<ParserField> iFields = new List<ParserField>();
+ #endregion
+ }
+}