[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] CVS: pnetlib/System/Collections/Specialized NameOb
From: |
Rhys Weatherley <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] CVS: pnetlib/System/Collections/Specialized NameObjectCollectionBase.cs,NONE,1.1 NameValueCollection.cs,1.1,1.2 |
Date: |
Mon, 18 Nov 2002 02:13:23 -0500 |
Update of /cvsroot/dotgnu-pnet/pnetlib/System/Collections/Specialized
In directory subversions:/tmp/cvs-serv18499/System/Collections/Specialized
Modified Files:
NameValueCollection.cs
Added Files:
NameObjectCollectionBase.cs
Log Message:
Implement the "NameValueCollection" class and its supporting structures.
--- NEW FILE ---
/*
* NameObjectCollectionBase.cs - Implementation of
* "System.Collections.Specialized.NameObjectCollectionBase".
*
* Copyright (C) 2002 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
namespace System.Collections.Specialized
{
using System;
using System.Collections;
using System.Runtime.Serialization;
#if !ECMA_COMPAT
public
#else
internal
#endif
abstract class NameObjectCollectionBase
: ICollection, IEnumerable
#if !ECMA_COMPAT
, ISerializable, IDeserializationCallback
#endif
{
// Internal state. We implement our own hash table rather than
// use the Hashtable class, because we have to handle multiple
// values per key, which Hashtable cannot do. Working around
// Hashtable's foibles can give unreliable behaviour as entries
// are added and removed.
private Entry[] table;
private IHashCodeProvider hcp;
private IComparer cmp;
private ArrayList entries;
private bool readOnly;
private const int HashTableSize = 61;
// Constructors.
protected NameObjectCollectionBase()
: this(0, null, null) {}
protected NameObjectCollectionBase(int capacity)
: this(capacity, null, null) {}
protected NameObjectCollectionBase(IHashCodeProvider hashProvider,
IComparer comparer)
: this(0, hashProvider, comparer) {}
protected NameObjectCollectionBase(int capacity,
IHashCodeProvider hashProvider,
IComparer comparer)
{
if(capacity < 0)
{
throw new ArgumentOutOfRangeException
("capacity",
S._("ArgRange_NonNegative"));
}
if(hashProvider == null)
{
hashProvider =
CaseInsensitiveHashCodeProvider.Default;
}
if(comparer == null)
{
comparer =
CaseInsensitiveComparer.Default;
}
table = new Entry [HashTableSize];
hcp = hashProvider;
cmp = comparer;
entries = new ArrayList(capacity);
readOnly = false;
}
#if !ECMA_COMPAT
protected NameObjectCollectionBase(SerializationInfo info,
StreamingContext context)
: this(0, null, null)
{
// TODO: serialization support.
}
#endif
// Properties.
public virtual KeysCollection Keys
{
get
{
// TODO
return null;
}
}
protected virtual bool IsReadOnly
{
get
{
return readOnly;
}
set
{
readOnly = value;
}
}
// Implement the ICollection interface.
public virtual int Count
{
get
{
return entries.Count;
}
}
void ICollection.CopyTo(Array array, int index)
{
foreach(Object obj in this)
{
array.SetValue(obj, index);
++index;
}
}
bool ICollection.IsSynchronized
{
get
{
return false;
}
}
Object ICollection.SyncRoot
{
get
{
return this;
}
}
// Implement the IEnumerator interface.
public IEnumerator GetEnumerator()
{
return new KeysEnumerator(this);
}
#if !ECMA_COMPAT
// Implement the ISerializable interface.
public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
{
// TODO: serialization support.
}
// Implement the IDeserializationCallback interface.
public virtual void OnDeserialization(Object sender)
{
// TODO: serialization support.
}
#endif // !ECMA_COMPAT
// Get the hash value for a string, restricted to the table size.
private int GetHash(String name)
{
int hash = (name != null ?
hcp.GetHashCode(name) : 0);
return (int)(((uint)hash) %
(uint)HashTableSize);
}
// Compare two keys for equality.
private bool Compare(String key1, String key2)
{
if(key1 == null || key2 == null)
{
return (key1 == key2);
}
else
{
return (cmp.Compare(key1, key2) == 0);
}
}
// Add a name/value pair to this collection.
protected void BaseAdd(String name, Object value)
{
if(readOnly)
{
throw new
NotSupportedException(S._("NotSupp_ReadOnly"));
}
Entry entry = new Entry(name, value);
int hash = GetHash(name);
Entry last = table[hash];
if(last == null)
{
table[hash] = entry;
}
else
{
while(last.next != null)
{
last = last.next;
}
last.next = entry;
}
entries.Add(entry);
}
// Clear this collection.
protected void BaseClear()
{
if(readOnly)
{
throw new
NotSupportedException(S._("NotSupp_ReadOnly"));
}
((IList)table).Clear();
entries.Clear();
}
// Get the item at a specific index within this collection.
protected Object BaseGet(int index)
{
return ((Entry)(entries[index])).value;
}
// Get the item associated with a specific name within this collection.
protected Object BaseGet(String name)
{
Entry entry = table[GetHash(name)];
while(entry != null)
{
if(Compare(entry.key, name))
{
return entry.value;
}
entry = entry.next;
}
return null;
}
// Get a list of all keys in the collection.
protected String[] BaseGetAllKeys()
{
String[] keys = new String [entries.Count];
int index = 0;
foreach(Entry entry in entries)
{
keys[index++] = (String)(entry.key);
}
return keys;
}
// Get a list of all values in the collection.
protected Object[] BaseGetAllValues()
{
Object[] values = new String [entries.Count];
int index = 0;
foreach(Entry entry in entries)
{
values[index++] = entry.value;
}
return values;
}
// Get an array of a specific type of all values in the collection.
protected Object[] BaseGetAllValues(Type type)
{
if(type == null)
{
throw new ArgumentNullException("type");
}
Object[] values = (Object[])
Array.CreateInstance(type,
entries.Count);
int index = 0;
foreach(Entry entry in entries)
{
values[index++] = entry.value;
}
return values;
}
// Get the key at a specific index.
protected String BaseGetKey(int index)
{
return ((Entry)(entries[index])).key;
}
// Determine if there a non-null keys in the collection.
protected bool BaseHasKeys()
{
Entry entry = table[GetHash(null)];
while(entry != null)
{
if(entry.key != null)
{
return true;
}
entry = entry.next;
}
return false;
}
// Remove all entries with a specific key.
protected void BaseRemove(String name)
{
if(readOnly)
{
throw new
NotSupportedException(S._("NotSupp_ReadOnly"));
}
int hash = GetHash(name);
Entry entry = table[hash];
Entry prev = null;
while(entry != null)
{
if(Compare(entry.key, name))
{
if(prev != null)
{
prev.next = entry.next;
}
else
{
table[hash] =
entry.next;
}
entry = entry.next;
}
else
{
prev = entry;
entry = entry.next;
}
}
int count = entries.Count;
int posn = 0;
while(posn < count)
{
if(Compare(((Entry)(entries[posn])).key, name))
{
entries.RemoveAt(posn);
--count;
}
else
{
++posn;
}
}
}
// Remove a specific entry by index.
protected void BaseRemoveAt(int index)
{
if(readOnly)
{
throw new
NotSupportedException(S._("NotSupp_ReadOnly"));
}
Entry entry = (Entry)(entries[index]);
entries.RemoveAt(index);
int hash = GetHash(entry.key);
Entry find = table[hash];
Entry prev = null;
while(find != null)
{
if(find == entry)
{
if(prev != null)
{
prev.next = find.next;
}
else
{
table[hash] = find.next;
}
return;
}
else
{
prev = find;
find = find.next;
}
}
}
// Set the value of an entry at a particular index.
protected void BaseSet(int index, Object value)
{
if(readOnly)
{
throw new
NotSupportedException(S._("NotSupp_ReadOnly"));
}
((Entry)(entries[index])).value = value;
}
// Set the value of the first entry with a particular name.
protected void BaseSet(String name, Object value)
{
if(readOnly)
{
throw new
NotSupportedException(S._("NotSupp_ReadOnly"));
}
int hash = GetHash(name);
Entry entry = table[hash];
while(entry != null)
{
if(Compare(entry.key, name))
{
entry.value = value;
return;
}
entry = entry.next;
}
entry = new Entry(name, value);
entry.next = table[hash];
table[hash] = entry;
entries.Add(entry);
}
// Structure of an entry in the collection.
private class Entry
{
public String key;
public Object value;
public Entry next;
// Constructor.
public Entry(String key, Object value)
{
this.key = key;
this.value = value;
this.next = null;
}
}; // class Entry
// Alternate interface to the keys in a name object collection.
public class KeysCollection : ICollection, IEnumerable
{
// Internal state.
private NameObjectCollectionBase c;
// Constructor.
internal KeysCollection(NameObjectCollectionBase c)
{
this.c = c;
}
// Implement the ICollection interface.
public int Count
{
get
{
return c.Count;
}
}
void ICollection.CopyTo(Array array, int index)
{
foreach(Object obj in this)
{
array.SetValue(obj, index);
++index;
}
}
bool ICollection.IsSynchronized
{
get
{
return false;
}
}
Object ICollection.SyncRoot
{
get
{
return c;
}
}
// Implement the IEnumerable interface.
public IEnumerator GetEnumerator()
{
return new KeysEnumerator(c);
}
// Get the key at a specific index.
public String Get(int index)
{
return c.BaseGetKey(index);
}
public String this[int index]
{
get
{
return Get(index);
}
}
}; // class KeysCollection
// Enumerator for the keys in a name object collection.
private class KeysEnumerator : IEnumerator
{
// Internal state.
private IEnumerator e;
// Constructor.
public KeysEnumerator(NameObjectCollectionBase c)
{
e = c.entries.GetEnumerator();
}
// Implement the IEnumerator interface.
bool IEnumerator.MoveNext()
{
return e.MoveNext();
}
void IEnumerator.Reset()
{
e.Reset();
}
Object IEnumerator.Current
{
get
{
return ((Entry)(e.Current)).key;
}
}
}; // class KeysEnumerator
}; // class NameObjectCollectionBase
}; // namespace System.Collections.Specialized
Index: NameValueCollection.cs
===================================================================
RCS file:
/cvsroot/dotgnu-pnet/pnetlib/System/Collections/Specialized/NameValueCollection.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** NameValueCollection.cs 21 Apr 2002 03:24:53 -0000 1.1
--- NameValueCollection.cs 18 Nov 2002 07:13:19 -0000 1.2
***************
*** 25,83 ****
using System;
using System.Collections;
! public class NameValueCollection : ICollection, IEnumerable
{
// Constructors.
! public NameValueCollection() : this(0) {}
! public NameValueCollection(NameValueCollection col) : this(0, col) {}
public NameValueCollection(IHashCodeProvider hashProvider,
IComparer comparer)
! : this(0, hashProvider, comparer) {}
! [TODO]
public NameValueCollection(int capacity)
{
! if(capacity < 0)
! {
! throw new ArgumentOutOfRangeException
! ("capacity",
S._("ArgRange_NonNegative"));
! }
! // TODO
}
- [TODO]
public NameValueCollection(int capacity, NameValueCollection col)
{
! if(capacity < 0)
! {
! throw new ArgumentOutOfRangeException
! ("capacity",
S._("ArgRange_NonNegative"));
! }
! if(col == null)
! {
! throw new ArgumentNullException("col");
! }
! // TODO
}
- [TODO]
public NameValueCollection(int capacity, IHashCodeProvider hashProvider,
IComparer comparer)
{
! if(capacity < 0)
! {
! throw new ArgumentOutOfRangeException
! ("capacity",
S._("ArgRange_NonNegative"));
! }
! // TODO
}
// Add a name/value pair to this collection.
- [TODO]
public virtual void Add(String name, String value)
{
! // TODO
}
// Add the contents of another name/value collection to this collection.
- [TODO]
public void Add(NameValueCollection c)
{
--- 25,104 ----
using System;
using System.Collections;
+ using System.Runtime.Serialization;
+ using System.Text;
! public class NameValueCollection : NameObjectCollectionBase
{
+ // Internal state.
+ private String[] allKeysResult;
+ private String[] copyToResult;
// Constructors.
! public NameValueCollection()
! : base(0, null, null)
! {
! // Nothing to do here.
! }
! public NameValueCollection(NameValueCollection col)
! : base(0, null, null)
! {
! Add(col);
! }
public NameValueCollection(IHashCodeProvider hashProvider,
IComparer comparer)
! : base(0, hashProvider, comparer)
! {
! // Nothing to do here.
! }
public NameValueCollection(int capacity)
+ : base(capacity, null, null)
{
! // Nothing to do here.
}
public NameValueCollection(int capacity, NameValueCollection col)
+ : base(capacity, null, null)
{
! Add(col);
}
public NameValueCollection(int capacity, IHashCodeProvider hashProvider,
IComparer comparer)
+ : base(capacity, hashProvider, comparer)
{
! // Nothing to do here.
}
+ #if !ECMA_COMPAT
+ protected NameValueCollection(SerializationInfo info,
+
StreamingContext context)
+ : base(info, context)
+ {
+ // TODO: serialization support.
+ }
+ #endif
// Add a name/value pair to this collection.
public virtual void Add(String name, String value)
{
! if(IsReadOnly)
! {
! throw new
NotSupportedException(S._("NotSupp_ReadOnly"));
! }
! InvalidateCachedArrays();
! ArrayList strings = (ArrayList)(BaseGet(name));
! if(strings == null)
! {
! strings = new ArrayList(1);
! if(value != null)
! {
! strings.Add(value);
! }
! BaseAdd(name, strings);
! }
! else if(value != null)
! {
! strings.Add(value);
! }
}
// Add the contents of another name/value collection to this collection.
public void Add(NameValueCollection c)
{
***************
*** 86,218 ****
throw new ArgumentNullException("c");
}
! // TODO
}
! // Implement the ICollection interface.
! [TODO]
public void CopyTo(Array array, int index)
{
! // TODO
! }
! int ICollection.Count
! {
! [TODO]
! get
{
! // TODO
! return 0;
}
}
! bool ICollection.IsSynchronized
! {
! [TODO]
! get
! {
! // TODO
! return false;
! }
! }
! Object ICollection.SyncRoot
{
! [TODO]
! get
{
! // TODO
! return this;
}
}
! // Implement the IEnumerable interface.
! [TODO]
! IEnumerator IEnumerable.GetEnumerator()
{
! // TODO
! return null;
}
! // Clear the contents of this collection.
! [TODO]
! public void Clear()
{
! // TODO
}
! // Get a key at a particular index within this collection.
! [TODO]
! public virtual String GetKey(int index)
{
! // TODO
! return null;
}
// Get a value at a particular index within this collection.
- [TODO]
public virtual String Get(int index)
{
! // TODO
! return null;
}
// Get an array of values at a particular index within this collection.
- [TODO]
public virtual String[] GetValues(int index)
{
! // TODO
! return null;
}
// Get the value associcated with a particular name.
- [TODO]
public virtual String Get(String name)
{
! // TODO
! return null;
}
// Get the array of values associcated with a particular name.
- [TODO]
public virtual String[] GetValues(String name)
{
! // TODO
! return null;
}
// Determine if the collection has keys that are not null.
- [TODO]
public bool HasKeys()
{
! // TODO
! return false;
}
// Invalidate cached arrays within this collection.
- [TODO]
protected void InvalidateCachedArrays()
{
! // TODO
}
// Remove an entry with a specified name from this collection.
- [TODO]
public virtual void Remove(String name)
{
! // TODO
}
// Set the value associated with a specified name in this collection.
- [TODO]
public virtual void Set(String name, String value)
{
! // TODO
}
// Get a list of all keys in this collection.
- [TODO]
public virtual String[] AllKeys
{
get
{
! // TODO
! return null;
}
}
--- 107,263 ----
throw new ArgumentNullException("c");
}
! int count = c.Count;
! int posn;
! String name;
! ArrayList strings;
! for(posn = 0; posn < count; ++posn)
! {
! name = c.BaseGetKey(posn);
! strings = (ArrayList)(c.BaseGet(posn));
! foreach(String value in strings)
! {
! Add(name, value);
! }
! }
}
! // Copy the strings in this collection to an array.
public void CopyTo(Array array, int index)
{
! if(copyToResult == null)
{
! int count = Count;
! int posn;
! copyToResult = new String [count];
! for(posn = 0; posn < count; ++posn)
! {
! copyToResult[posn] = Get(posn);
! }
}
+ copyToResult.CopyTo(array, index);
}
!
! // Clear the contents of this collection.
! public void Clear()
{
! if(!IsReadOnly)
{
! InvalidateCachedArrays();
}
+ BaseClear();
}
! // Get a key at a particular index within this collection.
! public virtual String GetKey(int index)
{
! return BaseGetKey(index);
}
! // Collapse an array list of strings into a comma-separated value.
! private static String CollapseToString(ArrayList strings)
{
! int count = strings.Count;
! if(count == 0)
! {
! return null;
! }
! else if(count == 1)
! {
! return (String)(strings[0]);
! }
! else
! {
! StringBuilder builder = new
StringBuilder();
! builder.Append((String)(strings[0]));
! int posn;
! for(posn = 1; posn < count; ++posn)
! {
! builder.Append(',');
!
builder.Append((String)(strings[posn]));
! }
! return builder.ToString();
! }
}
! // Collapse an array list of strings into an array.
! private static String[] CollapseToArray(ArrayList strings)
{
! String[] result = new String [strings.Count];
! strings.CopyTo(result, 0);
! return result;
}
// Get a value at a particular index within this collection.
public virtual String Get(int index)
{
! return
CollapseToString((ArrayList)(BaseGet(index)));
}
// Get an array of values at a particular index within this collection.
public virtual String[] GetValues(int index)
{
! return
CollapseToArray((ArrayList)(BaseGet(index)));
}
// Get the value associcated with a particular name.
public virtual String Get(String name)
{
! return
CollapseToString((ArrayList)(BaseGet(name)));
}
// Get the array of values associcated with a particular name.
public virtual String[] GetValues(String name)
{
! return
CollapseToArray((ArrayList)(BaseGet(name)));
}
// Determine if the collection has keys that are not null.
public bool HasKeys()
{
! return BaseHasKeys();
}
// Invalidate cached arrays within this collection.
protected void InvalidateCachedArrays()
{
! allKeysResult = null;
! copyToResult = null;
}
// Remove an entry with a specified name from this collection.
public virtual void Remove(String name)
{
! if(!IsReadOnly)
! {
! InvalidateCachedArrays();
! }
! BaseRemove(name);
}
// Set the value associated with a specified name in this collection.
public virtual void Set(String name, String value)
{
! if(!IsReadOnly)
! {
! InvalidateCachedArrays();
! }
! ArrayList strings = new ArrayList(1);
! if(value != null)
! {
! strings.Add(value);
! }
! BaseSet(name, strings);
}
// Get a list of all keys in this collection.
public virtual String[] AllKeys
{
get
{
! if(allKeysResult == null)
! {
! allKeysResult =
BaseGetAllKeys();
! }
! return allKeysResult;
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnetlib/System/Collections/Specialized NameObjectCollectionBase.cs,NONE,1.1 NameValueCollection.cs,1.1,1.2,
Rhys Weatherley <address@hidden> <=