Harald Wolff 2019-10-07 13:14:52 +02:00
commit a3b0745d95
9 changed files with 210 additions and 30 deletions

View File

@ -17,7 +17,7 @@ namespace ln.types.collections
public V this[K key]
{
get
{
{
if (TryGetValue(key, out V value))
return value;
throw new KeyNotFoundException();
@ -28,9 +28,16 @@ namespace ln.types.collections
}
}
private WeakKeyValuePair<K, V> FindKeyValuePair(K key)
public virtual bool KeyEquals(K key1,K key2)
{
return object.Equals(key1, key2);
}
public virtual int GetKeyHashcode(K key) => key.GetHashCode();
private WeakKeyValuePair<K, V> FindKeyValuePair(K key)
{
int keyHashCode = key.GetHashCode();
int keyHashCode = GetKeyHashcode(key);
if (store.ContainsKey(keyHashCode))
foreach (WeakKeyValuePair<K, V> weakKeyValuePair in store[keyHashCode].ToArray())
{
@ -39,7 +46,7 @@ namespace ln.types.collections
{
store.Remove(keyHashCode, weakKeyValuePair);
}
else if (Object.Equals(key, weakKey))
else if (KeyEquals(key, weakKey))
{
return weakKeyValuePair;
}

View File

@ -0,0 +1,31 @@
// /**
// * File: WeakKeyReferenceDictionary.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Runtime.CompilerServices;
namespace ln.types.collections
{
public class WeakKeyReferenceDictionary<K,V> : WeakKeyDictionary<K,V> where K:class
{
public WeakKeyReferenceDictionary()
{
}
public override bool KeyEquals(K key1, K key2)
{
return Object.ReferenceEquals(key1, key2);
}
public override int GetKeyHashcode(K key)
{
return RuntimeHelpers.GetHashCode(key);
}
}
}

View File

@ -124,6 +124,8 @@
<Compile Include="test\Test.cs" />
<Compile Include="collections\WeakValueDictionary.cs" />
<Compile Include="test\WeakValueDictionaryTests.cs" />
<Compile Include="collections\WeakKeyReferenceDictionary.cs" />
<Compile Include="odb\values\ODBByteBuffer.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="odb\" />

View File

@ -8,7 +8,7 @@ namespace ln.types.net
{
public class IPv6
{
public static readonly IPv6 ANY = new IPv6();
public static readonly IPv6 ANY = Parse("::/0");
public static readonly IPv6 V4Space = Parse("::ffff:0:0/96");
readonly UInt16[] value;
@ -44,14 +44,23 @@ namespace ln.types.net
public IPv6(byte[] bytes)
:this()
{
if (bytes.Length == 16)
{
for (int n = 0; n < 8; n++)
{
value[n] = (ushort)((bytes[(n << 1) + 0] << 8) | bytes[(n << 1) + 0]);
}
mask = 128;
} else if (bytes.Length == 4)
if (bytes.Length == 16)
{
for (int n = 0; n < 8; n++)
{
value[n] = (ushort)((bytes[(n << 1) + 0] << 8) | bytes[(n << 1) + 1]);
}
mask = 128;
}
else if (bytes.Length == 17)
{
for (int n = 0; n < 8; n++)
{
value[n] = (ushort)((bytes[(n << 1) + 0] << 8) | bytes[(n << 1) + 1]);
}
mask = bytes[16];
}
else if (bytes.Length == 4)
{
value[5] = 0xffff;
value[6] = (ushort)((bytes[0] << 8) | bytes[1]);
@ -90,20 +99,33 @@ namespace ln.types.net
return Network.Equals(ipNetwork);
}
public byte[] ToBytes()
{
byte[] bytes = new byte[16];
public byte[] ToBytes()
{
byte[] bytes = new byte[16];
for (int n = 0; n < 8; n++)
{
bytes[(n << 1) + 1] = (byte)((value[n] >> 0) & 0xff);
bytes[(n << 1) + 0] = (byte)((value[n] >> 8) & 0xff);
}
for (int n = 0; n < 8; n++)
{
bytes[(n << 1) + 1] = (byte)((value[n] >> 0) & 0xff);
bytes[(n << 1) + 0] = (byte)((value[n] >> 8) & 0xff);
}
return bytes;
}
return bytes;
}
public byte[] ToCIDRBytes()
{
byte[] bytes = new byte[17];
public IEnumerable<IPv6> Split(int splitWidth)
for (int n = 0; n < 8; n++)
{
bytes[(n << 1) + 1] = (byte)((value[n] >> 0) & 0xff);
bytes[(n << 1) + 0] = (byte)((value[n] >> 8) & 0xff);
}
bytes[16] = mask.GetBytes()[0];
return bytes;
}
public IEnumerable<IPv6> Split(int splitWidth)
{
List<IPv6> splitted = new List<IPv6>();
@ -287,7 +309,7 @@ namespace ln.types.net
if (obj is IPv6)
{
return value.SequenceEqual((obj as IPv6).value);
return value.SequenceEqual((obj as IPv6).value) && Equals(mask,(obj as IPv6).mask) ;
}
return false;
}

View File

@ -107,6 +107,11 @@ namespace ln.types.odb.ng
RegisterMapping<IPv4>(
(mapper, value) => new ODBUInteger(value.AsUInt),
(mapper, oval) => new IPv4(oval.As<uint>())
);
RegisterMapping<IPv6>(
(mapper, value) => new ODBByteBuffer(value.ToCIDRBytes()),
(mapper, oval) => new IPv6((oval.As<byte[]>()))
);
ObjectMapping = new mappings.ObjectMapping();

View File

@ -11,7 +11,7 @@ namespace ln.types.odb.ng.mappings
public class ClassMapping : IODBMapping
{
WeakKeyDictionary<object, Guid> reverseCache = new WeakKeyDictionary<object, Guid>();
WeakKeyReferenceDictionary<object, Guid> reverseCache = new WeakKeyReferenceDictionary<object, Guid>();
WeakValueDictionary<Guid, object> forwardCache = new WeakValueDictionary<Guid, object>();
public delegate object GetID(object o);
@ -36,9 +36,6 @@ namespace ln.types.odb.ng.mappings
{
mappedFields.Add(fieldinfo);
}
//foreach (PropertyInfo propInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
//{
//}
if ((type != null) && !type.IsValueType && (!typeof(object).Equals(type.BaseType)))
{

View File

@ -0,0 +1,59 @@
// /**
// * File: ODBByteBuffer.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
namespace ln.types.odb.values
{
public class ODBByteBuffer : ODBValue
{
public byte[] GetBytes() => (byte[])Value;
public ODBByteBuffer(byte[] bytes)
: base(0x0800, bytes.Slice(0))
{
}
public override object As(Type targetType)
{
if (typeof(byte[]).Equals(targetType))
return GetBytes();
throw new InvalidCastException();
}
public override byte[] GetStorageBytes() => GetBytes();
protected override int compare(ODBEntity other)
{
ODBByteBuffer you = other as ODBByteBuffer;
byte[] myBytes = GetBytes();
byte[] yourBytes = you.GetBytes();
int dl = myBytes.Length - yourBytes.Length;
if (dl != 0)
return dl;
while (dl < myBytes.Length)
{
int d = myBytes[dl] - yourBytes[dl++];
if (d != 0)
return d;
}
return 0;
}
static ODBByteBuffer()
{
RegisterDeserializer(0x0800, (storageBytes, offset, length) => new ODBByteBuffer(storageBytes.Slice(offset, length)));
}
}
}

View File

@ -24,6 +24,8 @@ using System.Text;
*
* 0x0020 ODBTypedMapping
*
* 0x0800 ODBByteBuffer
*
* 0x1000 ODBDocument
* 0x1001 Document (ln.types.odb.ng)
*
@ -212,6 +214,7 @@ namespace ln.types.odb.values
RuntimeHelpers.RunClassConstructor(typeof(ODBDouble).TypeHandle);
RuntimeHelpers.RunClassConstructor(typeof(ODBGuid).TypeHandle);
RuntimeHelpers.RunClassConstructor(typeof(ODBBool).TypeHandle);
RuntimeHelpers.RunClassConstructor(typeof(ODBByteBuffer).TypeHandle);
}
}
}

View File

@ -1,7 +1,8 @@
using NUnit.Framework;
using System;
using ln.types.net;
using System.Linq;
using System.Collections.Generic;
namespace ln.types.test
{
[TestFixture()]
@ -36,6 +37,59 @@ namespace ln.types.test
IPv6 ipv6 = IPv6.Parse("::/128") + 1;
Assert.AreEqual(ipv6, localhostv6);
}
{
Stack<IPv6> expectedNetworks = new Stack<IPv6>();
expectedNetworks.Push(IPv6.Parse("255.255.0.0/16"));
expectedNetworks.Push(IPv6.Parse("255.254.0.0/15"));
expectedNetworks.Push(IPv6.Parse("255.252.0.0/14"));
expectedNetworks.Push(IPv6.Parse("255.248.0.0/13"));
expectedNetworks.Push(IPv6.Parse("255.240.0.0/12"));
expectedNetworks.Push(IPv6.Parse("255.224.0.0/11"));
expectedNetworks.Push(IPv6.Parse("255.192.0.0/10"));
expectedNetworks.Push(IPv6.Parse("255.128.0.0/9"));
expectedNetworks.Push(IPv6.Parse("255.0.0.0/8"));
expectedNetworks.Push(IPv6.Parse("254.0.0.0/7"));
expectedNetworks.Push(IPv6.Parse("252.0.0.0/6"));
expectedNetworks.Push(IPv6.Parse("248.0.0.0/5"));
expectedNetworks.Push(IPv6.Parse("240.0.0.0/4"));
expectedNetworks.Push(IPv6.Parse("224.0.0.0/3"));
expectedNetworks.Push(IPv6.Parse("192.0.0.0/2"));
expectedNetworks.Push(IPv6.Parse("128.0.0.0/1"));
IPv6 pool = IPv6.V4Space;
for (int n = 0; n < 16; n++)
{
IPv6 expected = expectedNetworks.Pop();
Assert.IsTrue(pool.Contains(expected));
IPv6[] split = pool.Split(1).ToArray();
Assert.AreEqual(2, split.Length);
Assert.AreEqual(expected, split[1]);
pool = split[1];
}
IPv6 find = IPv6.Parse("10.117.0.0/16");
pool = IPv6.V4Space;
for (int n = 0; n < 16; n++)
{
IPv6[] split = pool.Split(1).ToArray();
Console.WriteLine("{0} => {1} / {2}", pool.ToCIDR(), split[0].ToCIDR(), split[1].ToCIDR());
if (split[0].Contains(find))
pool = split[0];
else
pool = split[1];
Console.WriteLine("using {0}", pool.ToCIDR());
}
}
}
}
}