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

  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;
  20.     using System.Text.RegularExpressions;
  21.    
  22.     public sealed class RegExpObject : JSObject
  23.     {
  24.         internal RegExpConstructor regExpConst;
  25.         private string sourceInt;
  26.         internal bool ignoreCaseInt, globalInt, multilineInt;
  27.         internal Regex regex;
  28.         internal object lastIndexInt;
  29.        
  30.         internal RegExpObject(RegExpPrototype parent, string source, bool ignoreCase, bool global, bool multiline, RegExpConstructor regExpConst) : base(parent)
  31.         {
  32.             this.regExpConst = regExpConst;
  33.             this.sourceInt = source;
  34.             this.ignoreCaseInt = ignoreCase;
  35.             this.globalInt = global;
  36.             this.multilineInt = multiline;
  37.            
  38.             RegexOptions flags = RegexOptions.CultureInvariant | RegexOptions.ECMAScript;
  39.             if (ignoreCase)
  40.                 flags |= RegexOptions.IgnoreCase;
  41.             if (multiline)
  42.                 flags |= RegexOptions.Multiline;
  43.             try {
  44.                 this.regex = new Regex(source, flags);
  45.             }
  46.             catch (System.ArgumentException) {
  47.                 throw new JScriptException(JSError.RegExpSyntax);
  48.             }
  49.             this.lastIndexInt = 0;
  50.             this.noExpando = false;
  51.         }
  52.        
  53.         //Only to be used by StringPrototype
  54.         internal RegExpObject(Regex regex) : base(null)
  55.         {
  56.             this.regExpConst = null;
  57.             this.sourceInt = "";
  58.             this.ignoreCaseInt = (regex.Options & RegexOptions.IgnoreCase) != 0;
  59.             this.globalInt = false;
  60.             this.multilineInt = (regex.Options & RegexOptions.Multiline) != 0;
  61.             this.regex = regex;
  62.             this.lastIndexInt = 0;
  63.             this.noExpando = true;
  64.         }
  65.        
  66.         internal RegExpObject compile(string source, string flags)
  67.         {
  68.             this.sourceInt = source;
  69.             this.ignoreCaseInt = this.globalInt = this.multilineInt = false;
  70.             RegexOptions regexFlags = RegexOptions.CultureInvariant | RegexOptions.ECMAScript;
  71.             for (int i = 0; i < flags.Length; i++)
  72.                 switch (flags[i]) {
  73.                     case 'i':
  74.                         if (this.ignoreCaseInt)
  75.                             throw new JScriptException(JSError.RegExpSyntax);
  76.                         this.ignoreCaseInt = true;
  77.                         regexFlags |= RegexOptions.IgnoreCase;
  78.                         break;
  79.                     case 'g':
  80.                         if (this.globalInt)
  81.                             throw new JScriptException(JSError.RegExpSyntax);
  82.                         this.globalInt = true;
  83.                         break;
  84.                     case 'm':
  85.                         if (this.multilineInt)
  86.                             throw new JScriptException(JSError.RegExpSyntax);
  87.                         this.multilineInt = true;
  88.                         regexFlags |= RegexOptions.Multiline;
  89.                         break;
  90.                     default:
  91.                         throw new JScriptException(JSError.RegExpSyntax);
  92.                         break;
  93.                 }
  94.             try {
  95.                 this.regex = new Regex(source, regexFlags);
  96.             }
  97.             catch (System.ArgumentException) {
  98.                 throw new JScriptException(JSError.RegExpSyntax);
  99.             }
  100.             return this;
  101.         }
  102.        
  103.         internal object exec(string input)
  104.         {
  105.             Match match = null;
  106.             if (!this.globalInt)
  107.                 match = this.regex.Match(input);
  108.             else {
  109.                 int lastIndex = (int)Runtime.DoubleToInt64(Convert.ToInteger(this.lastIndexInt));
  110.                 if (lastIndex <= 0)
  111.                     match = this.regex.Match(input);
  112.                 else if (lastIndex <= input.Length)
  113.                     match = this.regex.Match(input, lastIndex);
  114.             }
  115.             if (match == null || !match.Success) {
  116.                 this.lastIndexInt = 0;
  117.                 return DBNull.Value;
  118.             }
  119.             this.lastIndexInt = this.regExpConst.UpdateConstructor(this.regex, match, input);
  120.             return new RegExpMatch(this.regExpConst.arrayPrototype, this.regex, match, input);
  121.         }
  122.        
  123.         internal override string GetClassName()
  124.         {
  125.             return "RegExp";
  126.         }
  127.        
  128.         internal bool test(string input)
  129.         {
  130.             Match match = null;
  131.             if (!this.globalInt)
  132.                 match = this.regex.Match(input);
  133.             else {
  134.                 int lastIndex = (int)Runtime.DoubleToInt64(Convert.ToInteger(this.lastIndexInt));
  135.                 if (lastIndex <= 0)
  136.                     match = this.regex.Match(input);
  137.                 else if (lastIndex <= input.Length)
  138.                     match = this.regex.Match(input, lastIndex);
  139.             }
  140.             if (match == null || !match.Success) {
  141.                 this.lastIndexInt = 0;
  142.                 return false;
  143.             }
  144.             this.lastIndexInt = this.regExpConst.UpdateConstructor(this.regex, match, input);
  145.             return true;
  146.         }
  147.        
  148.         public override string ToString()
  149.         {
  150.             return "/" + this.sourceInt + "/" + (this.ignoreCaseInt ? "i" : "") + (this.globalInt ? "g" : "") + (this.multilineInt ? "m" : "");
  151.         }
  152.        
  153.         public string source {
  154.             get { return this.sourceInt; }
  155.         }
  156.        
  157.         public bool ignoreCase {
  158.             get { return this.ignoreCaseInt; }
  159.         }
  160.        
  161.         public bool global {
  162.             get { return this.globalInt; }
  163.         }
  164.        
  165.         public bool multiline {
  166.             get { return this.multilineInt; }
  167.         }
  168.        
  169.         public object lastIndex {
  170.             get { return this.lastIndexInt; }
  171.             set { this.lastIndexInt = value; }
  172.         }
  173.     }
  174. }

Developer Fusion