mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-06-26 21:13:13 +00:00
Rename
This commit is contained in:
311
Esiur/Data/AutoList.cs
Normal file
311
Esiur/Data/AutoList.cs
Normal file
@ -0,0 +1,311 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using Esiur.Core;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public class AutoList<T, ST> : IEnumerable<T>, ICollection, ICollection<T>
|
||||
{
|
||||
|
||||
private readonly object syncRoot = new object();
|
||||
private List<T> list = new List<T>();
|
||||
|
||||
public delegate void Modified(ST sender, int index, T oldValue, T newValue);
|
||||
public delegate void Added(ST sender, T value);
|
||||
public delegate void Removed(ST sender, T value);
|
||||
public delegate void Cleared(ST sender);
|
||||
|
||||
|
||||
public event Modified OnModified;
|
||||
public event Removed OnRemoved;
|
||||
public event Cleared OnCleared;
|
||||
public event Added OnAdd;
|
||||
|
||||
bool removableList;
|
||||
|
||||
|
||||
public ST State { get; set; }
|
||||
/*
|
||||
IOrderedEnumerable<T> OrderBy<T, TK>(Func<T, TK> keySelector)
|
||||
{
|
||||
return list.OrderBy<T,TK>(keySelector);
|
||||
}
|
||||
*/
|
||||
|
||||
public void Sort()
|
||||
{
|
||||
list.Sort();
|
||||
}
|
||||
|
||||
public void Sort(IComparer<T> comparer)
|
||||
{
|
||||
list.Sort(comparer);
|
||||
}
|
||||
|
||||
public void Sort(Comparison<T> comparison)
|
||||
{
|
||||
list.Sort(comparison);
|
||||
}
|
||||
|
||||
public IEnumerable<T> Where(Func<T, bool> predicate)
|
||||
{
|
||||
return list.Where(predicate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert AutoList to array
|
||||
/// </summary>
|
||||
/// <returns>Array</returns>
|
||||
public T[] ToArray()
|
||||
{
|
||||
// list.OrderBy()
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of AutoList
|
||||
/// </summary>
|
||||
/// <param name="state">State object to be included when an event is raised.</param>
|
||||
public AutoList(ST state)
|
||||
{
|
||||
State = state;
|
||||
#if NETSTANDARD
|
||||
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
|
||||
#else
|
||||
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of AutoList
|
||||
/// </summary>
|
||||
/// <param name="values">Populate the list with items</param>
|
||||
/// <returns></returns>
|
||||
public AutoList(ST state, T[] values)
|
||||
{
|
||||
State = state;
|
||||
#if NETSTANDARD
|
||||
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
|
||||
#else
|
||||
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
|
||||
#endif
|
||||
|
||||
AddRange(values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Synchronization lock of the list
|
||||
/// </summary>
|
||||
public object SyncRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
return syncRoot;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// First item in the list
|
||||
/// </summary>
|
||||
public T First()
|
||||
{
|
||||
return list.First();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an item at a specified index
|
||||
/// </summary>
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return list[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
var oldValue = list[index];
|
||||
|
||||
if (removableList)
|
||||
{
|
||||
if (oldValue != null)
|
||||
((IDestructible)oldValue).OnDestroy -= ItemDestroyed;
|
||||
if (value != null)
|
||||
((IDestructible)value).OnDestroy += ItemDestroyed;
|
||||
}
|
||||
|
||||
lock (syncRoot)
|
||||
list[index] = value;
|
||||
|
||||
OnModified?.Invoke(State, index, oldValue, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add item to the list
|
||||
/// </summary>
|
||||
public void Add(T value)
|
||||
{
|
||||
if (removableList)
|
||||
if (value != null)
|
||||
((IDestructible)value).OnDestroy += ItemDestroyed;
|
||||
|
||||
lock (syncRoot)
|
||||
list.Add(value);
|
||||
|
||||
OnAdd?.Invoke(State, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an array of items to the list
|
||||
/// </summary>
|
||||
public void AddRange(T[] values)
|
||||
{
|
||||
foreach (var v in values)
|
||||
Add(v);
|
||||
}
|
||||
|
||||
private void ItemDestroyed(object sender)
|
||||
{
|
||||
Remove((T)sender);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the list
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
if (removableList)
|
||||
foreach (IDestructible v in list)
|
||||
if (v != null)
|
||||
v.OnDestroy -= ItemDestroyed;
|
||||
|
||||
lock (syncRoot)
|
||||
list.Clear();
|
||||
|
||||
OnCleared?.Invoke(State);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove an item from the list
|
||||
/// <param name="value">Item to remove</param>
|
||||
/// </summary>
|
||||
public bool Remove(T value)
|
||||
{
|
||||
if (!list.Contains(value))
|
||||
return false;
|
||||
|
||||
if (removableList)
|
||||
if (value != null)
|
||||
((IDestructible)value).OnDestroy -= ItemDestroyed;
|
||||
|
||||
lock (syncRoot)
|
||||
list.Remove(value);
|
||||
|
||||
OnRemoved?.Invoke(State, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Number of items in the list
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return list.Count; }
|
||||
}
|
||||
|
||||
public bool IsSynchronized => (list as ICollection).IsSynchronized;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if an item exists in the list
|
||||
/// </summary>
|
||||
/// <param name="value">Item to check if exists</param>
|
||||
public bool Contains(T value)
|
||||
{
|
||||
return list.Contains(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if any item of the given array is in the list
|
||||
/// </summary>
|
||||
/// <param name="values">Array of items</param>
|
||||
public bool ContainsAny(T[] values)
|
||||
{
|
||||
foreach (var v in values)
|
||||
if (list.Contains(v))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if any item of the given list is in the list
|
||||
/// </summary>
|
||||
/// <param name="values">List of items</param>
|
||||
public bool ContainsAny(AutoList<T, ST> values)
|
||||
{
|
||||
foreach (var v in values)
|
||||
if (list.Contains((T)v))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<T>)list).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<T>)list).GetEnumerator();
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
lock (syncRoot)
|
||||
(list as ICollection).CopyTo(array, index);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
lock (syncRoot)
|
||||
list.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
//bool ICollection<T>.Remove(T item)
|
||||
//{
|
||||
// lock(syncRoot)
|
||||
// return Remove(item);
|
||||
//}
|
||||
}
|
||||
}
|
714
Esiur/Data/BinaryList.cs
Normal file
714
Esiur/Data/BinaryList.cs
Normal file
@ -0,0 +1,714 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Esiur.Misc;
|
||||
using System.Reflection;
|
||||
using Esiur.Core;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// BinaryList holds a list of items to be converted to binary for storage and transmission
|
||||
/// </summary>
|
||||
public class BinaryList
|
||||
{
|
||||
private List<byte> list = new List<byte>();
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of BinaryList
|
||||
/// </summary>
|
||||
public BinaryList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Converts parameters to binary in same order
|
||||
/// </summary>
|
||||
/// <param name="values">Variables to convert</param>
|
||||
public static byte[] ToBytes(params object[] values)
|
||||
{
|
||||
var list = new List<byte>();
|
||||
|
||||
foreach (var i in values)
|
||||
{
|
||||
if (i is byte)
|
||||
list.Add((byte)i);
|
||||
else
|
||||
{
|
||||
#if NETSTANDARD
|
||||
MethodInfo mi = typeof(DC).GetTypeInfo().GetMethod("ToBytes", new Type[] { i.GetType() });
|
||||
#else
|
||||
MethodInfo mi = typeof(DC).GetMethod("ToBytes", new Type[] { i.GetType() });
|
||||
#endif
|
||||
if (mi != null)
|
||||
{
|
||||
var b = (byte[])mi.Invoke(null, new object[] { i });
|
||||
list.AddRange(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of BinaryList
|
||||
/// </summary>
|
||||
/// <param name="values">Populate the list items</param>
|
||||
public BinaryList(params object[] values)
|
||||
{
|
||||
AddRange(values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an array of items at the end of the list
|
||||
/// </summary>
|
||||
/// <param name="values">Array of items</param>
|
||||
public void AddRange(object[] values)
|
||||
{
|
||||
foreach (var i in values)
|
||||
{
|
||||
if (i is byte)
|
||||
list.Add((byte)i);
|
||||
else
|
||||
{
|
||||
#if NETSTANDARD
|
||||
MethodInfo mi = typeof(DC).GetTypeInfo().GetMethod("ToBytes", new Type[] { i.GetType() });
|
||||
#else
|
||||
MethodInfo mi = typeof(DC).GetMethod("ToBytes", new Type[] { i.GetType() });
|
||||
#endif
|
||||
if (mi != null)
|
||||
{
|
||||
var b = (byte[])mi.Invoke(null, new object[] {i});
|
||||
list.AddRange(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add multiple items at the end of the list
|
||||
/// </summary>
|
||||
/// <param name="values">Parameters of items</param>
|
||||
public void Append(params object[] values)
|
||||
{
|
||||
AddRange(values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert new items to the list at a specified index
|
||||
/// </summary>
|
||||
/// <param name="offset">Position in the list</param>
|
||||
/// <param name="values">Items to insert</param>
|
||||
public void Insert(int offset, params object[] values)
|
||||
{
|
||||
foreach (var i in values)
|
||||
{
|
||||
if (i is byte)
|
||||
{
|
||||
list.Insert(offset++, (byte)i);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if NETSTANDARD
|
||||
MethodInfo mi = typeof(DC).GetTypeInfo().GetMethod("ToBytes", new Type[] { i.GetType() });
|
||||
#else
|
||||
MethodInfo mi = typeof(DC).GetMethod("ToBytes", new Type[] { i.GetType() });
|
||||
#endif
|
||||
if (mi != null)
|
||||
{
|
||||
var b = (byte[])mi.Invoke(null, new object[] { i });
|
||||
list.InsertRange(offset, b);
|
||||
offset += b.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Number of the items in the list
|
||||
/// </summary>
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return list.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void Append(byte data)
|
||||
{
|
||||
list.Add(data);
|
||||
}
|
||||
|
||||
public void Append(byte[] data)
|
||||
{
|
||||
list.AddRange(data);
|
||||
}
|
||||
|
||||
public void Append(int data)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(data));
|
||||
}
|
||||
|
||||
public void Append(uint data)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(data));
|
||||
}
|
||||
|
||||
public void Append(float data)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(data));
|
||||
}
|
||||
|
||||
public void Append(short data)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(data));
|
||||
}
|
||||
|
||||
public void Append(ushort data)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(data));
|
||||
}
|
||||
|
||||
public void Append(double data)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(data));
|
||||
}
|
||||
|
||||
public void Append(sbyte data)
|
||||
{
|
||||
list.Add((byte)data);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public int Length => list.Count;
|
||||
|
||||
public BinaryList AddDateTime(DateTime value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertDateTime(int position, DateTime value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddDateTimeArray(DateTime[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertDateTimeArray(int position, DateTime[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddGuid(Guid value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertGuid(int position, Guid value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddGuidArray(Guid[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertGuidArray(int position, Guid[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddUInt8Array(byte[] value)
|
||||
{
|
||||
list.AddRange(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList InsertUInt8Array(int position, byte[] value)
|
||||
{
|
||||
list.InsertRange(position, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddHex(string value)
|
||||
{
|
||||
return this.AddUInt8Array(DC.FromHex(value, null));
|
||||
}
|
||||
|
||||
public BinaryList InsertHex(int position, string value)
|
||||
{
|
||||
return this.InsertUInt8Array(position, DC.FromHex(value, null));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public BinaryList AddString(string value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertString(int position, string value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddStringArray(string[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertStringArray(int position, string[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertUInt8(int position, byte value)
|
||||
{
|
||||
list.Insert(position, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddUInt8(byte value)
|
||||
{
|
||||
list.Add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddInt8(sbyte value)
|
||||
{
|
||||
list.Add((byte)value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertInt8(int position, sbyte value)
|
||||
{
|
||||
list.Insert(position, (byte)value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddInt8Array(sbyte[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertInt8Array(int position, sbyte[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddChar(char value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertChar(int position, char value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddCharArray(char[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertCharArray(int position, char[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddBoolean(bool value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertBoolean(int position, bool value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddBooleanArray(bool[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertBooleanArray(int position, bool[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddUInt16(ushort value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
public BinaryList InsertUInt16(int position, ushort value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddUInt16Array(ushort[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertUInt16Array(int position, ushort[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddInt16(short value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertInt16(int position, short value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddInt16Array(short[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertInt16Array(int position, short[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddUInt32(uint value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
public BinaryList InsertUInt32(int position, uint value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddUInt32Array(uint[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
public BinaryList InsertUInt32Array(int position, uint[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddInt32(int value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
public BinaryList InsertInt32(int position, int value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddInt32Array(int[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
public BinaryList InsertInt32Array(int position, int[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddUInt64(ulong value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
public BinaryList InsertUInt64(int position, ulong value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddUInt64Array(ulong[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertUInt64Array(int position, ulong[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public BinaryList AddInt64(long value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertInt64(int position, long value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddInt64Array(long[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertInt64Array(int position, long[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddFloat32(float value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertFloat32(int position, float value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddFloat32Array(float[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertFloat32Array(int position, float[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public BinaryList AddFloat64(double value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertFloat64(int position, double value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList AddFloat64Array(double[] value)
|
||||
{
|
||||
list.AddRange(DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinaryList InsertFloat64Array(int position, double[] value)
|
||||
{
|
||||
list.InsertRange(position, DC.ToBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public BinaryList Add(DataType type, object value)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DataType.Bool:
|
||||
AddBoolean((bool)value);
|
||||
return this;
|
||||
case DataType.BoolArray:
|
||||
AddBooleanArray((bool[])value);
|
||||
return this;
|
||||
case DataType.UInt8:
|
||||
AddUInt8((byte)value);
|
||||
return this;
|
||||
case DataType.UInt8Array:
|
||||
AddUInt8Array((byte[])value);
|
||||
return this;
|
||||
case DataType.Int8:
|
||||
AddInt8((sbyte)value);
|
||||
return this;
|
||||
case DataType.Int8Array:
|
||||
AddInt8Array((sbyte[])value);
|
||||
return this;
|
||||
case DataType.Char:
|
||||
AddChar((char)value);
|
||||
return this;
|
||||
case DataType.CharArray:
|
||||
AddCharArray((char[])value);
|
||||
return this;
|
||||
case DataType.UInt16:
|
||||
AddUInt16((ushort)value);
|
||||
return this;
|
||||
case DataType.UInt16Array:
|
||||
AddUInt16Array((ushort[])value);
|
||||
return this;
|
||||
case DataType.Int16:
|
||||
AddInt16((short)value);
|
||||
return this;
|
||||
case DataType.Int16Array:
|
||||
AddInt16Array((short[])value);
|
||||
return this;
|
||||
case DataType.UInt32:
|
||||
AddUInt32((uint)value);
|
||||
return this;
|
||||
case DataType.UInt32Array:
|
||||
AddUInt32Array((uint[])value);
|
||||
return this;
|
||||
case DataType.Int32:
|
||||
AddInt32((int)value);
|
||||
return this;
|
||||
case DataType.Int32Array:
|
||||
AddInt32Array((int[])value);
|
||||
return this;
|
||||
case DataType.UInt64:
|
||||
AddUInt64((ulong)value);
|
||||
return this;
|
||||
case DataType.UInt64Array:
|
||||
AddUInt64Array((ulong[])value);
|
||||
return this;
|
||||
case DataType.Int64:
|
||||
AddInt64((long)value);
|
||||
return this;
|
||||
case DataType.Int64Array:
|
||||
AddInt64Array((long[])value);
|
||||
return this;
|
||||
|
||||
case DataType.Float32:
|
||||
AddFloat32((float)value);
|
||||
return this;
|
||||
case DataType.Float32Array:
|
||||
AddFloat32Array((float[])value);
|
||||
return this;
|
||||
|
||||
case DataType.Float64:
|
||||
AddFloat64((double)value);
|
||||
return this;
|
||||
case DataType.Float64Array:
|
||||
AddFloat64Array((double[])value);
|
||||
return this;
|
||||
|
||||
case DataType.String:
|
||||
AddString((string)value);
|
||||
return this;
|
||||
case DataType.StringArray:
|
||||
AddStringArray((string[])value);
|
||||
return this;
|
||||
|
||||
case DataType.DateTime:
|
||||
AddDateTime((DateTime)value);
|
||||
return this;
|
||||
case DataType.DateTimeArray:
|
||||
AddDateTimeArray((DateTime[])value);
|
||||
return this;
|
||||
|
||||
default:
|
||||
throw new Exception("Not Implemented " + type.ToString());
|
||||
//return this;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Convert the list to an array of bytes
|
||||
/// </summary>
|
||||
/// <returns>Bytes array</returns>
|
||||
public byte[] ToArray()
|
||||
{
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
public virtual AsyncReply<object[]> Done()
|
||||
{
|
||||
return null;
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
1297
Esiur/Data/Codec.cs
Normal file
1297
Esiur/Data/Codec.cs
Normal file
File diff suppressed because it is too large
Load Diff
985
Esiur/Data/DataConverter.cs
Normal file
985
Esiur/Data/DataConverter.cs
Normal file
@ -0,0 +1,985 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Esiur.Net.IIP;
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Reflection;
|
||||
using Esiur.Data;
|
||||
using Esiur.Core;
|
||||
using Esiur.Resource;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public static class DC // Data Converter
|
||||
{
|
||||
public static object CastConvert(object value, Type destinationType)
|
||||
{
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
var sourceType = value.GetType();
|
||||
|
||||
if (destinationType == sourceType)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sourceType.IsArray && (destinationType.IsArray || destinationType == typeof(object)))
|
||||
{
|
||||
destinationType = destinationType.GetElementType();
|
||||
|
||||
var v = value as Array;
|
||||
|
||||
var rt = Array.CreateInstance(destinationType, v.Length);
|
||||
|
||||
for (var i = 0; i < rt.Length; i++)
|
||||
{
|
||||
rt.SetValue(CastConvert(v.GetValue(i), destinationType), i);
|
||||
}
|
||||
|
||||
return rt;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
var underType = Nullable.GetUnderlyingType(destinationType);
|
||||
if (underType != null)
|
||||
{
|
||||
if (value == null)
|
||||
return null;
|
||||
else
|
||||
destinationType = underType;
|
||||
}
|
||||
|
||||
if (destinationType.IsInstanceOfType(value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
else if (typeof(IUserType).IsAssignableFrom(destinationType))
|
||||
{
|
||||
var rt = Activator.CreateInstance(destinationType) as IUserType;
|
||||
rt.Set(value);
|
||||
return rt;
|
||||
}
|
||||
else if (sourceType == typeof(Structure) && sourceType.IsAssignableFrom(destinationType))
|
||||
{
|
||||
return Structure.FromStructure((Structure)value, destinationType);
|
||||
}
|
||||
else if (destinationType.IsEnum)
|
||||
{
|
||||
return Enum.ToObject(destinationType, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ChangeType(value, destinationType);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] ToBytes(sbyte value)
|
||||
{
|
||||
return new byte[1] { (byte)value };
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(byte value)
|
||||
{
|
||||
return new byte[1] { value };
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(IPAddress ip)
|
||||
{
|
||||
return ip.GetAddressBytes();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(PhysicalAddress mac)
|
||||
{
|
||||
return mac.GetAddressBytes();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(bool value)
|
||||
{
|
||||
return new byte[1] { value ? (byte)1 : (byte)0 };
|
||||
}
|
||||
|
||||
public static byte ToByte(bool value)
|
||||
{
|
||||
return value ? (byte)1 : (byte)0;
|
||||
}
|
||||
|
||||
public static byte ToByte(sbyte value)
|
||||
{
|
||||
return (byte)value;
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(byte[] value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] ToBytes(bool[] value)
|
||||
{
|
||||
|
||||
byte[] ba = new byte[value.Length];
|
||||
|
||||
for (int i = 0; i < ba.Length; i++)
|
||||
ba[i] = DC.ToByte(value[i]);
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(sbyte[] value)
|
||||
{
|
||||
|
||||
byte[] ba = new byte[value.Length];
|
||||
|
||||
for (int i = 0; i < ba.Length; i++)
|
||||
ba[i] = DC.ToByte(value[i]);
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(char value)
|
||||
{
|
||||
byte[] ret = BitConverter.GetBytes(value);
|
||||
Array.Reverse(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(Guid value)
|
||||
{
|
||||
return value.ToByteArray();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(Guid[] value)
|
||||
{
|
||||
var rt = new List<byte>();
|
||||
foreach (var g in value)
|
||||
rt.AddRange(g.ToByteArray());
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(char[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(short[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static byte[] ToBytes(ushort[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static void Append(ref byte[] dst, byte[] src)
|
||||
{
|
||||
Append(ref dst, src, (uint)0, (uint)src.Length);
|
||||
}
|
||||
|
||||
public static void Append(ref byte[] dst, byte[] src, uint srcOffset, uint length)
|
||||
{
|
||||
var dstOffset = dst.Length;
|
||||
Array.Resize<byte>(ref dst, dstOffset + (int)length);
|
||||
Buffer.BlockCopy(src, (int)srcOffset, dst, dstOffset, (int)length);
|
||||
}
|
||||
|
||||
public static byte[] Combine(byte[] src1, uint src1Offset, uint src1Length, byte[] src2, uint src2Offset, uint src2Length)
|
||||
{
|
||||
var rt = new byte[src1Length + src2Length];
|
||||
Buffer.BlockCopy(src1, (int)src1Offset, rt, 0, (int)src1Length);
|
||||
Buffer.BlockCopy(src2, (int)src2Offset, rt, (int)src1Length, (int)src2Length);
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static byte[] Merge(params byte[][] arrays)
|
||||
{
|
||||
var s = arrays.Sum(x => x.Length);
|
||||
var r = new byte[s];
|
||||
var offset = 0;
|
||||
foreach (var array in arrays)
|
||||
{
|
||||
Buffer.BlockCopy(array, 0, r, offset, array.Length);
|
||||
offset += array.Length;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] ToBytes(this int[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(this uint[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(this long[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(this ulong[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(this float[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(this double[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public static byte[] ToBytes(this decimal[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public static byte[] ToBytes(this DateTime[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
rt.AddRange(ToBytes(value[i]));
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public static byte[] ToBytes(this string[] value)
|
||||
{
|
||||
List<byte> rt = new List<byte>();
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
byte[] ba = ToBytes(value[i]);
|
||||
// add string length
|
||||
rt.AddRange(ToBytes(ba.Length));
|
||||
// add encoded string
|
||||
rt.AddRange(ba);
|
||||
}
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static unsafe byte[] ToBytes(this int value)
|
||||
{
|
||||
var rt = new byte[4];
|
||||
byte* p = (byte*)&value;
|
||||
|
||||
rt[0] = *(p + 3);
|
||||
rt[1] = *(p + 2);
|
||||
rt[2] = *(p + 1);
|
||||
rt[3] = *(p + 0);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static unsafe byte[] ToBytes(this short value)
|
||||
{
|
||||
var rt = new byte[2];
|
||||
byte* p = (byte*)&value;
|
||||
|
||||
rt[0] = *(p + 1);
|
||||
rt[1] = *(p + 0);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static unsafe byte[] ToBytes(this float value)
|
||||
|
||||
{
|
||||
var rt = new byte[4];
|
||||
|
||||
//float rt = 0;
|
||||
byte* p = (byte*)&value;
|
||||
rt[0] = *(p + 3);
|
||||
rt[1] = *(p + 2);
|
||||
rt[2] = *(p + 1);
|
||||
rt[3] = *(p);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static byte[] ToBytes(this string value)
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(value);
|
||||
}
|
||||
|
||||
public unsafe static byte[] ToBytes(this double value)
|
||||
{
|
||||
var rt = new byte[8];
|
||||
|
||||
byte* p = (byte*)&value;
|
||||
|
||||
rt[0] = *(p + 7);
|
||||
rt[1] = *(p + 6);
|
||||
rt[2] = *(p + 5);
|
||||
rt[3] = *(p + 4);
|
||||
rt[4] = *(p + 3);
|
||||
rt[5] = *(p + 2);
|
||||
rt[6] = *(p + 1);
|
||||
rt[7] = *(p + 0);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static unsafe byte[] ToBytes(this long value)
|
||||
{
|
||||
var rt = new byte[8];
|
||||
|
||||
byte* p = (byte*)&value;
|
||||
|
||||
rt[0] = *(p + 7);
|
||||
rt[1] = *(p + 6);
|
||||
rt[2] = *(p + 5);
|
||||
rt[3] = *(p + 4);
|
||||
rt[4] = *(p + 3);
|
||||
rt[5] = *(p + 2);
|
||||
rt[6] = *(p + 1);
|
||||
rt[7] = *(p + 0);
|
||||
|
||||
return rt;
|
||||
|
||||
}
|
||||
|
||||
public static unsafe byte[] ToBytes(this DateTime value)
|
||||
{
|
||||
|
||||
var rt = new byte[8];
|
||||
var v = value.ToUniversalTime().Ticks;
|
||||
|
||||
byte* p = (byte*)&v;
|
||||
|
||||
rt[0] = *(p + 7);
|
||||
rt[1] = *(p + 6);
|
||||
rt[2] = *(p + 5);
|
||||
rt[3] = *(p + 4);
|
||||
rt[4] = *(p + 3);
|
||||
rt[5] = *(p + 2);
|
||||
rt[6] = *(p + 1);
|
||||
rt[7] = *(p + 0);
|
||||
|
||||
return rt;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static unsafe byte[] ToBytes(this ulong value)
|
||||
{
|
||||
var rt = new byte[8];
|
||||
|
||||
byte* p = (byte*)&value;
|
||||
|
||||
rt[0] = *(p + 7);
|
||||
rt[1] = *(p + 6);
|
||||
rt[2] = *(p + 5);
|
||||
rt[3] = *(p + 4);
|
||||
rt[4] = *(p + 3);
|
||||
rt[5] = *(p + 2);
|
||||
rt[6] = *(p + 1);
|
||||
rt[7] = *(p + 0);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static unsafe byte[] ToBytes(this uint value)
|
||||
{
|
||||
|
||||
var rt = new byte[4];
|
||||
|
||||
byte* p = (byte*)&value;
|
||||
|
||||
rt[0] = *(p + 3);
|
||||
rt[1] = *(p + 2);
|
||||
rt[2] = *(p + 1);
|
||||
rt[3] = *(p + 0);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static unsafe byte[] ToBytes(this ushort value)
|
||||
{
|
||||
var rt = new byte[2];
|
||||
|
||||
byte* p = (byte*)&value;
|
||||
|
||||
rt[0] = *(p + 1);
|
||||
rt[1] = *(p);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static byte[] ToBytes(this decimal value)
|
||||
{
|
||||
byte[] ret = new byte[0];// BitConverter.GetBytes(value);
|
||||
|
||||
Array.Reverse(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string ToHex(this byte[] ba)
|
||||
{
|
||||
if (ba == null)
|
||||
return "NULL";
|
||||
return ToHex(ba, 0, (uint)ba.Length);
|
||||
}
|
||||
|
||||
public static string ToHex(this byte[] ba, uint offset, uint length, string separator = " ")
|
||||
{
|
||||
StringBuilder hex = new StringBuilder((int)length * 2);
|
||||
|
||||
for (var i = offset; i < offset + length; i++)
|
||||
{
|
||||
hex.AppendFormat("{0:x2}", ba[i]);
|
||||
if (separator != null)
|
||||
hex.Append(separator);
|
||||
}
|
||||
|
||||
return hex.ToString();
|
||||
}
|
||||
|
||||
public static byte[] FromHex(string hexString, string separator = " ")
|
||||
{
|
||||
var rt = new List<byte>();
|
||||
|
||||
if (separator == null)
|
||||
{
|
||||
for (var i = 0; i < hexString.Length; i += 2)
|
||||
rt.Add(Convert.ToByte(hexString.Substring(i, 2), 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
var hexes = hexString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var h in hexes)
|
||||
rt.Add(Convert.ToByte(h, 16));
|
||||
}
|
||||
|
||||
return rt.ToArray();
|
||||
}
|
||||
|
||||
public static string FlagsEnumToString<T>(ulong value)
|
||||
{
|
||||
|
||||
string rt = typeof(T).Name + ":";
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
ulong bit = (ulong)(Convert.ToUInt64(Math.Pow(2, i)) & value);
|
||||
if (bit != 0)
|
||||
{
|
||||
rt += " " + Enum.GetName(typeof(T), bit);
|
||||
}
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static bool TryParse<T>(object Input, out T Results)
|
||||
{
|
||||
try
|
||||
{
|
||||
#if NETSTANDARD
|
||||
var tryParse = typeof(T).GetTypeInfo().GetDeclaredMethod("TryParse");
|
||||
if ((bool)tryParse.Invoke(null, new object[] { Input, null }))
|
||||
{
|
||||
var parse = typeof(T).GetTypeInfo().GetDeclaredMethod("Parse");
|
||||
|
||||
Results = (T)parse.Invoke(null, new object[] { Input });
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if ((bool)typeof(T).InvokeMember("TryParse", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { Input, null }))
|
||||
{
|
||||
Results = (T)typeof(T).InvokeMember("Parse", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { Input });
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
else
|
||||
{
|
||||
Results = default(T);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch //Exception ex)
|
||||
{
|
||||
Results = default(T);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static DateTime FromUnixTime(uint seconds)
|
||||
{
|
||||
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds((double)seconds);
|
||||
}
|
||||
|
||||
public static DateTime FromUnixTime(ulong milliseconds)
|
||||
{
|
||||
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds((double)milliseconds);
|
||||
}
|
||||
|
||||
|
||||
public static sbyte GetInt8(this byte[] data, uint offset)
|
||||
{
|
||||
return (sbyte)data[offset];
|
||||
}
|
||||
|
||||
public static sbyte[] GetInt8Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var rt = new sbyte[length];
|
||||
Buffer.BlockCopy(data, (int)offset, rt, 0, (int)length);
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static byte GetUInt8(this byte[] data, uint offset)
|
||||
{
|
||||
return data[offset];
|
||||
}
|
||||
|
||||
public static byte[] GetUInt8Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var rt = new byte[length];
|
||||
Buffer.BlockCopy(data, (int)offset, rt, 0, (int)length);
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static Int16 GetInt16(this byte[] data, uint offset)
|
||||
{
|
||||
return (Int16)((data[offset] << 8) | data[offset + 1]);
|
||||
}
|
||||
|
||||
public static Int16[] GetInt16Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
|
||||
var rt = new Int16[length / 2];
|
||||
for (var i = offset; i < end; i += 2)
|
||||
rt[j++] = GetInt16(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static UInt16 GetUInt16(this byte[] data, uint offset)
|
||||
{
|
||||
return (UInt16)((data[offset] << 8) | data[offset + 1]);
|
||||
}
|
||||
|
||||
public static UInt16[] GetUInt16Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new UInt16[length / 2];
|
||||
|
||||
for (var i = offset; i < end; i += 2)
|
||||
rt[j++] = GetUInt16(data, i);
|
||||
|
||||
return rt;
|
||||
|
||||
}
|
||||
|
||||
public static Int32 GetInt32(this byte[] data, uint offset)
|
||||
{
|
||||
return (Int32)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]);
|
||||
}
|
||||
|
||||
public static Int32[] GetInt32Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
|
||||
var rt = new Int32[length / 4];
|
||||
for (var i = offset; i < end; i += 4)
|
||||
rt[j++] = GetInt32(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static UInt32 GetUInt32(this byte[] data, uint offset)
|
||||
{
|
||||
return (UInt32)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]);
|
||||
}
|
||||
|
||||
public static UInt32[] GetUInt32Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new UInt32[length / 4];
|
||||
|
||||
for (var i = offset; i < end; i += 4)
|
||||
rt[j++] = GetUInt16(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
public static unsafe UInt64 GetUInt64(this byte[] data, uint offset)
|
||||
{
|
||||
UInt64 rt = 0;
|
||||
byte* p = (byte*)&rt;
|
||||
|
||||
*(p + 7) = data[offset++];
|
||||
*(p + 6) = data[offset++];
|
||||
*(p + 5) = data[offset++];
|
||||
*(p + 4) = data[offset++];
|
||||
*(p + 3) = data[offset++];
|
||||
*(p + 2) = data[offset++];
|
||||
*(p + 1) = data[offset++];
|
||||
*(p) = data[offset++];
|
||||
|
||||
return rt;
|
||||
|
||||
}
|
||||
|
||||
public static Int64[] GetInt64Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new Int64[length / 8];
|
||||
|
||||
for (var i = offset; i < end; i += 8)
|
||||
rt[j++] = GetInt64(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static unsafe Int64 GetInt64(this byte[] data, uint offset)
|
||||
{
|
||||
Int64 rt = 0;
|
||||
byte* p = (byte*)&rt;
|
||||
|
||||
*(p + 7) = data[offset++];
|
||||
*(p + 6) = data[offset++];
|
||||
*(p + 5) = data[offset++];
|
||||
*(p + 4) = data[offset++];
|
||||
*(p + 3) = data[offset++];
|
||||
*(p + 2) = data[offset++];
|
||||
*(p + 1) = data[offset++];
|
||||
*(p) = data[offset++];
|
||||
|
||||
return rt;
|
||||
|
||||
/* Or
|
||||
return (Int64)(
|
||||
(data[offset] << 56)
|
||||
| (data[offset + 1] << 48)
|
||||
| (data[offset + 2] << 40)
|
||||
| (data[offset + 3] << 32)
|
||||
| (data[offset + 4] << 24)
|
||||
| (data[offset + 5] << 16)
|
||||
| (data[offset + 6] << 8)
|
||||
| (data[offset + 7])
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
public static UInt64[] GetUInt64Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new UInt64[length / 8];
|
||||
|
||||
for (var i = offset; i < end; i += 8)
|
||||
rt[j++] = GetUInt64(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static unsafe float GetFloat32(this byte[] data, uint offset)
|
||||
{
|
||||
float rt = 0;
|
||||
byte* p = (byte*)&rt;
|
||||
*p = data[offset + 3];
|
||||
*(p + 1) = data[offset + 2];
|
||||
*(p + 2) = data[offset + 1];
|
||||
*(p + 3) = data[offset];
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static float[] GetFloat32Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new float[length / 4];
|
||||
|
||||
for (var i = offset; i < end; i += 4)
|
||||
rt[j++] = GetFloat32(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static unsafe double GetFloat64(this byte[] data, uint offset)
|
||||
{
|
||||
double rt = 0;
|
||||
byte* p = (byte*)&rt;
|
||||
|
||||
*(p + 7) = data[offset++];
|
||||
*(p + 6) = data[offset++];
|
||||
*(p + 5) = data[offset++];
|
||||
*(p + 4) = data[offset++];
|
||||
*(p + 3) = data[offset++];
|
||||
*(p + 2) = data[offset++];
|
||||
*(p + 1) = data[offset++];
|
||||
*(p) = data[offset++];
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static double[] GetFloat64Array(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new double[length / 8];
|
||||
|
||||
for (var i = offset; i < end; i += 8)
|
||||
rt[j++] = GetFloat64(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static bool GetBoolean(this byte[] data, uint offset)
|
||||
{
|
||||
return data[offset] > 0;
|
||||
}
|
||||
|
||||
public static bool[] GetBooleanArray(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var rt = new bool[length];
|
||||
for (var i = 0; i < length; i++)
|
||||
rt[i] = data[offset + i] > 0;
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static char GetChar(this byte[] data, uint offset)
|
||||
{
|
||||
return Convert.ToChar(((data[offset] << 8) | data[offset + 1]));
|
||||
}
|
||||
|
||||
public static char[] GetCharArray(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new char[length / 2];
|
||||
|
||||
for (var i = offset; i < end; i += 2)
|
||||
rt[j++] = GetChar(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static string GetString(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
return Encoding.UTF8.GetString(data, (int)offset, (int)length);
|
||||
}
|
||||
|
||||
public static string[] GetStringArray(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
List<string> ar = new List<string>();
|
||||
|
||||
uint i = 0;
|
||||
|
||||
while (i < length)
|
||||
{
|
||||
var cl = GetUInt32(data, offset + i);
|
||||
i += 4;
|
||||
ar.Add(Encoding.UTF8.GetString(data, (int)(offset + i), (int)cl));
|
||||
i += cl;
|
||||
}
|
||||
|
||||
return ar.ToArray();
|
||||
}
|
||||
|
||||
public static Guid GetGuid(this byte[] data, uint offset)
|
||||
{
|
||||
return new Guid(Clip(data, offset, 16));
|
||||
}
|
||||
|
||||
public static Guid[] GetGuidArray(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new Guid[length / 16];
|
||||
|
||||
for (var i = offset; i < end; i += 16)
|
||||
rt[j++] = GetGuid(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static DateTime GetDateTime(this byte[] data, uint offset)
|
||||
{
|
||||
var ticks = GetInt64(data, offset);
|
||||
return new DateTime(ticks, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
public static DateTime[] GetDateTimeArray(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new DateTime[length / 8];
|
||||
|
||||
for (var i = offset; i < end; i += 8)
|
||||
rt[j++] = GetDateTime(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static IPAddress GetIPv4Address(this byte[] data, uint offset)
|
||||
{
|
||||
return new IPAddress((long)GetUInt32(data, offset));
|
||||
}
|
||||
|
||||
public static IPAddress[] GetIPv4AddressArray(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new IPAddress[length / 4];
|
||||
|
||||
for (var i = offset; i < end; i += 4)
|
||||
rt[j++] = GetIPv6Address(data, i);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static IPAddress GetIPv6Address(this byte[] data, uint offset)
|
||||
{
|
||||
return new IPAddress(Clip(data, offset, 16));
|
||||
}
|
||||
|
||||
public static IPAddress[] GetIPv6AddressArray(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
var j = 0; var end = offset + length;
|
||||
var rt = new IPAddress[length / 16];
|
||||
|
||||
for (var i = offset; i < end; i += 16)
|
||||
rt[j++] = GetIPv6Address(data, i);
|
||||
|
||||
return rt;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static byte[] Clip(this byte[] data, uint offset, uint length)
|
||||
{
|
||||
if (data.Length < offset + length)
|
||||
return null;
|
||||
|
||||
// if (length == data.Length && offset == 0)
|
||||
// return data.ToArray();
|
||||
|
||||
var b = new byte[length];
|
||||
Buffer.BlockCopy(data, (int)offset, b, 0, (int)length);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static string ToISODateTime(this DateTime date)
|
||||
{
|
||||
return date.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
public static uint ToUnixTime(this DateTime date)
|
||||
{
|
||||
return (uint)(date - new DateTime(1970, 1, 1)).TotalSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
119
Esiur/Data/DataType.cs
Normal file
119
Esiur/Data/DataType.cs
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public enum DataType : byte
|
||||
{
|
||||
Void = 0x0,
|
||||
//Variant,
|
||||
Bool,
|
||||
Int8,
|
||||
UInt8,
|
||||
Char,
|
||||
Int16,
|
||||
UInt16,
|
||||
Int32,
|
||||
UInt32,
|
||||
Int64,
|
||||
UInt64,
|
||||
Float32,
|
||||
Float64,
|
||||
Decimal,
|
||||
DateTime,
|
||||
Resource,
|
||||
DistributedResource,
|
||||
ResourceLink,
|
||||
String,
|
||||
Structure,
|
||||
//Stream,
|
||||
//Array = 0x80,
|
||||
VarArray = 0x80,
|
||||
BoolArray,
|
||||
Int8Array,
|
||||
UInt8Array,
|
||||
CharArray,
|
||||
Int16Array,
|
||||
UInt16Array,
|
||||
Int32Array,
|
||||
UInt32Array,
|
||||
Int64Array,
|
||||
UInt64Array,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
DecimalArray,
|
||||
DateTimeArray,
|
||||
ResourceArray,
|
||||
DistributedResourceArray,
|
||||
ResourceLinkArray,
|
||||
StringArray,
|
||||
StructureArray,
|
||||
NotModified = 0x7f,
|
||||
Unspecified = 0xff,
|
||||
}
|
||||
|
||||
public static class DataTypeExpansions
|
||||
{
|
||||
public static int Size(this DataType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case DataType.Void:
|
||||
case DataType.NotModified:
|
||||
return 0;
|
||||
case DataType.Bool:
|
||||
case DataType.UInt8:
|
||||
case DataType.Int8:
|
||||
return 1;
|
||||
case DataType.Char:
|
||||
case DataType.UInt16:
|
||||
case DataType.Int16:
|
||||
return 2;
|
||||
case DataType.Int32:
|
||||
case DataType.UInt32:
|
||||
case DataType.Float32:
|
||||
case DataType.Resource:
|
||||
return 4;
|
||||
case DataType.Int64:
|
||||
case DataType.UInt64:
|
||||
case DataType.Float64:
|
||||
case DataType.DateTime:
|
||||
return 8;
|
||||
case DataType.DistributedResource:
|
||||
return 4;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
12
Esiur/Data/IUserType.cs
Normal file
12
Esiur/Data/IUserType.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public interface IUserType
|
||||
{
|
||||
object Get();
|
||||
void Set(object value);
|
||||
}
|
||||
}
|
244
Esiur/Data/KeyList.cs
Normal file
244
Esiur/Data/KeyList.cs
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Esiur.Core;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
|
||||
public class KeyList<KT, T> : IEnumerable<KeyValuePair<KT, T>>
|
||||
{
|
||||
private readonly object syncRoot = new object();
|
||||
private Dictionary<KT, T> dic;
|
||||
|
||||
public delegate void Modified(KT key, T oldValue, T newValue, KeyList<KT, T> sender);
|
||||
public delegate void Added(T value, KeyList<KT, T> sender);
|
||||
public delegate void Removed(KT key, T value, KeyList<KT, T> sender);
|
||||
public delegate void Cleared(KeyList<KT, T> sender);
|
||||
|
||||
public event Modified OnModified;
|
||||
public event Removed OnRemoved;
|
||||
public event Cleared OnCleared;
|
||||
public event Added OnAdd;
|
||||
|
||||
bool removableList;
|
||||
|
||||
public object SyncRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
return syncRoot;
|
||||
}
|
||||
}
|
||||
|
||||
public T Take(KT key)
|
||||
{
|
||||
if (dic.ContainsKey(key))
|
||||
{
|
||||
var v = dic[key];
|
||||
Remove(key);
|
||||
return v;
|
||||
}
|
||||
else
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public void Sort(Func<KeyValuePair<KT, T>, object> keySelector)
|
||||
{
|
||||
dic = dic.OrderBy(keySelector).ToDictionary(x => x.Key, x => x.Value);
|
||||
}
|
||||
|
||||
public T[] ToArray()
|
||||
{
|
||||
var a = new T[Count];
|
||||
dic.Values.CopyTo(a, 0);
|
||||
return a;
|
||||
}
|
||||
|
||||
public void Add(KT key, T value)
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
if (removableList)
|
||||
if (value != null)
|
||||
((IDestructible)value).OnDestroy += ItemDestroyed;
|
||||
|
||||
if (dic.ContainsKey(key))
|
||||
{
|
||||
var oldValue = dic[key];
|
||||
if (removableList)
|
||||
if (oldValue != null)
|
||||
((IDestructible)oldValue).OnDestroy -= ItemDestroyed;
|
||||
dic[key] = value;
|
||||
if (OnModified != null)
|
||||
OnModified(key, oldValue, value, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
dic.Add(key, value);
|
||||
|
||||
if (OnAdd != null)
|
||||
OnAdd(value, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ItemDestroyed(object sender)
|
||||
{
|
||||
RemoveValue((T)sender);
|
||||
}
|
||||
|
||||
public void RemoveValue(T value)
|
||||
{
|
||||
var toRemove = new List<KT>();
|
||||
foreach (var kv in dic)
|
||||
if (kv.Value.Equals(value))
|
||||
toRemove.Add(kv.Key);
|
||||
|
||||
foreach (var k in toRemove)
|
||||
Remove(k);
|
||||
}
|
||||
|
||||
public T this[KT key]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (dic.ContainsKey(key))
|
||||
return dic[key];
|
||||
else
|
||||
return default(T);
|
||||
}
|
||||
set
|
||||
{
|
||||
Add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IEnumerator<KeyValuePair<KT, T>> GetEnumerator()
|
||||
{
|
||||
return dic.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return dic.GetEnumerator();
|
||||
}
|
||||
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (removableList)
|
||||
foreach (IDestructible v in dic.Values)
|
||||
if (v != null)
|
||||
v.OnDestroy -= ItemDestroyed;
|
||||
|
||||
lock (syncRoot)
|
||||
dic.Clear();
|
||||
|
||||
if (OnCleared != null)
|
||||
OnCleared(this);
|
||||
}
|
||||
|
||||
public Dictionary<KT, T>.KeyCollection Keys
|
||||
{
|
||||
get { return dic.Keys; }
|
||||
}
|
||||
|
||||
public Dictionary<KT, T>.ValueCollection Values
|
||||
{
|
||||
get
|
||||
{
|
||||
return dic.Values;
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(KT key)
|
||||
{
|
||||
if (!dic.ContainsKey(key))
|
||||
return;
|
||||
|
||||
var value = dic[key];
|
||||
|
||||
if (removableList)
|
||||
if (value != null)
|
||||
((IDestructible)value).OnDestroy -= ItemDestroyed;
|
||||
|
||||
lock (syncRoot)
|
||||
dic.Remove(key);
|
||||
|
||||
if (OnRemoved != null)
|
||||
OnRemoved(key, value, this);
|
||||
}
|
||||
|
||||
public object Owner
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return dic.Count; }
|
||||
}
|
||||
public bool Contains(KT Key)
|
||||
{
|
||||
return dic.ContainsKey(Key);
|
||||
}
|
||||
public bool ContainsKey(KT Key)
|
||||
{
|
||||
return dic.ContainsKey(Key);
|
||||
}
|
||||
public bool ContainsValue(T Value)
|
||||
{
|
||||
return dic.ContainsValue(Value);
|
||||
}
|
||||
|
||||
|
||||
public KeyList(object owner = null)
|
||||
{
|
||||
#if NETSTANDARD
|
||||
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
|
||||
#else
|
||||
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
|
||||
#endif
|
||||
|
||||
this.Owner = owner;
|
||||
|
||||
if (typeof(KT) == typeof(string))
|
||||
dic = (Dictionary<KT, T>)(object)new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
|
||||
else
|
||||
dic = new Dictionary<KT, T>();
|
||||
}
|
||||
}
|
||||
}
|
37
Esiur/Data/NotModified.cs
Normal file
37
Esiur/Data/NotModified.cs
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public class NotModified
|
||||
{
|
||||
|
||||
}
|
||||
}
|
35
Esiur/Data/PropertyValue.cs
Normal file
35
Esiur/Data/PropertyValue.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public class PropertyValue
|
||||
{
|
||||
/// <summary>
|
||||
/// Get or set the value.
|
||||
/// </summary>
|
||||
public object Value { get; set; }
|
||||
/// <summary>
|
||||
/// Get or set date of modification or occurrence.
|
||||
/// </summary>
|
||||
public DateTime Date { get; set; }
|
||||
/// <summary>
|
||||
/// Get or set property age.
|
||||
/// </summary>
|
||||
public ulong Age { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of PropertyValue.
|
||||
/// </summary>
|
||||
/// <param name="value">Value.</param>
|
||||
/// <param name="age">Age.</param>
|
||||
/// <param name="date">Date.</param>
|
||||
public PropertyValue(object value, ulong age, DateTime date)
|
||||
{
|
||||
Value = value;
|
||||
Age = age;
|
||||
Date = date;
|
||||
}
|
||||
}
|
||||
}
|
274
Esiur/Data/ResourceList.cs
Normal file
274
Esiur/Data/ResourceList.cs
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using Esiur.Core;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public class ResourceList<T, ST> : IEnumerable<T>, ICollection, ICollection<T>
|
||||
{
|
||||
|
||||
private readonly object syncRoot = new object();
|
||||
private List<T> list = new List<T>();
|
||||
|
||||
public delegate void Modified(ST sender, int index, T oldValue, T newValue);
|
||||
public delegate void Added(ST sender, T value);
|
||||
public delegate void Removed(ST sender, int index, T value);
|
||||
public delegate void Cleared(ST sender);
|
||||
|
||||
|
||||
public event Modified OnModified;
|
||||
public event Removed OnRemoved;
|
||||
public event Cleared OnCleared;
|
||||
public event Added OnAdd;
|
||||
|
||||
ST state;
|
||||
|
||||
public void Sort()
|
||||
{
|
||||
list.Sort();
|
||||
}
|
||||
|
||||
public void Sort(IComparer<T> comparer)
|
||||
{
|
||||
list.Sort(comparer);
|
||||
}
|
||||
|
||||
public void Sort(Comparison<T> comparison)
|
||||
{
|
||||
list.Sort(comparison);
|
||||
}
|
||||
|
||||
public IEnumerable<T> Where(Func<T, bool> predicate)
|
||||
{
|
||||
return list.Where(predicate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert AutoList to array
|
||||
/// </summary>
|
||||
/// <returns>Array</returns>
|
||||
public T[] ToArray()
|
||||
{
|
||||
// list.OrderBy()
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of AutoList
|
||||
/// </summary>
|
||||
/// <param name="state">State object to be included when an event is raised.</param>
|
||||
public ResourceList(ST state)
|
||||
{
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of AutoList
|
||||
/// </summary>
|
||||
/// <param name="values">Populate the list with items</param>
|
||||
/// <returns></returns>
|
||||
public ResourceList(ST state, T[] values)
|
||||
{
|
||||
this.state = state;
|
||||
AddRange(values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Synchronization lock of the list
|
||||
/// </summary>
|
||||
public object SyncRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
return syncRoot;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// First item in the list
|
||||
/// </summary>
|
||||
public T First()
|
||||
{
|
||||
return list.First();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an item at a specified index
|
||||
/// </summary>
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return list[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
var oldValue = list[index];
|
||||
|
||||
lock (syncRoot)
|
||||
list[index] = value;
|
||||
|
||||
OnModified?.Invoke(state, index, oldValue, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add item to the list
|
||||
/// </summary>
|
||||
public void Add(T value)
|
||||
{
|
||||
lock (syncRoot)
|
||||
list.Add(value);
|
||||
|
||||
OnAdd?.Invoke(state, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an array of items to the list
|
||||
/// </summary>
|
||||
public void AddRange(T[] values)
|
||||
{
|
||||
foreach (var v in values)
|
||||
Add(v);
|
||||
}
|
||||
|
||||
private void ItemDestroyed(object sender)
|
||||
{
|
||||
Remove((T)sender);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the list
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
|
||||
lock (syncRoot)
|
||||
list.Clear();
|
||||
|
||||
OnCleared?.Invoke(state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove an item from the list
|
||||
/// <param name="value">Item to remove</param>
|
||||
/// </summary>
|
||||
public void Remove(T value)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
lock (syncRoot)
|
||||
{
|
||||
index = list.IndexOf(value);
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
list.RemoveAt(index);
|
||||
|
||||
|
||||
}
|
||||
|
||||
OnRemoved?.Invoke(state, index, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Number of items in the list
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return list.Count; }
|
||||
}
|
||||
|
||||
public bool IsSynchronized => (list as ICollection).IsSynchronized;
|
||||
|
||||
public bool IsReadOnly => throw new NotImplementedException();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if an item exists in the list
|
||||
/// </summary>
|
||||
/// <param name="value">Item to check if exists</param>
|
||||
public bool Contains(T value)
|
||||
{
|
||||
return list.Contains(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if any item of the given array is in the list
|
||||
/// </summary>
|
||||
/// <param name="values">Array of items</param>
|
||||
public bool ContainsAny(T[] values)
|
||||
{
|
||||
foreach (var v in values)
|
||||
if (list.Contains(v))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if any item of the given list is in the list
|
||||
/// </summary>
|
||||
/// <param name="values">List of items</param>
|
||||
public bool ContainsAny(AutoList<T, ST> values)
|
||||
{
|
||||
foreach (var v in values)
|
||||
if (list.Contains((T)v))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<T>)list).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<T>)list).GetEnumerator();
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
(list as ICollection).CopyTo(array, index);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
list.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
bool ICollection<T>.Remove(T item)
|
||||
{
|
||||
return list.Remove(item);
|
||||
}
|
||||
}
|
||||
}
|
220
Esiur/Data/StringKeyList.cs
Normal file
220
Esiur/Data/StringKeyList.cs
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
|
||||
public class StringKeyList : IEnumerable<KeyValuePair<string, string>>
|
||||
{
|
||||
|
||||
//private List<string> m_keys = new List<string>();
|
||||
//private List<string> m_values = new List<string>();
|
||||
|
||||
private List<KeyValuePair<string, string>> m_Variables = new List<KeyValuePair<string, string>>();
|
||||
|
||||
private bool allowMultiple;
|
||||
|
||||
public delegate void Modified(string Key, string NewValue);
|
||||
public event Modified OnModified;
|
||||
|
||||
public StringKeyList(bool AllowMultipleValues = false)
|
||||
{
|
||||
allowMultiple = AllowMultipleValues;
|
||||
}
|
||||
|
||||
public void Add(string Key, string Value)
|
||||
{
|
||||
if (OnModified != null)
|
||||
OnModified(Key, Value);
|
||||
|
||||
var key = Key.ToLower();
|
||||
|
||||
if (!allowMultiple)
|
||||
{
|
||||
foreach(var kv in m_Variables)
|
||||
{
|
||||
if (kv.Key.ToLower() == key)
|
||||
{
|
||||
m_Variables.Remove(kv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_Variables.Add(new KeyValuePair<string, string>(Key, Value));
|
||||
}
|
||||
|
||||
public string this[string Key]
|
||||
{
|
||||
get
|
||||
{
|
||||
var key = Key.ToLower();
|
||||
foreach (var kv in m_Variables)
|
||||
if (kv.Key.ToLower() == key)
|
||||
return kv.Value;
|
||||
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
var key = Key.ToLower();
|
||||
|
||||
var toRemove = m_Variables.Where(x => x.Key.ToLower() == key).ToArray();
|
||||
|
||||
foreach (var item in toRemove)
|
||||
m_Variables.Remove(item);
|
||||
|
||||
|
||||
m_Variables.Add(new KeyValuePair<string, string>(Key, value));
|
||||
|
||||
OnModified?.Invoke(Key, value);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
|
||||
{
|
||||
//return m_keys.GetEnumerator();
|
||||
return m_Variables.GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return m_Variables.GetEnumerator();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (OnModified != null)
|
||||
OnModified(null, null);
|
||||
|
||||
m_Variables.Clear();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
public string[] Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_keys.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//public Dictionary<string, string>.ValueCollection Values
|
||||
public string[] Values
|
||||
{
|
||||
get
|
||||
{
|
||||
//return m_Variables.Values;
|
||||
return m_values.ToArray();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public List<string> GetValues(string Key)
|
||||
{
|
||||
var key = Key.ToLower();
|
||||
|
||||
List<string> values = new List<string>();
|
||||
|
||||
foreach (var kv in m_Variables)
|
||||
if (kv.Key.ToLower() == key)
|
||||
values.Add(kv.Value);
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public void RemoveAll(string Key)
|
||||
{
|
||||
while (Remove(Key)){}
|
||||
}
|
||||
|
||||
public bool Remove(string Key)
|
||||
{
|
||||
var key = Key.ToLower();
|
||||
|
||||
foreach(var kv in m_Variables)
|
||||
{
|
||||
if (kv.Key.ToLower() == key)
|
||||
{
|
||||
if (OnModified != null)
|
||||
OnModified(Key, null);
|
||||
m_Variables.Remove(kv);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return m_Variables.Count; }
|
||||
}
|
||||
|
||||
public bool ContainsKey(string Key)
|
||||
{
|
||||
var key = Key.ToLower();
|
||||
foreach (var kv in m_Variables)
|
||||
if (kv.Key.ToLower() == key)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
public bool ContainsKey(string Key)
|
||||
{
|
||||
//return m_Variables.ContainsKey(Key);
|
||||
return m_keys.Contains(Key.ToLower());
|
||||
}
|
||||
*/
|
||||
|
||||
public bool ContainsValue(string Value)
|
||||
{
|
||||
var value = Value.ToLower();
|
||||
foreach (var kv in m_Variables)
|
||||
if (kv.Value.ToLower() == value)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//internal KeyList()
|
||||
//{
|
||||
// m_Session = Session;
|
||||
// m_Server = Server;
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
166
Esiur/Data/Structure.cs
Normal file
166
Esiur/Data/Structure.cs
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Esiur.Data;
|
||||
using Esiur.Misc;
|
||||
using Esiur.Core;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Esiur.Data
|
||||
{
|
||||
public class Structure : IEnumerable<KeyValuePair<string, object>>
|
||||
{
|
||||
|
||||
public struct StructureMetadata
|
||||
{
|
||||
public string[] Keys;
|
||||
public DataType[] Types;
|
||||
}
|
||||
|
||||
private Dictionary<string, object> dic = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
private object syncRoot = new object();
|
||||
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return dic.ContainsKey(key);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var rt = "";
|
||||
foreach (var kv in dic)
|
||||
rt += kv.Key + ": " + kv.Value.ToString() + " \r\n";
|
||||
|
||||
return rt.TrimEnd('\r', '\n');
|
||||
}
|
||||
|
||||
public Structure(Structure source)
|
||||
{
|
||||
dic = source.dic;
|
||||
}
|
||||
public Structure()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static Structure FromStructure(Structure source, Type destinationType)
|
||||
{
|
||||
var rt = Activator.CreateInstance(destinationType) as Structure;
|
||||
rt.dic = source.dic;
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static T FromStructure<T>(Structure source) where T : Structure
|
||||
{
|
||||
var rt = Activator.CreateInstance<T>();
|
||||
rt.dic = source.dic;
|
||||
return rt;
|
||||
}
|
||||
|
||||
public static Structure FromObject(object obj)
|
||||
{
|
||||
var type = obj.GetType();
|
||||
|
||||
if (obj is Structure)
|
||||
return obj as Structure;
|
||||
else //if (Codec.IsAnonymous(type))
|
||||
{
|
||||
var st = new Structure();
|
||||
|
||||
var pi = type.GetTypeInfo().GetProperties().Where(x=>x.CanRead);
|
||||
foreach (var p in pi)
|
||||
st[p.Name] = p.GetValue(obj);
|
||||
|
||||
return st;
|
||||
}
|
||||
//else
|
||||
// return null;
|
||||
}
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
return dic.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return dic.GetEnumerator();
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return dic.Count; }
|
||||
}
|
||||
|
||||
public KeyValuePair<string, object> At(int index)
|
||||
{
|
||||
return dic.ElementAt(index);
|
||||
}
|
||||
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return syncRoot; }
|
||||
}
|
||||
|
||||
public string[] GetKeys() => dic.Keys.ToArray();//GetKeys()
|
||||
//{
|
||||
// return dic.Keys.ToArray();
|
||||
//}
|
||||
|
||||
public Structure Add(string key, object value)
|
||||
{
|
||||
if (dic.ContainsKey(key))
|
||||
dic[key] = value;
|
||||
else
|
||||
dic.Add(key, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public object this[string index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (dic.ContainsKey(index))
|
||||
return dic[index];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (dic.ContainsKey(index))
|
||||
dic[index] = value;
|
||||
else
|
||||
dic.Add(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user