wasSharp

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 22  →  ?path2? @ 23
/Collections/Generic/SerializableDictionary.cs
@@ -18,22 +18,58 @@
/// </summary>
/// <typeparam name="TKey">the key</typeparam>
/// <typeparam name="TValue">the value</typeparam>
[XmlRoot("Dictionary")]
public class SerializableDictionary<TKey, TValue>
: Dictionary<TKey, TValue>, IXmlSerializable
{
#region IXmlSerializable Members
public XmlSchema GetSchema()
{
return null;
}
 
public SerializableDictionary(IEnumerable<KeyValuePair<TKey, TValue>> kvp)
public void ReadXml(XmlReader reader)
{
foreach (var i in kvp)
if (reader.IsEmptyElement)
{
Add(i.Key, i.Value);
return;
}
 
reader.ReadStartElement();
while (!reader.NodeType.Equals(XmlNodeType.EndElement))
{
reader.ReadStartElement(ItemNodeName);
 
reader.ReadStartElement(KeyNodeName);
var key = (TKey) KeySerializer.Deserialize(reader);
reader.ReadEndElement();
 
reader.ReadStartElement(ValueNodeName);
var value = (TValue) ValueSerializer.Deserialize(reader);
reader.ReadEndElement();
 
Add(key, value);
 
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
 
public SerializableDictionary()
public void WriteXml(XmlWriter writer)
{
foreach (var key in Keys)
{
writer.WriteStartElement(ItemNodeName);
 
writer.WriteStartElement(KeyNodeName);
KeySerializer.Serialize(writer, key);
writer.WriteEndElement();
 
writer.WriteStartElement(ValueNodeName);
ValueSerializer.Serialize(writer, this[key]);
writer.WriteEndElement();
 
writer.WriteEndElement();
}
}
 
/// <summary>
@@ -45,17 +81,16 @@
SerializableDictionary<TKey, TValue> clone;
try
{
using (var writer = new MemoryStream())
using (var memoryStream = new MemoryStream())
{
var serializer =
new XmlSerializer(
typeof(SerializableDictionary<TKey, TValue>));
serializer.Serialize(writer, this);
writer.Seek(0, SeekOrigin.Begin);
new XmlSerializer(
typeof(SerializableDictionary<TKey, TValue>), new XmlRootAttribute(DictionaryNodeName))
.Serialize(memoryStream, this);
memoryStream.Seek(0, SeekOrigin.Begin);
clone = (SerializableDictionary<TKey, TValue>)
new XmlSerializer(
typeof(SerializableDictionary<TKey, TValue>))
.Deserialize(writer);
typeof(SerializableDictionary<TKey, TValue>), new XmlRootAttribute(DictionaryNodeName))
.Deserialize(memoryStream);
}
}
/* cloning failed so return an empty dictionary */
@@ -66,64 +101,62 @@
return clone;
}
 
public XmlSchema GetSchema()
{
return null;
}
#region Constants
 
public void ReadXml(XmlReader reader)
{
var keySerializer = new XmlSerializer(typeof(TKey));
var valueSerializer = new XmlSerializer(typeof(TValue));
public string DictionaryNodeName { get; set; } = "Dictionary";
public string ItemNodeName { get; set; } = "Item";
public string KeyNodeName { get; set; } = "Key";
public string ValueNodeName { get; set; } = "Value";
 
var wasEmpty = reader.IsEmptyElement;
reader.Read();
#endregion
 
if (wasEmpty)
return;
#region Constructors
 
while (!reader.NodeType.Equals(XmlNodeType.EndElement))
{
reader.ReadStartElement("Item");
public SerializableDictionary()
{
}
 
reader.ReadStartElement("Key");
var key = (TKey) keySerializer.Deserialize(reader);
reader.ReadEndElement();
public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
: base(dictionary)
{
}
 
reader.ReadStartElement("Value");
var value = (TValue) valueSerializer.Deserialize(reader);
reader.ReadEndElement();
public SerializableDictionary(IEqualityComparer<TKey> comparer)
: base(comparer)
{
}
 
Add(key, value);
public SerializableDictionary(int capacity)
: base(capacity)
{
}
 
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
: base(dictionary, comparer)
{
}
 
public void WriteXml(XmlWriter writer)
public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
: base(capacity, comparer)
{
var keySerializer = new XmlSerializer(typeof(TKey));
var valueSerializer = new XmlSerializer(typeof(TValue));
}
 
foreach (var key in Keys)
{
writer.WriteStartElement("Item");
#endregion
 
writer.WriteStartElement("Key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
#region Private Properties
 
writer.WriteStartElement("Value");
var value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
protected XmlSerializer ValueSerializer
=> valueSerializer ?? (valueSerializer = new XmlSerializer(typeof(TValue)));
 
writer.WriteEndElement();
}
}
private XmlSerializer KeySerializer => keySerializer ?? (keySerializer = new XmlSerializer(typeof(TKey)));
 
#endregion
 
#region Private Members
 
private XmlSerializer keySerializer;
private XmlSerializer valueSerializer;
 
#endregion
}
}
/Collections/Specialized/MultiKeyDictionary.cs
@@ -29,15 +29,8 @@
}
}
 
public new IEnumerable<V> Values
{
get
{
return from baseDict in base.Values
from baseKey in baseDict.Keys
select baseDict[baseKey];
}
}
public new IEnumerable<V> Values =>
base.Values.SelectMany(baseDict => baseDict.Keys, (baseDict, baseKey) => baseDict[baseKey]);
 
public void Add(K1 key1, K2 key2, V value)
{
@@ -46,10 +39,29 @@
this[key1][key2] = value;
}
 
