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

  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.Collections;
  20.     using System.Reflection;
  21.     using System.Runtime.InteropServices;
  22.     using System.Configuration.Assemblies;
  23.     using System.Text;
  24.     using System.Security.Permissions;
  25.    
  26.     public class GlobalObject
  27.     {
  28.         static internal readonly GlobalObject commonInstance = new GlobalObject();
  29.         public const double Infinity = Double.PositiveInfinity;
  30.         public const double NaN = Double.NaN;
  31.         public static readonly Empty undefined = null;
  32.        
  33.         protected ActiveXObjectConstructor originalActiveXObjectField;
  34.         protected ArrayConstructor originalArrayField;
  35.         protected BooleanConstructor originalBooleanField;
  36.         protected DateConstructor originalDateField;
  37.         protected EnumeratorConstructor originalEnumeratorField;
  38.         protected ErrorConstructor originalErrorField;
  39.         protected ErrorConstructor originalEvalErrorField;
  40.         protected FunctionConstructor originalFunctionField;
  41.         protected NumberConstructor originalNumberField;
  42.         protected ObjectConstructor originalObjectField;
  43.         protected ObjectPrototype originalObjectPrototypeField;
  44.         protected ErrorConstructor originalRangeErrorField;
  45.         protected ErrorConstructor originalReferenceErrorField;
  46.         protected RegExpConstructor originalRegExpField;
  47.         protected StringConstructor originalStringField;
  48.         protected ErrorConstructor originalSyntaxErrorField;
  49.         protected ErrorConstructor originalTypeErrorField;
  50.         protected VBArrayConstructor originalVBArrayField;
  51.         protected ErrorConstructor originalURIErrorField;
  52.        
  53.         internal GlobalObject()
  54.         {
  55.             this.originalActiveXObjectField = null;
  56.             this.originalArrayField = null;
  57.             this.originalBooleanField = null;
  58.             this.originalDateField = null;
  59.             this.originalEnumeratorField = null;
  60.             this.originalEvalErrorField = null;
  61.             this.originalErrorField = null;
  62.             this.originalFunctionField = null;
  63.             this.originalNumberField = null;
  64.             this.originalObjectField = null;
  65.             this.originalObjectPrototypeField = null;
  66.             this.originalRangeErrorField = null;
  67.             this.originalReferenceErrorField = null;
  68.             this.originalRegExpField = null;
  69.             this.originalStringField = null;
  70.             this.originalSyntaxErrorField = null;
  71.             this.originalTypeErrorField = null;
  72.             this.originalVBArrayField = null;
  73.             this.originalURIErrorField = null;
  74.         }
  75.        
  76.         public static ActiveXObjectConstructor ActiveXObject {
  77.             get { return ActiveXObjectConstructor.ob; }
  78.         }
  79.        
  80.         private static void AppendInHex(StringBuilder bs, int value)
  81.         {
  82.             bs.Append('%');
  83.             int nibble = value >> 4 & 15;
  84.             bs.Append((char)(nibble >= 10 ? nibble - 10 + 'A' : nibble + '0'));
  85.             nibble = value & 15;
  86.             bs.Append((char)(nibble >= 10 ? nibble - 10 + 'A' : nibble + '0'));
  87.         }
  88.        
  89.         public static ArrayConstructor Array {
  90.             get { return ArrayConstructor.ob; }
  91.         }
  92.        
  93.         public static BooleanConstructor Boolean {
  94.             get { return BooleanConstructor.ob; }
  95.         }
  96.        
  97.         public static Type boolean {
  98.             get { return Typeob.Boolean; }
  99.         }
  100.        
  101.         public static Type @byte {
  102.             get { return Typeob.Byte; }
  103.         }
  104.        
  105.         public static Type @char {
  106.             get { return Typeob.Char; }
  107.         }
  108.        
  109.         [JSFunctionAttribute(0, JSBuiltin.Global_CollectGarbage)]
  110.         public static void CollectGarbage()
  111.         {
  112.             System.GC.Collect();
  113.         }
  114.        
  115.         public static DateConstructor Date {
  116.             get { return DateConstructor.ob; }
  117.         }
  118.        
  119.         public static Type @decimal {
  120.             get { return Typeob.Decimal; }
  121.         }
  122.        
  123.         private static string Decode(object encodedURI, URISetType flags)
  124.         {
  125.             string encodedURIStr = Convert.ToString(encodedURI);
  126.             StringBuilder resultStr = new StringBuilder();
  127.             for (int i = 0; i < encodedURIStr.Length; i++) {
  128.                 char ch = encodedURIStr[i];
  129.                 if (ch != '%')
  130.                     resultStr.Append(ch);
  131.                 else {
  132.                     int start = i;
  133.                     if (i + 2 >= encodedURIStr.Length)
  134.                         throw new JScriptException(JSError.URIDecodeError);
  135.                     byte b = HexValue(encodedURIStr[i + 1], encodedURIStr[i + 2]);
  136.                     i += 2;
  137.                    
  138.                     char ch1;
  139.                     if ((b & 128) == 0)
  140.                         ch1 = (char)b;
  141.                     else {
  142.                         int n;
  143.                         for (n = 1; ((b << n) & 128) != 0; n++)
  144.                             ;
  145.                         if (n == 1 || n > 4 || i + (n - 1) * 3 >= encodedURIStr.Length)
  146.                             throw new JScriptException(JSError.URIDecodeError);
  147.                         int value = (int)b & 255 >> (n + 1);
  148.                         for (; n > 1; n--) {
  149.                             if (encodedURIStr[i + 1] != '%')
  150.                                 throw new JScriptException(JSError.URIDecodeError);
  151.                             b = HexValue(encodedURIStr[i + 2], encodedURIStr[i + 3]);
  152.                             i += 3;
  153.                             // The two leading bits should be 10 for a valid UTF-8 encoding.
  154.                             if ((b & 192) != 128)
  155.                                 throw new JScriptException(JSError.URIDecodeError);
  156.                             value = value << 6 | (int)(b & 63);
  157.                         }
  158.                         if (value >= 55296 && value < 57344)
  159.                             throw new JScriptException(JSError.URIDecodeError);
  160.                         if (value < 65536)
  161.                             ch1 = (char)value;
  162.                         else {
  163.                             if (value > 1114111)
  164.                                 throw new JScriptException(JSError.URIDecodeError);
  165.                             resultStr.Append((char)((value - 65536 >> 10 & 1023) + 55296));
  166.                             resultStr.Append((char)((value - 65536 & 1023) + 56320));
  167.                             continue;
  168.                         }
  169.                     }
  170.                    
  171.                     if (GlobalObject.InURISet(ch1, flags))
  172.                         resultStr.Append(encodedURIStr, start, i - start + 1);
  173.                     else
  174.                         resultStr.Append(ch1);
  175.                 }
  176.             }
  177.            
  178.             return resultStr.ToString();
  179.         }
  180.        
  181.         [JSFunctionAttribute(0, JSBuiltin.Global_decodeURI)]
  182.         public static string decodeURI(object encodedURI)
  183.         {
  184.             return Decode(encodedURI, URISetType.Reserved);
  185.         }
  186.        
  187.         [JSFunctionAttribute(0, JSBuiltin.Global_decodeURIComponent)]
  188.         public static string decodeURIComponent(object encodedURI)
  189.         {
  190.             return Decode(encodedURI, URISetType.None);
  191.         }
  192.        
  193.         public static Type @double {
  194.             get { return Typeob.Double; }
  195.         }
  196.        
  197.         private static string Encode(object uri, URISetType flags)
  198.         {
  199.             string uriStr = Convert.ToString(uri);
  200.             StringBuilder resultStr = new StringBuilder();
  201.             for (int i = 0; i < uriStr.Length; i++) {
  202.                 char ch = uriStr[i];
  203.                 if (GlobalObject.InURISet(ch, flags))
  204.                     resultStr.Append(ch);
  205.                 else {
  206.                     int value = (int)ch;
  207.                     if (value >= 0 && value <= 127)
  208.                         GlobalObject.AppendInHex(resultStr, value);
  209.                     else if (value >= 128 && value <= 2047) {
  210.                         GlobalObject.AppendInHex(resultStr, value >> 6 | 192);
  211.                         GlobalObject.AppendInHex(resultStr, value & 63 | 128);
  212.                     }
  213.                     else if (value < 55296 || value > 57343) {
  214.                         GlobalObject.AppendInHex(resultStr, value >> 12 | 224);
  215.                         GlobalObject.AppendInHex(resultStr, value >> 6 & 63 | 128);
  216.                         GlobalObject.AppendInHex(resultStr, value & 63 | 128);
  217.                     }
  218.                     else {
  219.                         if (value >= 56320 && value <= 57343)
  220.                             throw new JScriptException(JSError.URIEncodeError);
  221.                         if (++i >= uriStr.Length)
  222.                             throw new JScriptException(JSError.URIEncodeError);
  223.                         int value1 = (int)uriStr[i];
  224.                         if (value1 < 56320 || value1 > 57343)
  225.                             throw new JScriptException(JSError.URIEncodeError);
  226.                         value = (value - 55296 << 10) + value1 + 9216;
  227.                         GlobalObject.AppendInHex(resultStr, value >> 18 | 240);
  228.                         GlobalObject.AppendInHex(resultStr, value >> 12 & 63 | 128);
  229.                         GlobalObject.AppendInHex(resultStr, value >> 6 & 63 | 128);
  230.                         GlobalObject.AppendInHex(resultStr, value & 63 | 128);
  231.                     }
  232.                 }
  233.             }
  234.             return resultStr.ToString();
  235.         }
  236.        
  237.         [JSFunctionAttribute(0, JSBuiltin.Global_encodeURI)]
  238.         public static string encodeURI(object uri)
  239.         {
  240.             return GlobalObject.Encode(uri, URISetType.Reserved | URISetType.Unescaped);
  241.         }
  242.        
  243.         [JSFunctionAttribute(0, JSBuiltin.Global_encodeURIComponent)]
  244.         public static string encodeURIComponent(object uriComponent)
  245.         {
  246.             return GlobalObject.Encode(uriComponent, URISetType.Unescaped);
  247.         }
  248.        
  249.         public static EnumeratorConstructor Enumerator {
  250.             get { return EnumeratorConstructor.ob; }
  251.         }
  252.        
  253.         public static ErrorConstructor Error {
  254.             get { return ErrorConstructor.ob; }
  255.         }
  256.        
  257.         [NotRecommended("escape")]
  258.         [JSFunctionAttribute(0, JSBuiltin.Global_escape)]
  259.         public static string escape(object @string)
  260.         {
  261.             string str = Convert.ToString(@string);
  262.             string hex = "0123456789ABCDEF";
  263.             int n = str.Length;
  264.             StringBuilder ustr = new StringBuilder(n * 2);
  265.             char c;
  266.             int d;
  267.             for (int k = -1; ++k < n; ustr.Append(c)) {
  268.                 c = str[k];
  269.                 d = (int)c;
  270.                 if ((int)'A' <= d && d <= (int)'Z')
  271.                     continue;
  272.                 if ((int)'a' <= d && d <= (int)'z')
  273.                     continue;
  274.                 if ((int)'0' <= d && d <= (int)'9')
  275.                     continue;
  276.                 if (c == '@' || c == '*' || c == '_' || c == '+' || c == '-' || c == '.' || c == '/')
  277.                     continue;
  278.                 ustr.Append('%');
  279.                 if (d < 256) {
  280.                     ustr.Append(hex[d / 16]);
  281.                     c = hex[d % 16];
  282.                 }
  283.                 else {
  284.                     ustr.Append('u');
  285.                     ustr.Append(hex[(d >> 12) % 16]);
  286.                     ustr.Append(hex[(d >> 8) % 16]);
  287.                     ustr.Append(hex[(d >> 4) % 16]);
  288.                     c = hex[d % 16];
  289.                 }
  290.             }
  291.             return ustr.ToString();
  292.         }
  293.        
  294.        
  295.         [JSFunctionAttribute(0, JSBuiltin.Global_eval)]
  296.         public static object eval(object x)
  297.         {
  298.             //The eval function is never called by JScript code because it is a special form that gets its own AST node.
  299.             //If this function is called, it is because of an illegal program.
  300.             throw new JScriptException(JSError.IllegalEval);
  301.         }
  302.        
  303.         public static ErrorConstructor EvalError {
  304.             get { return ErrorConstructor.evalOb; }
  305.         }
  306.        
  307.         public static Type @float {
  308.             get { return Typeob.Single; }
  309.         }
  310.        
  311.         public static FunctionConstructor Function {
  312.             get { return FunctionConstructor.ob; }
  313.         }
  314.        
  315.         [JSFunctionAttribute(0, JSBuiltin.Global_GetObject)]
  316.         [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  317.         public static object GetObject(object moniker, object progId)
  318.         {
  319.             // GetObject is not supported for FEATURE_PAL.
  320.             throw new JScriptException(JSError.InvalidCall);
  321.         }
  322.        
  323.         static internal int HexDigit(char c)
  324.         {
  325.             if (c >= '0' && c <= '9')
  326.                 return ((int)c) - ((int)'0');
  327.             if (c >= 'A' && c <= 'F')
  328.                 return 10 + ((int)c) - ((int)'A');
  329.             if (c >= 'a' && c <= 'f')
  330.                 return 10 + ((int)c) - ((int)'a');
  331.             return -1;
  332.         }
  333.        
  334.         private static byte HexValue(char ch1, char ch2)
  335.         {
  336.             int d1;
  337.             int d2;
  338.             if ((d1 = HexDigit(ch1)) < 0 || (d2 = HexDigit(ch2)) < 0)
  339.                 throw new JScriptException(JSError.URIDecodeError);
  340.             return (byte)(d1 << 4 | d2);
  341.         }
  342.        
  343.         public static Type @int {
  344.             get { return Typeob.Int32; }
  345.         }
  346.        
  347.         private static bool InURISet(char ch, URISetType flags)
  348.         {
  349.             if ((flags & URISetType.Unescaped) != URISetType.None) {
  350.                 if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
  351.                     return true;
  352.                 switch (ch) {
  353.                     case '-':
  354.                     case '_':
  355.                     case '.':
  356.                     case '!':
  357.                     case '~':
  358.                     case '*':
  359.                     case '\'':
  360.                     case '(':
  361.                     case ')':
  362.                         return true;
  363.                 }
  364.             }
  365.             if ((flags & URISetType.Reserved) != URISetType.None) {
  366.                 switch (ch) {
  367.                     case ';':
  368.                     case '/':
  369.                     case '?':
  370.                     case ':':
  371.                     case '@':
  372.                     case '&':
  373.                     case '=':
  374.                     case '+':
  375.                     case '$':
  376.                     case ',':
  377.                     case '#':
  378.                         return true;
  379.                 }
  380.             }
  381.             return false;
  382.         }
  383.        
  384.         [JSFunctionAttribute(0, JSBuiltin.Global_isNaN)]
  385.         public static bool isNaN(object num)
  386.         {
  387.             double number = Convert.ToNumber(num);
  388.             return number != number;
  389.         }
  390.        
  391.         [JSFunctionAttribute(0, JSBuiltin.Global_isFinite)]
  392.         public static bool isFinite(double number)
  393.         {
  394.             return !(Double.IsInfinity(number) || Double.IsNaN(number));
  395.         }
  396.        
  397.         public static Type @long {
  398.             get { return Typeob.Int64; }
  399.         }
  400.        
  401.         public static MathObject Math {
  402.             get {
  403.                 if (MathObject.ob == null)
  404.                     MathObject.ob = new MathObject(ObjectPrototype.ob);
  405.                 return MathObject.ob;
  406.             }
  407.         }
  408.        
  409.         public static NumberConstructor Number {
  410.             get { return NumberConstructor.ob; }
  411.         }
  412.        
  413.         public static ObjectConstructor Object {
  414.             get { return ObjectConstructor.ob; }
  415.         }
  416.        
  417.         internal virtual ActiveXObjectConstructor originalActiveXObject {
  418.             get {
  419.                 if (this.originalActiveXObjectField == null)
  420.                     this.originalActiveXObjectField = ActiveXObjectConstructor.ob;
  421.                 return this.originalActiveXObjectField;
  422.             }
  423.         }
  424.        
  425.         internal virtual ArrayConstructor originalArray {
  426.             get {
  427.                 if (this.originalArrayField == null)
  428.                     this.originalArrayField = ArrayConstructor.ob;
  429.                 return this.originalArrayField;
  430.             }
  431.         }
  432.        
  433.         internal virtual BooleanConstructor originalBoolean {
  434.             get {
  435.                 if (this.originalBooleanField == null)
  436.                     this.originalBooleanField = BooleanConstructor.ob;
  437.                 return this.originalBooleanField;
  438.             }
  439.         }
  440.        
  441.         internal virtual DateConstructor originalDate {
  442.             get {
  443.                 if (this.originalDateField == null)
  444.                     this.originalDateField = DateConstructor.ob;
  445.                 return this.originalDateField;
  446.             }
  447.         }
  448.        
  449.         internal virtual EnumeratorConstructor originalEnumerator {
  450.             get {
  451.                 if (this.originalEnumeratorField == null)
  452.                     this.originalEnumeratorField = EnumeratorConstructor.ob;
  453.                 return this.originalEnumeratorField;
  454.             }
  455.         }
  456.        
  457.         internal virtual ErrorConstructor originalError {
  458.             get {
  459.                 if (this.originalErrorField == null)
  460.                     this.originalErrorField = ErrorConstructor.ob;
  461.                 return this.originalErrorField;
  462.             }
  463.         }
  464.        
  465.         internal virtual ErrorConstructor originalEvalError {
  466.             get {
  467.                 if (this.originalEvalErrorField == null)
  468.                     this.originalEvalErrorField = ErrorConstructor.evalOb;
  469.                 return this.originalEvalErrorField;
  470.             }
  471.         }
  472.        
  473.         internal virtual FunctionConstructor originalFunction {
  474.             get {
  475.                 if (this.originalFunctionField == null)
  476.                     this.originalFunctionField = FunctionConstructor.ob;
  477.                 return this.originalFunctionField;
  478.             }
  479.         }
  480.        
  481.         internal virtual NumberConstructor originalNumber {
  482.             get {
  483.                 if (this.originalNumberField == null)
  484.                     this.originalNumberField = NumberConstructor.ob;
  485.                 return this.originalNumberField;
  486.             }
  487.         }
  488.        
  489.         internal virtual ObjectConstructor originalObject {
  490.             get {
  491.                 if (this.originalObjectField == null)
  492.                     this.originalObjectField = ObjectConstructor.ob;
  493.                 return this.originalObjectField;
  494.             }
  495.         }
  496.        
  497.         internal virtual ObjectPrototype originalObjectPrototype {
  498.             get {
  499.                 if (this.originalObjectPrototypeField == null)
  500.                     this.originalObjectPrototypeField = ObjectPrototype.ob;
  501.                 return this.originalObjectPrototypeField;
  502.             }
  503.         }
  504.        
  505.         internal virtual ErrorConstructor originalRangeError {
  506.             get {
  507.                 if (this.originalRangeErrorField == null)
  508.                     this.originalRangeErrorField = ErrorConstructor.rangeOb;
  509.                 return this.originalRangeErrorField;
  510.             }
  511.         }
  512.        
  513.         internal virtual ErrorConstructor originalReferenceError {
  514.             get {
  515.                 if (this.originalReferenceErrorField == null)
  516.                     this.originalReferenceErrorField = ErrorConstructor.referenceOb;
  517.                 return this.originalReferenceErrorField;
  518.             }
  519.         }
  520.        
  521.         internal virtual RegExpConstructor originalRegExp {
  522.             get {
  523.                 if (this.originalRegExpField == null)
  524.                     this.originalRegExpField = RegExpConstructor.ob;
  525.                 return this.originalRegExpField;
  526.             }
  527.         }
  528.        
  529.         internal virtual StringConstructor originalString {
  530.             get {
  531.                 if (this.originalStringField == null)
  532.                     this.originalStringField = StringConstructor.ob;
  533.                 return this.originalStringField;
  534.             }
  535.         }
  536.        
  537.         internal virtual ErrorConstructor originalSyntaxError {
  538.             get {
  539.                 if (this.originalSyntaxErrorField == null)
  540.                     this.originalSyntaxErrorField = ErrorConstructor.syntaxOb;
  541.                 return this.originalSyntaxErrorField;
  542.             }
  543.         }
  544.        
  545.         internal virtual ErrorConstructor originalTypeError {
  546.             get {
  547.                 if (this.originalTypeErrorField == null)
  548.                     this.originalTypeErrorField = ErrorConstructor.typeOb;
  549.                 return this.originalTypeErrorField;
  550.             }
  551.         }
  552.        
  553.         internal virtual ErrorConstructor originalURIError {
  554.             get {
  555.                 if (this.originalURIErrorField == null)
  556.                     this.originalURIErrorField = ErrorConstructor.uriOb;
  557.                 return this.originalURIErrorField;
  558.             }
  559.         }
  560.        
  561.         internal virtual VBArrayConstructor originalVBArray {
  562.             get {
  563.                 if (this.originalVBArrayField == null)
  564.                     this.originalVBArrayField = VBArrayConstructor.ob;
  565.                 return this.originalVBArrayField;
  566.             }
  567.         }
  568.        
  569.         [JSFunctionAttribute(0, JSBuiltin.Global_parseFloat)]
  570.         public static double parseFloat(object @string)
  571.         {
  572.             string str = Convert.ToString(@string);
  573.             return Convert.ToNumber(str, false, false, Missing.Value);
  574.         }
  575.        
  576.         [JSFunctionAttribute(0, JSBuiltin.Global_parseInt)]
  577.         public static double parseInt(object @string, object radix)
  578.         {
  579.             string str = Convert.ToString(@string);
  580.             return Convert.ToNumber(str, true, true, radix);
  581.         }
  582.        
  583.         public static ErrorConstructor RangeError {
  584.             get { return ErrorConstructor.rangeOb; }
  585.         }
  586.        
  587.         public static ErrorConstructor ReferenceError {
  588.             get { return ErrorConstructor.referenceOb; }
  589.         }
  590.        
  591.         public static RegExpConstructor RegExp {
  592.             get { return RegExpConstructor.ob; }
  593.         }
  594.        
  595.         [JSFunctionAttribute(0, JSBuiltin.Global_ScriptEngine)]
  596.         public static string ScriptEngine()
  597.         {
  598.             return "JScript";
  599.         }
  600.        
  601.         [JSFunctionAttribute(0, JSBuiltin.Global_ScriptEngineBuildVersion)]
  602.         public static int ScriptEngineBuildVersion()
  603.         {
  604.             return BuildVersionInfo.Build;
  605.         }
  606.        
  607.         [JSFunctionAttribute(0, JSBuiltin.Global_ScriptEngineMajorVersion)]
  608.         public static int ScriptEngineMajorVersion()
  609.         {
  610.             return BuildVersionInfo.MajorVersion;
  611.         }
  612.        
  613.         [JSFunctionAttribute(0, JSBuiltin.Global_ScriptEngineMinorVersion)]
  614.         public static int ScriptEngineMinorVersion()
  615.         {
  616.             return BuildVersionInfo.MinorVersion;
  617.         }
  618.        
  619.         public static Type @sbyte {
  620.             get { return Typeob.SByte; }
  621.         }
  622.        
  623.         public static Type @short {
  624.             get { return Typeob.Int16; }
  625.         }
  626.        
  627.         public static StringConstructor String {
  628.             get { return StringConstructor.ob; }
  629.         }
  630.        
  631.         public static ErrorConstructor SyntaxError {
  632.             get { return ErrorConstructor.syntaxOb; }
  633.         }
  634.        
  635.         public static ErrorConstructor TypeError {
  636.             get { return ErrorConstructor.typeOb; }
  637.         }
  638.        
  639.         [NotRecommended("unescape")]
  640.         [JSFunctionAttribute(0, JSBuiltin.Global_unescape)]
  641.         public static string unescape(object @string)
  642.         {
  643.             string str = Convert.ToString(@string);
  644.             int n = str.Length;
  645.             StringBuilder ustr = new StringBuilder(n);
  646.             char c;
  647.             int d1;
  648.             int d2;
  649.             int d3;
  650.             int d4;
  651.             for (int k = -1; ++k < n; ustr.Append(c)) {
  652.                 c = str[k];
  653.                 if (c == '%') {
  654.                     if (k + 5 < n && str[k + 1] == 'u' && (d1 = HexDigit(str[k + 2])) != -1 && (d2 = HexDigit(str[k + 3])) != -1 && (d3 = HexDigit(str[k + 4])) != -1 && (d4 = HexDigit(str[k + 5])) != -1) {
  655.                         c = (char)((d1 << 12) + (d2 << 8) + (d3 << 4) + d4);
  656.                         k += 5;
  657.                     }
  658.                     else if (k + 2 < n && (d1 = HexDigit(str[k + 1])) != -1 && (d2 = HexDigit(str[k + 2])) != -1) {
  659.                         c = (char)((d1 << 4) + d2);
  660.                         k += 2;
  661.                     }
  662.                 }
  663.             }
  664.             return ustr.ToString();
  665.         }
  666.        
  667.         public static ErrorConstructor URIError {
  668.             get { return ErrorConstructor.uriOb; }
  669.         }
  670.        
  671.         private enum URISetType
  672.         {
  673.             None = 0,
  674.             Reserved = 1,
  675.             Unescaped = 2
  676.         }
  677.        
  678.         public static VBArrayConstructor VBArray {
  679.             get { return VBArrayConstructor.ob; }
  680.         }
  681.        
  682.         public static Type @void {
  683.             get { return Typeob.Void; }
  684.         }
  685.        
  686.         public static Type @uint {
  687.             get { return Typeob.UInt32; }
  688.         }
  689.        
  690.         public static Type @ulong {
  691.             get { return Typeob.UInt64; }
  692.         }
  693.        
  694.         public static Type @ushort {
  695.             get { return Typeob.UInt16; }
  696.         }
  697.     }
  698. }

Developer Fusion