The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript \ RegExpMatch

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace Microsoft.JScript
  16. {
  17.    
  18.     using System;
  19.     using System.Text.RegularExpressions;
  20.     using System.Globalization;
  21.    
  22.     public sealed class RegExpMatch : ArrayObject
  23.     {
  24.         private bool hydrated;
  25.         private Regex regex;
  26.         private MatchCollection matches;
  27.         private Match match;
  28.        
  29.         internal RegExpMatch(ArrayPrototype parent, Regex regex, Match match, string input) : base(parent, typeof(RegExpMatch))
  30.         {
  31.             this.hydrated = false;
  32.             this.regex = regex;
  33.             this.matches = null;
  34.             this.match = match;
  35.             base.SetMemberValue("input", input);
  36.             base.SetMemberValue("index", match.Index);
  37.             base.SetMemberValue("lastIndex", match.Length == 0 ? match.Index + 1 : match.Index + match.Length);
  38.             string[] groupNames = regex.GetGroupNames();
  39.             int maxGroupNumber = 0;
  40.             for (int i = 1; i < groupNames.Length; i++) {
  41.                 string groupName = groupNames[i];
  42.                 int groupNumber = regex.GroupNumberFromName(groupName);
  43.                 if (groupName.Equals(groupNumber.ToString(CultureInfo.InvariantCulture))) {
  44.                     if (groupNumber > maxGroupNumber)
  45.                         maxGroupNumber = groupNumber;
  46.                 }
  47.                 else {
  48.                     Group group = match.Groups[groupName];
  49.                     base.SetMemberValue(groupName, group.Success ? group.ToString() : null);
  50.                 }
  51.             }
  52.             this.length = maxGroupNumber + 1;
  53.         }
  54.        
  55.         internal RegExpMatch(ArrayPrototype parent, Regex regex, MatchCollection matches, string input) : base(parent)
  56.         {
  57.             this.hydrated = false;
  58.             this.length = matches.Count;
  59.             this.regex = regex;
  60.             this.matches = matches;
  61.             this.match = null;
  62.             Match match = matches[matches.Count - 1];
  63.             base.SetMemberValue("input", input);
  64.             base.SetMemberValue("index", match.Index);
  65.             base.SetMemberValue("lastIndex", match.Length == 0 ? match.Index + 1 : match.Index + match.Length);
  66.         }
  67.        
  68.         internal override void Concat(ArrayObject source)
  69.         {
  70.             if (!this.hydrated)
  71.                 this.Hydrate();
  72.             base.Concat(source);
  73.         }
  74.        
  75.         internal override void Concat(object value)
  76.         {
  77.             if (!this.hydrated)
  78.                 this.Hydrate();
  79.             base.Concat(value);
  80.         }
  81.        
  82.         internal override bool DeleteValueAtIndex(uint index)
  83.         {
  84.             if (!this.hydrated)
  85.                 this.Hydrate();
  86.             return base.DeleteValueAtIndex(index);
  87.         }
  88.        
  89.         internal override object GetValueAtIndex(uint index)
  90.         {
  91.             if (!this.hydrated) {
  92.                 if (this.matches != null) {
  93.                     if (index < (long)this.matches.Count)
  94.                         return this.matches[(int)index].ToString();
  95.                 }
  96.                 else if (this.match != null) {
  97.                     int groupNumber = this.regex.GroupNumberFromName(index.ToString(CultureInfo.InvariantCulture));
  98.                     if (groupNumber >= 0) {
  99.                         Group group = this.match.Groups[groupNumber];
  100.                         return group.Success ? group.ToString() : "";
  101.                     }
  102.                 }
  103.             }
  104.             return base.GetValueAtIndex(index);
  105.         }
  106.        
  107.         internal override object GetMemberValue(string name)
  108.         {
  109.             if (!this.hydrated) {
  110.                 long index = ArrayObject.Array_index_for(name);
  111.                 if (index >= 0)
  112.                     return this.GetValueAtIndex((uint)index);
  113.             }
  114.             return base.GetMemberValue(name);
  115.         }
  116.        
  117.         private void Hydrate()
  118.         {
  119.             if (this.matches != null)
  120.                 for (int i = 0int n = this.matches.Count; i < n; i++)
  121.                     base.SetValueAtIndex((uint)i, this.matches[i].ToString());
  122.             else if (this.match != null) {
  123.                 string[] groupNames = this.regex.GetGroupNames();
  124.                 for (int i = 1int n = groupNames.Length; i < n; i++) {
  125.                     string groupName = groupNames[i];
  126.                     int groupNumber = this.regex.GroupNumberFromName(groupName);
  127.                     Group group = this.match.Groups[groupNumber];
  128.                     object propertyValue = group.Success ? group.ToString() : "";
  129.                     if (groupName.Equals(groupNumber.ToString(CultureInfo.InvariantCulture)))
  130.                         base.SetValueAtIndex((uint)groupNumber, propertyValue);
  131.                 }
  132.             }
  133.             this.hydrated = true;
  134.             this.regex = null;
  135.             this.matches = null;
  136.             this.match = null;
  137.         }
  138.        
  139.         internal override void SetValueAtIndex(uint index, object value)
  140.         {
  141.             if (!this.hydrated)
  142.                 this.Hydrate();
  143.             base.SetValueAtIndex(index, value);
  144.         }
  145.        
  146.         internal override object Shift()
  147.         {
  148.             if (!this.hydrated)
  149.                 this.Hydrate();
  150.             return base.Shift();
  151.         }
  152.        
  153.         internal override void Sort(ScriptFunction compareFn)
  154.         {
  155.             if (!this.hydrated)
  156.                 this.Hydrate();
  157.             base.Sort(compareFn);
  158.         }
  159.        
  160.         internal override void Splice(uint start, uint deleteItems, object[] args, ArrayObject outArray, uint oldLength, uint newLength)
  161.         {
  162.             if (!this.hydrated)
  163.                 this.Hydrate();
  164.             base.Splice(start, deleteItems, args, outArray, oldLength, newLength);
  165.         }
  166.        
  167.         internal override void SwapValues(uint pi, uint qi)
  168.         {
  169.             if (!this.hydrated)
  170.                 this.Hydrate();
  171.             base.SwapValues(pi, qi);
  172.         }
  173.        
  174.         internal override ArrayObject Unshift(object[] args)
  175.         {
  176.             if (!this.hydrated)
  177.                 this.Hydrate();
  178.             return base.Unshift(args);
  179.         }
  180.     }
  181. }

Developer Fusion