|
|
@@ -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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|