Просмотр исходного кода

Add StrinEnumerator.cs and StringCollection.cs

svn path=/trunk/mcs/; revision=240
Miguel de Icaza 24 лет назад
Родитель
Сommit
5f74e488d7

+ 292 - 14
mcs/class/System/System.Collections.Specialized/StringCollection.cs

@@ -1,14 +1,292 @@
-//
-// System.Collections.Specialized.StringCollection.cs
-//
-// Author:
-//   Sean MacIsaac ([email protected])
-//
-// (C) Ximian, Inc.  http://www.ximian.com
-//
-
-namespace System.Collections.Specialized {
-	
-	public class StringCollection {
-	}
-}
+/* System.Collections.Specialized.StringCollection.cs
+ * Authors:
+ *   John Barnette ([email protected])
+ *   Sean MacIsaac ([email protected])
+ *
+ *  Copyright (C) 2001 John Barnette
+ * (C) Ximian, Inc.  http://www.ximian.com
+ *
+ * NOTES:
+ * I bet Microsoft uses ArrayList as a backing store for this; I wonder what
+ * the performance difference will be.
+*/
+
+using System;
+
+namespace System.Collections.Specialized {
+	public class StringCollection : IList, ICollection, IEnumerable {
+		private static int   InitialCapacity    = 11;
+		private static float CapacityMultiplier = 2.0f;
+		
+		private int count;
+		private int modCount;
+		
+		private string[] entries;
+		
+		// Public Constructor
+		public StringCollection() {
+			entries  = new string[InitialCapacity];
+			count    = 0;
+			modCount = 0;
+		}
+		
+		// Public Instance Properties
+		public int Count {
+			get { return count; }
+		}
+		
+		public bool IsFixedSize {
+			get { return false; }
+		}
+		
+		public bool IsReadOnly {
+			get { return false; }
+		}
+		
+		public bool IsSynchronized {
+			get { return false; }
+		}
+		
+		object IList.this[int index] {
+			get { return this[index]; }
+			set { this[index] = value.ToString(); } 
+		}
+		
+		public string this[int index] {
+			get {
+				if (index < 0 || index >= count) {
+					throw new ArgumentOutOfRangeException("index");
+				}
+				
+				return entries[index];
+			}
+			
+			set {
+				if (index < 0 || index >= count) {
+					throw new ArgumentOutOfRangeException("index");
+				}
+				
+				modCount++;
+				entries[index] = value;
+			}
+		}
+		
+		public object SyncRoot {
+			get { return this; }
+		}
+		
+		
+		// Public Instance Methods
+		
+		int IList.Add(object value) {
+			return Add(value.ToString());
+		}
+		
+		public int Add(string value) {
+			modCount++;
+			Resize(count + 1);
+			int index = count++;
+			entries[index] = value;
+			
+			return index;
+		}
+		
+		public void AddRange(string[] value) {
+			int numEntries = value.Length;
+			
+			modCount++;
+			Resize(count + numEntries);
+			Array.Copy(value, 0, entries, count, numEntries);
+			count += numEntries;
+		}
+		
+		public void Clear() {
+			modCount++;
+			count = 0;
+		}
+		
+		bool IList.Contains(object value) {
+			return Contains(value.ToString());
+		}
+		
+		public bool Contains(string value) {
+			foreach (string entry in entries) {
+				if (value.Equals(entry)) {
+					return true;
+				}
+			}
+			
+			return false;
+		}
+		
+		void ICollection.CopyTo(Array array, int index) {
+			if (array == null) {
+				throw new ArgumentNullException("array");
+			} else if (index < 0) {
+				throw new ArgumentOutOfRangeException("index");
+			} else if (array.Rank > 1) {
+				throw new ArgumentException("array");
+			} else if (index >= array.Length) {
+				throw new ArgumentException("index");
+			} else if (array.Length - index < count) {
+				throw new ArgumentException("array");
+			}
+			
+			Array.Copy(entries, 0, array, index, count);
+		}
+		
+		public void CopyTo(string[] array, int index) {
+			if (array == null) {
+				throw new ArgumentNullException("array");
+			} else if (index < 0) {
+				throw new ArgumentOutOfRangeException("index");
+			} else if (array.Rank > 1) {
+				throw new ArgumentException("array");
+			} else if (index >= array.Length) {
+				throw new ArgumentException("index");
+			} else if (array.Length - index < count) {
+				throw new ArgumentException("array");
+			}
+			
+			Array.Copy(entries, 0, array, index, count);
+		}
+		
+		IEnumerator IEnumerable.GetEnumerator() {
+			return new InternalEnumerator(this);
+		}
+		
+		public StringEnumerator GetEnumerator() {
+			return new StringEnumerator(this);
+		}
+		
+		int IList.IndexOf(object value) {
+			return IndexOf(value.ToString());
+		}
+		
+		public int IndexOf(string value) {
+			for (int i = 0; i < count; i++) {
+				if (value.Equals(entries[i])) {
+					return i;
+				}
+			}
+			
+			return -1;
+		}
+		
+		void IList.Insert(int index, object value) {
+			Insert(index, value.ToString());
+		}
+		
+		public void Insert(int index, string value) {
+			if (index < 0 || index > count) {
+				throw new ArgumentOutOfRangeException("index");
+			}
+			
+			modCount++;
+			Resize(count + 1);
+			Array.Copy(entries, index, entries, index + 1, count - index);
+			entries[index] = value;
+			count++;
+		}
+
+		
+		void IList.Remove(object value) {
+			Remove(value.ToString());
+		}
+		
+		public void Remove(string value) {
+			for (int i = 0; i < count; i++) {
+				if (value.Equals(entries[i])) {
+					RemoveAt(i);
+					return;
+				}
+			}
+		}
+		
+		public void RemoveAt(int index) {
+			if (index < 0 || index >= count) {
+				throw new ArgumentOutOfRangeException("index");
+			}
+			
+			int remaining = count - index - 1;
+			
+			modCount++;
+			
+			if (remaining > 0) {
+				Array.Copy(entries, index + 1, entries, index, remaining);
+			}
+			
+			count--;
+			entries[count] = null;
+		}
+		
+		
+		// Private Instance Methods
+		
+		private void Resize(int minSize) {
+			int oldSize = entries.Length;
+			
+			if (minSize > oldSize) {
+				string[] oldEntries = entries;
+				int newSize = (int) (oldEntries.Length * CapacityMultiplier);
+				
+				if (newSize < minSize) newSize = minSize;
+				entries = new string[newSize];
+				Array.Copy(oldEntries, 0, entries, 0, count);
+			}
+		}
+		
+		
+		// Private classes
+		
+		private class InternalEnumerator : IEnumerator {
+			private StringCollection data;
+			private int index;
+			private int myModCount;
+			
+			public InternalEnumerator(StringCollection data) {
+				this.data  = data;
+				myModCount = data.modCount;
+				index      = -1;
+			}
+			
+			
+			// Public Instance Properties
+			
+			public object Current {
+				get {
+					if (myModCount != data.modCount) {
+						throw new InvalidOperationException();
+					} else if (index < 0 || index > data.count - 1) {
+						throw new InvalidOperationException();
+					}
+					
+					return data[index];
+				}
+			}
+			
+			
+			// Public Instance Methods
+			
+			public bool MoveNext() {
+				if (myModCount != data.modCount) {
+					throw new InvalidOperationException();
+				}
+				
+				if (++index >= data.count - 1) {
+					return false;
+				}
+				
+				return true;
+			}
+			
+			public void Reset() {
+				if (myModCount != data.modCount) {
+					throw new InvalidOperationException();
+				}
+				
+				index = -1;
+			}
+		}
+	}
+}

