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

  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.Diagnostics;
  22.    
  23.     public class ArrayWrapper : ArrayObject
  24.     {
  25.        
  26.         internal Array value;
  27.         private bool implicitWrapper;
  28.        
  29.         internal ArrayWrapper(ScriptObject prototype, Array value, bool implicitWrapper) : base(prototype, typeof(ArrayWrapper))
  30.         {
  31.             this.value = value;
  32.             this.implicitWrapper = implicitWrapper;
  33.             if (value != null) {
  34.                 if (value.Rank != 1)
  35.                     throw new JScriptException(JSError.TypeMismatch);
  36.                 this.len = (uint)value.Length;
  37.             }
  38.             else
  39.                 this.len = 0;
  40.         }
  41.        
  42.         internal override void Concat(ArrayObject source)
  43.         {
  44.             throw new JScriptException(JSError.ActionNotSupported);
  45.         }
  46.        
  47.         internal override void Concat(object value)
  48.         {
  49.             throw new JScriptException(JSError.ActionNotSupported);
  50.         }
  51.        
  52.         internal override void GetPropertyEnumerator(ArrayList enums, ArrayList objects)
  53.         {
  54.             enums.Add(new ArrayEnumerator(this, new RangeEnumerator(0, (int)this.len - 1)));
  55.             objects.Add(this);
  56.             if (this.parent != null)
  57.                 this.parent.GetPropertyEnumerator(enums, objects);
  58.         }
  59.        
  60.         public new Type GetType()
  61.         {
  62.             return this.implicitWrapper ? this.value.GetType() : typeof(ArrayObject);
  63.         }
  64.        
  65.         internal override object GetValueAtIndex(uint index)
  66.         {
  67.             checked {
  68.                 return this.value.GetValue((int)index);
  69.             }
  70.         }
  71.        
  72.         public override object length {
  73.             get { return this.len; }
  74.             set {
  75.                 throw new JScriptException(JSError.AssignmentToReadOnly);
  76.             }
  77.         }
  78.        
  79.         #if !DEBUG
  80.         [DebuggerStepThroughAttribute()]
  81.         [DebuggerHiddenAttribute()]
  82.         #endif
  83.         internal override void SetMemberValue(string name, object val)
  84.         {
  85.             if (name.Equals("length"))
  86.                 throw new JScriptException(JSError.AssignmentToReadOnly);
  87.             long index = ArrayObject.Array_index_for(name);
  88.             if (index < 0)
  89.                 base.SetMemberValue(name, val);
  90.             else
  91.                 this.value.SetValue(val, (int)index);
  92.         }
  93.        
  94.         internal override void SetValueAtIndex(uint index, object val)
  95.         {
  96.             Type arrayType = this.value.GetType();
  97.             checked {
  98.                 this.value.SetValue(Convert.CoerceT(val, arrayType.GetElementType()), (int)index);
  99.             }
  100.         }
  101.        
  102.        
  103.         internal override object Shift()
  104.         {
  105.             throw new JScriptException(JSError.ActionNotSupported);
  106.         }
  107.        
  108.         internal override void Splice(uint start, uint deleteCount, object[] args, ArrayObject outArray, uint oldLength, uint newLength)
  109.         {
  110.             if (oldLength != newLength)
  111.                 throw new JScriptException(JSError.ActionNotSupported);
  112.             SpliceSlowly(start, deleteCount, args, outArray, oldLength, newLength);
  113.         }
  114.        
  115.         internal override void Sort(ScriptFunction compareFn)
  116.         {
  117.             SortComparer sc = new SortComparer(compareFn);
  118.             System.Array.Sort(this.value, sc);
  119.         }
  120.        
  121.         internal override void SwapValues(uint pi, uint qi)
  122.         {
  123.             object po = this.GetValueAtIndex(pi);
  124.             object qo = this.GetValueAtIndex(qi);
  125.             this.SetValueAtIndex(pi, qo);
  126.             this.SetValueAtIndex(qi, po);
  127.         }
  128.        
  129.         internal override Array ToNativeArray(Type elementType)
  130.         {
  131.             // Ignore the type -- if there is a mismatch, the caller will throw.
  132.             return value;
  133.         }
  134.        
  135.         internal override object[] ToArray()
  136.         {
  137.             object[] result;
  138.             checked {
  139.                 result = new object[(int)this.len];
  140.             }
  141.             for (uint i = 0; i < this.len; i++)
  142.                 result[i] = this.GetValueAtIndex(i);
  143.             return result;
  144.         }
  145.        
  146.         internal override ArrayObject Unshift(object[] args)
  147.         {
  148.             throw new JScriptException(JSError.ActionNotSupported);
  149.         }
  150.        
  151.         internal sealed class SortComparer : IComparer
  152.         {
  153.             internal ScriptFunction compareFn;
  154.             internal SortComparer(ScriptFunction compareFn)
  155.             {
  156.                 this.compareFn = compareFn;
  157.             }
  158.             public int Compare(object x, object y)
  159.             {
  160.                 if (x == null || x is Missing)
  161.                     if (y == null || y is Missing)
  162.                         return 0;
  163.                     else
  164.                         return 1;
  165.                 else if (y == null || y is Missing)
  166.                     return -1;
  167.                 if (this.compareFn != null) {
  168.                     double result = Convert.ToNumber(this.compareFn.Call(new object[] {x, y}, null));
  169.                     if (result != result)
  170.                         throw new JScriptException(JSError.NumberExpected);
  171.                     return (int)Runtime.DoubleToInt64(result);
  172.                 }
  173.                 else
  174.                     return String.CompareOrdinal(Convert.ToString(x), Convert.ToString(y));
  175.             }
  176.         }
  177.     }
  178. }

Developer Fusion