XmlRpcStruct derives from Hashtable and so the ordering of the entries in
the collection depends on the hash value of each entry.
The XML-RPC spec doesn't say anything about the ordering of members in an
XML-RPC struct value but it is generally assumed that no ordering is
implied and struct is represented as a dictionary type of collection. But I
suppose you could argue that the ordering should correspond to that in the
XML-RPC struct. I just wrote the version of XmlRpcStruct.cs below which
implements the enumerator so the ordering is preserved. I've not fully
tested it but it could be a starting point for what you need. I'll add an
enhancement request to add this to the library later.
using System;
using System.Collections;
namespace CookComputing.XmlRpc
{
public class XmlRpcStruct : Hashtable
{
private ArrayList _keys = new ArrayList();
private ArrayList _values = new ArrayList();
public override void Add(object key, object value)
{
if (!(key is string))
{
throw new ArgumentException("XmlRpcStruct key must be a string.");
}
if (XmlRpcServiceInfo.GetXmlRpcType(value.GetType())
== XmlRpcType.tInvalid)
{
throw new ArgumentException(String.Format(
"Type {0} cannot be mapped to an XML-RPC type", value.GetType()));
}
base.Add(key, value);
_keys.Add(key);
_values.Add(value);
}
public override object this[object key]
{
get
{
return base[key];
}
set
{
if (!(key is string))
{
throw new ArgumentException("XmlRpcStruct key must be a string.");
}
if (XmlRpcServiceInfo.GetXmlRpcType(value.GetType())
== XmlRpcType.tInvalid)
{
throw new ArgumentException(String.Format(
"Type {0} cannot be mapped to an XML-RPC type", value.GetType()));
}
base[key] = value;
}
}
public override bool Equals(Object obj)
{
if (obj.GetType() != typeof(XmlRpcStruct))
return false;
XmlRpcStruct xmlRpcStruct = (XmlRpcStruct)obj;
if (this.Keys.Count != xmlRpcStruct.Count)
return false;
foreach (String key in this.Keys)
{
if (!xmlRpcStruct.ContainsKey(key))
return false;
if (!this[key].Equals(xmlRpcStruct[key]))
return false;
}
return true;
}
public override int GetHashCode()
{
int hash = 0;
foreach (object obj in Values)
{
hash ^= obj.GetHashCode();
}
return hash;
}
public override void Clear()
{
base.Clear();
_keys.Clear();
_values.Clear();
}
public override IDictionaryEnumerator GetEnumerator()
{
return new XmlRpcStruct.Enumerator(_keys, _values);
}
public override ICollection Keys
{
get
{
return _keys;
}
}
public override void Remove(object key)
{
base.Remove(key);
int idx = _keys.IndexOf(key);
if (idx >= 0)
{
_keys.RemoveAt(idx);
_values.RemoveAt(idx);
}
}
public override ICollection Values
{
get
{
return _values;
}
}
private class Enumerator : IDictionaryEnumerator
{
private ArrayList _keys;
private ArrayList _values;
private int _index;
public Enumerator(ArrayList keys, ArrayList values)
{
_keys = keys;
_values = values;
_index = -1;
}
public void Reset()
{
_index = -1;
}
public object Current
{
get { return new DictionaryEntry(_keys[_index], _values[_index]); }
}
public bool MoveNext()
{
_index++;
if (_index >= _keys.Count)
return false;
else
return true;
}
public DictionaryEntry Entry
{
get { return new DictionaryEntry(_keys[_index], _values[_index]); }
}
public object Key
{
get { return _keys[_index]; }
}
public object Value
{
get { return _values[_index]; }
}
}
}
}
Original issue reported on code.google.com by ChasC...@gmail.com on 3 Aug 2009 at 8:45
Original issue reported on code.google.com by
ChasC...@gmail.com
on 3 Aug 2009 at 8:45