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

  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. /*
  16. The indices in the dense part of an ArrayObject do not show up as properties in the field table of the object. This enumerator includes them in the enumeration.
  17. It is complicated by the fact that properties can be added to both the dense part and the field table as the enumeration proceeds.
  18. Another, major complication is that prior versions of JS enumerate properties in the order they were added to the object, and many test suites depend on this order.
  19. When an array is stored densely, it does not make sense to retain the order in which indices were added to the array, merely to make enumerations work exactly as
  20. they always have. However, some test at least, work if the numerical indices are listed before other properties, but numerical indices that are added after
  21. other properties, are listed afterwards.
  22. */
  23. namespace Microsoft.JScript
  24. {
  25.    
  26.     using System;
  27.     using System.Collections;
  28.     using System.Reflection;
  29.     using System.Globalization;
  30.    
  31.     internal class ArrayEnumerator : IEnumerator
  32.     {
  33.         private int curr;
  34.         private bool doDenseEnum;
  35.         private bool didDenseEnum;
  36.         private ArrayObject arrayOb;
  37.         private IEnumerator denseEnum;
  38.        
  39.         internal ArrayEnumerator(ArrayObject arrayOb, IEnumerator denseEnum)
  40.         {
  41.             this.curr = -1;
  42.             this.doDenseEnum = false;
  43.             this.didDenseEnum = false;
  44.             this.arrayOb = arrayOb;
  45.             this.denseEnum = denseEnum;
  46.         }
  47.        
  48.         public virtual bool MoveNext()
  49.         {
  50.             if (this.doDenseEnum)
  51.                 if (this.denseEnum.MoveNext())
  52.                     return true;
  53.                 else {
  54.                     this.doDenseEnum = false;
  55.                     this.didDenseEnum = true;
  56.                 }
  57.             int next = this.curr + 1;
  58.             if (next >= this.arrayOb.len || next >= this.arrayOb.denseArrayLength) {
  59.                 this.doDenseEnum = !this.didDenseEnum;
  60.                 return this.denseEnum.MoveNext();
  61.             }
  62.             this.curr = next;
  63.             if (this.arrayOb.GetValueAtIndex((uint)next) is Missing)
  64.                 return this.MoveNext();
  65.             return true;
  66.         }
  67.        
  68.         public virtual object Current {
  69.             //Always returns a String
  70.             get {
  71.                 if (this.doDenseEnum)
  72.                     return this.denseEnum.Current;
  73.                 if (this.curr >= this.arrayOb.len || this.curr >= this.arrayOb.denseArrayLength)
  74.                     return this.denseEnum.Current;
  75.                 else
  76.                     return this.curr.ToString(CultureInfo.InvariantCulture);
  77.             }
  78.         }
  79.        
  80.         public virtual void Reset()
  81.         {
  82.             this.curr = -1;
  83.             this.doDenseEnum = false;
  84.             this.didDenseEnum = false;
  85.             this.denseEnum.Reset();
  86.         }
  87.     }
  88. }

Developer Fusion