2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-27 05:23:13 +00:00
This commit is contained in:
2020-01-26 14:30:39 +03:00
parent 5f4660fde2
commit 61a1683c26
22 changed files with 409 additions and 346 deletions

View File

@ -73,7 +73,9 @@ namespace Esyur.Data
var types = new DataType[keys.Length];
for (var i = 0; i < keys.Length; i++)
types[i] = Codec.GetDataType(structure[keys[i]], connection);
{
types[i] = Codec.GetDataType(structure[keys[i]], connection).type;
}
return types;
}
@ -125,7 +127,7 @@ namespace Esyur.Data
{
if (structures == null || structures?.Length == 0)
return prependLength ? new byte[] { 0, 0, 0, 0 } : new byte[0];
var rt = new BinaryList();
var comparsion = StructureComparisonResult.Structure;
@ -173,8 +175,8 @@ namespace Esyur.Data
var result = (StructureComparisonResult)data[offset++];
AsyncReply<Structure> previous = null;
// string[] previousKeys = null;
// DataType[] previousTypes = null;
// string[] previousKeys = null;
// DataType[] previousTypes = null;
Structure.StructureMetadata metadata = new Structure.StructureMetadata();
@ -188,7 +190,7 @@ namespace Esyur.Data
previous = ParseStructure(data, offset, cs, connection, out metadata);
offset += cs;
}
reply.Add(previous);
@ -382,7 +384,7 @@ namespace Esyur.Data
/// <returns>Value</returns>
public static AsyncReply Parse(byte[] data, uint offset, out uint size, DistributedConnection connection, DataType dataType = DataType.Unspecified)
{
bool isArray;
DataType t;
@ -434,7 +436,7 @@ namespace Esyur.Data
return new AsyncReply<char[]>(data.GetCharArray(offset, contentLength));
case DataType.Int16:
return new AsyncReply<short[]>(data.GetInt16Array( offset, contentLength));
return new AsyncReply<short[]>(data.GetInt16Array(offset, contentLength));
case DataType.UInt16:
return new AsyncReply<ushort[]>(data.GetUInt16Array(offset, contentLength));
@ -595,7 +597,7 @@ namespace Esyur.Data
if (resource is DistributedResource)
if ((resource as DistributedResource).Connection == connection)
return true;
return false;
}
@ -658,7 +660,7 @@ namespace Esyur.Data
rt.AddUInt32((resources[0] as DistributedResource).Id);
else if (comparsion == ResourceComparisonResult.Distributed)
rt.AddUInt32(resources[0].Instance.Id);
for (var i = 1; i < resources.Length; i++)
{
comparsion = Compare(resources[i - 1], resources[i], connection);
@ -756,12 +758,12 @@ namespace Esyur.Data
/// <param name="connection">DistributedConnection is required to check locality.</param>
/// <param name="prependLength">If True, prepend the length as UInt32 at the beginning of the output.</param>
/// <returns>Array of bytes in the network byte order.</returns>
public static byte[] ComposeVarArray(object[] array, DistributedConnection connection, bool prependLength = false)
public static byte[] ComposeVarArray(Array array, DistributedConnection connection, bool prependLength = false)
{
var rt = new List<byte>();
for (var i = 0; i < array.Length; i++)
rt.AddRange(Compose(array[i], connection));
rt.AddRange(Compose(array.GetValue(i), connection));
if (prependLength)
rt.InsertRange(0, DC.ToBytes(rt.Count));
return rt.ToArray();
@ -844,9 +846,9 @@ namespace Esyur.Data
// age, date, value
//if (includeAge)
// return BinaryList.ToBytes(propertyValue.Age, propertyValue.Date, Compose(propertyValue.Value, connection));
// return BinaryList.ToBytes(propertyValue.Age, propertyValue.Date, Compose(propertyValue.Value, connection));
//else
// return BinaryList.ToBytes(propertyValue.Date, Compose(propertyValue.Value, connection));
// return BinaryList.ToBytes(propertyValue.Date, Compose(propertyValue.Value, connection));
}
@ -858,14 +860,14 @@ namespace Esyur.Data
/// <param name="offset">Zero-indexed offset.</param>
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
/// <param name="cs">Output content size.</param>
/// <returns>PropertyValue.</returns>
/// <returns>PropertyValue.</returns>
public static AsyncReply<PropertyValue> ParsePropertyValue(byte[] data, uint offset, out uint cs, DistributedConnection connection)//, bool ageIncluded = true)
{
var reply = new AsyncReply<PropertyValue>();
var age = data.GetUInt64(offset);
offset += 8;
DateTime date = data.GetDateTime(offset);
offset += 8;
@ -928,14 +930,14 @@ namespace Esyur.Data
bagOfBags.Then(x =>
{
for(var i = 0; i < list.Count; i++)
for (var i = 0; i < list.Count; i++)
list[list.Keys.ElementAt(i)] = x[i];
reply.Trigger(list);
});
return reply;
}
/// <summary>
@ -945,7 +947,7 @@ namespace Esyur.Data
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
/// <returns></returns>
public static byte[] ComposeHistory(KeyList<PropertyTemplate, PropertyValue[]> history,
DistributedConnection connection, bool prependLength = false)
DistributedConnection connection, bool prependLength = false)
{
var rt = new BinaryList();
@ -954,7 +956,7 @@ namespace Esyur.Data
.AddUInt8Array(ComposePropertyValueArray(history.Values.ElementAt(i), connection, true));
// rt.Append((byte)history.Keys.ElementAt(i).Index,
// ComposePropertyValueArray(history.Values.ElementAt(i), connection, true));
// ComposePropertyValueArray(history.Values.ElementAt(i), connection, true));
if (prependLength)
rt.InsertInt32(0, rt.Length);
@ -1001,15 +1003,10 @@ namespace Esyur.Data
/// <param name="connection">DistributedConnection is required to check locality.</param>
/// <param name="prependType">If True, prepend the DataType at the beginning of the output.</param>
/// <returns>Array of bytes in the network byte order.</returns>
public static byte[] Compose(object value, DistributedConnection connection, bool prependType = true)
public static byte[] Compose(object valueOrSource, DistributedConnection connection, bool prependType = true)
{
if (value is Func<DistributedConnection, object>)
value = (value as Func<DistributedConnection, object>)(connection);
else if (value is DistributedPropertyContext)
value = (value as DistributedPropertyContext).Method(connection);
var type = GetDataType(value, connection);
var (type, value) = GetDataType(valueOrSource, connection);
var rt = new BinaryList();
switch (type)
@ -1038,7 +1035,7 @@ namespace Esyur.Data
break;
case DataType.VarArray:
rt.AddUInt8Array(ComposeVarArray((object[])value, connection, true));
rt.AddUInt8Array(ComposeVarArray((Array)value, connection, true));
break;
case DataType.ResourceArray:
@ -1115,22 +1112,22 @@ namespace Esyur.Data
*/
//{
while (type != null)
{
if (type == iface)
return true;
while (type != null)
{
if (type == iface)
return true;
#if NETSTANDARD
if (type.GetTypeInfo().GetInterfaces().Contains(iface))
return true;
if (type.GetTypeInfo().GetInterfaces().Contains(iface))
return true;
type = type.GetTypeInfo().BaseType;
type = type.GetTypeInfo().BaseType;
#else
if (type.GetInterfaces().Contains(iface))
return true;
type = type.BaseType;
#endif
}
}
//}
return false;
@ -1165,16 +1162,36 @@ namespace Esyur.Data
/// <param name="value">Value to find its DataType.</param>
/// <param name="connection">DistributedConnection is required to check locality of resources.</param>
/// <returns>DataType.</returns>
public static DataType GetDataType(object value, DistributedConnection connection)
public static (DataType type, object value) GetDataType(object value, DistributedConnection connection)
{
if (value == null)
return DataType.Void;
return (DataType.Void, null);
if (value is IUserType)
value = (value as IUserType).Get();
if (value is Func<DistributedConnection, object>)
//if (connection != null)
value = (value as Func<DistributedConnection, object>)(connection);
//else
// return (DataType.Void, null);
else if (value is DistributedPropertyContext)
//if (connection != null)
value = (value as DistributedPropertyContext).Method(connection);
//else
// return (DataType.Void, null);
if (value == null)
return (DataType.Void, null);
var t = value.GetType();
var isArray = t.IsArray;
if (isArray)
t = t.GetElementType();
t = t.GetElementType();
DataType type;
@ -1208,27 +1225,27 @@ namespace Esyur.Data
type = DataType.String;
else if (t == typeof(DateTime))
type = DataType.DateTime;
else if (t == typeof(Structure))
else if (typeof(Structure).IsAssignableFrom(t))
type = DataType.Structure;
//else if (t == typeof(DistributedResource))
// type = DataType.DistributedResource;
// type = DataType.DistributedResource;
else if (ImplementsInterface(t, typeof(IResource)))
{
if (isArray)
return DataType.ResourceArray;
return (DataType.ResourceArray, value);
else
{
return IsLocalResource((IResource)value, connection) ? DataType.Resource : DataType.DistributedResource;
return (IsLocalResource((IResource)value, connection) ? DataType.Resource : DataType.DistributedResource, value);
}
}
else
type = DataType.Void;
if (isArray)
return (DataType)((byte)type | 0x80);
return ((DataType)((byte)type | 0x80), value);
else
return type;
return (type, value);
}

View File

@ -43,9 +43,13 @@ namespace Esyur.Data
{
public static object CastConvert(object value, Type destinationType)
{
if (value == null)
return null;
//if (destinationType.IsArray && destinationType.GetElementType().IsArray)
// Console.Beep();
var sourceType = value.GetType();
if (destinationType == sourceType)
@ -54,10 +58,9 @@ namespace Esyur.Data
}
else
{
if (sourceType.IsArray)
if (sourceType.IsArray && (destinationType.IsArray || destinationType == typeof(object)))
{
if (destinationType.IsArray)
destinationType = destinationType.GetElementType();
destinationType = destinationType.GetElementType();
var v = value as Array;
@ -65,29 +68,34 @@ namespace Esyur.Data
for (var i = 0; i < rt.Length; i++)
{
try
{
#if NETSTANDARD
if (destinationType.GetTypeInfo().IsInstanceOfType(v.GetValue(i)))
#else
if (destinationType.IsInstanceOfType(v.GetValue(i)))
#endif
rt.SetValue(v.GetValue(i), i);
else
rt.SetValue(Convert.ChangeType(v.GetValue(i), destinationType), i);
}
catch
{
rt.SetValue(null, i);
}
rt.SetValue(CastConvert(v.GetValue(i), destinationType), i);
// try
// {
//#if NETSTANDARD
// if (destinationType.GetTypeInfo().IsInstanceOfType(v.GetValue(i)))
//#else
// if (destinationType.IsInstanceOfType(v.GetValue(i)))
//#endif
// rt.SetValue(v.GetValue(i), i);
// else
// rt.SetValue(Convert.ChangeType(v.GetValue(i), destinationType), i);
// }
// catch
// {
// rt.SetValue(null, i);
// }
}
return rt;
}
else
{
try
{
var underType = Nullable.GetUnderlyingType(destinationType);
if (underType != null)
{
@ -96,15 +104,26 @@ namespace Esyur.Data
else
destinationType = underType;
}
#if NETSTANDARD
if (destinationType.GetTypeInfo().IsInstanceOfType(value))
#else
if (destinationType.IsInstanceOfType(value))
#endif
{
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
{
return Convert.ChangeType(value, destinationType);
}
}
catch
{

12
Esyur/Data/IUserType.cs Normal file
View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esyur.Data
{
public interface IUserType
{
object Get();
void Set(object value);
}
}

View File

@ -47,7 +47,7 @@ namespace Esyur.Data
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);
@ -57,11 +57,33 @@ namespace Esyur.Data
{
var rt = "";
foreach (var kv in dic)
rt += kv.Key + ": " + kv.Value.ToString() + "\r\n";
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)
{