2010-05-04 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / class / corlib / System.Collections / BitArray.cs
index 1ecb765c93227c1504740b34f0254dc0e7d89d7a..684295d07e4745785f2d134c3b2d32352e1ba7cd 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Authors:
 // Ben Maurer (bmaurer@users.sourceforge.net)
+// Marek Safar (marek.safar@gmail.com)
 //
 // (C) 2003 Ben Maurer
 //
@@ -34,11 +35,14 @@ using System;
 using System.Runtime.InteropServices;
 
 namespace System.Collections {
-#if NET_2_0
        [ComVisible(true)]
-#endif
        [Serializable]
-       public sealed class BitArray : ICollection, ICloneable {
+#if INSIDE_CORLIB
+       public
+#else
+       internal
+#endif
+       sealed class BitArray : ICollection, ICloneable {
                int [] m_array;
                int m_length;
                int _version = 0;
@@ -51,8 +55,10 @@ namespace System.Collections {
 
                        m_length = bits.m_length;
                        m_array = new int [(m_length + 31) / 32];
-
-                       Array.Copy(bits.m_array, m_array, m_array.Length);
+                       if (m_array.Length == 1)
+                               m_array [0] = bits.m_array [0];
+                       else
+                               Array.Copy(bits.m_array, m_array, m_array.Length);
                }
 
                public BitArray (bool [] values)
@@ -167,21 +173,32 @@ namespace System.Collections {
                public int Length {
                        get { return m_length; }
                        set {
+                               if (m_length == value)
+                                       return;
+                               
                                if (value < 0)
                                        throw new ArgumentOutOfRangeException ();
                                
-                               int newLen = value;
-                               if (m_length != newLen) {
-                                       int numints = (newLen + 31) / 32;
-                                       int [] newArr = new int [numints];
-                                       int copylen = (numints > m_array.Length) ? m_array.Length : numints;
-                                       Array.Copy (m_array, newArr, copylen);
-                                       
-                                       // set the internal state
-                                       m_array = newArr;
-                                       m_length = newLen;
-                                       _version++;
+                               // Currently we never shrink the array
+                               if (value > m_length) {
+                                       int numints = (value + 31) / 32;
+                                       int old_numints = (m_length + 31) / 32;
+                                       if (numints > m_array.Length) {
+                                               int [] newArr = new int [numints];
+                                               Array.Copy (m_array, newArr, m_array.Length);
+                                               m_array = newArr;
+                                       } else {
+                                               Array.Clear(m_array, old_numints, numints - old_numints);
+                                       }
+
+                                       int mask = m_length % 32;
+                                       if (mask > 0)
+                                               m_array [old_numints - 1] &= (1 << mask) - 1;
                                }
+                                       
+                               // set the internal state
+                               m_length = value;
+                               _version++;
                        }
                }
                
@@ -205,7 +222,7 @@ namespace System.Collections {
                        if (array.Rank != 1)
                                throw new ArgumentException ("array", "Array rank must be 1");
                        
-                       if (index >= array.Length)
+                       if (index >= array.Length && m_length > 0)
                                throw new ArgumentException ("index", "index is greater than array.Length");
                        
                        // in each case, check to make sure enough space in array
@@ -328,7 +345,7 @@ namespace System.Collections {
                class BitArrayEnumerator : IEnumerator, ICloneable {
                        BitArray _bitArray;
                        bool _current;
-                       int _index, _max, _version;
+                       int _index, _version;
                        
                        public object Clone () {
                                return MemberwiseClone ();
@@ -338,7 +355,6 @@ namespace System.Collections {
                        {
                                _index = -1;
                                _bitArray = ba;
-                               _max = ba.m_length;
                                _version = ba._version;
                        }
 
@@ -361,9 +377,8 @@ namespace System.Collections {
                                        _current = _bitArray [++_index];
                                        return true;
                                }
-                               else
-                                       _index = _bitArray.Count;
                                
+                               _index = _bitArray.Count;
                                return false;
                        }