Hi, I've got a few mono patches lined up today. I did a big cycle ride on Saturday and didn't want to move on Sunday so I got lots of coding done!
I've attached a further patch for BitVector32, created against the current cvs version. The patch contains: - Unit test for section indexers - Check for >32 bits when creating sections - Factored out helper methods for bit twiddling operations. - Removed ^M's from BitVector32Test.cs Unit tests pass, except those which were already broken prior to my changes. The failures are all in date/time classes, due to me being in the GMT time zone. I'll have a look at fixing those later. Andrew - www.tardis.ed.ac.uk/~adb -
Index: System/System.Collections.Specialized/BitVector32.cs =================================================================== RCS file: /mono/mcs/class/System/System.Collections.Specialized/BitVector32.cs,v retrieving revision 1.5 diff -u -r1.5 BitVector32.cs --- System/System.Collections.Specialized/BitVector32.cs 21 Jun 2002 18:12:03 -0000 1.5 +++ System/System.Collections.Specialized/BitVector32.cs 24 Jun 2002 11:06:45 +-0000 @@ -4,6 +4,7 @@ // Author: // Miguel de Icaza ([EMAIL PROTECTED]) // Lawrence Pit ([EMAIL PROTECTED]) +// Andrew Birkett ([EMAIL PROTECTED]) // // (C) Ximian, Inc. http://www.ximian.com // @@ -128,25 +129,15 @@ if (maxValue < 1) throw new ArgumentException ("maxValue"); - int newmask = (int) maxValue; - int mask = 0x8000; - while ((newmask & mask) == 0) - mask >>= 1; - while (mask > 0) { - newmask |= mask; - mask >>= 1; - } + int bit = HighestSetBit(maxValue) + 1; + int mask = (1 << bit) - 1; + int offset = previous.Offset + NumberOfSetBits +(previous.Mask); - short count = 0; - int prev = previous.Mask; - mask = 0x8000; - while (mask > 0) { - if ((prev & mask) != 0) - count++; - mask >>= 1; + if (offset + NumberOfSetBits (mask) > 32) { + throw new ArgumentException ("Sections cannot exceed +32 bits in total"); } - return new Section ((short) newmask, (short) (previous.Offset + count)); + return new Section ((short) mask, (short) offset); } public override bool Equals (object o) @@ -179,5 +170,30 @@ b.Append ('}'); return b.ToString (); } + + // Private utilities + private static int NumberOfSetBits (int i) + { + int count = 0; + for (int bit = 0; bit < 32; bit++) { + int mask = 1 << bit; + if ((i & mask) != 0) + count++; + } + return count; + } + + private static int HighestSetBit (int i) + { + for (int bit = 31; bit >= 0; bit--) { + int mask = 1 << bit; + if ((mask & i) != 0) { + return bit; + } + } + + return -1; + } + } } Index: System/System.Collections.Specialized/ChangeLog =================================================================== RCS file: /mono/mcs/class/System/System.Collections.Specialized/ChangeLog,v retrieving revision 1.10 diff -u -r1.10 ChangeLog --- System/System.Collections.Specialized/ChangeLog 11 May 2002 21:26:46 -0000 1.10 +++ System/System.Collections.Specialized/ChangeLog 24 Jun 2002 11:06:45 -0000 @@ -1,3 +1,8 @@ +2002-06-24 Andrew Birkett <[EMAIL PROTECTED]> + + * BitVector32.cs: Implemented 'set' section indexer. Check for + overly large sections. Factored out some helper methods. + 2002-05-11 Lawrence Pit <[EMAIL PROTECTED]> * NameValueCollection.AsStringArray: fixed ArgumentNullException bug. Index: System/Test/System.Collections.Specialized/BitVector32Test.cs =================================================================== RCS file: /mono/mcs/class/System/Test/System.Collections.Specialized/BitVector32Test.cs,v retrieving revision 1.1 diff -u -r1.1 BitVector32Test.cs --- System/Test/System.Collections.Specialized/BitVector32Test.cs 9 May 2002 20:05:33 -0000 1.1 +++ System/Test/System.Collections.Specialized/BitVector32Test.cs 24 Jun 2002 +11:06:45 -0000 @@ -1,140 +1,178 @@ -// -// BitVector32Test.cs - NUnit Test Cases for System.Net.BitVector32 -// -// Author: -// Lawrence Pit ([EMAIL PROTECTED]) -// - -using NUnit.Framework; -using System; -using System.Collections; -using System.Collections.Specialized; - -namespace MonoTests.System.Collections.Specialized -{ - public class BitVector32Test : TestCase - { - public BitVector32Test () : - base ("[MonoTests.System.Net.BitVector32Test]") {} - - public BitVector32Test (string name) : base (name) {} - - protected override void SetUp () {} - - protected override void TearDown () {} - - public static ITest Suite - { - get { - return new TestSuite (typeof (BitVector32Test)); - } - } - - public void TestConstructors () - { - BitVector32 b = new BitVector32 (31); - } - - public void TestIndexers () - { - BitVector32 b = new BitVector32 (7); - Assert ("#1", b [0]); - Assert ("#2", b [1]); - Assert ("#3", b [2]); - Assert ("#4", b [4]); - Assert ("#5", !b [8]); - Assert ("#6", !b [16]); - b [8] = true; - Assert ("#7", b [4]); - Assert ("#8", b [8]); - Assert ("#9", !b [16]); - b [8] = false; - Assert ("#10", b [4]); - Assert ("#11", !b [8]); - Assert ("#12", !b [16]); - - BitVector32.Section s = BitVector32.CreateSection (31); - s = BitVector32.CreateSection (64, s); - // Print (s); - - // b = new BitVector32 (0x777777); - BitVector32 b1 = new BitVector32 (0xffff77); - BitVector32 b2 = new BitVector32 (b1 [s]); - //Console.WriteLine (b1.ToString ()); - //Console.WriteLine (b2.ToString ()); - AssertEquals ("#14", 123, b1 [s]); - - // b1 [s] = 15; - //Console.WriteLine (b1.ToString ()); - } - - public void TestCreateMask () - { - AssertEquals ("#1", 1, BitVector32.CreateMask ()); - AssertEquals ("#2", 1, BitVector32.CreateMask (0)); - AssertEquals ("#3", 2, BitVector32.CreateMask (1)); - AssertEquals ("#4", 32, BitVector32.CreateMask (16)); - AssertEquals ("#6", -2, BitVector32.CreateMask (Int32.MaxValue)); - AssertEquals ("#5", -4, BitVector32.CreateMask (-2)); - try { - BitVector32.CreateMask (Int32.MinValue); - Fail ("#7"); - } catch (InvalidOperationException) {} - } - - public void TestCreateSection () - { - BitVector32.Section s = BitVector32.CreateSection (1); - AssertEquals ("#1", (short) 1, s.Mask); - - s = BitVector32.CreateSection (2); - AssertEquals ("#2", (short) 3, s.Mask); - - s = BitVector32.CreateSection (3); - AssertEquals ("#3", (short) 3, s.Mask); - - s = BitVector32.CreateSection (5); - AssertEquals ("#4", (short) 7, s.Mask); - - s = BitVector32.CreateSection (20); - AssertEquals ("#4", (short) 0x1f, s.Mask); - - s = BitVector32.CreateSection (Int16.MaxValue); - AssertEquals ("#5", (short) 0x7fff, s.Mask); - - s = BitVector32.CreateSection (Int16.MaxValue - 100); - AssertEquals ("#6", (short) 0x7fff, s.Mask); - - try { - BitVector32.Section s2 = BitVector32.CreateSection (0); - Fail ("#7"); - } catch (ArgumentException) {} - - try { - BitVector32.Section s2 = BitVector32.CreateSection (-1); - Fail ("#8"); - } catch (ArgumentException) {} - - try { - BitVector32.Section s2 = BitVector32.CreateSection (Int16.MinValue); - Fail ("#9"); - } catch (ArgumentException) {} - - s = BitVector32.CreateSection (20); - AssertEquals ("#10a", (short) 0x1f, s.Mask); - AssertEquals ("#10b", (short) 0x00, s.Offset); - s = BitVector32.CreateSection (120, s); - AssertEquals ("#10c", (short) 0x7f, s.Mask); - AssertEquals ("#10d", (short) 0x05, s.Offset); - s = BitVector32.CreateSection (1000, s); - AssertEquals ("#10e", (short) 0x3ff, s.Mask); - AssertEquals ("#10f", (short) 0x0c, s.Offset); - } - - - private void Print (BitVector32.Section s) - { - Console.WriteLine (s.ToString () + " : "+ s.Mask + " : " + s.Offset); - } - } +// +// BitVector32Test.cs - NUnit Test Cases for System.Net.BitVector32 +// +// Author: +// Lawrence Pit ([EMAIL PROTECTED]) +// Andrew Birkett ([EMAIL PROTECTED]) +// + +using NUnit.Framework; +using System; +using System.Collections; +using System.Collections.Specialized; + +namespace MonoTests.System.Collections.Specialized +{ + public class BitVector32Test : TestCase + { + public BitVector32Test () : + base ("[MonoTests.System.Net.BitVector32Test]") {} + + public BitVector32Test (string name) : base (name) {} + + protected override void SetUp () {} + + protected override void TearDown () {} + + public static ITest Suite + { + get { + return new TestSuite (typeof (BitVector32Test)); + } + } + + public void TestConstructors () + { + BitVector32 b = new BitVector32 (31); + } + + public void TestIndexers () + { + BitVector32 b = new BitVector32 (7); + Assert ("#1", b [0]); + Assert ("#2", b [1]); + Assert ("#3", b [2]); + Assert ("#4", b [4]); + Assert ("#5", !b [8]); + Assert ("#6", !b [16]); + b [8] = true; + Assert ("#7", b [4]); + Assert ("#8", b [8]); + Assert ("#9", !b [16]); + b [8] = false; + Assert ("#10", b [4]); + Assert ("#11", !b [8]); + Assert ("#12", !b [16]); + + BitVector32.Section s = BitVector32.CreateSection (31); + s = BitVector32.CreateSection (64, s); + + BitVector32 b1 = new BitVector32 (0xffff77); + BitVector32 b2 = new BitVector32 (b1 [s]); + + AssertEquals ("#14", 123, b1 [s]); + } + + public void TestCreateMask () + { + AssertEquals ("#1", 1, BitVector32.CreateMask ()); + AssertEquals ("#2", 1, BitVector32.CreateMask (0)); + AssertEquals ("#3", 2, BitVector32.CreateMask (1)); + AssertEquals ("#4", 32, BitVector32.CreateMask (16)); + AssertEquals ("#6", -2, BitVector32.CreateMask +(Int32.MaxValue)); + AssertEquals ("#5", -4, BitVector32.CreateMask (-2)); + try { + BitVector32.CreateMask (Int32.MinValue); + Fail ("#7"); + } catch (InvalidOperationException) {} + } + + public void TestCreateSection () + { + BitVector32.Section s = BitVector32.CreateSection (1); + AssertEquals ("#1", (short) 1, s.Mask); + + s = BitVector32.CreateSection (2); + AssertEquals ("#2", (short) 3, s.Mask); + + s = BitVector32.CreateSection (3); + AssertEquals ("#3", (short) 3, s.Mask); + + s = BitVector32.CreateSection (5); + AssertEquals ("#4", (short) 7, s.Mask); + + s = BitVector32.CreateSection (20); + AssertEquals ("#4", (short) 0x1f, s.Mask); + + s = BitVector32.CreateSection (Int16.MaxValue); + AssertEquals ("#5", (short) 0x7fff, s.Mask); + + s = BitVector32.CreateSection (Int16.MaxValue - 100); + AssertEquals ("#6", (short) 0x7fff, s.Mask); + + try { + BitVector32.Section s2 = BitVector32.CreateSection +(0); + Fail ("#7"); + } catch (ArgumentException) {} + + try { + BitVector32.Section s2 = BitVector32.CreateSection +(-1); + Fail ("#8"); + } catch (ArgumentException) {} + + try { + BitVector32.Section s2 = BitVector32.CreateSection +(Int16.MinValue); + Fail ("#9"); + } catch (ArgumentException) {} + + s = BitVector32.CreateSection (20); + AssertEquals ("#10a", (short) 0x1f, s.Mask); + AssertEquals ("#10b", (short) 0x00, s.Offset); + + s = BitVector32.CreateSection (120, s); + AssertEquals ("#10c", (short) 0x7f, s.Mask); + AssertEquals ("#10d", (short) 0x05, s.Offset); + + s = BitVector32.CreateSection (1000, s); + AssertEquals ("#10e", (short) 0x3ff, s.Mask); + AssertEquals ("#10f", (short) 0x0c, s.Offset); + + } + + public void TestUseSections() { + BitVector32.Section s0_1 = BitVector32.CreateSection(3); // 2 +bits + BitVector32.Section s2_15 = BitVector32.CreateSection(16383, +s0_1); // 14 bits + BitVector32.Section s16_30 = BitVector32.CreateSection(32767, +s2_15); // 15 bits + BitVector32.Section s31_31 = BitVector32.CreateSection(1, +s16_30); // 1 bits + + // Read sections from test value "0111 1111 1111 0000 1111 +1111 0000 1111" + BitVector32 b = new BitVector32(0x7ff0ff0f); + + AssertEquals ("#1a", 0x3, b[s0_1]); // 11 + AssertEquals ("#1b", 0x3fc3, b[s2_15]); // 11 1111 1100 0011 = +0x3fc3 + AssertEquals ("#1c", 0x7ff0, b[s16_30]); // 111 1111 1111 0000 += 0x7ff0 + AssertEquals ("#1d", 0x0, b[s31_31]); + + // Write sections + b = new BitVector32(); + b[s0_1] = 3; + AssertEquals ("#2a", 0x3, b.Data); + + b = new BitVector32(); + b[s2_15] = 16383; + AssertEquals ("#2b", 16383 << 2, b.Data); + + b = new BitVector32(); + b[s16_30] = 32767; + AssertEquals ("#2c", 32767 << 16, b.Data); + + b = new BitVector32(); + b[s31_31] = 1; + AssertEquals ("#2d", 1 << 31, b.Data); + + Console.WriteLine("HELLLOOO"); + } + + public void TestBadSections() { + // Can't create more than 32 bits of sections. + BitVector32.Section s0_14 = BitVector32.CreateSection(32767); + BitVector32.Section s15_29 = BitVector32.CreateSection(32767, +s0_14); + try { + BitVector32.Section s30_32 = +BitVector32.CreateSection(7, s15_29); + Fail("#1"); + } catch (ArgumentException) { } + } + + private void Print (BitVector32.Section s) + { + Console.WriteLine (s.ToString () + " : "+ s.Mask + " : " + +s.Offset); + } + } } Index: System/Test/System.Collections.Specialized/ChangeLog =================================================================== RCS file: /mono/mcs/class/System/Test/System.Collections.Specialized/ChangeLog,v retrieving revision 1.2 diff -u -r1.2 ChangeLog --- System/Test/System.Collections.Specialized/ChangeLog 11 May 2002 15:30:44 -0000 1.2 +++ System/Test/System.Collections.Specialized/ChangeLog 24 Jun 2002 11:06:45 +-0000 @@ -1,3 +1,7 @@ +2002-06-24 Andrew Birkett <[EMAIL PROTECTED]> + + * BitVector32Test.cs: New tests for sections and removed ^M's. + 2002-05-11 Lawrence Pit <[EMAIL PROTECTED]> * Added NameValueCollectionTest.TestGetValues
