crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianParserLib/Elements/ParserElementLine.cs
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 //#define SHOW_EACH_LINE
       
     2 /*
       
     3 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     4 * All rights reserved.
       
     5 * This component and the accompanying materials are made available
       
     6 * under the terms of "Eclipse Public License v1.0"
       
     7 * which accompanies this distribution, and is available
       
     8 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     9 *
       
    10 * Initial Contributors:
       
    11 * Nokia Corporation - initial contribution.
       
    12 *
       
    13 * Contributors:
       
    14 * 
       
    15 * Description:
       
    16 *
       
    17 */
       
    18 using System;
       
    19 using System.Collections.Generic;
       
    20 using System.Text;
       
    21 using System.Text.RegularExpressions;
       
    22 using System.Reflection;
       
    23 using SymbianParserLib.Utilities;
       
    24 using SymbianParserLib.RegExTranslators;
       
    25 using SymbianParserLib.BaseStructures;
       
    26 using SymbianParserLib.ValueStores;
       
    27 
       
    28 namespace SymbianParserLib.Elements
       
    29 {
       
    30     public class ParserLine : ParserElementBaseWithValueStore, IEnumerable<ParserField>
       
    31     {
       
    32         #region Enumerations
       
    33         public enum TLineType
       
    34         {
       
    35             ELineTypeSimpleStringMatch = 0,
       
    36             ELineTypeSymbianFormatString,
       
    37             ELineTypeRegEx
       
    38         }
       
    39 
       
    40         [Flags]
       
    41         internal enum TLineFlags
       
    42         {
       
    43             ELineFlagNone = 0,
       
    44             ELineFlagDequeueIfComplete = 1,
       
    45             ELineFlagNeverConsumesLine = 2
       
    46         }
       
    47         #endregion
       
    48 
       
    49         #region Static constructors
       
    50         public static ParserLine New( string aText )
       
    51         {
       
    52             ParserLine self = new ParserLine( TLineType.ELineTypeSimpleStringMatch );
       
    53             self.OriginalValue = ParserUtils.RemoveLineEndings( aText );
       
    54             return self;
       
    55         }
       
    56         
       
    57         public static ParserLine NewSymFormat( string aFormat )
       
    58         {
       
    59             // First check with cache
       
    60             ParserLine self = RegExTranslatorManager.PreCachedCompiledEntry( aFormat );
       
    61             if ( self == null )
       
    62             {
       
    63                 // Wasn't cached so we need to parse and create a new entry
       
    64                 self = new ParserLine( TLineType.ELineTypeSymbianFormatString );
       
    65                 self.OriginalValue = aFormat;
       
    66                 //
       
    67                 RegExTranslatorManager.CompileToRegularExpression( self );
       
    68             }
       
    69             //
       
    70             return self;
       
    71         }
       
    72 
       
    73         public static ParserLine NewRegEx( string aRegEx )
       
    74         {
       
    75             throw new NotSupportedException();
       
    76         }
       
    77 
       
    78         internal static ParserLine NewCopy( ParserLine aLine )
       
    79         {
       
    80             ParserLine ret = new ParserLine( aLine );
       
    81             return ret;
       
    82         }
       
    83         #endregion
       
    84 
       
    85         #region Constructors
       
    86         private ParserLine( TLineType aLineType )
       
    87         {
       
    88             iLineType = aLineType;
       
    89         }
       
    90 
       
    91         private ParserLine( ParserLine aLine )
       
    92         {
       
    93             iLineType = aLine.LineType;
       
    94             iOriginalValue = aLine.OriginalValue;
       
    95             iFinalValue = new StringBuilder( aLine.FinalValue );
       
    96             iFlags = aLine.iFlags;
       
    97 
       
    98             foreach ( ParserField templateField in aLine )
       
    99             {
       
   100                 ParserField copy = new ParserField( templateField );
       
   101                 Add( copy );
       
   102             }
       
   103 
       
   104             CreateRegEx();
       
   105         }
       
   106         #endregion
       
   107 
       
   108         #region API
       
   109         public void Add( ParserField aField )
       
   110         {
       
   111             aField.Parent = this;
       
   112             aField.DisableWhenComplete = this.DisableWhenComplete;
       
   113             iFields.Add( aField );
       
   114         }
       
   115 
       
   116         internal void Finalise()
       
   117         {
       
   118             if ( Count != 0 )
       
   119             {
       
   120                 FinalValue = OriginalValue;
       
   121 
       
   122                 // Fixup the final string to be a new "dynamically" generated regular expression. Work
       
   123                 // backwards since we adjust the string by index and therefore we must not affect earlier
       
   124                 // indexes when forming the replacement.
       
   125                 for( int i=Count-1; i>=0; i-- )
       
   126                 {
       
   127                     ParserField field = this[ i ];
       
   128                     //
       
   129                     string regex = field.FormatSpecifier.RegularExpressionString;
       
   130                     int origPos = field.FormatSpecifier.OriginalLocation;
       
   131                     int origLen = field.FormatSpecifier.OriginalLength;
       
   132                     iFinalValue.Remove( origPos, origLen );
       
   133                     iFinalValue.Insert( origPos, regex );
       
   134                 }
       
   135 
       
   136                 CreateRegEx();
       
   137             }
       
   138         }
       
   139         #endregion
       
   140 
       
   141         #region Properties
       
   142         public int Count
       
   143         {
       
   144             get { return iFields.Count; }
       
   145         }
       
   146 
       
   147         public ParserField this[ int aIndex ]
       
   148         {
       
   149             get { return iFields[ aIndex ]; }
       
   150         }
       
   151 
       
   152         public ParserParagraph Paragraph
       
   153         {
       
   154             get
       
   155             {
       
   156                 ParserParagraph ret = null;
       
   157                 //
       
   158                 if ( Parent != null && Parent is ParserParagraph )
       
   159                 {
       
   160                     ret = Parent as ParserParagraph;
       
   161                 }
       
   162                 //
       
   163                 return ret;
       
   164             }
       
   165         }
       
   166 
       
   167         public bool DequeueIfComplete
       
   168         {
       
   169             get { return ( iFlags & TLineFlags.ELineFlagDequeueIfComplete ) == TLineFlags.ELineFlagDequeueIfComplete; }
       
   170             set
       
   171             {
       
   172                 if ( value )
       
   173                 {
       
   174                     iFlags |= TLineFlags.ELineFlagDequeueIfComplete;
       
   175                 }
       
   176                 else
       
   177                 {
       
   178                     iFlags &= ~TLineFlags.ELineFlagDequeueIfComplete;
       
   179                 }
       
   180             }
       
   181         }
       
   182 
       
   183         public bool NeverConsumesLine
       
   184         {
       
   185             get { return ( iFlags & TLineFlags.ELineFlagNeverConsumesLine ) == TLineFlags.ELineFlagNeverConsumesLine; }
       
   186             set
       
   187             {
       
   188                 if ( value )
       
   189                 {
       
   190                     iFlags |= TLineFlags.ELineFlagNeverConsumesLine;
       
   191                 }
       
   192                 else
       
   193                 {
       
   194                     iFlags &= ~TLineFlags.ELineFlagNeverConsumesLine;
       
   195                 }
       
   196             }
       
   197         }
       
   198 
       
   199         public string OriginalValue
       
   200         {
       
   201             get { return iOriginalValue; }
       
   202             set { iOriginalValue = value; }
       
   203         }
       
   204 
       
   205         public TLineType LineType
       
   206         {
       
   207             get { return iLineType; }
       
   208         }
       
   209 
       
   210         internal string FinalValue
       
   211         {
       
   212             get { return FinalValueBuilder.ToString(); }
       
   213             set { iFinalValue = new StringBuilder( value ); }
       
   214         }
       
   215 
       
   216         internal StringBuilder FinalValueBuilder
       
   217         {
       
   218             get { return iFinalValue; }
       
   219             set { iFinalValue = value; }
       
   220         }
       
   221         #endregion
       
   222 
       
   223         #region From ParserElementBase
       
   224         internal override ParserResponse Offer( ref string aLine )
       
   225         {
       
   226             ParserResponse ret = new ParserResponse();
       
   227             //
       
   228             if ( iLineType == TLineType.ELineTypeSimpleStringMatch )
       
   229             {
       
   230                 bool match = ( aLine.Contains( OriginalValue ) );
       
   231                 if ( match )
       
   232                 {
       
   233 #if SHOW_EACH_LINE
       
   234                     System.Diagnostics.Debug.WriteLine( aLine );
       
   235 #endif
       
   236                     ret = new ParserResponse( ParserResponse.TResponseType.EResponseTypeHandled );
       
   237                 }
       
   238             }
       
   239             else if ( iLineType == TLineType.ELineTypeSymbianFormatString )
       
   240             {
       
   241                 if ( iFinalRegEx != null )
       
   242                 {
       
   243                     Match m = iFinalRegEx.Match( aLine );
       
   244                     bool match = m.Success;
       
   245                     if ( match )
       
   246                     {
       
   247 #if SHOW_EACH_LINE
       
   248                         System.Diagnostics.Debug.WriteLine( aLine );
       
   249 #endif
       
   250 
       
   251                         GroupCollection groups = m.Groups;
       
   252                         ExtractValues( groups );
       
   253 
       
   254                         ret = new ParserResponse( ParserResponse.TResponseType.EResponseTypeHandled );
       
   255                     }
       
   256                 }
       
   257             }
       
   258 
       
   259             // Update completion - will trigger observers
       
   260             IsComplete = ret.WasHandled;
       
   261 
       
   262             if ( IsComplete )
       
   263             {
       
   264                 // Dequeue the line from parent paragraph if it is
       
   265                 // complete and so adorned
       
   266                 if ( DequeueIfComplete )
       
   267                 {
       
   268                     Paragraph.Remove( this );
       
   269                 }
       
   270 
       
   271                 // If this object never consumes the input string, then
       
   272                 // instead throw a nonconsuming exception, and the engine
       
   273                 // will re-offer it to all objects
       
   274                 if ( NeverConsumesLine )
       
   275                 {
       
   276                     ret = new ParserResponse( ParserResponse.TResponseType.EResponseTypeHandledByRequiresReProcessing );
       
   277                 }
       
   278             }
       
   279 
       
   280             return ret;
       
   281         }
       
   282 
       
   283         internal override void OnDisableWhenComplete()
       
   284         {
       
   285             base.OnDisableWhenComplete();
       
   286             //
       
   287             foreach( ParserField f in iFields )
       
   288             {
       
   289                 f.DisableWhenComplete = this.DisableWhenComplete;
       
   290             }
       
   291         }
       
   292 
       
   293         internal override void OnNeverEnding()
       
   294         {
       
   295             base.OnNeverEnding();
       
   296             //
       
   297             foreach ( ParserField f in iFields )
       
   298             {
       
   299                 f.IsNeverEnding = this.IsNeverEnding;
       
   300             }
       
   301         }
       
   302         #endregion
       
   303 
       
   304         #region From ParserElementBaseWithValueStore
       
   305         public override void SetTargetObject()
       
   306         {
       
   307             base.SetTargetObject();
       
   308             foreach ( ParserField field in this )
       
   309             {
       
   310                 field.SetTargetObject();
       
   311             }
       
   312         }
       
   313 
       
   314         internal override void SetTargetProperty( object aPropertyObject, string aPropertyName, int aIndex )
       
   315         {
       
   316             if ( aIndex == ParserElementBaseWithValueStore.KGloballyApplicable )
       
   317             {
       
   318                 // Applicable to all
       
   319                 iValueStore = new ValueStore();
       
   320                 iValueStore.SetTargetProperty( aPropertyObject, aPropertyName );
       
   321             }
       
   322             else
       
   323             {
       
   324                 // Specific to a field
       
   325                 if ( aIndex < 0 || aIndex >= Count )
       
   326                 {
       
   327                     throw new ArgumentOutOfRangeException( "aIndex" );
       
   328                 }
       
   329 
       
   330                 this[ aIndex ].SetTargetProperty( aPropertyObject, aPropertyName );
       
   331             }
       
   332         }
       
   333         #endregion
       
   334 
       
   335         #region Internal methods
       
   336         private void CreateRegEx()
       
   337         {
       
   338             iFinalRegEx = new Regex( FinalValue, RegexOptions.Singleline );
       
   339         }
       
   340 
       
   341         private void ExtractValues( GroupCollection aGroups )
       
   342         {
       
   343             for ( int i = 1; i < aGroups.Count; i++ )
       
   344             {
       
   345                 Group group = aGroups[ i ];
       
   346                 if ( group.Success )
       
   347                 {
       
   348                     int pos = group.Index;
       
   349                     string value = group.Value;
       
   350                     //
       
   351                     if ( i <= Count )
       
   352                     {
       
   353                         ParserField field = this[ i - 1 ];
       
   354                         field.ExtractValue( group );
       
   355                     }
       
   356                 }
       
   357             }
       
   358         }
       
   359         #endregion
       
   360 
       
   361         #region Internal constants
       
   362         #endregion
       
   363 
       
   364         #region From System.Object
       
   365         public override string ToString()
       
   366         {
       
   367             return base.ToString();
       
   368         }
       
   369         #endregion
       
   370 
       
   371         #region From IEnumerable<ParserField>
       
   372         public IEnumerator<ParserField> GetEnumerator()
       
   373         {
       
   374             foreach ( ParserField field in iFields )
       
   375             {
       
   376                 yield return field;
       
   377             }
       
   378         }
       
   379 
       
   380         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
       
   381         {
       
   382             foreach ( ParserField field in iFields )
       
   383             {
       
   384                 yield return field;
       
   385             }
       
   386         }
       
   387         #endregion
       
   388 
       
   389         #region Data members
       
   390         private readonly TLineType iLineType;
       
   391         private string iOriginalValue = string.Empty;
       
   392         private StringBuilder iFinalValue = new StringBuilder();
       
   393         private Regex iFinalRegEx = null;
       
   394         private TLineFlags iFlags = TLineFlags.ELineFlagNone;
       
   395         private List<ParserField> iFields = new List<ParserField>();
       
   396         #endregion
       
   397     }
       
   398 }