public void Remove(K1 key1, K2 key2)
{
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2))
return;
this[key1].Remove(key2);
Remove(key1);
}
 
public bool ContainsKey(K1 key1, K2 key2)
{
return base.ContainsKey(key1) && this[key1].ContainsKey(key2);
return ContainsKey(key1) && this[key1].ContainsKey(key2);
}
 
public bool TryGetValue(K1 key1, K2 key2, out V value)
{
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2))
{
value = default(V);
return false;
}
value = base[key1][key2];
return true;
}
}
 
public class MultiKeyDictionary<K1, K2, K3, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, V>>
@@ -67,8 +79,35 @@
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3)
{
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3);
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3);
}
 
public void Add(K1 key1, K2 key2, K3 key3, V value)
{
if (!ContainsKey(key1))
this[key1] = new MultiKeyDictionary<K2, K3, V>();
this[key1][key2, key3] = value;
}
 
public void Remove(K1 key1, K2 key2, K3 key3)
{
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2, key3))
return;
this[key1][key2].Remove(key3);
this[key1].Remove(key2);
Remove(key1);
}
 
public bool TryGetValue(K1 key1, K2 key2, K3 key3, out V value)
{
if (!ContainsKey(key1) || !this[key1].ContainsKey(key2, key3))
{
value = default(V);
return false;
}
value = base[key1][key2, key3];
return true;
}
}
 
public class MultiKeyDictionary<K1, K2, K3, K4, V> : Dictionary<K1, MultiKeyDictionary<K2, K3, K4, V>>
@@ -86,7 +125,7 @@
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4)
{
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4);
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4);
}
}
 
@@ -105,7 +144,7 @@
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5)
{
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5);
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5);
}
}
 
@@ -125,7 +164,7 @@
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6)
{
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6);
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6);
}
}
 
@@ -145,7 +184,7 @@
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7)
{
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7);
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7);
}
}
 
@@ -165,7 +204,7 @@
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8)
{
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8);
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8);
}
}
 
@@ -185,7 +224,7 @@
 
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9)
{
return base.ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9);
return ContainsKey(key1) && this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9);
}
}
 
@@ -209,7 +248,7 @@
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9,
K10 key10)
{
return base.ContainsKey(key1) &&
return ContainsKey(key1) &&
this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9, key10);
}
}
@@ -237,7 +276,7 @@
public bool ContainsKey(K1 key1, K2 key2, K3 key3, K4 key4, K5 key5, K6 key6, K7 key7, K8 key8, K9 key9,
K10 key10, K11 key11)
{
return base.ContainsKey(key1) &&
return ContainsKey(key1) &&
this[key1].ContainsKey(key2, key3, key4, key5, key6, key7, key8, key9, key10, key11);
}
}
/Collections/Specialized/ObservableHashSet.cs
@@ -19,7 +19,7 @@
/// An implementation of an observable HashSet.
/// </summary>
/// <typeparam name="T">the object type</typeparam>
public class ObservableHashSet<T> : ICollection<T>, INotifyCollectionChanged
public class ObservableHashSet<T> : ICollection<T>, INotifyCollectionChanged, IEnumerable<T>
{
private readonly HashSet<T> store = new HashSet<T>();
 
@@ -132,5 +132,10 @@
removed));
IsVirgin = false;
}
 
public IEnumerable<T> AsEnumerable()
{
return store.AsEnumerable();
}
}
}
/KeyValue.cs
@@ -61,8 +61,7 @@
.AsParallel()
.Select(o => o.Split('='))
.Where(o => o.Length.Equals(2) && !Strings.StringEquals(o[0], key, StringComparison.Ordinal))
.Select(o => string.Join("=", o[0], o[1]))
.ToArray());
.Select(o => string.Join("=", o[0], o[1])));
}
 
///////////////////////////////////////////////////////////////////////////
@@ -84,7 +83,7 @@
v = o[1]
})
.GroupBy(o => o.k)
.ToDictionary(o => o.Key, p => p.First().v);
.ToDictionary(o => o.Key, p => p.FirstOrDefault()?.v);
}
 
///////////////////////////////////////////////////////////////////////////
/NetHash.cs
@@ -0,0 +1,43 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
 
using System.Collections.Generic;
 
namespace wasSharp
{
public struct NetHash
{
private readonly int hashCode;
 
public NetHash(int hashCode = 17)
{
this.hashCode = hashCode;
}
 
public static NetHash Init => new NetHash();
 
public static implicit operator int(NetHash hashCode)
{
return hashCode.GetHashCode();
}
 
public NetHash Hash<T>(T obj)
{
var c = EqualityComparer<T>.Default;
var h = c.Equals(obj, default(T)) ? 0 : obj.GetHashCode();
unchecked
{
h += hashCode*31;
}
return new NetHash(h);
}
 
public override int GetHashCode()
{
return hashCode;
}
}
}
/Properties/AssemblyInfo.cs
@@ -26,4 +26,4 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
 
[assembly: AssemblyVersion("1.38.*")]
[assembly: AssemblyVersion("1.39.*")]
/wasSharp.csproj
@@ -32,6 +32,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="Arrays.cs" />
@@ -51,6 +52,7 @@
<Compile Include="Geo\Distance.cs" />
<Compile Include="Geo\GeodesicExtensions.cs" />
<Compile Include="Geo\GeographicCoordinate.cs" />
<Compile Include="NetHash.cs" />
<Compile Include="IO.cs" />
<Compile Include="KeyValue.cs" />
<Compile Include="Linq.cs" />