+ 36 - 0
mcs/class/System/System.Collections.Specialized/StringEnumerator.cs

@@ -0,0 +1,36 @@
+/* System.Collections.Specialized.StringEnumerator.cs
+ * Authors:
+ *   John Barnette ([email protected])
+ *
+ *  Copyright (C) 2001 John Barnette
+*/
+
+namespace System.Collections.Specialized {
+	public class StringEnumerator {
+		private StringCollection coll;
+		private IEnumerator enumerable;
+		
+		// assembly-scoped constructor
+		internal StringEnumerator(StringCollection coll) {
+			this.coll = coll;
+			this.enumerable = ((IEnumerable)coll).GetEnumerator();
+		}
+		
+		// Public Instance Properties
+		
+		public string Current {
+			get { return (string) enumerable.Current; }
+		}
+		
+		
+		// Public Instance Methods
+		
+		public bool MoveNext() {
+			return enumerable.MoveNext();
+		}
+		
+		public void Reset() {
+			enumerable.Reset();
+		}
+	}
+}

+ 2 - 0
mcs/class/System/System.Collections.Specialized/common.src

@@ -1,2 +1,4 @@
 BitVector32.cs
 StringCollection.cs
+StringCollection.cs
+StringEnumerator.cs

+ 152 - 0
mcs/class/System/Test/StringCollectionTest.cs

@@ -0,0 +1,152 @@
+/* System.Collections.Specialized.StringCollection.cs
+ * Authors:
+ *   John Barnette ([email protected])
+ *
+ *  Copyright (C) 2001 John Barnette
+*/
+
+using NUnit.Framework;
+
+namespace System.Collections.Specialized {
+	public class StringCollectionTest : TestCase {
+		private StringCollection sc;
+		string[] strings = {
+			"foo",
+			"bar",
+			"baz",
+			"john",
+			"paul",
+			"george",
+			"ringo"
+		};
+		
+		public StringCollectionTest(string name) : base(name) {}
+		
+		protected override void SetUp() {
+			sc = new StringCollection();
+			sc.AddRange(strings);
+		}
+
+		// Simple Tests
+		
+		public void TestSimpleCount() {
+			Assert(sc.Count == 7);
+		}
+		
+		public void TestSimpleIsFixedSize() {
+			Assert(!sc.IsFixedSize);
+		}
+		
+		public void TestSimpleIsReadOnly() {
+			Assert(!sc.IsReadOnly);
+		}
+		
+		public void TestSimpleIsSynchronized() {
+			Assert(!sc.IsSynchronized);
+		}
+		
+		public void TestSimpleItemGet() {
+			for(int i = 0; i < strings.Length; i++) {
+				Assert(strings[i].Equals(sc[i]));
+			}
+		}
+		
+		public void TestSimpleItemSet() {
+			sc[0] = "bob";
+			Assert(sc[0].Equals("bob"));
+		}
+		
+		public void TestSimpleSyncRoot() {
+			Assert(sc.Equals(sc.SyncRoot));
+		}
+		
+		public void TestSimpleAdd() {
+			int index = sc.Add("chuck");
+			Assert(index == strings.Length);
+			Assert(sc[strings.Length].Equals("chuck"));
+			
+		}
+		
+		public void TestSimpleAddRange() {
+			string[] newStrings = {
+				"peter",
+				"paul",
+				"mary"
+			};
+			
+			int index = sc.Count;
+			sc.AddRange(newStrings);
+			
+			Assert(sc.Count == index + newStrings.Length);
+			
+			for (int i = 0; i+index <= sc.Count-1; i++) {
+				Assert(newStrings[i].Equals(sc[i+index]));
+			}
+		}
+		
+		public void TestSimpleClear() {
+			sc.Clear();
+			Assert(sc.Count == 0);
+		}
+		
+		public void TestSimpleContains() {
+			Assert(sc.Contains(strings[0]));
+			Assert(!sc.Contains("NOT CONTAINED"));
+		}
+		
+		public void TestSimpleCopyTo() {
+			string[] copyArray = new string[sc.Count];
+			sc.CopyTo(copyArray, 0);
+			for (int i = 0; i < copyArray.Length; i++) {
+				Assert(copyArray[i] == sc[i]);
+			}
+		}
+		
+		public void TestSimpleGetEnumerator() {
+			int index = 0;
+			foreach(string s in sc) {
+				Assert(s.Equals(strings[index]));
+				index++;
+			}
+		}
+		
+		public void TestSimpleIndexOf() {
+			Assert(sc.IndexOf(strings[0]) == 0);
+		}
+		
+		public void TestSimpleInsert() {
+			int index = 3;
+			int oldCount = sc.Count;
+			string before  = sc[index - 1];
+			string current = sc[index];
+			string after   = sc[index + 1];
+			string newStr  = "paco";
+			
+			sc.Insert(index, newStr);
+			
+			Assert(sc.Count == oldCount + 1);
+			Assert(sc[index].Equals(newStr));
+			Assert(sc[index-1].Equals(before));
+			Assert(sc[index+1].Equals(current));
+			Assert(sc[index+2].Equals(after));
+		}
+		
+		public void TestSimpleRemove() {
+			int oldCount = sc.Count;
+			sc.Remove(strings[0]);
+			Assert(oldCount == sc.Count + 1);
+			Assert(!sc.Contains(strings[0]));
+		}
+		
+		public void TestSimpleRemoveAt() {
+			int index = 3;
+			int oldCount = sc.Count;
+			string after = sc[index+1];
+			
+			sc.RemoveAt(index);
+			Assert(oldCount == sc.Count + 1);
+			Assert(sc[index].Equals(after));
+		}
+			
+	}
+}