mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-07 12:02:59 +00:00
2.2
This commit is contained in:
parent
530df018ec
commit
9a174f406f
@ -39,6 +39,11 @@ public class EntityStore : IStore
|
|||||||
{
|
{
|
||||||
public Instance Instance { get; set; }
|
public Instance Instance { get; set; }
|
||||||
|
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
|
|
||||||
|
public bool Initialized => initialized;
|
||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
Dictionary<Type, Dictionary<object, WeakReference>> DB = new Dictionary<Type, Dictionary<object, WeakReference>>();
|
Dictionary<Type, Dictionary<object, WeakReference>> DB = new Dictionary<Type, Dictionary<object, WeakReference>>();
|
||||||
@ -92,6 +97,9 @@ public class EntityStore : IStore
|
|||||||
|
|
||||||
public IResource GetById(Type type, object id)
|
public IResource GetById(Type type, object id)
|
||||||
{
|
{
|
||||||
|
if (!initialized)
|
||||||
|
throw new Exception("Store not initalized. Make sure the Warehouse is open.");
|
||||||
|
|
||||||
lock (DBLock)
|
lock (DBLock)
|
||||||
{
|
{
|
||||||
if (!DB[type].ContainsKey(id))
|
if (!DB[type].ContainsKey(id))
|
||||||
@ -136,13 +144,13 @@ public class EntityStore : IStore
|
|||||||
return this.Instance.Name + "/" + type.Name;
|
return this.Instance.Name + "/" + type.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
//throw new NotImplementedException();
|
//throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
//throw new NotImplementedException();
|
//throw new NotImplementedException();
|
||||||
@ -201,6 +209,8 @@ public class EntityStore : IStore
|
|||||||
|
|
||||||
|
|
||||||
ReloadModel();
|
ReloadModel();
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<Product>Esiur Entity Framework Extension</Product>
|
<Product>Esiur Entity Framework Extension</Product>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<PackageId>Esiur.Stores.EntityCore</PackageId>
|
<PackageId>Esiur.Stores.EntityCore</PackageId>
|
||||||
<Version>1.2.5</Version>
|
<Version>1.2.9</Version>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
|
||||||
<PackageReference Include="System.Collections" Version="4.3.0" />
|
<PackageReference Include="System.Collections" Version="4.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -54,6 +54,8 @@ public static class EsiurExtensions
|
|||||||
{
|
{
|
||||||
var store = dbSet.GetInfrastructure().GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>().Store;
|
var store = dbSet.GetInfrastructure().GetService<IDbContextOptions>().FindExtension<EsiurExtensionOptions>().Store;
|
||||||
|
|
||||||
|
if (!store.Initialized)
|
||||||
|
throw new Exception("Store not initialized. Make sure the Warehouse is open");
|
||||||
|
|
||||||
var manager = store.Instance.Managers.FirstOrDefault();// > 0 ? store.Instance.Managers.First() : null;
|
var manager = store.Instance.Managers.FirstOrDefault();// > 0 ? store.Instance.Managers.First() : null;
|
||||||
|
|
||||||
@ -75,7 +77,7 @@ public static class EsiurExtensions
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = Activator.CreateInstance(proxyType) as IResource;
|
res = Activator.CreateInstance(proxyType) as IResource;
|
||||||
var ps = Structure.FromObject(resource);
|
var ps = Map<string,object>.FromObject(resource);
|
||||||
|
|
||||||
foreach (var p in ps)
|
foreach (var p in ps)
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/esiur/esiur-dotnet/</RepositoryUrl>
|
<RepositoryUrl>https://github.com/esiur/esiur-dotnet/</RepositoryUrl>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<Version>1.5.2</Version>
|
<Version>1.5.4</Version>
|
||||||
<PackageId>Esiur.Stores.MongoDB</PackageId>
|
<PackageId>Esiur.Stores.MongoDB</PackageId>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -83,7 +83,7 @@ public class MongoDBStore : IStore
|
|||||||
|
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime date)
|
public bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? date)
|
||||||
{
|
{
|
||||||
var objectId = resource.Instance.Variables["objectId"].ToString();
|
var objectId = resource.Instance.Variables["objectId"].ToString();
|
||||||
//var bsonObjectId = new BsonObjectId(new ObjectId(objectId));
|
//var bsonObjectId = new BsonObjectId(new ObjectId(objectId));
|
||||||
@ -168,7 +168,7 @@ public class MongoDBStore : IStore
|
|||||||
|
|
||||||
var attributes = Parse(document["attributes"]).Then(x =>
|
var attributes = Parse(document["attributes"]).Then(x =>
|
||||||
{
|
{
|
||||||
resource.Instance.SetAttributes(x as Structure);
|
resource.Instance.SetAttributes(x as Map<string, object>);
|
||||||
});
|
});
|
||||||
|
|
||||||
// var bag = new AsyncBag<object>();
|
// var bag = new AsyncBag<object>();
|
||||||
@ -230,10 +230,10 @@ public class MongoDBStore : IStore
|
|||||||
else if (doc["type"] == 1)
|
else if (doc["type"] == 1)
|
||||||
{
|
{
|
||||||
var bag = new AsyncBag<object>();
|
var bag = new AsyncBag<object>();
|
||||||
var rt = new AsyncReply<Structure>();
|
var rt = new AsyncReply<Map<string, object>>();
|
||||||
|
|
||||||
var bs = (BsonDocument)doc["values"].AsBsonDocument;
|
var bs = (BsonDocument)doc["values"].AsBsonDocument;
|
||||||
var s = new Structure();
|
var s = new Map<string, object>();
|
||||||
|
|
||||||
foreach (var v in bs)
|
foreach (var v in bs)
|
||||||
bag.Add(Parse(v.Value));
|
bag.Add(Parse(v.Value));
|
||||||
@ -414,7 +414,7 @@ public class MongoDBStore : IStore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsonDocument ComposeStructure(Structure value)
|
public BsonDocument ComposeStructure(Map<string, object> value)
|
||||||
{
|
{
|
||||||
var rt = new BsonDocument { { "type", 1 } };
|
var rt = new BsonDocument { { "type", 1 } };
|
||||||
|
|
||||||
@ -436,7 +436,7 @@ public class MongoDBStore : IStore
|
|||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
BsonArray ComposeStructureArray(Structure[] structures)
|
BsonArray ComposeStructureArray(Map<string, object>[] structures)
|
||||||
{
|
{
|
||||||
var rt = new BsonArray();
|
var rt = new BsonArray();
|
||||||
|
|
||||||
@ -466,44 +466,48 @@ public class MongoDBStore : IStore
|
|||||||
|
|
||||||
private BsonValue Compose(object valueObj)
|
private BsonValue Compose(object valueObj)
|
||||||
{
|
{
|
||||||
var (type, value) = Codec.GetDataType(valueObj, null);
|
|
||||||
|
|
||||||
switch (type)
|
//@TODO : Rewrite
|
||||||
{
|
//var (type, value) = Tra Codec.GetDataType(valueObj, null);
|
||||||
case DataType.Void:
|
|
||||||
// nothing to do;
|
|
||||||
return BsonNull.Value;
|
|
||||||
|
|
||||||
case DataType.String:
|
//switch (type)
|
||||||
return new BsonString((string)value);
|
//{
|
||||||
|
// case DataType.Void:
|
||||||
|
// // nothing to do;
|
||||||
|
// return BsonNull.Value;
|
||||||
|
|
||||||
case DataType.Resource:
|
// case DataType.String:
|
||||||
case DataType.DistributedResource:
|
// return new BsonString((string)value);
|
||||||
|
|
||||||
return new BsonDocument { { "type", 0 }, { "link", (value as IResource).Instance.Link } };
|
// case DataType.Resource:
|
||||||
|
// case DataType.DistributedResource:
|
||||||
|
|
||||||
//return new BsonObjectId(new ObjectId((string)(value as IResource).Instance.Variables["objectId"]));
|
// return new BsonDocument { { "type", 0 }, { "link", (value as IResource).Instance.Link } };
|
||||||
|
|
||||||
case DataType.Structure:
|
// //return new BsonObjectId(new ObjectId((string)(value as IResource).Instance.Variables["objectId"]));
|
||||||
return ComposeStructure((Structure)value);
|
|
||||||
|
|
||||||
case DataType.VarArray:
|
// case DataType.Structure:
|
||||||
return ComposeVarArray((Array)value);
|
// return ComposeStructure((Structure)value);
|
||||||
|
|
||||||
case DataType.ResourceArray:
|
// case DataType.VarArray:
|
||||||
if (value is IResource[])
|
// return ComposeVarArray((Array)value);
|
||||||
return ComposeResourceArray((IResource[])value);
|
|
||||||
else
|
// case DataType.ResourceArray:
|
||||||
return ComposeResourceArray((IResource[])DC.CastConvert(value, typeof(IResource[])));
|
// if (value is IResource[])
|
||||||
|
// return ComposeResourceArray((IResource[])value);
|
||||||
|
// else
|
||||||
|
// return ComposeResourceArray((IResource[])DC.CastConvert(value, typeof(IResource[])));
|
||||||
|
|
||||||
|
|
||||||
case DataType.StructureArray:
|
// case DataType.StructureArray:
|
||||||
return ComposeStructureArray((Structure[])value);
|
// return ComposeStructureArray((Structure[])value);
|
||||||
|
|
||||||
|
|
||||||
default:
|
// default:
|
||||||
return BsonValue.Create(value);
|
// return BsonValue.Create(value);
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
return BsonValue.Create(valueObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncReply<IResource> Retrieve(uint iid)
|
public AsyncReply<IResource> Retrieve(uint iid)
|
||||||
@ -776,7 +780,7 @@ public class MongoDBStore : IStore
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (resource == this)
|
if (resource == this)
|
||||||
|
10
Esiur.sln
10
Esiur.sln
@ -1,6 +1,6 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.29324.140
|
VisualStudioVersion = 17.0.31919.166
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esiur", "Esiur\Esiur.csproj", "{4F74A8C1-D38F-4CC0-ACD1-24459BA0EAFC}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esiur", "Esiur\Esiur.csproj", "{4F74A8C1-D38F-4CC0-ACD1-24459BA0EAFC}"
|
||||||
EndProject
|
EndProject
|
||||||
@ -8,6 +8,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esiur.Stores.MongoDB", "Esi
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esiur.Stores.EntityCore", "Esiur.Stores.EntityCore\Esiur.Stores.EntityCore.csproj", "{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esiur.Stores.EntityCore", "Esiur.Stores.EntityCore\Esiur.Stores.EntityCore.csproj", "{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{331F82B6-6B90-4533-9718-F7C8090D8F19}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -26,6 +28,10 @@ Global
|
|||||||
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{53DE5A30-CFA9-4DE7-A840-77CFF519D31B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{331F82B6-6B90-4533-9718-F7C8090D8F19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{331F82B6-6B90-4533-9718-F7C8090D8F19}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{331F82B6-6B90-4533-9718-F7C8090D8F19}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{331F82B6-6B90-4533-9718-F7C8090D8F19}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -32,7 +32,7 @@ public class AsyncAwaiter<T> : INotifyCompletion
|
|||||||
public T GetResult()
|
public T GetResult()
|
||||||
{
|
{
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
throw exception;
|
throw exception;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,37 +30,42 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Esiur.Core;
|
namespace Esiur.Core;
|
||||||
|
|
||||||
public class AsyncBag : AsyncReply
|
interface IAsyncBag
|
||||||
|
{
|
||||||
|
public void Add(AsyncReply reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AsyncBag<T> : AsyncReply, IAsyncBag
|
||||||
{
|
{
|
||||||
|
|
||||||
protected List<AsyncReply> replies = new List<AsyncReply>();
|
protected List<AsyncReply> replies = new List<AsyncReply>();
|
||||||
List<object> results = new List<object>();
|
List<T> results = new();
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
bool sealedBag = false;
|
bool sealedBag = false;
|
||||||
|
|
||||||
|
|
||||||
public Type ArrayType { get; set; }
|
public virtual Type ArrayType { get; set; } = typeof(T);
|
||||||
|
|
||||||
public AsyncBag Then(Action<object[]> callback)
|
public AsyncBag<T> Then(Action<T[]> callback)
|
||||||
{
|
{
|
||||||
base.Then(new Action<object>(o => callback((object[])o)));
|
base.Then(new Action<object>(o => callback((T[])o)));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public new AsyncBagAwaiter GetAwaiter()
|
public new AsyncBagAwaiter<T> GetAwaiter()
|
||||||
{
|
{
|
||||||
return new AsyncBagAwaiter(this);
|
return new AsyncBagAwaiter<T>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public new object[] Wait()
|
public new T[] Wait()
|
||||||
{
|
{
|
||||||
return (object[])base.Wait();
|
return (T[])base.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
public new object[] Wait(int timeout)
|
public new T[] Wait(int timeout)
|
||||||
{
|
{
|
||||||
return (object[])base.Wait(timeout);
|
return (T[])base.Wait(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Seal()
|
public void Seal()
|
||||||
@ -71,7 +76,17 @@ public class AsyncBag : AsyncReply
|
|||||||
sealedBag = true;
|
sealedBag = true;
|
||||||
|
|
||||||
if (results.Count == 0)
|
if (results.Count == 0)
|
||||||
Trigger(new object[0]);
|
{
|
||||||
|
if (ArrayType != null)
|
||||||
|
{
|
||||||
|
var ar = Array.CreateInstance(ArrayType, 0);
|
||||||
|
Trigger(ar);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Trigger(new object[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < results.Count; i++)
|
for (var i = 0; i < results.Count; i++)
|
||||||
//foreach(var reply in results.Keys)
|
//foreach(var reply in results.Keys)
|
||||||
@ -81,16 +96,24 @@ public class AsyncBag : AsyncReply
|
|||||||
|
|
||||||
k.Then((r) =>
|
k.Then((r) =>
|
||||||
{
|
{
|
||||||
results[index] = r;
|
results[index] = (T)r;
|
||||||
count++;
|
count++;
|
||||||
if (count == results.Count)
|
if (count == results.Count)
|
||||||
{
|
{
|
||||||
if (ArrayType != null)
|
if (ArrayType != null)
|
||||||
{
|
{
|
||||||
var ar = Array.CreateInstance(ArrayType, count);
|
try
|
||||||
for (var i = 0; i < count; i++)
|
{
|
||||||
ar.SetValue(results[i], i);
|
// @TODO: Safe casting check
|
||||||
Trigger(ar);
|
var ar = Array.CreateInstance(ArrayType, count);
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
ar.SetValue(results[i], i);
|
||||||
|
Trigger(ar);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Trigger(results.ToArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Trigger(results.ToArray());
|
Trigger(results.ToArray());
|
||||||
@ -103,12 +126,12 @@ public class AsyncBag : AsyncReply
|
|||||||
{
|
{
|
||||||
if (!sealedBag)
|
if (!sealedBag)
|
||||||
{
|
{
|
||||||
results.Add(null);
|
results.Add(default(T));
|
||||||
replies.Add(reply);
|
replies.Add(reply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddBag(AsyncBag bag)
|
public void AddBag(AsyncBag<T> bag)
|
||||||
{
|
{
|
||||||
foreach (var r in bag.replies)
|
foreach (var r in bag.replies)
|
||||||
Add(r);
|
Add(r);
|
||||||
@ -121,10 +144,11 @@ public class AsyncBag : AsyncReply
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncBag(object[] results)
|
public AsyncBag(T[] results)
|
||||||
: base(results)
|
: base(results)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,15 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Esiur.Core;
|
namespace Esiur.Core;
|
||||||
|
|
||||||
public class AsyncBagAwaiter : INotifyCompletion
|
public class AsyncBagAwaiter<T> : INotifyCompletion
|
||||||
{
|
{
|
||||||
Action callback = null;
|
Action callback = null;
|
||||||
|
|
||||||
AsyncException exception = null;
|
AsyncException exception = null;
|
||||||
|
|
||||||
object[] result;
|
T[] result;
|
||||||
|
|
||||||
public AsyncBagAwaiter(AsyncBag reply)
|
public AsyncBagAwaiter(AsyncBag<T> reply)
|
||||||
{
|
{
|
||||||
reply.Then(x =>
|
reply.Then(x =>
|
||||||
{
|
{
|
||||||
@ -29,7 +29,7 @@ public class AsyncBagAwaiter : INotifyCompletion
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public object[] GetResult()
|
public T[] GetResult()
|
||||||
{
|
{
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
throw exception;
|
throw exception;
|
||||||
|
@ -34,10 +34,13 @@ public class AsyncBag<T> : AsyncBag
|
|||||||
{
|
{
|
||||||
public AsyncBag<T> Then(Action<T[]> callback)
|
public AsyncBag<T> Then(Action<T[]> callback)
|
||||||
{
|
{
|
||||||
base.Then(new Action<object>((o) => callback(((object[])o).Select(x => (T)x).ToArray())));
|
//base.Then(new Action<object>((o) => callback(((object[])o).Select(x => (T)x).ToArray())));
|
||||||
|
base.Then(x => callback((T[])x));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Type ArrayType => typeof(T);
|
||||||
|
|
||||||
public void Add(AsyncReply<T> reply)
|
public void Add(AsyncReply<T> reply)
|
||||||
{
|
{
|
||||||
@ -58,9 +61,15 @@ public class AsyncBag<T> : AsyncBag
|
|||||||
|
|
||||||
public new T[] Wait()
|
public new T[] Wait()
|
||||||
{
|
{
|
||||||
return base.Wait().Select(x => (T)x).ToArray();
|
return (T[])base.Wait();// base.Wait().Select(x => (T)x).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public new T[] Wait(int timeout)
|
||||||
|
{
|
||||||
|
return (T[])base.Wait(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public AsyncBag()
|
public AsyncBag()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -47,170 +47,7 @@ public class BinaryList
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
public Endian Endian { get; set; } = Endian.Little;
|
||||||
/// <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 int Length => list.Count;
|
||||||
|
|
||||||
@ -227,18 +64,6 @@ public class BinaryList
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
public BinaryList AddGuid(Guid value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(DC.ToBytes(value));
|
||||||
@ -251,17 +76,6 @@ public class BinaryList
|
|||||||
return this;
|
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)
|
public BinaryList AddUInt8Array(byte[] value)
|
||||||
@ -302,17 +116,6 @@ public class BinaryList
|
|||||||
return this;
|
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)
|
public BinaryList InsertUInt8(int position, byte value)
|
||||||
{
|
{
|
||||||
@ -338,17 +141,7 @@ public class BinaryList
|
|||||||
return this;
|
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)
|
public BinaryList AddChar(char value)
|
||||||
@ -363,20 +156,7 @@ public class BinaryList
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryList AddCharArray(char[] value)
|
public BinaryList AddBoolean(bool 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));
|
list.AddRange(DC.ToBytes(value));
|
||||||
return this;
|
return this;
|
||||||
@ -388,314 +168,106 @@ public class BinaryList
|
|||||||
return this;
|
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)
|
public BinaryList AddUInt16(ushort value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(DC.ToBytes(value, Endian));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public BinaryList InsertUInt16(int position, ushort value)
|
public BinaryList InsertUInt16(int position, ushort value)
|
||||||
{
|
{
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
list.InsertRange(position, DC.ToBytes(value, Endian));
|
||||||
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public BinaryList AddInt16(short value)
|
public BinaryList AddInt16(short value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(DC.ToBytes(value, Endian));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryList InsertInt16(int position, short value)
|
public BinaryList InsertInt16(int position, short value)
|
||||||
{
|
{
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
list.InsertRange(position, DC.ToBytes(value, Endian));
|
||||||
return this;
|
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)
|
public BinaryList AddUInt32(uint value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(DC.ToBytes(value, Endian));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public BinaryList InsertUInt32(int position, uint value)
|
public BinaryList InsertUInt32(int position, uint value)
|
||||||
{
|
{
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
list.InsertRange(position, DC.ToBytes(value, Endian));
|
||||||
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public BinaryList AddInt32(int value)
|
public BinaryList AddInt32(int value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(DC.ToBytes(value, Endian));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public BinaryList InsertInt32(int position, int value)
|
public BinaryList InsertInt32(int position, int value)
|
||||||
{
|
{
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
list.InsertRange(position, DC.ToBytes(value, Endian));
|
||||||
return this;
|
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)
|
public BinaryList AddUInt64(ulong value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(DC.ToBytes(value, Endian));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public BinaryList InsertUInt64(int position, ulong value)
|
public BinaryList InsertUInt64(int position, ulong value)
|
||||||
{
|
{
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
list.InsertRange(position, DC.ToBytes(value, Endian));
|
||||||
return this;
|
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)
|
public BinaryList AddInt64(long value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(DC.ToBytes(value, Endian));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryList InsertInt64(int position, long value)
|
public BinaryList InsertInt64(int position, long value)
|
||||||
{
|
{
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
list.InsertRange(position, DC.ToBytes(value, Endian));
|
||||||
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public BinaryList AddFloat32(float value)
|
public BinaryList AddFloat32(float value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(value.ToBytes(Endian));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryList InsertFloat32(int position, float value)
|
public BinaryList InsertFloat32(int position, float value)
|
||||||
{
|
{
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
list.InsertRange(position, value.ToBytes(Endian));
|
||||||
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public BinaryList AddFloat64(double value)
|
public BinaryList AddFloat64(double value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(value.ToBytes(Endian));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryList InsertFloat64(int position, double value)
|
public BinaryList InsertFloat64(int position, double value)
|
||||||
{
|
{
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
list.InsertRange(position, value.ToBytes(Endian));
|
||||||
return this;
|
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>
|
/// <summary>
|
||||||
/// Convert the list to an array of bytes
|
/// Convert the list to an array of bytes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -708,6 +280,5 @@ public class BinaryList
|
|||||||
public virtual AsyncReply<object[]> Done()
|
public virtual AsyncReply<object[]> Done()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1687
Esiur/Data/Codec.cs
1687
Esiur/Data/Codec.cs
File diff suppressed because it is too large
Load Diff
@ -93,10 +93,10 @@ public static class DC // Data Converter
|
|||||||
rt.Set(value);
|
rt.Set(value);
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
else if (sourceType == typeof(Structure) && sourceType.IsAssignableFrom(destinationType))
|
//else if (sourceType == typeof(Structure) && sourceType.IsAssignableFrom(destinationType))
|
||||||
{
|
//{
|
||||||
return Structure.FromStructure((Structure)value, destinationType);
|
// return Structure.FromStructure((Structure)value, destinationType);
|
||||||
}
|
//}
|
||||||
else if (destinationType.IsEnum)
|
else if (destinationType.IsEnum)
|
||||||
{
|
{
|
||||||
return Enum.ToObject(destinationType, value);
|
return Enum.ToObject(destinationType, value);
|
||||||
@ -190,45 +190,6 @@ public static class DC // Data Converter
|
|||||||
return value.ToByteArray();
|
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)
|
public static void Append(ref byte[] dst, byte[] src)
|
||||||
{
|
{
|
||||||
@ -265,88 +226,6 @@ public static class DC // Data Converter
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
public static byte[] ToBytes(this string[] value)
|
||||||
{
|
{
|
||||||
@ -356,7 +235,7 @@ public static class DC // Data Converter
|
|||||||
{
|
{
|
||||||
byte[] ba = ToBytes(value[i]);
|
byte[] ba = ToBytes(value[i]);
|
||||||
// add string length
|
// add string length
|
||||||
rt.AddRange(ToBytes(ba.Length));
|
rt.AddRange(ToBytes(ba.Length, Endian.Little));
|
||||||
// add encoded string
|
// add encoded string
|
||||||
rt.AddRange(ba);
|
rt.AddRange(ba);
|
||||||
}
|
}
|
||||||
@ -364,41 +243,68 @@ public static class DC // Data Converter
|
|||||||
return rt.ToArray();
|
return rt.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe byte[] ToBytes(this int value)
|
|
||||||
|
public static unsafe byte[] ToBytes(this int value, Endian endian)
|
||||||
{
|
{
|
||||||
var rt = new byte[4];
|
var rt = new byte[4];
|
||||||
byte* p = (byte*)&value;
|
|
||||||
|
|
||||||
rt[0] = *(p + 3);
|
if (endian == Endian.Little)
|
||||||
rt[1] = *(p + 2);
|
{
|
||||||
rt[2] = *(p + 1);
|
fixed (byte* ptr = rt)
|
||||||
rt[3] = *(p + 0);
|
*((int*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte* p = (byte*)&value;
|
||||||
|
|
||||||
|
rt[0] = *(p + 3);
|
||||||
|
rt[1] = *(p + 2);
|
||||||
|
rt[2] = *(p + 1);
|
||||||
|
rt[3] = *(p + 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe byte[] ToBytes(this short value)
|
|
||||||
|
|
||||||
|
public static unsafe byte[] ToBytes(this short value, Endian endian)
|
||||||
{
|
{
|
||||||
var rt = new byte[2];
|
var rt = new byte[2];
|
||||||
byte* p = (byte*)&value;
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((short*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte* p = (byte*)&value;
|
||||||
|
|
||||||
rt[0] = *(p + 1);
|
rt[0] = *(p + 1);
|
||||||
rt[1] = *(p + 0);
|
rt[1] = *(p + 0);
|
||||||
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe byte[] ToBytes(this float value)
|
public static unsafe byte[] ToBytes(this float value, Endian endian)
|
||||||
|
|
||||||
{
|
{
|
||||||
var rt = new byte[4];
|
var rt = new byte[4];
|
||||||
|
if (endian == Endian.Little)
|
||||||
//float rt = 0;
|
{
|
||||||
byte* p = (byte*)&value;
|
fixed (byte* ptr = rt)
|
||||||
rt[0] = *(p + 3);
|
*((float*)ptr) = value;
|
||||||
rt[1] = *(p + 2);
|
}
|
||||||
rt[2] = *(p + 1);
|
else
|
||||||
rt[3] = *(p);
|
{
|
||||||
|
byte* p = (byte*)&value;
|
||||||
|
rt[0] = *(p + 3);
|
||||||
|
rt[1] = *(p + 2);
|
||||||
|
rt[2] = *(p + 1);
|
||||||
|
rt[3] = *(p);
|
||||||
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
@ -406,122 +312,153 @@ public static class DC // Data Converter
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static byte[] ToBytes(this string value)
|
public static byte[] ToBytes(this string value)
|
||||||
{
|
{
|
||||||
return Encoding.UTF8.GetBytes(value);
|
return Encoding.UTF8.GetBytes(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe static byte[] ToBytes(this double value)
|
public unsafe static byte[] ToBytes(this double value, Endian endian)
|
||||||
{
|
{
|
||||||
var rt = new byte[8];
|
var rt = new byte[8];
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((double*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte* p = (byte*)&value;
|
||||||
|
|
||||||
byte* p = (byte*)&value;
|
rt[0] = *(p + 7);
|
||||||
|
rt[1] = *(p + 6);
|
||||||
rt[0] = *(p + 7);
|
rt[2] = *(p + 5);
|
||||||
rt[1] = *(p + 6);
|
rt[3] = *(p + 4);
|
||||||
rt[2] = *(p + 5);
|
rt[4] = *(p + 3);
|
||||||
rt[3] = *(p + 4);
|
rt[5] = *(p + 2);
|
||||||
rt[4] = *(p + 3);
|
rt[6] = *(p + 1);
|
||||||
rt[5] = *(p + 2);
|
rt[7] = *(p + 0);
|
||||||
rt[6] = *(p + 1);
|
}
|
||||||
rt[7] = *(p + 0);
|
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe byte[] ToBytes(this long value)
|
public static unsafe byte[] ToBytes(this long value, Endian endian)
|
||||||
{
|
{
|
||||||
var rt = new byte[8];
|
var rt = new byte[8];
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((long*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte* p = (byte*)&value;
|
||||||
|
|
||||||
byte* p = (byte*)&value;
|
rt[0] = *(p + 7);
|
||||||
|
rt[1] = *(p + 6);
|
||||||
rt[0] = *(p + 7);
|
rt[2] = *(p + 5);
|
||||||
rt[1] = *(p + 6);
|
rt[3] = *(p + 4);
|
||||||
rt[2] = *(p + 5);
|
rt[4] = *(p + 3);
|
||||||
rt[3] = *(p + 4);
|
rt[5] = *(p + 2);
|
||||||
rt[4] = *(p + 3);
|
rt[6] = *(p + 1);
|
||||||
rt[5] = *(p + 2);
|
rt[7] = *(p + 0);
|
||||||
rt[6] = *(p + 1);
|
}
|
||||||
rt[7] = *(p + 0);
|
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe byte[] ToBytes(this DateTime value)
|
public static unsafe byte[] ToBytes(this DateTime value)
|
||||||
{
|
{
|
||||||
|
|
||||||
var rt = new byte[8];
|
var rt = new byte[8];
|
||||||
var v = value.ToUniversalTime().Ticks;
|
var v = value.ToUniversalTime().Ticks;
|
||||||
|
|
||||||
byte* p = (byte*)&v;
|
fixed (byte* ptr = rt)
|
||||||
|
*((long*)ptr) = 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;
|
return rt;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static unsafe byte[] ToBytes(this ulong value)
|
public static unsafe byte[] ToBytes(this ulong value, Endian endia)
|
||||||
{
|
{
|
||||||
var rt = new byte[8];
|
var rt = new byte[8];
|
||||||
|
if (endia == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((ulong*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
byte* p = (byte*)&value;
|
byte* p = (byte*)&value;
|
||||||
|
|
||||||
rt[0] = *(p + 7);
|
rt[0] = *(p + 7);
|
||||||
rt[1] = *(p + 6);
|
rt[1] = *(p + 6);
|
||||||
rt[2] = *(p + 5);
|
rt[2] = *(p + 5);
|
||||||
rt[3] = *(p + 4);
|
rt[3] = *(p + 4);
|
||||||
rt[4] = *(p + 3);
|
rt[4] = *(p + 3);
|
||||||
rt[5] = *(p + 2);
|
rt[5] = *(p + 2);
|
||||||
rt[6] = *(p + 1);
|
rt[6] = *(p + 1);
|
||||||
rt[7] = *(p + 0);
|
rt[7] = *(p + 0);
|
||||||
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe byte[] ToBytes(this uint value)
|
public static unsafe byte[] ToBytes(this uint value, Endian endian)
|
||||||
{
|
{
|
||||||
|
|
||||||
var rt = new byte[4];
|
var rt = new byte[4];
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((uint*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
byte* p = (byte*)&value;
|
byte* p = (byte*)&value;
|
||||||
|
|
||||||
rt[0] = *(p + 3);
|
rt[0] = *(p + 3);
|
||||||
rt[1] = *(p + 2);
|
rt[1] = *(p + 2);
|
||||||
rt[2] = *(p + 1);
|
rt[2] = *(p + 1);
|
||||||
rt[3] = *(p + 0);
|
rt[3] = *(p + 0);
|
||||||
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe byte[] ToBytes(this ushort value)
|
public static unsafe byte[] ToBytes(this ushort value, Endian endian)
|
||||||
{
|
{
|
||||||
var rt = new byte[2];
|
var rt = new byte[2];
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((ushort*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte* p = (byte*)&value;
|
||||||
|
|
||||||
byte* p = (byte*)&value;
|
rt[0] = *(p + 1);
|
||||||
|
rt[1] = *(p);
|
||||||
rt[0] = *(p + 1);
|
}
|
||||||
rt[1] = *(p);
|
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] ToBytes(this decimal value)
|
public static unsafe byte[] ToBytes(this decimal value, Endian endian)
|
||||||
{
|
{
|
||||||
byte[] ret = new byte[0];// BitConverter.GetBytes(value);
|
var rt = new byte[16];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((decimal*)ptr) = value;
|
||||||
|
|
||||||
Array.Reverse(ret);
|
if (endian == Endian.Big)
|
||||||
|
Array.Reverse(rt);
|
||||||
|
|
||||||
return ret;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToHex(this byte[] ba)
|
public static string ToHex(this byte[] ba)
|
||||||
@ -533,22 +470,10 @@ public static class DC // Data Converter
|
|||||||
|
|
||||||
public static string ToHex(this byte[] ba, uint offset, uint length, string separator = " ")
|
public static string ToHex(this byte[] ba, uint offset, uint length, string separator = " ")
|
||||||
{
|
{
|
||||||
|
|
||||||
if (separator == null)
|
if (separator == null)
|
||||||
separator = "";
|
separator = "";
|
||||||
|
|
||||||
return string.Join(separator, ba.Skip((int)offset).Take((int)length).Select(x => x.ToString("x2")).ToArray());
|
return string.Join(separator, ba.Skip((int)offset).Take((int)length).Select(x => x.ToString("x2")).ToArray());
|
||||||
|
|
||||||
//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 = " ")
|
public static byte[] FromHex(string hexString, string separator = " ")
|
||||||
@ -639,240 +564,186 @@ public static class DC // Data Converter
|
|||||||
return (sbyte)data[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)
|
public static byte GetUInt8(this byte[] data, uint offset)
|
||||||
{
|
{
|
||||||
return data[offset];
|
return data[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] GetUInt8Array(this byte[] data, uint offset, uint length)
|
public static unsafe short GetInt16(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
var rt = new byte[length];
|
if (endian == Endian.Little)
|
||||||
Buffer.BlockCopy(data, (int)offset, rt, 0, (int)length);
|
{
|
||||||
return rt;
|
fixed (byte* ptr = &data[offset])
|
||||||
}
|
return *(short*)ptr;
|
||||||
|
}
|
||||||
public static Int16 GetInt16(this byte[] data, uint offset)
|
else
|
||||||
{
|
{
|
||||||
return (Int16)((data[offset] << 8) | data[offset + 1]);
|
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)
|
|
||||||
|
public static unsafe ushort GetUInt16(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
UInt64 rt = 0;
|
if (endian == Endian.Little)
|
||||||
byte* p = (byte*)&rt;
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
*(p + 7) = data[offset++];
|
return *(ushort*)ptr;
|
||||||
*(p + 6) = data[offset++];
|
}
|
||||||
*(p + 5) = data[offset++];
|
else
|
||||||
*(p + 4) = data[offset++];
|
{
|
||||||
*(p + 3) = data[offset++];
|
return (UInt16)((data[offset] << 8) | data[offset + 1]);
|
||||||
*(p + 2) = data[offset++];
|
}
|
||||||
*(p + 1) = data[offset++];
|
|
||||||
*(p) = data[offset++];
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64[] GetInt64Array(this byte[] data, uint offset, uint length)
|
public static unsafe int GetInt32(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
var j = 0; var end = offset + length;
|
if (endian == Endian.Little)
|
||||||
var rt = new Int64[length / 8];
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
for (var i = offset; i < end; i += 8)
|
return *(int*)ptr;
|
||||||
rt[j++] = GetInt64(data, i);
|
}
|
||||||
|
else
|
||||||
return rt;
|
{
|
||||||
|
return (Int32)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe Int64 GetInt64(this byte[] data, uint offset)
|
public static unsafe uint GetUInt32(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
Int64 rt = 0;
|
|
||||||
byte* p = (byte*)&rt;
|
|
||||||
|
|
||||||
*(p + 7) = data[offset++];
|
if (endian == Endian.Little)
|
||||||
*(p + 6) = data[offset++];
|
{
|
||||||
*(p + 5) = data[offset++];
|
fixed (byte* ptr = &data[offset])
|
||||||
*(p + 4) = data[offset++];
|
return *(uint*)ptr;
|
||||||
*(p + 3) = data[offset++];
|
}
|
||||||
*(p + 2) = data[offset++];
|
else
|
||||||
*(p + 1) = data[offset++];
|
{
|
||||||
*(p) = data[offset++];
|
return (uint)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]);
|
||||||
|
}
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
|
public static unsafe ulong GetUInt64(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
var j = 0; var end = offset + length;
|
if (endian == Endian.Little)
|
||||||
var rt = new UInt64[length / 8];
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return *(ulong*)ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt64 rt = 0;
|
||||||
|
byte* p = (byte*)&rt;
|
||||||
|
|
||||||
for (var i = offset; i < end; i += 8)
|
*(p + 7) = data[offset++];
|
||||||
rt[j++] = GetUInt64(data, i);
|
*(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;
|
return rt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe float GetFloat32(this byte[] data, uint offset)
|
|
||||||
|
public static unsafe long GetInt64(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
float rt = 0;
|
if (endian == Endian.Little)
|
||||||
byte* p = (byte*)&rt;
|
{
|
||||||
*p = data[offset + 3];
|
fixed (byte* ptr = &data[offset])
|
||||||
*(p + 1) = data[offset + 2];
|
return *(long*)ptr;
|
||||||
*(p + 2) = data[offset + 1];
|
}
|
||||||
*(p + 3) = data[offset];
|
else
|
||||||
return rt;
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float[] GetFloat32Array(this byte[] data, uint offset, uint length)
|
public static unsafe float GetFloat32(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
var j = 0; var end = offset + length;
|
if (endian == Endian.Little)
|
||||||
var rt = new float[length / 4];
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return *(float*)ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
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)
|
|
||||||
|
public static unsafe double GetFloat64(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
double rt = 0;
|
if (endian == Endian.Little)
|
||||||
byte* p = (byte*)&rt;
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return *(double*)ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double rt = 0;
|
||||||
|
byte* p = (byte*)&rt;
|
||||||
|
|
||||||
*(p + 7) = data[offset++];
|
*(p + 7) = data[offset++];
|
||||||
*(p + 6) = data[offset++];
|
*(p + 6) = data[offset++];
|
||||||
*(p + 5) = data[offset++];
|
*(p + 5) = data[offset++];
|
||||||
*(p + 4) = data[offset++];
|
*(p + 4) = data[offset++];
|
||||||
*(p + 3) = data[offset++];
|
*(p + 3) = data[offset++];
|
||||||
*(p + 2) = data[offset++];
|
*(p + 2) = data[offset++];
|
||||||
*(p + 1) = data[offset++];
|
*(p + 1) = data[offset++];
|
||||||
*(p) = data[offset++];
|
*(p) = data[offset++];
|
||||||
|
|
||||||
return rt;
|
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)
|
public static bool GetBoolean(this byte[] data, uint offset)
|
||||||
{
|
{
|
||||||
return data[offset] > 0;
|
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)
|
public static char GetChar(this byte[] data, uint offset)
|
||||||
{
|
{
|
||||||
return Convert.ToChar(((data[offset] << 8) | data[offset + 1]));
|
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)
|
public static string GetString(this byte[] data, uint offset, uint length)
|
||||||
{
|
{
|
||||||
@ -887,7 +758,7 @@ public static class DC // Data Converter
|
|||||||
|
|
||||||
while (i < length)
|
while (i < length)
|
||||||
{
|
{
|
||||||
var cl = GetUInt32(data, offset + i);
|
var cl = GetUInt32(data, offset + i, Endian.Little);
|
||||||
i += 4;
|
i += 4;
|
||||||
ar.Add(Encoding.UTF8.GetString(data, (int)(offset + i), (int)cl));
|
ar.Add(Encoding.UTF8.GetString(data, (int)(offset + i), (int)cl));
|
||||||
i += cl;
|
i += cl;
|
||||||
@ -901,69 +772,24 @@ public static class DC // Data Converter
|
|||||||
return new Guid(Clip(data, offset, 16));
|
return new Guid(Clip(data, offset, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Guid[] GetGuidArray(this byte[] data, uint offset, uint length)
|
public static DateTime GetDateTime(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
var j = 0; var end = offset + length;
|
var ticks = GetInt64(data, offset, endian);
|
||||||
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);
|
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)
|
public static IPAddress GetIPv4Address(this byte[] data, uint offset)
|
||||||
{
|
{
|
||||||
return new IPAddress((long)GetUInt32(data, offset));
|
return new IPAddress((long)GetUInt32(data, offset, Endian.Little));
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static IPAddress GetIPv6Address(this byte[] data, uint offset)
|
||||||
{
|
{
|
||||||
return new IPAddress(Clip(data, offset, 16));
|
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)
|
public static byte[] Clip(this byte[] data, uint offset, uint length)
|
||||||
{
|
{
|
||||||
if (data.Length < offset + length)
|
if (data.Length < offset + length)
|
||||||
|
554
Esiur/Data/DataDeserializer.cs
Normal file
554
Esiur/Data/DataDeserializer.cs
Normal file
@ -0,0 +1,554 @@
|
|||||||
|
using Esiur.Core;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Resource.Template;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Esiur.Data;
|
||||||
|
|
||||||
|
public static class DataDeserializer
|
||||||
|
{
|
||||||
|
public static AsyncReply NullParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply BooleanTrueParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply<bool>(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply BooleanFalseParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply<bool>(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply NotModifiedParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply<NotModified>(new NotModified());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply ByteParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply<byte>(data[offset]);
|
||||||
|
}
|
||||||
|
public static AsyncReply SByteParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply<sbyte>((sbyte)data[offset]);
|
||||||
|
}
|
||||||
|
public static unsafe AsyncReply Char16Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<char>(*(char*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply Char8Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply<char>((char)data[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static unsafe AsyncReply Int16Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<short>(*(short*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply UInt16Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<ushort>(*(ushort*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply Int32Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<int>(*(int*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply UInt32Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<uint>(*(uint*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply Float32Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<float>(*(float*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply Float64Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<double>(*(double*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply Float128Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<decimal>(*(decimal*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply Int128Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<decimal>(*(decimal*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static unsafe AsyncReply UInt128Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<decimal>(*(decimal*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static unsafe AsyncReply Int64Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<long>(*(long*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply UInt64Parser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<ulong>(*(ulong*)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply DateTimeParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return new AsyncReply<DateTime>(new DateTime(*(long*)ptr, DateTimeKind.Utc));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static unsafe AsyncReply ResourceParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return connection.Fetch(*(uint*)ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply LocalResourceParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return Warehouse.GetById(*(uint*)ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static unsafe AsyncReply RawDataParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply<byte[]>(data.Clip(offset, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply StringParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return new AsyncReply<string>(data.GetString(offset, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply RecordParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
|
||||||
|
var reply = new AsyncReply<IRecord>();
|
||||||
|
|
||||||
|
var classId = data.GetGuid(offset);
|
||||||
|
offset += 16;
|
||||||
|
length -= 16;
|
||||||
|
|
||||||
|
|
||||||
|
var template = Warehouse.GetTemplateByClassId((Guid)classId, TemplateType.Record);
|
||||||
|
|
||||||
|
if (template != null)
|
||||||
|
{
|
||||||
|
//ListParser(data, offset, length, connection)
|
||||||
|
ListParser(data, offset, length, connection).Then(r =>
|
||||||
|
{
|
||||||
|
var ar = (object[])r;
|
||||||
|
|
||||||
|
if (template.DefinedType != null)
|
||||||
|
{
|
||||||
|
var record = Activator.CreateInstance(template.DefinedType) as IRecord;
|
||||||
|
for (var i = 0; i < template.Properties.Length; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var v = Convert.ChangeType(ar[i], template.Properties[i].PropertyInfo.PropertyType);
|
||||||
|
template.Properties[i].PropertyInfo.SetValue(record, v);
|
||||||
|
} catch ( Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reply.Trigger(record);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var record = new Record();
|
||||||
|
|
||||||
|
for (var i = 0; i < template.Properties.Length; i++)
|
||||||
|
record.Add(template.Properties[i].Name, ar[i]);
|
||||||
|
|
||||||
|
reply.Trigger(record);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
connection.GetTemplate((Guid)classId).Then(tmp =>
|
||||||
|
{
|
||||||
|
ListParser(data, offset, length, connection).Then(r =>
|
||||||
|
{
|
||||||
|
var ar = (object[])r;
|
||||||
|
|
||||||
|
var record = new Record();
|
||||||
|
|
||||||
|
for (var i = 0; i < tmp.Properties.Length; i++)
|
||||||
|
record.Add(tmp.Properties[i].Name, ar[i]);
|
||||||
|
|
||||||
|
reply.Trigger(record);
|
||||||
|
});
|
||||||
|
}).Error(x => reply.TriggerError(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply ConstantParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe AsyncReply EnumParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
|
||||||
|
var classId = data.GetGuid(offset);
|
||||||
|
offset += 16;
|
||||||
|
var index = data[offset++];
|
||||||
|
|
||||||
|
var template = Warehouse.GetTemplateByClassId((Guid)classId, TemplateType.Enum);
|
||||||
|
|
||||||
|
if (template != null)
|
||||||
|
{
|
||||||
|
return new AsyncReply(template.Constants[index].Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var reply = new AsyncReply();
|
||||||
|
|
||||||
|
connection.GetTemplate((Guid)classId).Then(tmp =>
|
||||||
|
{
|
||||||
|
reply.Trigger(tmp.Constants[index].Value);
|
||||||
|
}).Error(x => reply.TriggerError(x));
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static AsyncReply RecordListParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var rt = new AsyncBag<IRecord>();
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
var (cs, reply) = Codec.Parse(data, offset, connection);
|
||||||
|
|
||||||
|
rt.Add(reply);
|
||||||
|
|
||||||
|
if (cs > 0)
|
||||||
|
{
|
||||||
|
offset += (uint)cs;
|
||||||
|
length -= (uint)cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Error while parsing structured data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rt.Seal();
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply ResourceListParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var rt = new AsyncBag<IResource>();
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
var (cs, reply) = Codec.Parse(data, offset, connection);
|
||||||
|
|
||||||
|
rt.Add(reply);
|
||||||
|
|
||||||
|
if (cs > 0)
|
||||||
|
{
|
||||||
|
offset += (uint)cs;
|
||||||
|
length -= (uint)cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Error while parsing structured data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rt.Seal();
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static AsyncBag<object> ListParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var rt = new AsyncBag<object>();
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
var (cs, reply) = Codec.Parse(data, offset, connection);
|
||||||
|
|
||||||
|
rt.Add(reply);
|
||||||
|
|
||||||
|
if (cs > 0)
|
||||||
|
{
|
||||||
|
offset += (uint)cs;
|
||||||
|
length -= (uint)cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Error while parsing structured data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rt.Seal();
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply TypedMapParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
// get key type
|
||||||
|
var (keyCs, keyRepType) = RepresentationType.Parse(data, offset);
|
||||||
|
offset += keyCs;
|
||||||
|
length -= keyCs;
|
||||||
|
|
||||||
|
var (valueCs, valueRepType) = RepresentationType.Parse(data, offset);
|
||||||
|
offset += valueCs;
|
||||||
|
length -= valueCs;
|
||||||
|
|
||||||
|
var map = (IMap)Activator.CreateInstance(typeof(Map<,>).MakeGenericType(keyRepType.GetRuntimeType(), valueRepType.GetRuntimeType()));
|
||||||
|
|
||||||
|
var rt = new AsyncReply();
|
||||||
|
|
||||||
|
var results = new AsyncBag<object>();
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
var (cs, reply) = Codec.Parse(data, offset, connection);
|
||||||
|
|
||||||
|
|
||||||
|
results.Add(reply);
|
||||||
|
|
||||||
|
if (cs > 0)
|
||||||
|
{
|
||||||
|
offset += (uint)cs;
|
||||||
|
length -= (uint)cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Error while parsing structured data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Seal();
|
||||||
|
|
||||||
|
results.Then(ar =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < ar.Length; i += 2)
|
||||||
|
map.Add(ar[i], ar[i + 1]);
|
||||||
|
|
||||||
|
rt.Trigger(map);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply TupleParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var results = new AsyncBag<object>();
|
||||||
|
var rt = new AsyncReply();
|
||||||
|
|
||||||
|
var tupleSize = data[offset++];
|
||||||
|
length--;
|
||||||
|
|
||||||
|
var types = new List<Type>();
|
||||||
|
|
||||||
|
for (var i = 0; i < tupleSize; i++)
|
||||||
|
{
|
||||||
|
var (cs, rep) = RepresentationType.Parse(data, offset);
|
||||||
|
types.Add(rep.GetRuntimeType());
|
||||||
|
offset += cs;
|
||||||
|
length -= cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
var (cs, reply) = Codec.Parse(data, offset, connection);
|
||||||
|
|
||||||
|
results.Add(reply);
|
||||||
|
|
||||||
|
if (cs > 0)
|
||||||
|
{
|
||||||
|
offset += (uint)cs;
|
||||||
|
length -= (uint)cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Error while parsing structured data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Seal();
|
||||||
|
|
||||||
|
|
||||||
|
results.Then(ar =>
|
||||||
|
{
|
||||||
|
if (ar.Length == 2)
|
||||||
|
{
|
||||||
|
var type = typeof(ValueTuple<,>).MakeGenericType(types.ToArray());
|
||||||
|
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1]));
|
||||||
|
}
|
||||||
|
else if (ar.Length == 3)
|
||||||
|
{
|
||||||
|
var type = typeof(ValueTuple<,,>).MakeGenericType(types.ToArray());
|
||||||
|
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2]));
|
||||||
|
}
|
||||||
|
else if (ar.Length == 4)
|
||||||
|
{
|
||||||
|
var type = typeof(ValueTuple<,,,>).MakeGenericType(types.ToArray());
|
||||||
|
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var rt = new AsyncBag<object>();
|
||||||
|
|
||||||
|
// get the type
|
||||||
|
var (hdrCs, rep) = RepresentationType.Parse(data, offset);
|
||||||
|
|
||||||
|
offset += hdrCs;
|
||||||
|
length -= hdrCs;
|
||||||
|
|
||||||
|
var runtimeType = rep.GetRuntimeType();
|
||||||
|
|
||||||
|
rt.ArrayType = runtimeType;
|
||||||
|
|
||||||
|
while (length > 0)
|
||||||
|
{
|
||||||
|
var (cs, reply) = Codec.Parse(data, offset, connection);
|
||||||
|
|
||||||
|
rt.Add(reply);
|
||||||
|
|
||||||
|
if (cs > 0)
|
||||||
|
{
|
||||||
|
offset += (uint)cs;
|
||||||
|
length -= (uint)cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new Exception("Error while parsing structured data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rt.Seal();
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static AsyncBag<PropertyValue> PropertyValueArrayParser(byte[] data, uint offset, uint length, DistributedConnection connection)//, bool ageIncluded = true)
|
||||||
|
{
|
||||||
|
var rt = new AsyncBag<PropertyValue>();
|
||||||
|
|
||||||
|
|
||||||
|
ListParser(data, offset, length, connection).Then(x =>
|
||||||
|
{
|
||||||
|
var ar = (object[])x;
|
||||||
|
var pvs = new List<PropertyValue>();
|
||||||
|
|
||||||
|
for (var i = 0; i < ar.Length; i += 3)
|
||||||
|
pvs.Add(new PropertyValue(ar[2], (ulong?)ar[0], (DateTime?)ar[1]));
|
||||||
|
|
||||||
|
|
||||||
|
rt.Trigger(pvs.ToArray());
|
||||||
|
});
|
||||||
|
|
||||||
|
return rt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (uint, AsyncReply<PropertyValue>) PropertyValueParser(byte[] data, uint offset, DistributedConnection connection)//, bool ageIncluded = true)
|
||||||
|
{
|
||||||
|
var reply = new AsyncReply<PropertyValue>();
|
||||||
|
|
||||||
|
var age = data.GetUInt64(offset, Endian.Little);
|
||||||
|
offset += 8;
|
||||||
|
|
||||||
|
DateTime date = data.GetDateTime(offset, Endian.Little);
|
||||||
|
offset += 8;
|
||||||
|
|
||||||
|
|
||||||
|
var (valueSize, results) = Codec.Parse(data, offset, connection);
|
||||||
|
|
||||||
|
results.Then(value =>
|
||||||
|
{
|
||||||
|
reply.Trigger(new PropertyValue(value, age, date));
|
||||||
|
});
|
||||||
|
|
||||||
|
return (16 + valueSize, reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParser(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
//var count = (int)toAge - (int)fromAge;
|
||||||
|
|
||||||
|
var list = new KeyList<PropertyTemplate, PropertyValue[]>();
|
||||||
|
|
||||||
|
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
|
||||||
|
|
||||||
|
var bagOfBags = new AsyncBag<PropertyValue[]>();
|
||||||
|
|
||||||
|
var ends = offset + length;
|
||||||
|
while (offset < ends)
|
||||||
|
{
|
||||||
|
var index = data[offset++];
|
||||||
|
var pt = resource.Instance.Template.GetPropertyTemplateByIndex(index);
|
||||||
|
list.Add(pt, null);
|
||||||
|
var cs = data.GetUInt32(offset, Endian.Little);
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
var (len, pv) = PropertyValueParser(data, offset, connection);
|
||||||
|
|
||||||
|
bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
|
||||||
|
offset += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bagOfBags.Seal();
|
||||||
|
|
||||||
|
bagOfBags.Then(x =>
|
||||||
|
{
|
||||||
|
for (var i = 0; i < list.Count; i++)
|
||||||
|
list[list.Keys.ElementAt(i)] = x[i];
|
||||||
|
|
||||||
|
reply.Trigger(list);
|
||||||
|
});
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
416
Esiur/Data/DataSerializer.cs
Normal file
416
Esiur/Data/DataSerializer.cs
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
using Esiur.Core;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using Esiur.Resource.Template;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Data;
|
||||||
|
|
||||||
|
public static class DataSerializer
|
||||||
|
{
|
||||||
|
public delegate byte[] Serializer(object value);
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Int32Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (int)value;
|
||||||
|
var rt = new byte[4];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((int*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.Int32, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) UInt32Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (uint)value;
|
||||||
|
var rt = new byte[4];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((uint*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.UInt32, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Int16Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (short)value;
|
||||||
|
var rt = new byte[2];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((short*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.Int16, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) UInt16Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (ushort)value;
|
||||||
|
var rt = new byte[2];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((ushort*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.UInt16, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Float32Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (float)value;
|
||||||
|
var rt = new byte[4];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((float*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.Float32, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Float64Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (double)value;
|
||||||
|
var rt = new byte[8];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((double*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.Float64, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Int64Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (long)value;
|
||||||
|
var rt = new byte[8];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((long*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.Int64, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) UIn64Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (ulong)value;
|
||||||
|
var rt = new byte[8];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((ulong*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.UInt64, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) DateTimeComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = ((DateTime)value).ToUniversalTime().Ticks;
|
||||||
|
var rt = new byte[8];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((long*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.DateTime, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Float128Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var v = (decimal)value;
|
||||||
|
var rt = new byte[16];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((decimal*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.Float128, rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) StringComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return (TransmissionTypeIdentifier.String, Encoding.UTF8.GetBytes((string)value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) EnumComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
var template = Warehouse.GetTemplateByType(value.GetType());
|
||||||
|
|
||||||
|
var intVal = Convert.ChangeType(value, (value as Enum).GetTypeCode());
|
||||||
|
|
||||||
|
var ct = template.Constants.FirstOrDefault(x => x.Value.Equals(intVal));
|
||||||
|
|
||||||
|
if (ct == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
|
||||||
|
var rt = new List<byte>();
|
||||||
|
rt.AddRange(template.ClassId.ToByteArray());
|
||||||
|
rt.Add(ct.Index);
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.Enum, rt.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) UInt8Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return (TransmissionTypeIdentifier.UInt8, new byte[] { (byte)value });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) Int8Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return (TransmissionTypeIdentifier.Int8, new byte[] { (byte)(sbyte)value });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Char8Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return (TransmissionTypeIdentifier.Char8, new byte[] { (byte)(char)value });
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) Char16Composer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
|
||||||
|
var v = (char)value;
|
||||||
|
var rt = new byte[2];
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((char*)ptr) = v;
|
||||||
|
return (TransmissionTypeIdentifier.Char16, rt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) BoolComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return ((bool)value ? TransmissionTypeIdentifier.True : TransmissionTypeIdentifier.False, new byte[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) NotModifiedComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return (TransmissionTypeIdentifier.NotModified, new byte[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) RawDataComposerFromArray(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return (TransmissionTypeIdentifier.RawData, (byte[])value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) RawDataComposerFromList(dynamic value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return (TransmissionTypeIdentifier.RawData, (value as List<byte>).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static (TransmissionTypeIdentifier, byte[]) ListComposerFromArray(dynamic value, DistributedConnection connection)
|
||||||
|
//{
|
||||||
|
// var rt = new List<byte>();
|
||||||
|
// var array = (object[])value;
|
||||||
|
|
||||||
|
// for (var i = 0; i < array.Length; i++)
|
||||||
|
// rt.AddRange(Codec.Compose(array[i], connection));
|
||||||
|
|
||||||
|
// return (TransmissionTypeIdentifier.List, rt.ToArray());
|
||||||
|
//}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) ListComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
|
||||||
|
var rt = ArrayComposer((IEnumerable)value, connection);
|
||||||
|
|
||||||
|
if (rt == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
else
|
||||||
|
return (TransmissionTypeIdentifier.List, rt);
|
||||||
|
|
||||||
|
|
||||||
|
//var rt = new List<byte>();
|
||||||
|
//var list = (IEnumerable)value;// ((List<object>)value);
|
||||||
|
|
||||||
|
//foreach (var o in list)
|
||||||
|
// rt.AddRange(Codec.Compose(o, connection));
|
||||||
|
|
||||||
|
//return (TransmissionTypeIdentifier.List, rt.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) TypedListComposer(IEnumerable value, Type type, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var composed = ArrayComposer((IEnumerable)value, connection);
|
||||||
|
|
||||||
|
if (composed == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
var header = RepresentationType.FromType(type).Compose();
|
||||||
|
|
||||||
|
var rt = new List<byte>();
|
||||||
|
|
||||||
|
rt.AddRange(header);
|
||||||
|
rt.AddRange(composed);
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.TypedList, rt.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static byte[] PropertyValueComposer(PropertyValue propertyValue, DistributedConnection connection)//, bool includeAge = true)
|
||||||
|
//{
|
||||||
|
// var rt = new BinaryList();
|
||||||
|
|
||||||
|
// return
|
||||||
|
// .AddUInt64(propertyValue.Age)
|
||||||
|
// .AddDateTime(propertyValue.Date)
|
||||||
|
// .AddUInt8Array(Codec.Compose(propertyValue.Value, connection))
|
||||||
|
// .ToArray();
|
||||||
|
//}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) PropertyValueArrayComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
var rt = new List<byte>();
|
||||||
|
var ar = value as PropertyValue[];
|
||||||
|
|
||||||
|
foreach (var pv in ar)
|
||||||
|
{
|
||||||
|
rt.AddRange(Codec.Compose(pv.Age, connection));
|
||||||
|
rt.AddRange(Codec.Compose(pv.Date, connection));
|
||||||
|
rt.AddRange(Codec.Compose(pv.Value, connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.List, rt.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) TypedMapComposer(object value, Type keyType, Type valueType, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
var kt = RepresentationType.FromType(keyType).Compose();
|
||||||
|
var vt = RepresentationType.FromType(valueType).Compose();
|
||||||
|
|
||||||
|
var rt = new List<byte>();
|
||||||
|
|
||||||
|
rt.AddRange(kt);
|
||||||
|
rt.AddRange(vt);
|
||||||
|
|
||||||
|
var map = (IMap)value;
|
||||||
|
|
||||||
|
foreach(var el in map.Serialize())
|
||||||
|
rt.AddRange(Codec.Compose(el, connection));
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.TypedMap, rt.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] ArrayComposer(IEnumerable value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var rt = new List<byte>();
|
||||||
|
|
||||||
|
foreach (var i in value)
|
||||||
|
rt.AddRange(Codec.Compose(i, connection));
|
||||||
|
|
||||||
|
return rt.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) ResourceListComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.ResourceList, ArrayComposer((IEnumerable)value, connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) RecordListComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.RecordList, ArrayComposer((IEnumerable)value, connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) ResourceComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var resource = (IResource)value;
|
||||||
|
var rt = new byte[4];
|
||||||
|
|
||||||
|
if (Codec.IsLocalResource(resource, connection))
|
||||||
|
{
|
||||||
|
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((uint*)ptr) = (resource as DistributedResource).Id;
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.ResourceLocal, rt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//rt.Append((value as IResource).Instance.Template.ClassId, (value as IResource).Instance.Id);
|
||||||
|
connection.cache.Add(value as IResource, DateTime.UtcNow);
|
||||||
|
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((uint*)ptr) = resource.Instance.Id;
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.Resource, rt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) MapComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
var rt = new List<byte>();
|
||||||
|
var map = (IMap)value;
|
||||||
|
|
||||||
|
foreach (var el in map.Serialize())
|
||||||
|
rt.AddRange(Codec.Compose(el, connection));
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.Map, rt.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe (TransmissionTypeIdentifier, byte[]) RecordComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
var rt = new List<byte>();// BinaryList();
|
||||||
|
var record = (IRecord)value;
|
||||||
|
|
||||||
|
var template = Warehouse.GetTemplateByType(record.GetType());
|
||||||
|
|
||||||
|
|
||||||
|
rt.AddRange(template.ClassId.ToByteArray());
|
||||||
|
|
||||||
|
foreach (var pt in template.Properties)
|
||||||
|
{
|
||||||
|
var propValue = pt.PropertyInfo.GetValue(record, null);
|
||||||
|
rt.AddRange(Codec.Compose(propValue, connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TransmissionTypeIdentifier.Record, rt.ToArray());
|
||||||
|
}
|
||||||
|
public static byte[] HistoryComposer(KeyList<PropertyTemplate, PropertyValue[]> history,
|
||||||
|
DistributedConnection connection, bool prependLength = false)
|
||||||
|
{
|
||||||
|
//@TODO:Test
|
||||||
|
var rt = new BinaryList();
|
||||||
|
|
||||||
|
for (var i = 0; i < history.Count; i++)
|
||||||
|
rt.AddUInt8(history.Keys.ElementAt(i).Index)
|
||||||
|
.AddUInt8Array(Codec.Compose(history.Values.ElementAt(i), connection));
|
||||||
|
|
||||||
|
if (prependLength)
|
||||||
|
rt.InsertInt32(0, rt.Length);
|
||||||
|
|
||||||
|
return rt.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (TransmissionTypeIdentifier, byte[]) TupleComposer(object value, DistributedConnection connection)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
|
||||||
|
var rt = new List<byte>();
|
||||||
|
|
||||||
|
var fields = value.GetType().GetFields();
|
||||||
|
var list = fields.Select(x => x.GetValue(value)).ToArray();
|
||||||
|
var types = fields.Select(x => RepresentationType.FromType(x.FieldType).Compose()).ToArray();
|
||||||
|
|
||||||
|
rt.Add((byte)list.Length);
|
||||||
|
|
||||||
|
foreach (var t in types)
|
||||||
|
rt.AddRange(t);
|
||||||
|
|
||||||
|
var composed = ArrayComposer(list, connection);
|
||||||
|
|
||||||
|
if (composed == null)
|
||||||
|
return (TransmissionTypeIdentifier.Null, new byte[0]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt.AddRange(composed);
|
||||||
|
return (TransmissionTypeIdentifier.Tuple, rt.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
12
Esiur/Data/Endian.cs
Normal file
12
Esiur/Data/Endian.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Data
|
||||||
|
{
|
||||||
|
public enum Endian
|
||||||
|
{
|
||||||
|
Big,
|
||||||
|
Little
|
||||||
|
}
|
||||||
|
}
|
@ -229,7 +229,7 @@ public class KeyList<KT, T> : IEnumerable<KeyValuePair<KT, T>>
|
|||||||
#if NETSTANDARD
|
#if NETSTANDARD
|
||||||
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
|
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
|
||||||
#else
|
#else
|
||||||
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
|
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.Owner = owner;
|
this.Owner = owner;
|
||||||
|
248
Esiur/Data/Map.cs
Normal file
248
Esiur/Data/Map.cs
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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;
|
||||||
|
using System.Dynamic;
|
||||||
|
|
||||||
|
namespace Esiur.Data;
|
||||||
|
|
||||||
|
//public class Map : IEnumerable<KeyValuePair<object, object>>
|
||||||
|
//{
|
||||||
|
// private Dictionary<object, object> dic = new();
|
||||||
|
|
||||||
|
// public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
|
||||||
|
// {
|
||||||
|
// return dic.GetEnumerator();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
// {
|
||||||
|
// return dic.GetEnumerator();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public interface IMap
|
||||||
|
{
|
||||||
|
public void Add(object key, object value);
|
||||||
|
public void Remove(object key);
|
||||||
|
public void Clear();
|
||||||
|
public bool ContainsKey(object key);
|
||||||
|
public object[] Serialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Map<KT, VT> : IEnumerable<KeyValuePair<KT, VT>>, IMap
|
||||||
|
{
|
||||||
|
|
||||||
|
//public struct StructureMetadata
|
||||||
|
//{
|
||||||
|
// public KT[] Keys;
|
||||||
|
// public VT[] Types;
|
||||||
|
//}
|
||||||
|
|
||||||
|
private Dictionary<KT, VT> dic = new Dictionary<KT, VT>();// StringComparer.OrdinalIgnoreCase);
|
||||||
|
private object syncRoot = new object();
|
||||||
|
|
||||||
|
|
||||||
|
public bool ContainsKey(KT 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 Map(Map<KT,VT> source)
|
||||||
|
{
|
||||||
|
dic = source.dic;
|
||||||
|
}
|
||||||
|
public Map()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<KT,VT> FromMap(Map<KT,VT> source, Type destinationType)
|
||||||
|
{
|
||||||
|
var rt = Activator.CreateInstance(destinationType) as Map<KT, VT>;
|
||||||
|
rt.dic = source.dic;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static T FromStructure<T>(Map<KT, VT> source) where T : Map<KT, VT>
|
||||||
|
//{
|
||||||
|
// var rt = Activator.CreateInstance<T>();
|
||||||
|
// rt.dic = source.dic;
|
||||||
|
// return rt;
|
||||||
|
//}
|
||||||
|
|
||||||
|
// public static explicit operator Map<string, object>(ExpandoObject obj) => FromDynamic(obj);
|
||||||
|
|
||||||
|
public static Map<string, object> FromDynamic(ExpandoObject obj)
|
||||||
|
{
|
||||||
|
var rt = new Map<string, object>();
|
||||||
|
foreach (var kv in obj)
|
||||||
|
rt[kv.Key] = kv.Value;
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<string,object> FromObject(object obj)
|
||||||
|
{
|
||||||
|
var type = obj.GetType();
|
||||||
|
|
||||||
|
var st = new Map<string,object>();
|
||||||
|
|
||||||
|
var pi = type.GetTypeInfo().GetProperties().Where(x => x.CanRead);
|
||||||
|
foreach (var p in pi)
|
||||||
|
st[p.Name] = p.GetValue(obj);
|
||||||
|
|
||||||
|
var fi = type.GetTypeInfo().GetFields().Where(x => x.IsPublic);
|
||||||
|
foreach (var f in fi)
|
||||||
|
st[f.Name] = f.GetValue(obj);
|
||||||
|
|
||||||
|
return st;
|
||||||
|
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// var fi = type.GetTypeInfo().GetFields().Where(x => x.IsPublic);
|
||||||
|
// foreach (var f in fi)
|
||||||
|
// st[f.Name] = f.GetValue(obj);
|
||||||
|
|
||||||
|
// return st;
|
||||||
|
// }
|
||||||
|
// //else
|
||||||
|
// // return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<KeyValuePair<KT, VT>> GetEnumerator()
|
||||||
|
{
|
||||||
|
return dic.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return dic.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Length
|
||||||
|
{
|
||||||
|
get { return dic.Count; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyValuePair<KT, VT> At(int index)
|
||||||
|
{
|
||||||
|
return dic.ElementAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object SyncRoot
|
||||||
|
{
|
||||||
|
get { return syncRoot; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public KT[] GetKeys() => dic.Keys.ToArray();//GetKeys()
|
||||||
|
//{
|
||||||
|
// return dic.Keys.ToArray();
|
||||||
|
//}
|
||||||
|
|
||||||
|
public void Add(KT key, VT value)
|
||||||
|
{
|
||||||
|
if (dic.ContainsKey(key))
|
||||||
|
dic[key] = value;
|
||||||
|
else
|
||||||
|
dic.Add(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(object key, object value)
|
||||||
|
{
|
||||||
|
Add((KT)key, (VT)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(object key)
|
||||||
|
{
|
||||||
|
Remove((KT)key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
dic.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ContainsKey(object key)
|
||||||
|
{
|
||||||
|
return ContainsKey((KT)key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] Serialize()
|
||||||
|
{
|
||||||
|
var rt = new List<object>();
|
||||||
|
foreach(var kv in dic)
|
||||||
|
{
|
||||||
|
rt.Add(kv.Key);
|
||||||
|
rt.Add(kv.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rt.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public VT this[KT index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (dic.ContainsKey(index))
|
||||||
|
return dic[index];
|
||||||
|
else
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (dic.ContainsKey(index))
|
||||||
|
dic[index] = value;
|
||||||
|
else
|
||||||
|
dic.Add(index, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,11 +13,11 @@ public class PropertyValue
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get or set date of modification or occurrence.
|
/// Get or set date of modification or occurrence.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime Date { get; set; }
|
public DateTime? Date { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get or set property age.
|
/// Get or set property age.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ulong Age { get; set; }
|
public ulong? Age { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create an instance of PropertyValue.
|
/// Create an instance of PropertyValue.
|
||||||
@ -25,7 +25,7 @@ public class PropertyValue
|
|||||||
/// <param name="value">Value.</param>
|
/// <param name="value">Value.</param>
|
||||||
/// <param name="age">Age.</param>
|
/// <param name="age">Age.</param>
|
||||||
/// <param name="date">Date.</param>
|
/// <param name="date">Date.</param>
|
||||||
public PropertyValue(object value, ulong age, DateTime date)
|
public PropertyValue(object value, ulong? age, DateTime? date)
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = value;
|
||||||
Age = age;
|
Age = age;
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Esiur.Data;
|
|
||||||
|
|
||||||
public enum RecordComparisonResult : byte
|
|
||||||
{
|
|
||||||
Null,
|
|
||||||
Record,
|
|
||||||
RecordSameType,
|
|
||||||
Same
|
|
||||||
}
|
|
372
Esiur/Data/RepresentationType.cs
Normal file
372
Esiur/Data/RepresentationType.cs
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
using Esiur.Net.IIP;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using Esiur.Resource.Template;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Dynamic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Data
|
||||||
|
{
|
||||||
|
public enum RepresentationTypeIdentifier
|
||||||
|
{
|
||||||
|
Void,
|
||||||
|
Dynamic,
|
||||||
|
Bool,
|
||||||
|
UInt8,
|
||||||
|
Int8,
|
||||||
|
Char,
|
||||||
|
Int16,
|
||||||
|
UInt16,
|
||||||
|
Int32,
|
||||||
|
UInt32,
|
||||||
|
Float32,
|
||||||
|
Int64,
|
||||||
|
UInt64,
|
||||||
|
Float64,
|
||||||
|
DateTime,
|
||||||
|
Int128,
|
||||||
|
UInt128,
|
||||||
|
Decimal,
|
||||||
|
String,
|
||||||
|
RawData,
|
||||||
|
Resource,
|
||||||
|
Record,
|
||||||
|
List,
|
||||||
|
Map,
|
||||||
|
Enum = 0x44,
|
||||||
|
TypedResource = 0x45, // Followed by UUID
|
||||||
|
TypedRecord = 0x46, // Followed by UUID
|
||||||
|
TypedList = 0x48, // Followed by element type
|
||||||
|
Tuple2 = 0x50, // Followed by element type
|
||||||
|
TypedMap = 0x51, // Followed by key type and value type
|
||||||
|
Tuple3 = 0x58,
|
||||||
|
Tuple4 = 0x60,
|
||||||
|
Tuple5 = 0x68,
|
||||||
|
Tuple6 = 0x70,
|
||||||
|
Tuple7 = 0x78
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RepresentationType
|
||||||
|
{
|
||||||
|
public Type? GetRuntimeType()
|
||||||
|
{
|
||||||
|
return Identifier switch
|
||||||
|
{
|
||||||
|
(RepresentationTypeIdentifier.Void) => typeof(void),
|
||||||
|
(RepresentationTypeIdentifier.Dynamic) => typeof(object),
|
||||||
|
(RepresentationTypeIdentifier.Bool) => Nullable ? typeof(bool?) : typeof(bool),
|
||||||
|
(RepresentationTypeIdentifier.Char) => Nullable ? typeof(char?) : typeof(char),
|
||||||
|
(RepresentationTypeIdentifier.UInt8) => Nullable ? typeof(byte?) : typeof(byte),
|
||||||
|
(RepresentationTypeIdentifier.Int8) => Nullable ? typeof(sbyte?) : typeof(sbyte),
|
||||||
|
(RepresentationTypeIdentifier.Int16) => Nullable ? typeof(short?) : typeof(short),
|
||||||
|
(RepresentationTypeIdentifier.UInt16) => Nullable ? typeof(ushort?) : typeof(ushort),
|
||||||
|
(RepresentationTypeIdentifier.Int32) => Nullable ? typeof(int?) : typeof(int),
|
||||||
|
(RepresentationTypeIdentifier.UInt32) => Nullable ? typeof(uint?) : typeof(uint),
|
||||||
|
(RepresentationTypeIdentifier.Int64) => Nullable ? typeof(ulong?) : typeof(long),
|
||||||
|
(RepresentationTypeIdentifier.UInt64) => Nullable ? typeof(ulong?) : typeof(ulong),
|
||||||
|
(RepresentationTypeIdentifier.Float32) => Nullable ? typeof(float?) : typeof(float),
|
||||||
|
(RepresentationTypeIdentifier.Float64) => Nullable ? typeof(double?) : typeof(double),
|
||||||
|
(RepresentationTypeIdentifier.Decimal) => Nullable ? typeof(decimal?) : typeof(decimal),
|
||||||
|
(RepresentationTypeIdentifier.String) => typeof(string), //Nullable ? typeof(Nullable<string>) : typeof(string),
|
||||||
|
(RepresentationTypeIdentifier.DateTime) => Nullable ? typeof(DateTime?) : typeof(DateTime),
|
||||||
|
(RepresentationTypeIdentifier.Resource) => typeof(IResource),
|
||||||
|
(RepresentationTypeIdentifier.Record) => typeof(IRecord),
|
||||||
|
(RepresentationTypeIdentifier.TypedRecord) => Warehouse.GetTemplateByClassId((Guid)GUID, TemplateType.Record).DefinedType,
|
||||||
|
(RepresentationTypeIdentifier.TypedResource) => Warehouse.GetTemplateByClassId((Guid)GUID, TemplateType.Unspecified).DefinedType,
|
||||||
|
(RepresentationTypeIdentifier.Enum) => Warehouse.GetTemplateByClassId((Guid)GUID, TemplateType.Enum).DefinedType,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepresentationTypeIdentifier Identifier;
|
||||||
|
public bool Nullable;
|
||||||
|
public Guid? GUID;
|
||||||
|
//public RepresentationType? SubType1; // List + Map
|
||||||
|
//public RepresentationType? SubType2; // Map
|
||||||
|
//public RepresentationType? SubType3; // No types yet
|
||||||
|
|
||||||
|
public RepresentationType?[] SubTypes = new RepresentationType[3];
|
||||||
|
|
||||||
|
public static RepresentationType? FromType(Type type)
|
||||||
|
{
|
||||||
|
var nullType = System.Nullable.GetUnderlyingType(type);
|
||||||
|
var nullable = false;
|
||||||
|
|
||||||
|
if (nullType != null) {
|
||||||
|
type = nullType;
|
||||||
|
nullable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.IsGenericType)
|
||||||
|
{
|
||||||
|
var genericType = type.GetGenericTypeDefinition();
|
||||||
|
if (genericType == typeof(List<>))
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
if (args[0] == typeof(object))
|
||||||
|
{
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.List, nullable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var subType = FromType(args[0]);
|
||||||
|
if (subType == null) // unrecongnized type
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.TypedList, nullable, null, subType);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(Map<,>))
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
if (args[0] == typeof(object) && args[1] == typeof(object))
|
||||||
|
{
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Map, nullable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var subType1 = FromType(args[0]);
|
||||||
|
if (subType1 == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var subType2 = FromType(args[1]);
|
||||||
|
if (subType2 == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.TypedMap, nullable, null, subType1, subType2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(DistributedPropertyContext<>))
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
return FromType(args[0]);
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(ValueTuple<,>))
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
var subTypes = new RepresentationType[args.Length];
|
||||||
|
for (var i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
subTypes[i] = FromType(args[i]);
|
||||||
|
if (subTypes[i] == null)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Tuple2, nullable, null, subTypes);
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(ValueTuple<,,>))
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
var subTypes = new RepresentationType[args.Length];
|
||||||
|
for(var i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
subTypes[i] = FromType(args[i]);
|
||||||
|
if (subTypes[i] == null)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Tuple3, nullable, null, subTypes);
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(ValueTuple<,,,>))
|
||||||
|
{
|
||||||
|
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
var subTypes = new RepresentationType[args.Length];
|
||||||
|
for (var i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
subTypes[i] = FromType(args[i]);
|
||||||
|
if (subTypes[i] == null)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Tuple4, nullable, null, subTypes);
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(ValueTuple<,,,,>))
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
var subTypes = new RepresentationType[args.Length];
|
||||||
|
for (var i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
subTypes[i] = FromType(args[i]);
|
||||||
|
if (subTypes[i] == null)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Tuple5, nullable, null, subTypes);
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(ValueTuple<,,,,,>))
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
var subTypes = new RepresentationType[args.Length];
|
||||||
|
for (var i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
subTypes[i] = FromType(args[i]);
|
||||||
|
if (subTypes[i] == null)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Tuple6, nullable, null, subTypes);
|
||||||
|
}
|
||||||
|
else if (genericType == typeof(ValueTuple<,,,,,,>))
|
||||||
|
{
|
||||||
|
var args = type.GetGenericArguments();
|
||||||
|
var subTypes = new RepresentationType[args.Length];
|
||||||
|
for (var i = 0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
subTypes[i] = FromType(args[i]);
|
||||||
|
if (subTypes[i] == null)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Tuple7, nullable, null, subTypes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (type.IsArray)
|
||||||
|
{
|
||||||
|
var elementType = type.GetElementType();
|
||||||
|
if (elementType == typeof(object))
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.List, nullable);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var subType = FromType(elementType);
|
||||||
|
|
||||||
|
if (subType == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.TypedList, nullable, null, subType);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == typeof(IResource))
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Resource, nullable);
|
||||||
|
else if (type == typeof(IRecord) || type == typeof(Record))
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Record, nullable);
|
||||||
|
else if (type == typeof(Map<object, object>))
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Map, nullable);
|
||||||
|
else if (Codec.ImplementsInterface(type, typeof(IResource)))
|
||||||
|
{
|
||||||
|
return new RepresentationType(
|
||||||
|
RepresentationTypeIdentifier.TypedResource,
|
||||||
|
nullable,
|
||||||
|
TypeTemplate.GetTypeGuid(type)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
|
||||||
|
{
|
||||||
|
return new RepresentationType(
|
||||||
|
RepresentationTypeIdentifier.TypedRecord,
|
||||||
|
nullable,
|
||||||
|
TypeTemplate.GetTypeGuid(type)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (type.IsEnum)
|
||||||
|
{
|
||||||
|
return new RepresentationType(RepresentationTypeIdentifier.Enum, nullable, TypeTemplate.GetTypeGuid(type));
|
||||||
|
}
|
||||||
|
//else if (typeof(Structure).IsAssignableFrom(t) || t == typeof(ExpandoObject) => RepresentationTypeIdentifier.Structure)
|
||||||
|
//{
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
return type switch
|
||||||
|
{
|
||||||
|
_ when type == typeof(void) => new RepresentationType(RepresentationTypeIdentifier.Void, nullable),
|
||||||
|
_ when type == typeof(object) => new RepresentationType(RepresentationTypeIdentifier.Dynamic, nullable),
|
||||||
|
_ when type == typeof(bool) => new RepresentationType(RepresentationTypeIdentifier.Bool, nullable),
|
||||||
|
_ when type == typeof(char) => new RepresentationType(RepresentationTypeIdentifier.Char, nullable),
|
||||||
|
_ when type == typeof(byte) => new RepresentationType(RepresentationTypeIdentifier.UInt8, nullable),
|
||||||
|
_ when type == typeof(sbyte) => new RepresentationType(RepresentationTypeIdentifier.Int8, nullable),
|
||||||
|
_ when type == typeof(short) => new RepresentationType(RepresentationTypeIdentifier.Int16, nullable),
|
||||||
|
_ when type == typeof(ushort) => new RepresentationType(RepresentationTypeIdentifier.UInt16, nullable),
|
||||||
|
_ when type == typeof(int) => new RepresentationType(RepresentationTypeIdentifier.Int32, nullable),
|
||||||
|
_ when type == typeof(uint) => new RepresentationType(RepresentationTypeIdentifier.UInt32, nullable),
|
||||||
|
_ when type == typeof(long) => new RepresentationType(RepresentationTypeIdentifier.Int64, nullable),
|
||||||
|
_ when type == typeof(ulong) => new RepresentationType(RepresentationTypeIdentifier.UInt64, nullable),
|
||||||
|
_ when type == typeof(float) => new RepresentationType(RepresentationTypeIdentifier.Float32, nullable),
|
||||||
|
_ when type == typeof(double) => new RepresentationType(RepresentationTypeIdentifier.Float64, nullable),
|
||||||
|
_ when type == typeof(decimal) => new RepresentationType(RepresentationTypeIdentifier.Decimal, nullable),
|
||||||
|
_ when type == typeof(string) => new RepresentationType(RepresentationTypeIdentifier.String, nullable),
|
||||||
|
_ when type == typeof(DateTime) => new RepresentationType(RepresentationTypeIdentifier.DateTime, nullable),
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepresentationType(RepresentationTypeIdentifier identifier, bool nullable, Guid? guid = null, params RepresentationType[] subTypes)
|
||||||
|
{
|
||||||
|
Nullable = nullable;
|
||||||
|
Identifier = identifier;
|
||||||
|
GUID = guid;
|
||||||
|
SubTypes = subTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Compose()
|
||||||
|
{
|
||||||
|
var rt = new BinaryList();
|
||||||
|
|
||||||
|
if (Nullable)
|
||||||
|
rt.AddUInt8((byte)(0x80 | (byte)Identifier));
|
||||||
|
else
|
||||||
|
rt.AddUInt8((byte)Identifier);
|
||||||
|
|
||||||
|
if (GUID != null)
|
||||||
|
rt.AddUInt8Array(DC.ToBytes((Guid)GUID));
|
||||||
|
|
||||||
|
if (SubTypes != null)
|
||||||
|
for (var i = 0; i < SubTypes.Length; i++)
|
||||||
|
rt.AddUInt8Array(SubTypes[i].Compose());
|
||||||
|
|
||||||
|
return rt.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//public override string ToString() => Identifier.ToString() + (Nullable ? "?" : "")
|
||||||
|
// + TypeTemplate != null ? "<" + TypeTemplate.ClassName + ">" : "";
|
||||||
|
|
||||||
|
|
||||||
|
public static (uint, RepresentationType) Parse(byte[] data, uint offset)
|
||||||
|
{
|
||||||
|
var oOffset = offset;
|
||||||
|
|
||||||
|
var header = data[offset++];
|
||||||
|
bool nullable = (header & 0x80) > 0;
|
||||||
|
var identifier = (RepresentationTypeIdentifier)(header & 0x7F);
|
||||||
|
|
||||||
|
|
||||||
|
if ((header & 0x40) > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
var hasGUID = (header & 0x4) > 0;
|
||||||
|
var subsCount = (header >> 3) & 0x7;
|
||||||
|
|
||||||
|
Guid? guid = null;
|
||||||
|
|
||||||
|
if (hasGUID)
|
||||||
|
{
|
||||||
|
guid = data.GetGuid(offset);
|
||||||
|
offset += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
var subs = new RepresentationType[subsCount];
|
||||||
|
|
||||||
|
for (var i = 0; i < subsCount; i++)
|
||||||
|
{
|
||||||
|
(var len, subs[i]) = RepresentationType.Parse(data, offset);
|
||||||
|
offset += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (offset - oOffset, new RepresentationType(identifier, nullable, guid, subs));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (1, new RepresentationType(identifier, nullable));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Esiur.Data;
|
|
||||||
|
|
||||||
public enum ResourceComparisonResult
|
|
||||||
{
|
|
||||||
Null, // null
|
|
||||||
Distributed, // resource is distributed
|
|
||||||
Local, // resource is local
|
|
||||||
Same, // Same as previous
|
|
||||||
}
|
|
@ -55,7 +55,7 @@ class ResourceJsonConverter : JsonConverter<IResource>
|
|||||||
foreach (var pt in resource.Instance.Template.Properties)
|
foreach (var pt in resource.Instance.Template.Properties)
|
||||||
{
|
{
|
||||||
var rt = pt.PropertyInfo.GetValue(resource, null);
|
var rt = pt.PropertyInfo.GetValue(resource, null);
|
||||||
if (rt is DistributedPropertyContext)
|
if (rt != null && rt.GetType().IsGenericType)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
writer.WritePropertyName(options.PropertyNamingPolicy?.ConvertName(pt.Name) ?? pt.Name);
|
writer.WritePropertyName(options.PropertyNamingPolicy?.ConvertName(pt.Name) ?? pt.Name);
|
||||||
|
@ -1,180 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
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;
|
|
||||||
using System.Dynamic;
|
|
||||||
|
|
||||||
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 explicit operator Structure(ExpandoObject obj) => FromDynamic(obj);
|
|
||||||
|
|
||||||
public static Structure FromDynamic(ExpandoObject obj)
|
|
||||||
{
|
|
||||||
var rt = new Structure();
|
|
||||||
foreach (var kv in obj)
|
|
||||||
rt[kv.Key] = kv.Value;
|
|
||||||
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);
|
|
||||||
|
|
||||||
var fi = type.GetTypeInfo().GetFields().Where(x => x.IsPublic);
|
|
||||||
foreach (var f in fi)
|
|
||||||
st[f.Name] = f.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Esiur.Data;
|
|
||||||
|
|
||||||
public enum StructureComparisonResult : byte
|
|
||||||
{
|
|
||||||
Null,
|
|
||||||
Structure,
|
|
||||||
StructureSameKeys,
|
|
||||||
StructureSameTypes,
|
|
||||||
Same
|
|
||||||
}
|
|
247
Esiur/Data/TransmissionType.cs
Normal file
247
Esiur/Data/TransmissionType.cs
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
using Esiur.Net.IIP;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Data;
|
||||||
|
|
||||||
|
public enum TransmissionTypeIdentifier : byte
|
||||||
|
{
|
||||||
|
Null = 0x0,
|
||||||
|
False = 0x1,
|
||||||
|
True = 0x2,
|
||||||
|
NotModified = 0x3,
|
||||||
|
UInt8 = 0x8,
|
||||||
|
Int8 = 0x9,
|
||||||
|
Char8 = 0xA,
|
||||||
|
Int16 = 0x10,
|
||||||
|
UInt16 = 0x11,
|
||||||
|
Char16 = 0x12,
|
||||||
|
Int32 = 0x18,
|
||||||
|
UInt32 = 0x19,
|
||||||
|
Float32 = 0x1A,
|
||||||
|
Resource = 0x1B,
|
||||||
|
ResourceLocal = 0x1C,
|
||||||
|
Int64 = 0x20,
|
||||||
|
UInt64 = 0x21,
|
||||||
|
Float64 = 0x22,
|
||||||
|
DateTime = 0x23,
|
||||||
|
Int128 = 0x28,
|
||||||
|
UInt128 = 0x29,
|
||||||
|
Float128 = 0x2A,
|
||||||
|
|
||||||
|
RawData = 0x40,
|
||||||
|
String = 0x41,
|
||||||
|
List = 0x42,
|
||||||
|
ResourceList = 0x43,
|
||||||
|
RecordList = 0x44,
|
||||||
|
Map = 0x45,
|
||||||
|
MapList = 0x46,
|
||||||
|
//Tuple = 0x47,
|
||||||
|
|
||||||
|
Record = 0x80,
|
||||||
|
TypedList = 0x81,
|
||||||
|
TypedMap = 0x82,
|
||||||
|
Tuple = 0x83,
|
||||||
|
Enum = 0x84,
|
||||||
|
Constant = 0x85
|
||||||
|
//TypedResourceList = 0x81,
|
||||||
|
//TypedRecordList = 0x82,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TransmissionTypeClass
|
||||||
|
{
|
||||||
|
Fixed = 0,
|
||||||
|
Dynamic = 1,
|
||||||
|
Typed = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TransmissionType
|
||||||
|
{
|
||||||
|
public TransmissionTypeIdentifier Identifier;
|
||||||
|
public int Index;
|
||||||
|
public TransmissionTypeClass Class;
|
||||||
|
public uint Offset;
|
||||||
|
public ulong ContentLength;
|
||||||
|
public byte Exponent;
|
||||||
|
|
||||||
|
|
||||||
|
public TransmissionType(TransmissionTypeIdentifier identifier, TransmissionTypeClass cls, int index, uint offset, ulong contentLength, byte exponent = 0)
|
||||||
|
{
|
||||||
|
Identifier = identifier;
|
||||||
|
Index = index;
|
||||||
|
Class = cls;
|
||||||
|
Offset=offset;
|
||||||
|
ContentLength = contentLength;
|
||||||
|
Exponent = exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] Compose(TransmissionTypeIdentifier identifier, byte[] data)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (data == null || data.Length == 0)
|
||||||
|
return new byte[] { (byte)identifier };
|
||||||
|
|
||||||
|
var cls = (TransmissionTypeClass)((int)identifier >> 6);
|
||||||
|
if (cls == TransmissionTypeClass.Fixed)
|
||||||
|
{
|
||||||
|
return DC.Combine(new byte[] { (byte)identifier }, 0, 1, data, 0, (uint)data.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var len = (ulong)data.LongLength;
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
return new byte[1] { (byte) identifier };
|
||||||
|
}
|
||||||
|
else if (len <= 0xFF)
|
||||||
|
{
|
||||||
|
var rt = new byte[2 + len];
|
||||||
|
rt[0] = (byte)((byte)identifier | 0x8);
|
||||||
|
rt[1] = (byte)len;
|
||||||
|
Buffer.BlockCopy(data, 0, rt, 2, (int)len);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
else if (len <= 0xFF_FF)
|
||||||
|
{
|
||||||
|
var rt = new byte[3 + len];
|
||||||
|
rt[0] = (byte)((byte)identifier | 0x10);
|
||||||
|
rt[1] = (byte)((len >> 8) & 0xFF);
|
||||||
|
rt[2] = (byte)(len & 0xFF);
|
||||||
|
Buffer.BlockCopy(data, 0, rt, 3, (int)len);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
else if (len <= 0xFF_FF_FF)
|
||||||
|
{
|
||||||
|
var rt = new byte[4 + len];
|
||||||
|
rt[0] = (byte)((byte)identifier | 0x18);
|
||||||
|
rt[1] = (byte)((len >> 16) & 0xFF);
|
||||||
|
rt[2] = (byte)((len >> 8) & 0xFF);
|
||||||
|
rt[3] = (byte)(len & 0xFF);
|
||||||
|
Buffer.BlockCopy(data, 0, rt, 4, (int)len);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
else if (len <= 0xFF_FF_FF_FF)
|
||||||
|
{
|
||||||
|
var rt = new byte[5 + len];
|
||||||
|
rt[0] = (byte)((byte)identifier | 0x20);
|
||||||
|
rt[1] = (byte)((len >> 24) & 0xFF);
|
||||||
|
rt[2] = (byte)((len >> 16) & 0xFF);
|
||||||
|
rt[3] = (byte)((len >> 8) & 0xFF);
|
||||||
|
rt[4] = (byte)(len & 0xFF);
|
||||||
|
Buffer.BlockCopy(data, 0, rt, 5, (int)len);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
else if (len <= 0xFF_FF_FF_FF_FF)
|
||||||
|
{
|
||||||
|
var rt = new byte[6 + len];
|
||||||
|
rt[0] = (byte)((byte)identifier | 0x28);
|
||||||
|
rt[1] = (byte)((len >> 32) & 0xFF);
|
||||||
|
rt[2] = (byte)((len >> 24) & 0xFF);
|
||||||
|
rt[3] = (byte)((len >> 16) & 0xFF);
|
||||||
|
rt[4] = (byte)((len >> 8) & 0xFF);
|
||||||
|
rt[5] = (byte)(len & 0xFF);
|
||||||
|
Buffer.BlockCopy(data, 0, rt, 6, (int)len);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
else if (len <= 0xFF_FF_FF_FF_FF_FF)
|
||||||
|
{
|
||||||
|
var rt = new byte[7 + len];
|
||||||
|
rt[0] = (byte)((byte)identifier | 0x30);
|
||||||
|
rt[1] = (byte)((len >> 40) & 0xFF);
|
||||||
|
rt[2] = (byte)((len >> 32) & 0xFF);
|
||||||
|
rt[3] = (byte)((len >> 24) & 0xFF);
|
||||||
|
rt[4] = (byte)((len >> 16) & 0xFF);
|
||||||
|
rt[5] = (byte)((len >> 8) & 0xFF);
|
||||||
|
rt[6] = (byte)(len & 0xFF);
|
||||||
|
Buffer.BlockCopy(data, 0, rt, 7, (int)len);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
else //if (len <= 0xFF_FF_FF_FF_FF_FF_FF)
|
||||||
|
{
|
||||||
|
var rt = new byte[8 + len];
|
||||||
|
rt[0] = (byte)((byte)identifier | 0x38);
|
||||||
|
rt[1] = (byte)((len >> 48) & 0xFF);
|
||||||
|
rt[2] = (byte)((len >> 40) & 0xFF);
|
||||||
|
rt[3] = (byte)((len >> 32) & 0xFF);
|
||||||
|
rt[4] = (byte)((len >> 24) & 0xFF);
|
||||||
|
rt[5] = (byte)((len >> 16) & 0xFF);
|
||||||
|
rt[6] = (byte)((len >> 8) & 0xFF);
|
||||||
|
rt[7] = (byte)(len & 0xFF);
|
||||||
|
Buffer.BlockCopy(data, 0, rt, 8, (int)len);
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
//else // if (len <= 0xFF_FF_FF_FF_FF_FF_FF_FF)
|
||||||
|
//{
|
||||||
|
// var rt = new byte[9 + len];
|
||||||
|
// rt[0] = (byte)((byte)identifier | 0x8);
|
||||||
|
// rt[1] = (byte)((len >> 56) & 0xFF);
|
||||||
|
// rt[2] = (byte)((len >> 48) & 0xFF);
|
||||||
|
// rt[3] = (byte)((len >> 40) & 0xFF);
|
||||||
|
// rt[4] = (byte)((len >> 32) & 0xFF);
|
||||||
|
// rt[5] = (byte)((len >> 24) & 0xFF);
|
||||||
|
// rt[6] = (byte)((len >> 16) & 0xFF);
|
||||||
|
// rt[7] = (byte)((len >> 8) & 0xFF);
|
||||||
|
// rt[8] = (byte)(len & 0xFF);
|
||||||
|
// Buffer.BlockCopy(data, 0, rt, 9, (int)len);
|
||||||
|
// return rt;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
// // add length
|
||||||
|
// int bytes = 1;
|
||||||
|
//for (var i = 56; i > 0; i -= 8, bytes++)
|
||||||
|
// if (len <= (0xFF_FF_FF_FF_FF_FF_FF_FF >> i))
|
||||||
|
// break;
|
||||||
|
|
||||||
|
//var rt = new byte[1 + bytes + data.Length];
|
||||||
|
//rt[0] = (byte)((byte)identifier | (bytes << 3));
|
||||||
|
|
||||||
|
//for (var i = 1; i <= bytes; i++)
|
||||||
|
// rt[i] = data.LongLength >> i * 8;
|
||||||
|
|
||||||
|
//Buffer.BlockCopy(data, 0, rt, 1 + bytes, data.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (ulong, TransmissionType?) Parse(byte[] data, uint offset, uint ends)
|
||||||
|
{
|
||||||
|
var h = data[offset++];
|
||||||
|
|
||||||
|
var cls = (TransmissionTypeClass)(h >> 6);
|
||||||
|
|
||||||
|
if (cls == TransmissionTypeClass.Fixed)
|
||||||
|
{
|
||||||
|
var exp = (h & 0x38) >> 3;
|
||||||
|
|
||||||
|
if (exp == 0)
|
||||||
|
return (1, new TransmissionType((TransmissionTypeIdentifier)h, cls, h & 0x7, 0, (byte)exp));
|
||||||
|
|
||||||
|
ulong cl = (ulong)(1 << (exp -1));
|
||||||
|
|
||||||
|
if (ends - offset < cl)
|
||||||
|
return (ends - offset - (uint)cl, null);
|
||||||
|
|
||||||
|
//offset += (uint)cl;
|
||||||
|
|
||||||
|
return (1 + cl, new TransmissionType((TransmissionTypeIdentifier)h, cls, h & 0x7, offset, cl, (byte)exp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulong cll = (ulong)(h >> 3) & 0x7;
|
||||||
|
|
||||||
|
if (ends - offset < cll)
|
||||||
|
return (ends - offset - (uint)cll, null);
|
||||||
|
|
||||||
|
ulong cl = 0;
|
||||||
|
|
||||||
|
for (uint i = 0; i < cll; i++)
|
||||||
|
cl = cl << 8 | data[offset++];
|
||||||
|
|
||||||
|
return (1 + cl + cll, new TransmissionType((TransmissionTypeIdentifier)(h & 0xC7), cls, h & 0x7, offset, cl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,12 +6,12 @@
|
|||||||
<Copyright>Ahmed Kh. Zamil</Copyright>
|
<Copyright>Ahmed Kh. Zamil</Copyright>
|
||||||
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Version>2.0.0-alpha</Version>
|
<Version>2.1.1</Version>
|
||||||
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
||||||
<Authors>Ahmed Kh. Zamil</Authors>
|
<Authors>Ahmed Kh. Zamil</Authors>
|
||||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
<AssemblyVersion></AssemblyVersion>
|
||||||
<Company>Esiur Foundation</Company>
|
<Company>Esiur Foundation</Company>
|
||||||
<FileVersion>2.0.0.0</FileVersion>
|
<FileVersion></FileVersion>
|
||||||
<AssemblyName>Esiur</AssemblyName>
|
<AssemblyName>Esiur</AssemblyName>
|
||||||
<RootNamespace>Esiur</RootNamespace>
|
<RootNamespace>Esiur</RootNamespace>
|
||||||
<PackageId>Esiur</PackageId>
|
<PackageId>Esiur</PackageId>
|
||||||
@ -36,11 +36,15 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Remove="Core\AsyncBagAwaiterGeneric.cs" />
|
||||||
|
<Compile Remove="Core\AsyncBagGeneric.cs" />
|
||||||
<Compile Remove="Core\AsyncReplyNon.cs" />
|
<Compile Remove="Core\AsyncReplyNon.cs" />
|
||||||
<Compile Remove="Core\IAsyncReply.cs" />
|
<Compile Remove="Core\IAsyncReply.cs" />
|
||||||
|
<Compile Remove="Data\DataType.cs" />
|
||||||
<Compile Remove="Resource\ResourceEvent.cs" />
|
<Compile Remove="Resource\ResourceEvent.cs" />
|
||||||
<Compile Remove="Resource\ResourceFunction.cs" />
|
<Compile Remove="Resource\ResourceFunction.cs" />
|
||||||
<Compile Remove="Resource\ResourceProperty.cs" />
|
<Compile Remove="Resource\ResourceProperty.cs" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -48,29 +52,31 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="Core\AsyncBagAwaiterGeneric.cs" />
|
||||||
<None Include="Core\AsyncReplyNon.cs" />
|
<None Include="Core\AsyncReplyNon.cs" />
|
||||||
<None Include="Core\IAsyncReply.cs" />
|
<None Include="Core\IAsyncReply.cs" />
|
||||||
|
<None Include="Data\DataType.cs" />
|
||||||
<None Include="Resource\ResourceEvent.cs" />
|
<None Include="Resource\ResourceEvent.cs" />
|
||||||
<None Include="Resource\ResourceFunction.cs" />
|
<None Include="Resource\ResourceFunction.cs" />
|
||||||
<None Include="Resource\ResourceProperty.cs" />
|
<None Include="Resource\ResourceProperty.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.9.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.0.1" />
|
||||||
<PackageReference Include="System.Collections" Version="4.3.0" />
|
<PackageReference Include="System.Collections" Version="4.3.0" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
<PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" />
|
<PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
|
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Interactive.Async" Version="5.0.0" />
|
<PackageReference Include="System.Interactive.Async" Version="5.1.0" />
|
||||||
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
|
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
<PackageReference Include="System.Net.Security" Version="4.3.2" />
|
||||||
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
|
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
|
||||||
<PackageReference Include="System.Text.Json" Version="5.0.2" GeneratePathProperty="true" />
|
<PackageReference Include="System.Text.Json" Version="6.0.1" GeneratePathProperty="true" />
|
||||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
||||||
|
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="all" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
@ -83,9 +89,22 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Core\AsyncBagGeneric.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="LICENSE" Pack="true" PackagePath="">
|
<None Include="LICENSE" Pack="true" PackagePath="">
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Include="Core\AsyncBagAwaiterGeneric.cs" />
|
||||||
|
<Page Include="Core\AsyncBagGeneric.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
@ -43,6 +43,7 @@ public abstract class PacketFilter : IResource
|
|||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
|
|
||||||
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
||||||
|
|
||||||
public abstract bool Execute(Packet packet);
|
public abstract bool Execute(Packet packet);
|
||||||
@ -51,4 +52,6 @@ public abstract class PacketFilter : IResource
|
|||||||
{
|
{
|
||||||
OnDestroy?.Invoke(this);
|
OnDestroy?.Invoke(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ public class PacketServer : IResource
|
|||||||
}
|
}
|
||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
|
public event PropertyModifiedEvent PropertyModified;
|
||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
|
@ -103,26 +103,36 @@ public class HTTPConnection : NetworkConnection
|
|||||||
|
|
||||||
public bool Upgrade()
|
public bool Upgrade()
|
||||||
{
|
{
|
||||||
if (IsWebsocketRequest())
|
var ok = Upgrade(Request, Response);
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
WSMode = true;
|
||||||
|
Send();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Upgrade(HTTPRequestPacket request, HTTPResponsePacket response)
|
||||||
|
{
|
||||||
|
if (IsWebsocketRequest(request))
|
||||||
{
|
{
|
||||||
string magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
string magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
string ret = Request.Headers["Sec-WebSocket-Key"] + magicString;
|
string ret = request.Headers["Sec-WebSocket-Key"] + magicString;
|
||||||
// Compute the SHA1 hash
|
// Compute the SHA1 hash
|
||||||
SHA1 sha = SHA1.Create();
|
SHA1 sha = SHA1.Create();
|
||||||
byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));
|
byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));
|
||||||
Response.Headers["Upgrade"] = Request.Headers["Upgrade"];
|
response.Headers["Upgrade"] = request.Headers["Upgrade"];
|
||||||
Response.Headers["Connection"] = Request.Headers["Connection"];// "Upgrade";
|
response.Headers["Connection"] = request.Headers["Connection"];// "Upgrade";
|
||||||
Response.Headers["Sec-WebSocket-Accept"] = Convert.ToBase64String(sha1Hash);
|
response.Headers["Sec-WebSocket-Accept"] = Convert.ToBase64String(sha1Hash);
|
||||||
|
|
||||||
if (Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
|
if (request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
|
||||||
Response.Headers["Sec-WebSocket-Protocol"] = Request.Headers["Sec-WebSocket-Protocol"];
|
response.Headers["Sec-WebSocket-Protocol"] = request.Headers["Sec-WebSocket-Protocol"];
|
||||||
|
|
||||||
|
|
||||||
Response.Number = HTTPResponsePacket.ResponseCode.Switching;
|
response.Number = HTTPResponsePacket.ResponseCode.Switching;
|
||||||
Response.Text = "Switching Protocols";
|
response.Text = "Switching Protocols";
|
||||||
WSMode = true;
|
|
||||||
|
|
||||||
Send();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -212,13 +222,18 @@ public class HTTPConnection : NetworkConnection
|
|||||||
|
|
||||||
public bool IsWebsocketRequest()
|
public bool IsWebsocketRequest()
|
||||||
{
|
{
|
||||||
if (Request.Headers.ContainsKey("connection")
|
return IsWebsocketRequest(this.Request);
|
||||||
&& Request.Headers["connection"].ToLower().Contains("upgrade")
|
}
|
||||||
&& Request.Headers.ContainsKey("upgrade")
|
|
||||||
&& Request.Headers["upgrade"].ToLower() == "websocket"
|
public static bool IsWebsocketRequest(HTTPRequestPacket request)
|
||||||
&& Request.Headers.ContainsKey("Sec-WebSocket-Version")
|
{
|
||||||
&& Request.Headers["Sec-WebSocket-Version"] == "13"
|
if (request.Headers.ContainsKey("connection")
|
||||||
&& Request.Headers.ContainsKey("Sec-WebSocket-Key"))
|
&& request.Headers["connection"].ToLower().Contains("upgrade")
|
||||||
|
&& request.Headers.ContainsKey("upgrade")
|
||||||
|
&& request.Headers["upgrade"].ToLower() == "websocket"
|
||||||
|
&& request.Headers.ContainsKey("Sec-WebSocket-Version")
|
||||||
|
&& request.Headers["Sec-WebSocket-Version"] == "13"
|
||||||
|
&& request.Headers.ContainsKey("Sec-WebSocket-Key"))
|
||||||
//&& Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
|
//&& Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -284,7 +299,7 @@ public class HTTPConnection : NetworkConnection
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (IsWebsocketRequest() & !WSMode)
|
if (IsWebsocketRequest(Request) & !WSMode)
|
||||||
{
|
{
|
||||||
Upgrade();
|
Upgrade();
|
||||||
//return;
|
//return;
|
||||||
|
@ -46,7 +46,6 @@ public abstract class HTTPFilter : IResource
|
|||||||
}
|
}
|
||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -155,7 +155,12 @@ public class HTTPServer : NetworkServer<HTTPConnection>, IResource
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//public delegate void HTTPGetHandler(HTTPConnection connection, object[] params values);
|
||||||
|
|
||||||
|
public void MapGet(string pattern, Delegate handler)
|
||||||
|
{
|
||||||
|
// if (p)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -39,6 +39,7 @@ using Esiur.Resource.Template;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using static Esiur.Net.Packets.IIPPacket;
|
using static Esiur.Net.Packets.IIPPacket;
|
||||||
|
using Esiur.Net.HTTP;
|
||||||
|
|
||||||
namespace Esiur.Net.IIP;
|
namespace Esiur.Net.IIP;
|
||||||
public partial class DistributedConnection : NetworkConnection, IStore
|
public partial class DistributedConnection : NetworkConnection, IStore
|
||||||
@ -56,6 +57,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event ErrorEvent OnError;
|
public event ErrorEvent OnError;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IIPPacket packet = new IIPPacket();
|
IIPPacket packet = new IIPPacket();
|
||||||
IIPAuthPacket authPacket = new IIPAuthPacket();
|
IIPAuthPacket authPacket = new IIPAuthPacket();
|
||||||
|
|
||||||
@ -71,8 +74,12 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
string _hostname;
|
string _hostname;
|
||||||
ushort _port;
|
ushort _port;
|
||||||
|
|
||||||
|
bool initialPacket = true;
|
||||||
|
|
||||||
DateTime loginDate;
|
DateTime loginDate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Local username to authenticate ourselves.
|
/// Local username to authenticate ourselves.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -350,7 +357,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
if (ready)
|
if (ready)
|
||||||
{
|
{
|
||||||
var rt = packet.Parse(msg, offset, ends);
|
var rt = packet.Parse(msg, offset, ends);
|
||||||
//Console.WriteLine("Rec: " + chunkId + " " + packet.ToString());
|
Console.WriteLine("Rec: " + chunkId + " " + packet.ToString());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (packet.Command == IIPPacketCommand.Event)
|
if (packet.Command == IIPPacketCommand.Event)
|
||||||
@ -394,10 +401,10 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
IIPEventResourceDestroyed(packet.ResourceId);
|
IIPEventResourceDestroyed(packet.ResourceId);
|
||||||
break;
|
break;
|
||||||
case IIPPacket.IIPPacketEvent.PropertyUpdated:
|
case IIPPacket.IIPPacketEvent.PropertyUpdated:
|
||||||
IIPEventPropertyUpdated(packet.ResourceId, packet.MethodIndex, packet.Content);
|
IIPEventPropertyUpdated(packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);// packet.Content);
|
||||||
break;
|
break;
|
||||||
case IIPPacket.IIPPacketEvent.EventOccurred:
|
case IIPPacket.IIPPacketEvent.EventOccurred:
|
||||||
IIPEventEventOccurred(packet.ResourceId, packet.MethodIndex, packet.Content);
|
IIPEventEventOccurred(packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);//packet.Content);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacketEvent.ChildAdded:
|
case IIPPacketEvent.ChildAdded:
|
||||||
@ -407,10 +414,11 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
IIPEventChildRemoved(packet.ResourceId, packet.ChildId);
|
IIPEventChildRemoved(packet.ResourceId, packet.ChildId);
|
||||||
break;
|
break;
|
||||||
case IIPPacketEvent.Renamed:
|
case IIPPacketEvent.Renamed:
|
||||||
IIPEventRenamed(packet.ResourceId, packet.Content);
|
IIPEventRenamed(packet.ResourceId, packet.ResourceLink);
|
||||||
break;
|
break;
|
||||||
case IIPPacketEvent.AttributesUpdated:
|
case IIPPacketEvent.AttributesUpdated:
|
||||||
IIPEventAttributesUpdated(packet.ResourceId, packet.Content);
|
// @TODO: fix this
|
||||||
|
//IIPEventAttributesUpdated(packet.ResourceId, packet.Content);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,7 +437,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
IIPRequestDetachResource(packet.CallbackId, packet.ResourceId);
|
IIPRequestDetachResource(packet.CallbackId, packet.ResourceId);
|
||||||
break;
|
break;
|
||||||
case IIPPacket.IIPPacketAction.CreateResource:
|
case IIPPacket.IIPPacketAction.CreateResource:
|
||||||
IIPRequestCreateResource(packet.CallbackId, packet.StoreId, packet.ResourceId, packet.Content);
|
//@TODO : fix this
|
||||||
|
//IIPRequestCreateResource(packet.CallbackId, packet.StoreId, packet.ResourceId, packet.Content);
|
||||||
break;
|
break;
|
||||||
case IIPPacket.IIPPacketAction.DeleteResource:
|
case IIPPacket.IIPPacketAction.DeleteResource:
|
||||||
IIPRequestDeleteResource(packet.CallbackId, packet.ResourceId);
|
IIPRequestDeleteResource(packet.CallbackId, packet.ResourceId);
|
||||||
@ -441,7 +450,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
IIPRequestRemoveChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
|
IIPRequestRemoveChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
|
||||||
break;
|
break;
|
||||||
case IIPPacketAction.RenameResource:
|
case IIPPacketAction.RenameResource:
|
||||||
IIPRequestRenameResource(packet.CallbackId, packet.ResourceId, packet.Content);
|
IIPRequestRenameResource(packet.CallbackId, packet.ResourceId, packet.ResourceName);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Inquire
|
// Inquire
|
||||||
@ -474,13 +483,13 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Invoke
|
// Invoke
|
||||||
case IIPPacket.IIPPacketAction.InvokeFunctionArrayArguments:
|
case IIPPacket.IIPPacketAction.InvokeFunction:
|
||||||
IIPRequestInvokeFunctionArrayArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
|
IIPRequestInvokeFunction(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments:
|
//case IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments:
|
||||||
IIPRequestInvokeFunctionNamedArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
|
// IIPRequestInvokeFunctionNamedArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
//case IIPPacket.IIPPacketAction.GetProperty:
|
//case IIPPacket.IIPPacketAction.GetProperty:
|
||||||
// IIPRequestGetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
// IIPRequestGetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
|
||||||
@ -498,27 +507,33 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacket.IIPPacketAction.SetProperty:
|
case IIPPacket.IIPPacketAction.SetProperty:
|
||||||
IIPRequestSetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
|
IIPRequestSetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex, (TransmissionType)packet.DataType, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Attribute
|
// Attribute
|
||||||
case IIPPacketAction.GetAllAttributes:
|
case IIPPacketAction.GetAllAttributes:
|
||||||
IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
// @TODO : fix this
|
||||||
|
//IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
||||||
break;
|
break;
|
||||||
case IIPPacketAction.UpdateAllAttributes:
|
case IIPPacketAction.UpdateAllAttributes:
|
||||||
IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
// @TODO : fix this
|
||||||
|
//IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
||||||
break;
|
break;
|
||||||
case IIPPacketAction.ClearAllAttributes:
|
case IIPPacketAction.ClearAllAttributes:
|
||||||
IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
// @TODO : fix this
|
||||||
|
//IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
|
||||||
break;
|
break;
|
||||||
case IIPPacketAction.GetAttributes:
|
case IIPPacketAction.GetAttributes:
|
||||||
IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
// @TODO : fix this
|
||||||
|
//IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
||||||
break;
|
break;
|
||||||
case IIPPacketAction.UpdateAttributes:
|
case IIPPacketAction.UpdateAttributes:
|
||||||
IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
// @TODO : fix this
|
||||||
|
//IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
||||||
break;
|
break;
|
||||||
case IIPPacketAction.ClearAttributes:
|
case IIPPacketAction.ClearAttributes:
|
||||||
IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
// @TODO : fix this
|
||||||
|
//IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,11 +543,11 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
{
|
{
|
||||||
// Manage
|
// Manage
|
||||||
case IIPPacket.IIPPacketAction.AttachResource:
|
case IIPPacket.IIPPacketAction.AttachResource:
|
||||||
IIPReply(packet.CallbackId, packet.ClassId, packet.ResourceAge, packet.ResourceLink, packet.Content);
|
IIPReply(packet.CallbackId, packet.ClassId, packet.ResourceAge, packet.ResourceLink, packet.DataType, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacket.IIPPacketAction.ReattachResource:
|
case IIPPacket.IIPPacketAction.ReattachResource:
|
||||||
IIPReply(packet.CallbackId, packet.ResourceAge, packet.Content);
|
IIPReply(packet.CallbackId, packet.ResourceAge, packet.DataType, msg);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case IIPPacket.IIPPacketAction.DetachResource:
|
case IIPPacket.IIPPacketAction.DetachResource:
|
||||||
@ -555,7 +570,9 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
case IIPPacket.IIPPacketAction.TemplateFromClassName:
|
case IIPPacket.IIPPacketAction.TemplateFromClassName:
|
||||||
case IIPPacket.IIPPacketAction.TemplateFromClassId:
|
case IIPPacket.IIPPacketAction.TemplateFromClassId:
|
||||||
case IIPPacket.IIPPacketAction.TemplateFromResourceId:
|
case IIPPacket.IIPPacketAction.TemplateFromResourceId:
|
||||||
IIPReply(packet.CallbackId, TypeTemplate.Parse(packet.Content));
|
|
||||||
|
var content = msg.Clip(packet.DataType.Value.Offset, (uint)packet.DataType.Value.ContentLength);
|
||||||
|
IIPReply(packet.CallbackId, TypeTemplate.Parse(content));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacketAction.QueryLink:
|
case IIPPacketAction.QueryLink:
|
||||||
@ -563,13 +580,12 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
case IIPPacketAction.ResourceParents:
|
case IIPPacketAction.ResourceParents:
|
||||||
case IIPPacketAction.ResourceHistory:
|
case IIPPacketAction.ResourceHistory:
|
||||||
case IIPPacketAction.LinkTemplates:
|
case IIPPacketAction.LinkTemplates:
|
||||||
IIPReply(packet.CallbackId, packet.Content);
|
IIPReply(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Invoke
|
// Invoke
|
||||||
case IIPPacket.IIPPacketAction.InvokeFunctionArrayArguments:
|
case IIPPacket.IIPPacketAction.InvokeFunction:
|
||||||
case IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments:
|
IIPReplyInvoke(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
|
||||||
IIPReplyInvoke(packet.CallbackId, packet.Content);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//case IIPPacket.IIPPacketAction.GetProperty:
|
//case IIPPacket.IIPPacketAction.GetProperty:
|
||||||
@ -589,7 +605,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
// Attribute
|
// Attribute
|
||||||
case IIPPacketAction.GetAllAttributes:
|
case IIPPacketAction.GetAllAttributes:
|
||||||
case IIPPacketAction.GetAttributes:
|
case IIPPacketAction.GetAttributes:
|
||||||
IIPReply(packet.CallbackId, packet.Content);
|
IIPReply(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IIPPacketAction.UpdateAllAttributes:
|
case IIPPacketAction.UpdateAllAttributes:
|
||||||
@ -616,7 +632,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
IIPReportProgress(packet.CallbackId, ProgressType.Execution, packet.ProgressValue, packet.ProgressMax);
|
IIPReportProgress(packet.CallbackId, ProgressType.Execution, packet.ProgressValue, packet.ProgressMax);
|
||||||
break;
|
break;
|
||||||
case IIPPacketReport.ChunkStream:
|
case IIPPacketReport.ChunkStream:
|
||||||
IIPReportChunk(packet.CallbackId, packet.Content);
|
IIPReportChunk(packet.CallbackId, (TransmissionType)packet.DataType, msg);// packet.Content);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -626,6 +642,62 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// check if the reqeust through websockets
|
||||||
|
|
||||||
|
if (initialPacket)
|
||||||
|
{
|
||||||
|
initialPacket = false;
|
||||||
|
|
||||||
|
if (msg.Length > 3 && Encoding.Default.GetString(msg, 0, 3) == "GET")
|
||||||
|
{
|
||||||
|
// Parse with http packet
|
||||||
|
var req = new HTTPRequestPacket();
|
||||||
|
var pSize = req.Parse(msg, 0, (uint)msg.Length);
|
||||||
|
if (pSize > 0)
|
||||||
|
{
|
||||||
|
// check for WS upgrade
|
||||||
|
|
||||||
|
if (HTTPConnection.IsWebsocketRequest(req))
|
||||||
|
{
|
||||||
|
|
||||||
|
Socket?.Unhold();
|
||||||
|
|
||||||
|
var res = new HTTPResponsePacket();
|
||||||
|
|
||||||
|
HTTPConnection.Upgrade(req, res);
|
||||||
|
|
||||||
|
|
||||||
|
res.Compose(HTTPResponsePacket.ComposeOptions.AllCalculateLength);
|
||||||
|
Send(res.Data);
|
||||||
|
// replace my socket with websockets
|
||||||
|
var tcpSocket = this.Unassign();
|
||||||
|
var wsSocket = new WSocket(tcpSocket);
|
||||||
|
this.Assign(wsSocket);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
var res = new HTTPResponsePacket();
|
||||||
|
res.Number = HTTPResponsePacket.ResponseCode.BadRequest;
|
||||||
|
res.Compose(HTTPResponsePacket.ComposeOptions.AllCalculateLength);
|
||||||
|
Send(res.Data);
|
||||||
|
//@TODO: kill the connection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// packet incomplete
|
||||||
|
return (uint)pSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// switching completed
|
||||||
|
return (uint)msg.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(msg.GetString(offset, ends - offset));
|
||||||
|
|
||||||
var rt = authPacket.Parse(msg, offset, ends);
|
var rt = authPacket.Parse(msg, offset, ends);
|
||||||
|
|
||||||
//Console.WriteLine(session.LocalAuthentication.Type.ToString() + " " + offset + " " + ends + " " + rt + " " + authPacket.ToString());
|
//Console.WriteLine(session.LocalAuthentication.Type.ToString() + " " + offset + " " + ends + " " + rt + " " + authPacket.ToString());
|
||||||
@ -649,7 +721,16 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Server.Membership.UserExists(authPacket.RemoteUsername, authPacket.Domain).Then(x =>
|
if (Server.Membership == null)
|
||||||
|
{
|
||||||
|
var errMsg = DC.ToBytes("Membership not set.");
|
||||||
|
|
||||||
|
SendParams().AddUInt8(0xc0)
|
||||||
|
.AddUInt8((byte)ExceptionCode.GeneralFailure)
|
||||||
|
.AddUInt16((ushort)errMsg.Length)
|
||||||
|
.AddUInt8Array(errMsg).Done();
|
||||||
|
}
|
||||||
|
else Server.Membership.UserExists(authPacket.RemoteUsername, authPacket.Domain).Then(x =>
|
||||||
{
|
{
|
||||||
if (x)
|
if (x)
|
||||||
{
|
{
|
||||||
@ -660,15 +741,15 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
.AddUInt8(0xa0)
|
.AddUInt8(0xa0)
|
||||||
.AddUInt8Array(localNonce)
|
.AddUInt8Array(localNonce)
|
||||||
.Done();
|
.Done();
|
||||||
//SendParams((byte)0xa0, localNonce);
|
//SendParams((byte)0xa0, localNonce);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Console.WriteLine("User not found");
|
//Console.WriteLine("User not found");
|
||||||
SendParams().AddUInt8(0xc0)
|
SendParams().AddUInt8(0xc0)
|
||||||
.AddUInt8((byte)ExceptionCode.UserOrTokenNotFound)
|
.AddUInt8((byte)ExceptionCode.UserOrTokenNotFound)
|
||||||
.AddUInt16(14)
|
.AddUInt16(14)
|
||||||
.AddString("User not found").Done();
|
.AddString("User not found").Done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -686,31 +767,43 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Check if user and token exists
|
if (Server.Membership == null)
|
||||||
Server.Membership.TokenExists(authPacket.RemoteTokenIndex, authPacket.Domain).Then(x =>
|
|
||||||
{
|
{
|
||||||
if (x != null)
|
SendParams()
|
||||||
{
|
|
||||||
session.RemoteAuthentication.Username = x;
|
|
||||||
session.RemoteAuthentication.TokenIndex = authPacket.RemoteTokenIndex;
|
|
||||||
remoteNonce = authPacket.RemoteNonce;
|
|
||||||
session.RemoteAuthentication.Domain = authPacket.Domain;
|
|
||||||
SendParams()
|
|
||||||
.AddUInt8(0xa0)
|
|
||||||
.AddUInt8Array(localNonce)
|
|
||||||
.Done();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Console.WriteLine("User not found");
|
|
||||||
SendParams()
|
|
||||||
.AddUInt8(0xc0)
|
.AddUInt8(0xc0)
|
||||||
.AddUInt8((byte)ExceptionCode.UserOrTokenNotFound)
|
.AddUInt8((byte)ExceptionCode.UserOrTokenNotFound)
|
||||||
.AddUInt16(15)
|
.AddUInt16(15)
|
||||||
.AddString("Token not found")
|
.AddString("Token not found")
|
||||||
.Done();
|
.Done();
|
||||||
}
|
}
|
||||||
});
|
// Check if user and token exists
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Server.Membership.TokenExists(authPacket.RemoteTokenIndex, authPacket.Domain).Then(x =>
|
||||||
|
{
|
||||||
|
if (x != null)
|
||||||
|
{
|
||||||
|
session.RemoteAuthentication.Username = x;
|
||||||
|
session.RemoteAuthentication.TokenIndex = authPacket.RemoteTokenIndex;
|
||||||
|
remoteNonce = authPacket.RemoteNonce;
|
||||||
|
session.RemoteAuthentication.Domain = authPacket.Domain;
|
||||||
|
SendParams()
|
||||||
|
.AddUInt8(0xa0)
|
||||||
|
.AddUInt8Array(localNonce)
|
||||||
|
.Done();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Console.WriteLine("User not found");
|
||||||
|
SendParams()
|
||||||
|
.AddUInt8(0xc0)
|
||||||
|
.AddUInt8((byte)ExceptionCode.UserOrTokenNotFound)
|
||||||
|
.AddUInt16(15)
|
||||||
|
.AddString("Token not found")
|
||||||
|
.Done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -729,7 +822,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Check if guests are allowed
|
// Check if guests are allowed
|
||||||
if (Server.Membership.GuestsAllowed)
|
if (Server.Membership?.GuestsAllowed ?? true)
|
||||||
{
|
{
|
||||||
session.RemoteAuthentication.Username = "g-" + Global.GenerateCode();
|
session.RemoteAuthentication.Username = "g-" + Global.GenerateCode();
|
||||||
session.RemoteAuthentication.Domain = authPacket.Domain;
|
session.RemoteAuthentication.Domain = authPacket.Domain;
|
||||||
@ -789,31 +882,31 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
if (pw != null)
|
if (pw != null)
|
||||||
{
|
{
|
||||||
var hashFunc = SHA256.Create();
|
var hashFunc = SHA256.Create();
|
||||||
//var hash = hashFunc.ComputeHash(BinaryList.ToBytes(pw, remoteNonce, localNonce));
|
//var hash = hashFunc.ComputeHash(BinaryList.ToBytes(pw, remoteNonce, localNonce));
|
||||||
var hash = hashFunc.ComputeHash((new BinaryList())
|
var hash = hashFunc.ComputeHash((new BinaryList())
|
||||||
.AddUInt8Array(pw)
|
.AddUInt8Array(pw)
|
||||||
.AddUInt8Array(remoteNonce)
|
.AddUInt8Array(remoteNonce)
|
||||||
.AddUInt8Array(localNonce)
|
.AddUInt8Array(localNonce)
|
||||||
.ToArray());
|
.ToArray());
|
||||||
if (hash.SequenceEqual(remoteHash))
|
if (hash.SequenceEqual(remoteHash))
|
||||||
{
|
{
|
||||||
// send our hash
|
// send our hash
|
||||||
//var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localNonce, remoteNonce, pw));
|
//var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localNonce, remoteNonce, pw));
|
||||||
//SendParams((byte)0, localHash);
|
//SendParams((byte)0, localHash);
|
||||||
|
|
||||||
var localHash = hashFunc.ComputeHash((new BinaryList()).AddUInt8Array(localNonce).AddUInt8Array(remoteNonce).AddUInt8Array(pw).ToArray());
|
var localHash = hashFunc.ComputeHash((new BinaryList()).AddUInt8Array(localNonce).AddUInt8Array(remoteNonce).AddUInt8Array(pw).ToArray());
|
||||||
SendParams().AddUInt8(0).AddUInt8Array(localHash).Done();
|
SendParams().AddUInt8(0).AddUInt8Array(localHash).Done();
|
||||||
|
|
||||||
readyToEstablish = true;
|
readyToEstablish = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:DENIED");
|
//Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:DENIED");
|
||||||
SendParams().AddUInt8(0xc0)
|
SendParams().AddUInt8(0xc0)
|
||||||
.AddUInt8((byte)ExceptionCode.AccessDenied)
|
.AddUInt8((byte)ExceptionCode.AccessDenied)
|
||||||
.AddUInt16(13)
|
.AddUInt16(13)
|
||||||
.AddString("Access Denied")
|
.AddString("Access Denied")
|
||||||
.Done();
|
.Done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -849,7 +942,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
openReply?.Trigger(true);
|
openReply?.Trigger(true);
|
||||||
OnReady?.Invoke(this);
|
OnReady?.Invoke(this);
|
||||||
|
|
||||||
Server?.Membership.Login(session);
|
Server?.Membership?.Login(session);
|
||||||
loginDate = DateTime.Now;
|
loginDate = DateTime.Now;
|
||||||
|
|
||||||
}).Error(x =>
|
}).Error(x =>
|
||||||
@ -862,7 +955,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
ready = true;
|
ready = true;
|
||||||
openReply?.Trigger(true);
|
openReply?.Trigger(true);
|
||||||
OnReady?.Invoke(this);
|
OnReady?.Invoke(this);
|
||||||
Server?.Membership.Login(session);
|
Server?.Membership?.Login(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:AUTH");
|
//Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:AUTH");
|
||||||
@ -988,7 +1081,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
protected override void DataReceived(NetworkBuffer data)
|
protected override void DataReceived(NetworkBuffer data)
|
||||||
{
|
{
|
||||||
// Console.WriteLine("DR " + hostType + " " + data.Available + " " + RemoteEndPoint.ToString());
|
//Console.WriteLine("DR " + data.Available + " " + RemoteEndPoint.ToString());
|
||||||
var msg = data.Read();
|
var msg = data.Read();
|
||||||
uint offset = 0;
|
uint offset = 0;
|
||||||
uint ends = (uint)msg.Length;
|
uint ends = (uint)msg.Length;
|
||||||
@ -997,7 +1090,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
var chunkId = (new Random()).Next(1000, 1000000);
|
var chunkId = (new Random()).Next(1000, 1000000);
|
||||||
|
|
||||||
var list = new List<Structure>();// double, IIPPacketCommand>();
|
//var list = new List<Map<string, object>>();// double, IIPPacketCommand>();
|
||||||
|
|
||||||
|
|
||||||
this.Socket.Hold();
|
this.Socket.Hold();
|
||||||
@ -1127,7 +1220,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var bag = new AsyncBag();
|
var bag = new AsyncBag<IResource>();
|
||||||
|
|
||||||
for (var i = 0; i < resources.Keys.Count; i++)
|
for (var i = 0; i < resources.Keys.Count; i++)
|
||||||
{
|
{
|
||||||
@ -1168,13 +1261,13 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
return true;
|
return true;
|
||||||
@ -1202,9 +1295,10 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AsyncBag<T> Children<T>(IResource resource, string name) where T : IResource
|
public AsyncBag<T> Children<T>(IResource resource, string name) where T : IResource
|
||||||
{
|
{
|
||||||
throw new Exception("SS");
|
throw new Exception("Not implemented");
|
||||||
|
|
||||||
//if (Codec.IsLocalResource(resource, this))
|
//if (Codec.IsLocalResource(resource, this))
|
||||||
// return new AsyncBag<T>((resource as DistributedResource).children.Where(x => x.GetType() == typeof(T)).Select(x => (T)x));
|
// return new AsyncBag<T>((resource as DistributedResource).children.Where(x => x.GetType() == typeof(T)).Select(x => (T)x));
|
||||||
@ -1214,7 +1308,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
|
|
||||||
public AsyncBag<T> Parents<T>(IResource resource, string name) where T : IResource
|
public AsyncBag<T> Parents<T>(IResource resource, string name) where T : IResource
|
||||||
{
|
{
|
||||||
throw new Exception("SS");
|
throw new Exception("Not implemented");
|
||||||
//if (Codec.IsLocalResource(resource, this))
|
//if (Codec.IsLocalResource(resource, this))
|
||||||
// return (resource as DistributedResource).parents.Where(x => x.GetType() == typeof(T)).Select(x => (T)x);
|
// return (resource as DistributedResource).parents.Where(x => x.GetType() == typeof(T)).Select(x => (T)x);
|
||||||
|
|
||||||
@ -1253,7 +1347,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
Warehouse.Remove(this);
|
Warehouse.Remove(this);
|
||||||
|
|
||||||
if (ready)
|
if (ready)
|
||||||
Server?.Membership.Logout(session);
|
Server?.Membership?.Logout(session);
|
||||||
|
|
||||||
ready = false;
|
ready = false;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -3,23 +3,34 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Esiur.Net.IIP;
|
namespace Esiur.Net.IIP;
|
||||||
public class DistributedPropertyContext
|
|
||||||
{
|
|
||||||
public object Value { get; private set; }
|
|
||||||
public DistributedConnection Connection { get; private set; }
|
|
||||||
public Func<DistributedConnection, object> Method { get; private set; }
|
|
||||||
|
|
||||||
public DistributedPropertyContext(DistributedConnection connection, object value)
|
public interface IDistributedPropertyContext
|
||||||
|
{
|
||||||
|
object GetValue(DistributedConnection connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DistributedPropertyContext<T> : IDistributedPropertyContext
|
||||||
|
{
|
||||||
|
public T Value { get; private set; }
|
||||||
|
public DistributedConnection Connection { get; private set; }
|
||||||
|
public Func<DistributedConnection, T> Method { get; private set; }
|
||||||
|
|
||||||
|
public DistributedPropertyContext(DistributedConnection connection, T value)
|
||||||
{
|
{
|
||||||
this.Value = value;
|
this.Value = value;
|
||||||
this.Connection = connection;
|
this.Connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DistributedPropertyContext(Func<DistributedConnection, object> method)
|
public DistributedPropertyContext(Func<DistributedConnection, T> method)
|
||||||
{
|
{
|
||||||
this.Method = method;
|
this.Method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator DistributedPropertyContext(Func<DistributedConnection, object> method)
|
public static implicit operator DistributedPropertyContext<T>(Func<DistributedConnection, T> method)
|
||||||
=> new DistributedPropertyContext(method);
|
=> new DistributedPropertyContext<T>(method);
|
||||||
|
|
||||||
|
public object GetValue(DistributedConnection connection)
|
||||||
|
{
|
||||||
|
return Method.Invoke(connection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,8 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
/// Raised when the distributed resource is destroyed.
|
/// Raised when the distributed resource is destroyed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
public event Instance.ResourceModifiedEvent OnModified;
|
public event PropertyModifiedEvent PropertyModified;
|
||||||
|
|
||||||
uint instanceId;
|
uint instanceId;
|
||||||
DistributedConnection connection;
|
DistributedConnection connection;
|
||||||
|
|
||||||
@ -83,6 +84,8 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connection responsible for the distributed resource.
|
/// Connection responsible for the distributed resource.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -214,12 +217,10 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
{
|
{
|
||||||
var et = Instance.Template.GetEventTemplateByIndex(index);
|
var et = Instance.Template.GetEventTemplateByIndex(index);
|
||||||
events[index]?.Invoke(this, args);
|
events[index]?.Invoke(this, args);
|
||||||
Instance.EmitResourceEvent(et.Name, args);
|
Instance.EmitResourceEvent(et, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AsyncReply<object> _Invoke(byte index, Map<byte, object> args)
|
||||||
|
|
||||||
public AsyncReply<object> _InvokeByNamedArguments(byte index, Structure namedArgs)
|
|
||||||
{
|
{
|
||||||
if (destroyed)
|
if (destroyed)
|
||||||
throw new Exception("Trying to access destroyed object");
|
throw new Exception("Trying to access destroyed object");
|
||||||
@ -231,23 +232,7 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
throw new Exception("Function index is incorrect");
|
throw new Exception("Function index is incorrect");
|
||||||
|
|
||||||
|
|
||||||
return connection.SendInvokeByNamedArguments(instanceId, index, namedArgs);
|
return connection.SendInvoke(instanceId, index, args);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public AsyncReply<object> _InvokeByArrayArguments(byte index, object[] args)
|
|
||||||
{
|
|
||||||
if (destroyed)
|
|
||||||
throw new Exception("Trying to access destroyed object");
|
|
||||||
|
|
||||||
if (suspended)
|
|
||||||
throw new Exception("Trying to access suspended object");
|
|
||||||
|
|
||||||
if (index >= Instance.Template.Functions.Length)
|
|
||||||
throw new Exception("Function index is incorrect");
|
|
||||||
|
|
||||||
|
|
||||||
return connection.SendInvokeByArrayArguments(instanceId, index, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -297,28 +282,40 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
|
|
||||||
if (attached && ft != null)
|
if (attached && ft != null)
|
||||||
{
|
{
|
||||||
|
var indexedArgs = new Map<byte, object>();
|
||||||
|
|
||||||
if (args.Length == 1)
|
if (args.Length == 1)
|
||||||
{
|
{
|
||||||
// Detect anonymous types
|
// Detect anonymous types
|
||||||
var type = args[0].GetType();
|
var type = args[0].GetType();
|
||||||
|
|
||||||
|
|
||||||
if (Codec.IsAnonymous(type))
|
if (Codec.IsAnonymous(type))
|
||||||
{
|
{
|
||||||
var namedArgs = new Structure();
|
|
||||||
|
|
||||||
var pi = type.GetTypeInfo().GetProperties();
|
var pis = type.GetProperties();
|
||||||
foreach (var p in pi)
|
|
||||||
namedArgs[p.Name] = p.GetValue(args[0]);
|
for (byte i = 0; i < ft.Arguments.Length; i++)
|
||||||
result = _InvokeByNamedArguments(ft.Index, namedArgs);
|
{
|
||||||
|
var pi = pis.FirstOrDefault(x => x.Name == ft.Arguments[i].Name);
|
||||||
|
if (pi != null)
|
||||||
|
indexedArgs.Add(i, pi.GetValue(args[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
result =_Invoke(ft.Index, indexedArgs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = _InvokeByArrayArguments(ft.Index, args);
|
indexedArgs.Add((byte)0, args[0]);
|
||||||
|
result = _Invoke(ft.Index, indexedArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = _InvokeByArrayArguments(ft.Index, args);
|
for (byte i = 0; i < args.Length; i++)
|
||||||
|
indexedArgs.Add(i, args[i]);
|
||||||
|
|
||||||
|
result = _Invoke(ft.Index, indexedArgs);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -341,6 +338,20 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
return properties[index];
|
return properties[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryGetPropertyValue(byte index, out object value)
|
||||||
|
{
|
||||||
|
if (index >= properties.Length)
|
||||||
|
{
|
||||||
|
value = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = properties[index];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||||
{
|
{
|
||||||
if (destroyed)
|
if (destroyed)
|
||||||
@ -409,6 +420,7 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||||
{
|
{
|
||||||
if (destroyed)
|
if (destroyed)
|
||||||
@ -496,7 +508,7 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (trigger == ResourceTrigger.Initialize)
|
if (trigger == ResourceTrigger.Initialize)
|
||||||
this.Instance.ResourceModified += this.OnModified;
|
this.Instance.PropertyModified += this.PropertyModified;
|
||||||
|
|
||||||
// do nothing.
|
// do nothing.
|
||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
|
@ -38,6 +38,9 @@ using Esiur.Security.Membership;
|
|||||||
namespace Esiur.Net.IIP;
|
namespace Esiur.Net.IIP;
|
||||||
public class DistributedServer : NetworkServer<DistributedConnection>, IResource
|
public class DistributedServer : NetworkServer<DistributedConnection>, IResource
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Attribute]
|
[Attribute]
|
||||||
public string IP
|
public string IP
|
||||||
{
|
{
|
||||||
@ -81,6 +84,8 @@ public class DistributedServer : NetworkServer<DistributedConnection>, IResource
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public event PropertyModifiedEvent PropertyModified;
|
||||||
|
|
||||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||||
{
|
{
|
||||||
if (trigger == ResourceTrigger.Initialize)
|
if (trigger == ResourceTrigger.Initialize)
|
||||||
|
@ -170,6 +170,7 @@ public class NetworkBuffer
|
|||||||
{
|
{
|
||||||
rt = data;
|
rt = data;
|
||||||
data = new byte[0];
|
data = new byte[0];
|
||||||
|
return rt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -200,7 +201,6 @@ public class NetworkBuffer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,8 @@ public abstract class NetworkServer<TConnection> : IDestructible where TConnecti
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("New Socket ... " + DateTime.Now);
|
||||||
|
|
||||||
var c = new TConnection();
|
var c = new TConnection();
|
||||||
//c.OnClose += ClientDisconnectedEventReceiver;
|
//c.OnClose += ClientDisconnectedEventReceiver;
|
||||||
c.Assign(s);
|
c.Assign(s);
|
||||||
|
@ -222,7 +222,7 @@ class IIPAuthPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 2))
|
if (NotEnough(offset, ends, 2))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var length = data.GetUInt16(offset);
|
var length = data.GetUInt16(offset, Endian.Little);
|
||||||
|
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
@ -311,7 +311,7 @@ class IIPAuthPacket : Packet
|
|||||||
|
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
|
||||||
RemoteTokenIndex = data.GetUInt64(offset);
|
RemoteTokenIndex = data.GetUInt64(offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,7 +321,7 @@ class IIPAuthPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 2))
|
if (NotEnough(offset, ends, 2))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var keyLength = data.GetUInt16(offset);
|
var keyLength = data.GetUInt16(offset, Endian.Little);
|
||||||
|
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ class IIPAuthPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 2))
|
if (NotEnough(offset, ends, 2))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var keyLength = data.GetUInt16(offset);
|
var keyLength = data.GetUInt16(offset, Endian.Little);
|
||||||
|
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
@ -394,7 +394,7 @@ class IIPAuthPacket : Packet
|
|||||||
ErrorCode = data[offset++];
|
ErrorCode = data[offset++];
|
||||||
|
|
||||||
|
|
||||||
var cl = data.GetUInt16(offset);
|
var cl = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
|
@ -109,8 +109,8 @@ class IIPPacket : Packet
|
|||||||
LinkTemplates,
|
LinkTemplates,
|
||||||
|
|
||||||
// Request Invoke
|
// Request Invoke
|
||||||
InvokeFunctionArrayArguments = 0x10,
|
InvokeFunction = 0x10,
|
||||||
InvokeFunctionNamedArguments,
|
Reserved,
|
||||||
Listen,
|
Listen,
|
||||||
Unlisten,
|
Unlisten,
|
||||||
SetProperty,
|
SetProperty,
|
||||||
@ -173,6 +173,7 @@ class IIPPacket : Packet
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransmissionType? DataType { get; set; }
|
||||||
|
|
||||||
public uint ResourceId { get; set; }
|
public uint ResourceId { get; set; }
|
||||||
public uint NewResourceId { get; set; }
|
public uint NewResourceId { get; set; }
|
||||||
@ -181,11 +182,13 @@ class IIPPacket : Packet
|
|||||||
public uint StoreId { get; set; }
|
public uint StoreId { get; set; }
|
||||||
|
|
||||||
public ulong ResourceAge { get; set; }
|
public ulong ResourceAge { get; set; }
|
||||||
public byte[] Content { get; set; }
|
//public byte[] Content { get; set; }
|
||||||
public ushort ErrorCode { get; set; }
|
public ushort ErrorCode { get; set; }
|
||||||
public string ErrorMessage { get; set; }
|
public string ErrorMessage { get; set; }
|
||||||
public string ClassName { get; set; }
|
public string ClassName { get; set; }
|
||||||
public string ResourceLink { get; set; }
|
public string ResourceLink { get; set; }
|
||||||
|
|
||||||
|
public string ResourceName { get; set; }
|
||||||
public Guid ClassId { get; set; }
|
public Guid ClassId { get; set; }
|
||||||
public byte MethodIndex { get; set; }
|
public byte MethodIndex { get; set; }
|
||||||
public string MethodName { get; set; }
|
public string MethodName { get; set; }
|
||||||
@ -236,7 +239,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
else if (Command == IIPPacketCommand.Report)
|
else if (Command == IIPPacketCommand.Report)
|
||||||
@ -246,7 +249,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
CallbackId = data.GetUInt32(offset);
|
CallbackId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -257,7 +260,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
CallbackId = data.GetUInt32(offset);
|
CallbackId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +271,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
NewResourceId = data.GetUInt32(offset);
|
NewResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -282,7 +285,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ChildId = data.GetUInt32(offset);
|
ChildId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
else if (Event == IIPPacketEvent.Renamed)
|
else if (Event == IIPPacketEvent.Renamed)
|
||||||
@ -290,13 +293,15 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 2))
|
if (NotEnough(offset, ends, 2))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var cl = data.GetUInt16(offset);
|
var cl = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
Content = data.Clip(offset, cl);
|
ResourceName = data.GetString(offset, cl);
|
||||||
|
|
||||||
|
//Content = data.Clip(offset, cl);
|
||||||
|
|
||||||
offset += cl;
|
offset += cl;
|
||||||
}
|
}
|
||||||
@ -308,31 +313,19 @@ class IIPPacket : Packet
|
|||||||
|
|
||||||
MethodIndex = data[offset++];
|
MethodIndex = data[offset++];
|
||||||
|
|
||||||
var dt = (DataType)data[offset++];
|
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
|
||||||
var size = dt.Size();// Codec.SizeOf(dt);
|
|
||||||
|
|
||||||
if (size < 0)
|
|
||||||
{
|
|
||||||
if (NotEnough(offset, ends, 4))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
var cl = data.GetUInt32(offset);
|
//var dt = (DataType)data[offset++];
|
||||||
offset += 4;
|
//var size = dt.Size();// Codec.SizeOf(dt);
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (DataType == null)
|
||||||
return -dataLengthNeeded;
|
return -(int)size;
|
||||||
|
|
||||||
Content = data.Clip(offset - 5, cl + 5);
|
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
|
||||||
offset += cl;
|
|
||||||
}
|
offset += (uint)size;
|
||||||
else
|
|
||||||
{
|
|
||||||
if (NotEnough(offset, ends, (uint)size))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset - 1, (uint)size + 1);
|
|
||||||
offset += (uint)size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//else if (Event == IIPPacketEvent.EventOccurred)
|
//else if (Event == IIPPacketEvent.EventOccurred)
|
||||||
//{
|
//{
|
||||||
@ -357,13 +350,14 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var cl = data.GetUInt32(offset);
|
var cl = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
Content = data.Clip(offset, cl);
|
//@TODO: Fix this
|
||||||
|
//Content = data.Clip(offset, cl);
|
||||||
|
|
||||||
offset += cl;
|
offset += cl;
|
||||||
}
|
}
|
||||||
@ -375,7 +369,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.ReattachResource)
|
else if (Action == IIPPacketAction.ReattachResource)
|
||||||
@ -383,10 +377,10 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 12))
|
if (NotEnough(offset, ends, 12))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
ResourceAge = data.GetUInt64(offset);
|
ResourceAge = data.GetUInt64(offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -395,7 +389,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -404,25 +398,26 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 12))
|
if (NotEnough(offset, ends, 12))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
StoreId = data.GetUInt32(offset);
|
StoreId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
var cl = data.GetUInt32(offset);
|
var cl = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
this.Content = data.Clip(offset, cl);
|
// @TODO: fix this
|
||||||
|
//this.Content = data.Clip(offset, cl);
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.DeleteResource)
|
else if (Action == IIPPacketAction.DeleteResource)
|
||||||
{
|
{
|
||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -432,9 +427,9 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 8))
|
if (NotEnough(offset, ends, 8))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
ChildId = data.GetUInt32(offset);
|
ChildId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.RenameResource)
|
else if (Action == IIPPacketAction.RenameResource)
|
||||||
@ -442,15 +437,16 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 6))
|
if (NotEnough(offset, ends, 6))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
var cl = data.GetUInt16(offset);
|
var cl = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
Content = data.Clip(offset, cl);
|
ResourceName = data.GetString(offset, cl);
|
||||||
|
//Content = data.Clip(offset, cl);
|
||||||
offset += cl;
|
offset += cl;
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.TemplateFromClassName)
|
else if (Action == IIPPacketAction.TemplateFromClassName)
|
||||||
@ -481,7 +477,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.QueryLink
|
else if (Action == IIPPacketAction.QueryLink
|
||||||
@ -490,7 +486,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 2))
|
if (NotEnough(offset, ends, 2))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var cl = data.GetUInt16(offset);
|
var cl = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
@ -505,7 +501,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.ResourceHistory)
|
else if (Action == IIPPacketAction.ResourceHistory)
|
||||||
@ -513,35 +509,42 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 20))
|
if (NotEnough(offset, ends, 20))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
FromDate = data.GetDateTime(offset);
|
FromDate = data.GetDateTime(offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
ToDate = data.GetDateTime(offset);
|
ToDate = data.GetDateTime(offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.InvokeFunctionArrayArguments
|
else if (Action == IIPPacketAction.InvokeFunction)
|
||||||
|| Action == IIPPacketAction.InvokeFunctionNamedArguments)
|
|
||||||
{
|
{
|
||||||
if (NotEnough(offset, ends, 9))
|
if (NotEnough(offset, ends, 6))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
MethodIndex = data[offset++];
|
MethodIndex = data[offset++];
|
||||||
|
|
||||||
var cl = data.GetUInt32(offset);
|
|
||||||
offset += 4;
|
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset, cl);
|
if (DataType == null)
|
||||||
offset += cl;
|
return -(int)size;
|
||||||
|
|
||||||
|
offset += (uint)size;
|
||||||
|
|
||||||
|
//var cl = data.GetUInt32(offset);
|
||||||
|
//offset += 4;
|
||||||
|
|
||||||
|
//if (NotEnough(offset, ends, cl))
|
||||||
|
// return -dataLengthNeeded;
|
||||||
|
|
||||||
|
//Content = data.Clip(offset, cl);
|
||||||
|
//offset += cl;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.Listen
|
else if (Action == IIPPacketAction.Listen
|
||||||
@ -550,7 +553,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 5))
|
if (NotEnough(offset, ends, 5))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
MethodIndex = data[offset++];
|
MethodIndex = data[offset++];
|
||||||
@ -575,37 +578,21 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 6))
|
if (NotEnough(offset, ends, 6))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
MethodIndex = data[offset++];
|
MethodIndex = data[offset++];
|
||||||
|
|
||||||
|
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
|
||||||
|
|
||||||
var dt = (DataType)data[offset++];
|
if (DataType == null)
|
||||||
var size = dt.Size();// Codec.SizeOf(dt);
|
return -(int)size;
|
||||||
|
|
||||||
if (size < 0)
|
|
||||||
{
|
|
||||||
if (NotEnough(offset, ends, 4))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
var cl = data.GetUInt32(offset);
|
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
|
||||||
offset += 4;
|
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
offset += (uint)size;
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset - 5, cl + 5);
|
|
||||||
offset += cl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (NotEnough(offset, ends, (uint)size))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset - 1, (uint)size + 1);
|
|
||||||
offset += (uint)size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Attributes
|
// Attributes
|
||||||
else if (Action == IIPPacketAction.UpdateAllAttributes
|
else if (Action == IIPPacketAction.UpdateAllAttributes
|
||||||
@ -616,15 +603,16 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 8))
|
if (NotEnough(offset, ends, 8))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
var cl = data.GetUInt32(offset);
|
var cl = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
Content = data.Clip(offset, cl);
|
// @TODO: fix this
|
||||||
|
//Content = data.Clip(offset, cl);
|
||||||
offset += cl;
|
offset += cl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,10 +628,10 @@ class IIPPacket : Packet
|
|||||||
ClassId = data.GetGuid(offset);
|
ClassId = data.GetGuid(offset);
|
||||||
offset += 16;
|
offset += 16;
|
||||||
|
|
||||||
ResourceAge = data.GetUInt64(offset);
|
ResourceAge = data.GetUInt64(offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
uint cl = data.GetUInt16(offset);
|
uint cl = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
@ -652,17 +640,19 @@ class IIPPacket : Packet
|
|||||||
ResourceLink = data.GetString(offset, cl);
|
ResourceLink = data.GetString(offset, cl);
|
||||||
offset += cl;
|
offset += cl;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, 4))
|
//if (NotEnough(offset, ends, 4))
|
||||||
return -dataLengthNeeded;
|
// return -dataLengthNeeded;
|
||||||
|
|
||||||
cl = data.GetUInt32(offset);
|
|
||||||
offset += 4;
|
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
if (DataType == null)
|
||||||
|
return -(int)size;
|
||||||
|
|
||||||
|
offset += (uint)size;
|
||||||
|
|
||||||
|
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
|
||||||
|
|
||||||
Content = data.Clip(offset, cl);
|
|
||||||
offset += cl;
|
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.DetachResource)
|
else if (Action == IIPPacketAction.DetachResource)
|
||||||
{
|
{
|
||||||
@ -676,7 +666,7 @@ class IIPPacket : Packet
|
|||||||
//ClassId = data.GetGuid(offset);
|
//ClassId = data.GetGuid(offset);
|
||||||
//offset += 16;
|
//offset += 16;
|
||||||
|
|
||||||
ResourceId = data.GetUInt32(offset);
|
ResourceId = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -697,51 +687,40 @@ class IIPPacket : Packet
|
|||||||
|| Action == IIPPacketAction.GetAllAttributes
|
|| Action == IIPPacketAction.GetAllAttributes
|
||||||
|| Action == IIPPacketAction.GetAttributes)
|
|| Action == IIPPacketAction.GetAttributes)
|
||||||
{
|
{
|
||||||
if (NotEnough(offset, ends, 4))
|
if (NotEnough(offset, ends, 1))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var cl = data.GetUInt32(offset);
|
(var size, DataType) = TransmissionType.Parse(data, offset, ends );
|
||||||
offset += 4;
|
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (DataType == null)
|
||||||
return -dataLengthNeeded;
|
return -(int)size;
|
||||||
|
|
||||||
Content = data.Clip(offset, cl);
|
offset += (uint)size;
|
||||||
offset += cl;
|
|
||||||
|
//var cl = data.GetUInt32(offset);
|
||||||
|
//offset += 4;
|
||||||
|
|
||||||
|
//if (NotEnough(offset, ends, cl))
|
||||||
|
// return -dataLengthNeeded;
|
||||||
|
|
||||||
|
//Content = data.Clip(offset, cl);
|
||||||
|
//offset += cl;
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.InvokeFunctionArrayArguments
|
else if (Action == IIPPacketAction.InvokeFunction)
|
||||||
|| Action == IIPPacketAction.InvokeFunctionNamedArguments)
|
|
||||||
//|| Action == IIPPacketAction.GetProperty
|
//|| Action == IIPPacketAction.GetProperty
|
||||||
//|| Action == IIPPacketAction.GetPropertyIfModified)
|
//|| Action == IIPPacketAction.GetPropertyIfModified)
|
||||||
{
|
{
|
||||||
if (NotEnough(offset, ends, 1))
|
if (NotEnough(offset, ends, 1))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var dt = (DataType)data[offset++];
|
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
|
||||||
var size = dt.Size();// Codec.SizeOf(dt);
|
|
||||||
|
|
||||||
if (size < 0)
|
if (DataType == null)
|
||||||
{
|
return -(int)size;
|
||||||
if (NotEnough(offset, ends, 4))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
var cl = data.GetUInt32(offset);
|
offset += (uint)size;
|
||||||
offset += 4;
|
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset - 5, cl + 5);
|
|
||||||
offset += cl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (NotEnough(offset, ends, (uint)size))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset - 1, (uint)size + 1);
|
|
||||||
offset += (uint)size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (Action == IIPPacketAction.SetProperty
|
else if (Action == IIPPacketAction.SetProperty
|
||||||
|| Action == IIPPacketAction.Listen
|
|| Action == IIPPacketAction.Listen
|
||||||
@ -757,7 +736,7 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 2))
|
if (NotEnough(offset, ends, 2))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ErrorCode = data.GetUInt16(offset);
|
ErrorCode = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
}
|
}
|
||||||
else if (Report == IIPPacketReport.ExecutionError)
|
else if (Report == IIPPacketReport.ExecutionError)
|
||||||
@ -765,13 +744,13 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 2))
|
if (NotEnough(offset, ends, 2))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ErrorCode = data.GetUInt16(offset);
|
ErrorCode = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, 2))
|
if (NotEnough(offset, ends, 2))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var cl = data.GetUInt16(offset);
|
var cl = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
if (NotEnough(offset, ends, cl))
|
||||||
@ -785,9 +764,9 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 8))
|
if (NotEnough(offset, ends, 8))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
ProgressValue = data.GetInt32(offset);
|
ProgressValue = data.GetInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
ProgressMax = data.GetInt32(offset);
|
ProgressMax = data.GetInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
else if (Report == IIPPacketReport.ChunkStream)
|
else if (Report == IIPPacketReport.ChunkStream)
|
||||||
@ -795,31 +774,16 @@ class IIPPacket : Packet
|
|||||||
if (NotEnough(offset, ends, 1))
|
if (NotEnough(offset, ends, 1))
|
||||||
return -dataLengthNeeded;
|
return -dataLengthNeeded;
|
||||||
|
|
||||||
var dt = (DataType)data[offset++];
|
|
||||||
var size = dt.Size();// Codec.SizeOf(dt);
|
|
||||||
|
|
||||||
if (size < 0)
|
(var size, DataType) = TransmissionType.Parse(Data, offset, ends );
|
||||||
{
|
|
||||||
if (NotEnough(offset, ends, 4))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
var cl = data.GetUInt32(offset);
|
if (DataType == null)
|
||||||
offset += 4;
|
return -(int)size;
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
offset += (uint)size;
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset - 5, cl + 5);
|
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
|
||||||
offset += cl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (NotEnough(offset, ends, (uint)size))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset - 1, (uint)size + 1);
|
|
||||||
offset += (uint)size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,13 +88,13 @@ public class WebsocketPacket : Packet
|
|||||||
// 4 bytes
|
// 4 bytes
|
||||||
{
|
{
|
||||||
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 127));
|
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 127));
|
||||||
pkt.AddRange(DC.ToBytes((UInt64)Message.LongCount()));
|
pkt.AddRange(DC.ToBytes((UInt64)Message.LongCount(), Endian.Big));
|
||||||
}
|
}
|
||||||
else if (Message.Length > 125)
|
else if (Message.Length > 125)
|
||||||
// 2 bytes
|
// 2 bytes
|
||||||
{
|
{
|
||||||
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 126));
|
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 126));
|
||||||
pkt.AddRange(DC.ToBytes((UInt16)Message.Length));
|
pkt.AddRange(DC.ToBytes((UInt16)Message.Length, Endian.Big));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -145,7 +145,7 @@ public class WebsocketPacket : Packet
|
|||||||
//Console.WriteLine("stage 2 " + needed);
|
//Console.WriteLine("stage 2 " + needed);
|
||||||
return length - needed;
|
return length - needed;
|
||||||
}
|
}
|
||||||
PayloadLength = data.GetUInt16(offset);
|
PayloadLength = data.GetUInt16(offset, Endian.Big);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
}
|
}
|
||||||
else if (PayloadLength == 127)
|
else if (PayloadLength == 127)
|
||||||
@ -157,7 +157,7 @@ public class WebsocketPacket : Packet
|
|||||||
return length - needed;
|
return length - needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
PayloadLength = data.GetInt64(offset);
|
PayloadLength = data.GetInt64(offset, Endian.Big);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ namespace Esiur.Net.TCP;
|
|||||||
|
|
||||||
public abstract class TCPFilter : IResource
|
public abstract class TCPFilter : IResource
|
||||||
{
|
{
|
||||||
|
|
||||||
public Instance Instance
|
public Instance Instance
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@ -44,6 +45,7 @@ public abstract class TCPFilter : IResource
|
|||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
|
|
||||||
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
||||||
|
|
||||||
public virtual bool Connected(TCPConnection sender)
|
public virtual bool Connected(TCPConnection sender)
|
||||||
|
@ -66,7 +66,6 @@ public class TCPServer : NetworkServer<TCPConnection>, IResource
|
|||||||
|
|
||||||
TCPFilter[] filters = null;
|
TCPFilter[] filters = null;
|
||||||
|
|
||||||
|
|
||||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
||||||
{
|
{
|
||||||
if (trigger == ResourceTrigger.Initialize)
|
if (trigger == ResourceTrigger.Initialize)
|
||||||
|
@ -35,6 +35,9 @@ using Esiur.Resource;
|
|||||||
namespace Esiur.Net.UDP;
|
namespace Esiur.Net.UDP;
|
||||||
public abstract class UDPFilter : IResource
|
public abstract class UDPFilter : IResource
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Instance Instance
|
public Instance Instance
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
@ -48,6 +48,7 @@ public class UDPServer : IResource
|
|||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
|
|
||||||
public Instance Instance
|
public Instance Instance
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
@ -74,6 +74,15 @@ public class ResourceGenerator : ISourceGenerator
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static string SuggestPropertyName(string propertyName)
|
||||||
|
{
|
||||||
|
if (Char.IsUpper(propertyName[0]))
|
||||||
|
return propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
|
||||||
|
else
|
||||||
|
return propertyName.Substring(0, 1).ToUpper() + propertyName.Substring(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void Execute(GeneratorExecutionContext context)
|
public void Execute(GeneratorExecutionContext context)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -146,27 +155,30 @@ namespace { ci.ClassSymbol.ContainingNamespace.ToDisplayString() } {{
|
|||||||
";
|
";
|
||||||
|
|
||||||
if (ci.HasInterface)
|
if (ci.HasInterface)
|
||||||
code += $"public partial class {ci.Name} {{";
|
code += $"public partial class {ci.Name} {{\r\n";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code += @$"public partial class {ci.Name} : IResource {{
|
code +=
|
||||||
public Instance Instance {{ get; set; }}
|
@$" public partial class {ci.Name} : IResource {{
|
||||||
public event DestroyedEvent OnDestroy;
|
public Instance Instance {{ get; set; }}
|
||||||
public virtual void Destroy() {{ OnDestroy?.Invoke(this); }}
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
|
public virtual void Destroy() {{ OnDestroy?.Invoke(this); }}
|
||||||
";
|
";
|
||||||
|
|
||||||
if (!ci.HasTrigger)
|
if (!ci.HasTrigger)
|
||||||
code += "public AsyncReply<bool> Trigger(ResourceTrigger trigger) => new AsyncReply<bool>(true);\r\n";
|
code +=
|
||||||
|
" public AsyncReply<bool> Trigger(ResourceTrigger trigger) => new AsyncReply<bool>(true);\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
//Debugger.Launch();
|
//Debugger.Launch();
|
||||||
|
|
||||||
foreach (var f in ci.Fields)
|
foreach (var f in ci.Fields)
|
||||||
{
|
{
|
||||||
var givenName = f.GetAttributes().Where(x => x.AttributeClass.Name == "PublicAttribute").FirstOrDefault()?.ConstructorArguments.FirstOrDefault().Value;
|
var givenName = f.GetAttributes().Where(x => x.AttributeClass.Name == "PublicAttribute").FirstOrDefault()?.ConstructorArguments.FirstOrDefault().Value as string;
|
||||||
|
|
||||||
var fn = f.Name;
|
var fn = f.Name;
|
||||||
var pn = givenName ?? fn.Substring(0, 1).ToUpper() + fn.Substring(1);
|
var pn =string.IsNullOrEmpty(givenName) ? SuggestPropertyName(fn): givenName;
|
||||||
|
|
||||||
//System.IO.File.AppendAllText("c:\\gen\\fields.txt", fn + " -> " + pn + "\r\n");
|
//System.IO.File.AppendAllText("c:\\gen\\fields.txt", fn + " -> " + pn + "\r\n");
|
||||||
|
|
||||||
|
@ -29,10 +29,11 @@ public class ResourceGeneratorReceiver : ISyntaxContextReceiver
|
|||||||
{
|
{
|
||||||
// Debugger.Launch();
|
// Debugger.Launch();
|
||||||
|
|
||||||
var url = import.ConstructorArguments.First().Value.ToString();
|
var urls = import.ConstructorArguments.Select(x => x.Value.ToString());//.ToString();
|
||||||
|
|
||||||
if (!Imports.Contains(url))
|
foreach(var url in urls)
|
||||||
Imports.Add(url);
|
if (!Imports.Contains(url))
|
||||||
|
Imports.Add(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.ResourceAttribute"))
|
if (attrs.Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.ResourceAttribute"))
|
||||||
@ -48,6 +49,7 @@ public class ResourceGeneratorReceiver : ISyntaxContextReceiver
|
|||||||
|
|
||||||
var fields = cds.Members.Where(x => x is FieldDeclarationSyntax)
|
var fields = cds.Members.Where(x => x is FieldDeclarationSyntax)
|
||||||
.Select(x => context.SemanticModel.GetDeclaredSymbol((x as FieldDeclarationSyntax).Declaration.Variables.First()) as IFieldSymbol)
|
.Select(x => context.SemanticModel.GetDeclaredSymbol((x as FieldDeclarationSyntax).Declaration.Variables.First()) as IFieldSymbol)
|
||||||
|
.Where(x => !x.IsConst)
|
||||||
.Where(x => x.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.PublicAttribute"))
|
.Where(x => x.GetAttributes().Any(a => a.AttributeClass.ToDisplayString() == "Esiur.Resource.PublicAttribute"))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public static class TemplateGenerator
|
|||||||
|
|
||||||
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Net.IIP;");
|
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Net.IIP;");
|
||||||
rt.AppendLine($"namespace { nameSpace} {{");
|
rt.AppendLine($"namespace { nameSpace} {{");
|
||||||
rt.AppendLine($"public class {className} : IRecord {{");
|
rt.AppendLine($"[Public] public class {className} : IRecord {{");
|
||||||
|
|
||||||
|
|
||||||
foreach (var p in template.Properties)
|
foreach (var p in template.Properties)
|
||||||
@ -41,58 +41,81 @@ public static class TemplateGenerator
|
|||||||
return rt.ToString();
|
return rt.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static string GetTypeName(TemplateDataType templateDataType, TypeTemplate[] templates)
|
internal static string GenerateEnum(TypeTemplate template, TypeTemplate[] templates)
|
||||||
{
|
{
|
||||||
|
var cls = template.ClassName.Split('.');
|
||||||
|
|
||||||
if (templateDataType.Type == DataType.Resource)
|
var nameSpace = string.Join(".", cls.Take(cls.Length - 1));
|
||||||
return templates.First(x => x.ClassId == templateDataType.TypeGuid && (x.Type == TemplateType.Resource || x.Type == TemplateType.Wrapper)).ClassName;
|
var className = cls.Last();
|
||||||
else if (templateDataType.Type == DataType.ResourceArray)
|
|
||||||
return templates.First(x => x.ClassId == templateDataType.TypeGuid && (x.Type == TemplateType.Resource || x.Type == TemplateType.Wrapper)).ClassName + "[]";
|
|
||||||
else if (templateDataType.Type == DataType.Record)
|
|
||||||
return templates.First(x => x.ClassId == templateDataType.TypeGuid && x.Type == TemplateType.Record).ClassName;
|
|
||||||
else if (templateDataType.Type == DataType.RecordArray)
|
|
||||||
return templates.First(x => x.ClassId == templateDataType.TypeGuid && x.Type == TemplateType.Record).ClassName + "[]";
|
|
||||||
|
|
||||||
var name = templateDataType.Type switch
|
var rt = new StringBuilder();
|
||||||
|
|
||||||
|
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Net.IIP;");
|
||||||
|
rt.AppendLine($"namespace { nameSpace} {{");
|
||||||
|
rt.AppendLine($"[Public] public enum {className} {{");
|
||||||
|
|
||||||
|
rt.AppendLine(String.Join(",\r\n", template.Constants.Select(x => $"{x.Name}={x.Value}")));
|
||||||
|
|
||||||
|
rt.AppendLine("\r\n}\r\n}");
|
||||||
|
|
||||||
|
return rt.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static string GetTypeName(RepresentationType representationType, TypeTemplate[] templates)
|
||||||
|
{
|
||||||
|
string name;
|
||||||
|
|
||||||
|
if (representationType.Identifier == RepresentationTypeIdentifier.TypedResource)// == DataType.Resource)
|
||||||
|
name = templates.First(x => x.ClassId == representationType.GUID && (x.Type == TemplateType.Resource || x.Type == TemplateType.Wrapper)).ClassName;
|
||||||
|
else if (representationType.Identifier == RepresentationTypeIdentifier.TypedRecord)
|
||||||
|
name = templates.First(x => x.ClassId == representationType.GUID && x.Type == TemplateType.Record).ClassName;
|
||||||
|
else if (representationType.Identifier == RepresentationTypeIdentifier.Enum)
|
||||||
|
name = templates.First(x => x.ClassId == representationType.GUID && x.Type == TemplateType.Enum).ClassName;
|
||||||
|
else if (representationType.Identifier == RepresentationTypeIdentifier.TypedList)
|
||||||
|
name = GetTypeName(representationType.SubTypes[0], templates) + "[]";
|
||||||
|
else if (representationType.Identifier == RepresentationTypeIdentifier.TypedMap)
|
||||||
|
name = "Map<" + GetTypeName(representationType.SubTypes[0], templates)
|
||||||
|
+ "," + GetTypeName(representationType.SubTypes[1], templates)
|
||||||
|
+ ">";
|
||||||
|
else if (representationType.Identifier == RepresentationTypeIdentifier.Tuple2 ||
|
||||||
|
representationType.Identifier == RepresentationTypeIdentifier.Tuple3 ||
|
||||||
|
representationType.Identifier == RepresentationTypeIdentifier.Tuple4 ||
|
||||||
|
representationType.Identifier == RepresentationTypeIdentifier.Tuple5 ||
|
||||||
|
representationType.Identifier == RepresentationTypeIdentifier.Tuple6 ||
|
||||||
|
representationType.Identifier == RepresentationTypeIdentifier.Tuple7)
|
||||||
|
name = "(" + String.Join(",", representationType.SubTypes.Select(x=> GetTypeName(x, templates)))
|
||||||
|
+ ")";
|
||||||
|
else
|
||||||
{
|
{
|
||||||
DataType.Bool => "bool",
|
|
||||||
DataType.BoolArray => "bool[]",
|
|
||||||
DataType.Char => "char",
|
|
||||||
DataType.CharArray => "char[]",
|
|
||||||
DataType.DateTime => "DateTime",
|
|
||||||
DataType.DateTimeArray => "DateTime[]",
|
|
||||||
DataType.Decimal => "decimal",
|
|
||||||
DataType.DecimalArray => "decimal[]",
|
|
||||||
DataType.Float32 => "float",
|
|
||||||
DataType.Float32Array => "float[]",
|
|
||||||
DataType.Float64 => "double",
|
|
||||||
DataType.Float64Array => "double[]",
|
|
||||||
DataType.Int16 => "short",
|
|
||||||
DataType.Int16Array => "short[]",
|
|
||||||
DataType.Int32 => "int",
|
|
||||||
DataType.Int32Array => "int[]",
|
|
||||||
DataType.Int64 => "long",
|
|
||||||
DataType.Int64Array => "long[]",
|
|
||||||
DataType.Int8 => "sbyte",
|
|
||||||
DataType.Int8Array => "sbyte[]",
|
|
||||||
DataType.String => "string",
|
|
||||||
DataType.StringArray => "string[]",
|
|
||||||
DataType.Structure => "Structure",
|
|
||||||
DataType.StructureArray => "Structure[]",
|
|
||||||
DataType.UInt16 => "ushort",
|
|
||||||
DataType.UInt16Array => "ushort[]",
|
|
||||||
DataType.UInt32 => "uint",
|
|
||||||
DataType.UInt32Array => "uint[]",
|
|
||||||
DataType.UInt64 => "ulong",
|
|
||||||
DataType.UInt64Array => "ulong[]",
|
|
||||||
DataType.UInt8 => "byte",
|
|
||||||
DataType.UInt8Array => "byte[]",
|
|
||||||
DataType.VarArray => "object[]",
|
|
||||||
DataType.Void => "object",
|
|
||||||
_ => "object"
|
|
||||||
};
|
|
||||||
|
|
||||||
return name;
|
name = representationType.Identifier switch
|
||||||
|
{
|
||||||
|
RepresentationTypeIdentifier.Dynamic => "object",
|
||||||
|
RepresentationTypeIdentifier.Bool => "bool",
|
||||||
|
RepresentationTypeIdentifier.Char => "char",
|
||||||
|
RepresentationTypeIdentifier.DateTime => "DateTime",
|
||||||
|
RepresentationTypeIdentifier.Decimal => "decimal",
|
||||||
|
RepresentationTypeIdentifier.Float32 => "float",
|
||||||
|
RepresentationTypeIdentifier.Float64 => "double",
|
||||||
|
RepresentationTypeIdentifier.Int16 => "short",
|
||||||
|
RepresentationTypeIdentifier.Int32 => "int",
|
||||||
|
RepresentationTypeIdentifier.Int64 => "long",
|
||||||
|
RepresentationTypeIdentifier.Int8 => "sbyte",
|
||||||
|
RepresentationTypeIdentifier.String => "string",
|
||||||
|
RepresentationTypeIdentifier.Map => "Map<object, object>",
|
||||||
|
RepresentationTypeIdentifier.UInt16 => "ushort",
|
||||||
|
RepresentationTypeIdentifier.UInt32 => "uint",
|
||||||
|
RepresentationTypeIdentifier.UInt64 => "ulong",
|
||||||
|
RepresentationTypeIdentifier.UInt8 => "byte",
|
||||||
|
RepresentationTypeIdentifier.List => "object[]",
|
||||||
|
RepresentationTypeIdentifier.Resource => "IResource",
|
||||||
|
RepresentationTypeIdentifier.Record => "IRecord",
|
||||||
|
_ => "object"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return (representationType.Nullable) ? name + "?" : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetTemplate(string url, string dir = null, string username = null, string password = null)
|
public static string GetTemplate(string url, string dir = null, string username = null, string password = null)
|
||||||
@ -142,16 +165,27 @@ public static class TemplateGenerator
|
|||||||
var source = GenerateRecord(tmp, templates);
|
var source = GenerateRecord(tmp, templates);
|
||||||
File.WriteAllText(tempDir.FullName + Path.DirectorySeparatorChar + tmp.ClassName + ".Generated.cs", source);
|
File.WriteAllText(tempDir.FullName + Path.DirectorySeparatorChar + tmp.ClassName + ".Generated.cs", source);
|
||||||
}
|
}
|
||||||
|
else if (tmp.Type == TemplateType.Enum)
|
||||||
|
{
|
||||||
|
var source = GenerateEnum(tmp, templates);
|
||||||
|
File.WriteAllText(tempDir.FullName + Path.DirectorySeparatorChar + tmp.ClassName + ".Generated.cs", source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate info class
|
// generate info class
|
||||||
|
|
||||||
var typesFile = "using System; \r\n namespace Esiur { public static class Generated { public static Type[] Resources {get;} = new Type[] { " +
|
var typesFile = @"using System;
|
||||||
|
namespace Esiur {
|
||||||
|
public static class Generated {
|
||||||
|
public static Type[] Resources {get;} = new Type[] { " +
|
||||||
string.Join(",", templates.Where(x => x.Type == TemplateType.Resource).Select(x => $"typeof({x.ClassName})"))
|
string.Join(",", templates.Where(x => x.Type == TemplateType.Resource).Select(x => $"typeof({x.ClassName})"))
|
||||||
+ " }; \r\n public static Type[] Records { get; } = new Type[] { " +
|
+ @" };
|
||||||
|
public static Type[] Records { get; } = new Type[] { " +
|
||||||
string.Join(",", templates.Where(x => x.Type == TemplateType.Record).Select(x => $"typeof({x.ClassName})"))
|
string.Join(",", templates.Where(x => x.Type == TemplateType.Record).Select(x => $"typeof({x.ClassName})"))
|
||||||
+ " }; " +
|
+ @" };
|
||||||
|
public static Type[] Enums { get; } = new Type[] { " +
|
||||||
|
string.Join(",", templates.Where(x => x.Type == TemplateType.Enum).Select(x => $"typeof({x.ClassName})"))
|
||||||
|
+ @" };" +
|
||||||
"\r\n } \r\n}";
|
"\r\n } \r\n}";
|
||||||
|
|
||||||
|
|
||||||
@ -163,7 +197,6 @@ public static class TemplateGenerator
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
//File.WriteAllText("C:\\gen\\gettemplate.err", ex.ToString());
|
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,13 +212,22 @@ public static class TemplateGenerator
|
|||||||
|
|
||||||
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Net.IIP;");
|
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Net.IIP;");
|
||||||
rt.AppendLine($"namespace { nameSpace} {{");
|
rt.AppendLine($"namespace { nameSpace} {{");
|
||||||
rt.AppendLine($"public class {className} : DistributedResource {{");
|
|
||||||
|
// extends
|
||||||
|
if (template.ParentId == null)
|
||||||
|
rt.AppendLine($"public class {className} : DistributedResource {{");
|
||||||
|
else
|
||||||
|
rt.AppendLine($"public class {className} : {templates.First(x => x.ClassId == template.ParentId && x.Type == TemplateType.Resource).ClassName} {{");
|
||||||
|
|
||||||
|
|
||||||
rt.AppendLine($"public {className}(DistributedConnection connection, uint instanceId, ulong age, string link) : base(connection, instanceId, age, link) {{}}");
|
rt.AppendLine($"public {className}(DistributedConnection connection, uint instanceId, ulong age, string link) : base(connection, instanceId, age, link) {{}}");
|
||||||
rt.AppendLine($"public {className}() {{}}");
|
rt.AppendLine($"public {className}() {{}}");
|
||||||
|
|
||||||
foreach (var f in template.Functions)
|
foreach (var f in template.Functions)
|
||||||
{
|
{
|
||||||
|
if (f.Inherited)
|
||||||
|
continue;
|
||||||
|
|
||||||
var rtTypeName = GetTypeName(f.ReturnType, templates);
|
var rtTypeName = GetTypeName(f.ReturnType, templates);
|
||||||
rt.Append($"public AsyncReply<{rtTypeName}> {f.Name}(");
|
rt.Append($"public AsyncReply<{rtTypeName}> {f.Name}(");
|
||||||
rt.Append(string.Join(",", f.Arguments.Select(x => GetTypeName(x.Type, templates) + " " + x.Name)));
|
rt.Append(string.Join(",", f.Arguments.Select(x => GetTypeName(x.Type, templates) + " " + x.Name)));
|
||||||
@ -201,6 +243,9 @@ public static class TemplateGenerator
|
|||||||
|
|
||||||
foreach (var p in template.Properties)
|
foreach (var p in template.Properties)
|
||||||
{
|
{
|
||||||
|
if (p.Inherited)
|
||||||
|
continue;
|
||||||
|
|
||||||
var ptTypeName = GetTypeName(p.ValueType, templates);
|
var ptTypeName = GetTypeName(p.ValueType, templates);
|
||||||
rt.AppendLine($"public {ptTypeName} {p.Name} {{");
|
rt.AppendLine($"public {ptTypeName} {p.Name} {{");
|
||||||
rt.AppendLine($"get => ({ptTypeName})properties[{p.Index}];");
|
rt.AppendLine($"get => ({ptTypeName})properties[{p.Index}];");
|
||||||
@ -208,8 +253,19 @@ public static class TemplateGenerator
|
|||||||
rt.AppendLine("}");
|
rt.AppendLine("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var c in template.Constants)
|
||||||
|
{
|
||||||
|
if (c.Inherited)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var ctTypeName = GetTypeName(c.ValueType, templates);
|
||||||
|
rt.AppendLine($"public const {ctTypeName} {c.Name} = {c.Value};");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (template.Events.Length > 0)
|
if (template.Events.Length > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
rt.AppendLine("protected override void _EmitEventByIndex(byte index, object args) {");
|
rt.AppendLine("protected override void _EmitEventByIndex(byte index, object args) {");
|
||||||
rt.AppendLine("switch (index) {");
|
rt.AppendLine("switch (index) {");
|
||||||
|
|
||||||
|
7
Esiur/Resource/CustomEventOccurredEvent.cs
Normal file
7
Esiur/Resource/CustomEventOccurredEvent.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Resource;
|
||||||
|
|
||||||
|
public delegate void CustomEventOccurredEvent(CustomEventOccurredInfo info);
|
27
Esiur/Resource/CustomEventOccurredInfo.cs
Normal file
27
Esiur/Resource/CustomEventOccurredInfo.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using Esiur.Resource.Template;
|
||||||
|
using Esiur.Security.Authority;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Resource;
|
||||||
|
|
||||||
|
public class CustomEventOccurredInfo
|
||||||
|
{
|
||||||
|
public readonly EventTemplate EventTemplate;
|
||||||
|
public readonly IResource Resource;
|
||||||
|
public readonly object Value;
|
||||||
|
public readonly object Issuer;
|
||||||
|
public readonly Func<Session, bool> Receivers;
|
||||||
|
|
||||||
|
public string Name => EventTemplate.Name;
|
||||||
|
|
||||||
|
public CustomEventOccurredInfo(IResource resource, EventTemplate eventTemplate, Func<Session, bool> receivers, object issuer, object value)
|
||||||
|
{
|
||||||
|
Resource = resource;
|
||||||
|
EventTemplate = eventTemplate;
|
||||||
|
Receivers = receivers;
|
||||||
|
Issuer = issuer;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
}
|
8
Esiur/Resource/EventOccurredEvent.cs
Normal file
8
Esiur/Resource/EventOccurredEvent.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Resource
|
||||||
|
{
|
||||||
|
public delegate void EventOccurredEvent(EventOccurredInfo info);
|
||||||
|
}
|
26
Esiur/Resource/EventOccurredInfo.cs
Normal file
26
Esiur/Resource/EventOccurredInfo.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Esiur.Resource.Template;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
public class EventOccurredInfo
|
||||||
|
{
|
||||||
|
|
||||||
|
public readonly EventTemplate EventTemplate;
|
||||||
|
|
||||||
|
public string Name => EventTemplate.Name;
|
||||||
|
|
||||||
|
public readonly IResource Resource;
|
||||||
|
public readonly object Value;
|
||||||
|
|
||||||
|
public EventOccurredInfo(IResource resource, EventTemplate eventTemplate, object value)
|
||||||
|
{
|
||||||
|
Resource = resource;
|
||||||
|
Value = value;
|
||||||
|
EventTemplate = eventTemplate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,6 @@ public delegate bool QueryFilter<T>(T value);
|
|||||||
|
|
||||||
public interface IResource : IDestructible///, INotifyPropertyChanged
|
public interface IResource : IDestructible///, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
|
||||||
AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
|
@ -40,8 +40,8 @@ public interface IStore : IResource
|
|||||||
//AsyncReply<IResource> Retrieve(uint iid);
|
//AsyncReply<IResource> Retrieve(uint iid);
|
||||||
AsyncReply<bool> Put(IResource resource);
|
AsyncReply<bool> Put(IResource resource);
|
||||||
string Link(IResource resource);
|
string Link(IResource resource);
|
||||||
bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
|
bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
|
||||||
bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
|
bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
|
||||||
bool Remove(IResource resource);
|
bool Remove(IResource resource);
|
||||||
|
|
||||||
//bool RemoveAttributes(IResource resource, string[] attributes = null);
|
//bool RemoveAttributes(IResource resource, string[] attributes = null);
|
||||||
|
@ -7,7 +7,7 @@ namespace Esiur.Resource;
|
|||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
public class ImportAttribute : Attribute
|
public class ImportAttribute : Attribute
|
||||||
{
|
{
|
||||||
public ImportAttribute(string url)
|
public ImportAttribute(params string[] urls)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,24 +32,20 @@ public class Instance
|
|||||||
AutoList<IPermissionsManager, Instance> managers;
|
AutoList<IPermissionsManager, Instance> managers;
|
||||||
|
|
||||||
|
|
||||||
public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue);
|
public event PropertyModifiedEvent PropertyModified;
|
||||||
public delegate void ResourceEventOccurredEvent(IResource resource, string eventName, object args);
|
|
||||||
|
|
||||||
public delegate void CustomResourceEventOccurredEvent(IResource resource, object issuer, Func<Session, bool> receivers, string eventName, object args);
|
|
||||||
|
|
||||||
public delegate void ResourceDestroyedEvent(IResource resource);
|
|
||||||
|
|
||||||
public event ResourceModifiedEvent ResourceModified;
|
public event EventOccurredEvent EventOccurred;
|
||||||
public event ResourceEventOccurredEvent ResourceEventOccurred;
|
public event CustomEventOccurredEvent CustomEventOccurred;
|
||||||
public event CustomResourceEventOccurredEvent CustomResourceEventOccurred;
|
public event ResourceDestroyedEvent Destroyed;
|
||||||
public event ResourceDestroyedEvent ResourceDestroyed;
|
|
||||||
|
|
||||||
bool loading = false;
|
bool loading = false;
|
||||||
|
|
||||||
//KeyList<string, object> attributes;
|
//KeyList<string, object> attributes;
|
||||||
|
|
||||||
List<ulong> ages = new List<ulong>();
|
List<ulong?> ages = new();
|
||||||
List<DateTime> modificationDates = new List<DateTime>();
|
List<DateTime?> modificationDates = new ();
|
||||||
private ulong instanceAge;
|
private ulong instanceAge;
|
||||||
private DateTime instanceModificationDate;
|
private DateTime instanceModificationDate;
|
||||||
|
|
||||||
@ -100,10 +96,10 @@ public class Instance
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public Structure GetAttributes(string[] attributes = null)
|
public Map<string,object> GetAttributes(string[] attributes = null)
|
||||||
{
|
{
|
||||||
// @TODO
|
// @TODO
|
||||||
Structure rt = new Structure();
|
var rt = new Map<string,object>();
|
||||||
|
|
||||||
if (attributes != null)
|
if (attributes != null)
|
||||||
{
|
{
|
||||||
@ -172,7 +168,7 @@ public class Instance
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetAttributes(Structure attributes, bool clearAttributes = false)
|
public bool SetAttributes(Map<string,object> attributes, bool clearAttributes = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
// @ TODO
|
// @ TODO
|
||||||
@ -274,7 +270,7 @@ public class Instance
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Zero-based property index.</param>
|
/// <param name="index">Zero-based property index.</param>
|
||||||
/// <returns>Age.</returns>
|
/// <returns>Age.</returns>
|
||||||
public ulong GetAge(byte index)
|
public ulong? GetAge(byte index)
|
||||||
{
|
{
|
||||||
if (index < ages.Count)
|
if (index < ages.Count)
|
||||||
return ages[index];
|
return ages[index];
|
||||||
@ -287,13 +283,13 @@ public class Instance
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Zero-based property index.</param>
|
/// <param name="index">Zero-based property index.</param>
|
||||||
/// <param name="value">Age.</param>
|
/// <param name="value">Age.</param>
|
||||||
public void SetAge(byte index, ulong value)
|
public void SetAge(byte index, ulong? value)
|
||||||
{
|
{
|
||||||
if (index < ages.Count)
|
if (index < ages.Count)
|
||||||
{
|
{
|
||||||
ages[index] = value;
|
ages[index] = value;
|
||||||
if (value > instanceAge)
|
if (value > instanceAge)
|
||||||
instanceAge = value;
|
instanceAge = (ulong)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,13 +298,13 @@ public class Instance
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Zero-based property index.</param>
|
/// <param name="index">Zero-based property index.</param>
|
||||||
/// <param name="value">Modification date.</param>
|
/// <param name="value">Modification date.</param>
|
||||||
public void SetModificationDate(byte index, DateTime value)
|
public void SetModificationDate(byte index, DateTime? value)
|
||||||
{
|
{
|
||||||
if (index < modificationDates.Count)
|
if (index < modificationDates.Count)
|
||||||
{
|
{
|
||||||
modificationDates[index] = value;
|
modificationDates[index] = value;
|
||||||
if (value > instanceModificationDate)
|
if (value > instanceModificationDate)
|
||||||
instanceModificationDate = value;
|
instanceModificationDate = (DateTime) value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +313,7 @@ public class Instance
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Zero-based property index</param>
|
/// <param name="index">Zero-based property index</param>
|
||||||
/// <returns>Modification date.</returns>
|
/// <returns>Modification date.</returns>
|
||||||
public DateTime GetModificationDate(byte index)
|
public DateTime? GetModificationDate(byte index)
|
||||||
{
|
{
|
||||||
if (index < modificationDates.Count)
|
if (index < modificationDates.Count)
|
||||||
return modificationDates[index];
|
return modificationDates[index];
|
||||||
@ -333,7 +329,7 @@ public class Instance
|
|||||||
/// <param name="age">Property age</param>
|
/// <param name="age">Property age</param>
|
||||||
/// <param name="value">Property value</param>
|
/// <param name="value">Property value</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool LoadProperty(string name, ulong age, DateTime modificationDate, object value)
|
public bool LoadProperty(string name, ulong? age, DateTime? modificationDate, object value)
|
||||||
{
|
{
|
||||||
|
|
||||||
IResource res;
|
IResource res;
|
||||||
@ -354,7 +350,8 @@ public class Instance
|
|||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (pt.PropertyInfo.PropertyType == typeof(DistributedPropertyContext))
|
if (pt.PropertyInfo.PropertyType.IsGenericType
|
||||||
|
&& pt.PropertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(DistributedPropertyContext<>))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
@ -394,7 +391,7 @@ public class Instance
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Last modification date.
|
/// Last modification date.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime ModificationDate
|
public DateTime? ModificationDate
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -559,14 +556,15 @@ public class Instance
|
|||||||
if (pt.Recordable)
|
if (pt.Recordable)
|
||||||
{
|
{
|
||||||
store.Record(res, pt.Name, value, ages[pt.Index], now);
|
store.Record(res, pt.Name, value, ages[pt.Index], now);
|
||||||
|
|
||||||
}
|
}
|
||||||
else //if (pt.Storage == StorageMode.Recordable)
|
else //if (pt.Storage == StorageMode.Recordable)
|
||||||
{
|
{
|
||||||
store.Modify(res, pt.Name, value, ages[pt.Index], now);
|
store.Modify(res, pt.Name, value, ages[pt.Index], now);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceModified?.Invoke(res, pt.Name, value);
|
//ResourceModified?.Invoke(res, pt.Name, value);
|
||||||
|
|
||||||
|
PropertyModified?.Invoke(new PropertyModificationInfo(res, pt, value, instanceAge));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,21 +589,21 @@ public class Instance
|
|||||||
|
|
||||||
// internal void EmitResourceEvent(string name, string[] users, DistributedConnection[] connections, object[] args)
|
// internal void EmitResourceEvent(string name, string[] users, DistributedConnection[] connections, object[] args)
|
||||||
|
|
||||||
internal void EmitCustomResourceEvent(object issuer, Func<Session, bool> receivers, string name, object args)
|
internal void EmitCustomResourceEvent(object issuer, Func<Session, bool> receivers, EventTemplate eventTemplate, object value)
|
||||||
{
|
{
|
||||||
IResource res;
|
IResource res;
|
||||||
if (this.resource.TryGetTarget(out res))
|
if (this.resource.TryGetTarget(out res))
|
||||||
{
|
{
|
||||||
CustomResourceEventOccurred?.Invoke(res, issuer, receivers, name, args);
|
CustomEventOccurred?.Invoke(new CustomEventOccurredInfo(res, eventTemplate, receivers, issuer, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void EmitResourceEvent(string name, object args)
|
internal void EmitResourceEvent(EventTemplate eventTemplate, object value)
|
||||||
{
|
{
|
||||||
IResource res;
|
IResource res;
|
||||||
if (this.resource.TryGetTarget(out res))
|
if (this.resource.TryGetTarget(out res))
|
||||||
{
|
{
|
||||||
ResourceEventOccurred?.Invoke(res, name, args);
|
EventOccurred?.Invoke(new EventOccurredInfo(res, eventTemplate, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -912,7 +910,7 @@ public class Instance
|
|||||||
// if (ca.Length == 0)
|
// if (ca.Length == 0)
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
ResourceEventHandler<object> proxyDelegate = (args) => EmitResourceEvent(evt.Name, args);
|
ResourceEventHandler<object> proxyDelegate = (args) => EmitResourceEvent(evt, args);
|
||||||
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
|
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -922,7 +920,7 @@ public class Instance
|
|||||||
//if (ca.Length == 0)
|
//if (ca.Length == 0)
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt.Name, args);
|
CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt, args);
|
||||||
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
|
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -991,6 +989,6 @@ public class Instance
|
|||||||
|
|
||||||
private void Resource_OnDestroy(object sender)
|
private void Resource_OnDestroy(object sender)
|
||||||
{
|
{
|
||||||
ResourceDestroyed?.Invoke((IResource)sender);
|
Destroyed?.Invoke((IResource)sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
Esiur/Resource/PropertyModificationInfo.cs
Normal file
26
Esiur/Resource/PropertyModificationInfo.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using Esiur.Resource.Template;
|
||||||
|
|
||||||
|
namespace Esiur.Resource;
|
||||||
|
|
||||||
|
public struct PropertyModificationInfo
|
||||||
|
{
|
||||||
|
public readonly IResource Resource;
|
||||||
|
public readonly PropertyTemplate PropertyTemplate;
|
||||||
|
public string Name => PropertyTemplate.Name;
|
||||||
|
public readonly ulong Age;
|
||||||
|
public object Value;
|
||||||
|
|
||||||
|
public PropertyModificationInfo(IResource resource, PropertyTemplate propertyTemplate, object value, ulong age)
|
||||||
|
{
|
||||||
|
Resource = resource;
|
||||||
|
PropertyTemplate = propertyTemplate;
|
||||||
|
Age = age;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
7
Esiur/Resource/PropertyModifiedEvent.cs
Normal file
7
Esiur/Resource/PropertyModifiedEvent.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Resource;
|
||||||
|
|
||||||
|
public delegate void PropertyModifiedEvent(PropertyModificationInfo data);
|
@ -4,7 +4,7 @@ using System.Text;
|
|||||||
|
|
||||||
namespace Esiur.Resource;
|
namespace Esiur.Resource;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class | AttributeTargets.Enum)]
|
||||||
|
|
||||||
public class PublicAttribute : Attribute
|
public class PublicAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,7 @@ public class Resource : IResource
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
~Resource()
|
~Resource()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
8
Esiur/Resource/ResourceDestroyedEvent.cs
Normal file
8
Esiur/Resource/ResourceDestroyedEvent.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Resource
|
||||||
|
{
|
||||||
|
public delegate void ResourceDestroyedEvent(IResource resource);
|
||||||
|
}
|
@ -34,42 +34,21 @@ namespace Esiur.Resource;
|
|||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
public class ResourceProperty : System.Attribute
|
public class ResourceProperty : System.Attribute
|
||||||
{
|
{
|
||||||
bool serialize;
|
|
||||||
string readExpansion;
|
|
||||||
string writeExpansion;
|
|
||||||
// bool recordable;
|
|
||||||
//bool storable;
|
|
||||||
|
|
||||||
//public bool Recordable => recordable;
|
|
||||||
|
|
||||||
//public bool Storable => storable;
|
public readonly bool Nullable;
|
||||||
StorageMode storage;
|
public readonly StorageMode Storage;
|
||||||
|
public readonly bool Serialize;
|
||||||
|
public readonly string ReadExpansion;
|
||||||
|
public readonly string WriteExpansion;
|
||||||
|
|
||||||
public StorageMode Storage => storage;
|
|
||||||
|
|
||||||
public bool Serialize => serialize;
|
public ResourceProperty(StorageMode storage = StorageMode.NonVolatile, bool serialize = true,
|
||||||
|
string readExpansion = null, string writeExpansion = null)
|
||||||
public string ReadExpansion
|
|
||||||
{
|
{
|
||||||
get
|
this.ReadExpansion = readExpansion;
|
||||||
{
|
this.WriteExpansion = writeExpansion;
|
||||||
return readExpansion;
|
this.Storage = storage;
|
||||||
}
|
this.Serialize = serialize;
|
||||||
}
|
|
||||||
|
|
||||||
public string WriteExpansion
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return writeExpansion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResourceProperty(StorageMode storage = StorageMode.NonVolatile, bool serialize = true, string readExpansion = null, string writeExpansion = null)
|
|
||||||
{
|
|
||||||
this.readExpansion = readExpansion;
|
|
||||||
this.writeExpansion = writeExpansion;
|
|
||||||
this.storage = storage;
|
|
||||||
this.serialize = serialize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,11 +40,11 @@ public class Storable : global::System.Attribute
|
|||||||
|
|
||||||
SerializerFunction serializer;
|
SerializerFunction serializer;
|
||||||
DeserializerFunction deserializer;
|
DeserializerFunction deserializer;
|
||||||
DataType type;
|
RepresentationType dataType;
|
||||||
|
|
||||||
public Storable()
|
public Storable()
|
||||||
{
|
{
|
||||||
type = DataType.Void;
|
//dataType = = DataType.Void;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeserializerFunction Deserializer
|
public DeserializerFunction Deserializer
|
||||||
@ -57,14 +57,14 @@ public class Storable : global::System.Attribute
|
|||||||
get { return serializer; }
|
get { return serializer; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Storable(DataType type)
|
public Storable(RepresentationType type)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.dataType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Storable(DataType type, SerializerFunction serializer, DeserializerFunction deserializer)
|
public Storable(RepresentationType type, SerializerFunction serializer, DeserializerFunction deserializer)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.dataType = type;
|
||||||
this.serializer = serializer;
|
this.serializer = serializer;
|
||||||
this.deserializer = deserializer;
|
this.deserializer = deserializer;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ public abstract class Store<T> : IStore where T : IResource
|
|||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
|
|
||||||
public abstract AsyncReply<bool> AddChild(IResource parent, IResource child);
|
public abstract AsyncReply<bool> AddChild(IResource parent, IResource child);
|
||||||
|
|
||||||
public abstract AsyncReply<bool> AddParent(IResource child, IResource parent);
|
public abstract AsyncReply<bool> AddParent(IResource child, IResource parent);
|
||||||
@ -30,13 +31,13 @@ public abstract class Store<T> : IStore where T : IResource
|
|||||||
|
|
||||||
public abstract string Link(IResource resource);
|
public abstract string Link(IResource resource);
|
||||||
|
|
||||||
public abstract bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
|
public abstract bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
|
||||||
|
|
||||||
public abstract AsyncBag<T1> Parents<T1>(IResource resource, string name) where T1 : IResource;
|
public abstract AsyncBag<T1> Parents<T1>(IResource resource, string name) where T1 : IResource;
|
||||||
|
|
||||||
public abstract AsyncReply<bool> Put(IResource resource);
|
public abstract AsyncReply<bool> Put(IResource resource);
|
||||||
|
|
||||||
public abstract bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
|
public abstract bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
|
||||||
|
|
||||||
public abstract bool Remove(IResource resource);
|
public abstract bool Remove(IResource resource);
|
||||||
|
|
||||||
|
@ -9,18 +9,24 @@ public class ArgumentTemplate
|
|||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
public TemplateDataType Type { get; set; }
|
public bool Optional { get; set; }
|
||||||
|
|
||||||
|
public RepresentationType Type { get; set; }
|
||||||
|
|
||||||
public ParameterInfo ParameterInfo { get; set; }
|
public ParameterInfo ParameterInfo { get; set; }
|
||||||
|
|
||||||
public static (uint, ArgumentTemplate) Parse(byte[] data, uint offset)
|
public int Index { get; set; }
|
||||||
|
|
||||||
|
public static (uint, ArgumentTemplate) Parse(byte[] data, uint offset, int index)
|
||||||
{
|
{
|
||||||
|
var optional = (data[offset++] & 0x1) == 0x1;
|
||||||
|
|
||||||
var cs = (uint)data[offset++];
|
var cs = (uint)data[offset++];
|
||||||
var name = data.GetString(offset, cs);
|
var name = data.GetString(offset, cs);
|
||||||
offset += cs;
|
offset += cs;
|
||||||
var (size, type) = TemplateDataType.Parse(data, offset);
|
var (size, type) = RepresentationType.Parse(data, offset);
|
||||||
|
|
||||||
return (cs + 1 + size, new ArgumentTemplate(name, type));
|
return (cs + 2 + size, new ArgumentTemplate(name, index, type, optional));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArgumentTemplate()
|
public ArgumentTemplate()
|
||||||
@ -28,10 +34,12 @@ public class ArgumentTemplate
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArgumentTemplate(string name, TemplateDataType type)
|
public ArgumentTemplate(string name, int index, RepresentationType type, bool optional)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
|
Index = index;
|
||||||
Type = type;
|
Type = type;
|
||||||
|
Optional = optional;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] Compose()
|
public byte[] Compose()
|
||||||
@ -39,6 +47,7 @@ public class ArgumentTemplate
|
|||||||
var name = DC.ToBytes(Name);
|
var name = DC.ToBytes(Name);
|
||||||
|
|
||||||
return new BinaryList()
|
return new BinaryList()
|
||||||
|
.AddUInt8(Optional ? (byte)1 : (byte)0)
|
||||||
.AddUInt8((byte)name.Length)
|
.AddUInt8((byte)name.Length)
|
||||||
.AddUInt8Array(name)
|
.AddUInt8Array(name)
|
||||||
.AddUInt8Array(Type.Compose())
|
.AddUInt8Array(Type.Compose())
|
||||||
|
@ -16,8 +16,8 @@ public class AttributeTemplate : MemberTemplate
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AttributeTemplate(TypeTemplate template, byte index, string name)
|
public AttributeTemplate(TypeTemplate template, byte index, string name, bool inherited)
|
||||||
: base(template, MemberType.Attribute, index, name)
|
: base(template, index, name, inherited)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
67
Esiur/Resource/Template/ConstantTemplate.cs
Normal file
67
Esiur/Resource/Template/ConstantTemplate.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using Esiur.Data;
|
||||||
|
|
||||||
|
namespace Esiur.Resource.Template;
|
||||||
|
|
||||||
|
public class ConstantTemplate : MemberTemplate
|
||||||
|
{
|
||||||
|
public readonly object Value;
|
||||||
|
//public readonly byte[] ValueData;
|
||||||
|
public readonly string Expansion;
|
||||||
|
public readonly RepresentationType ValueType;
|
||||||
|
|
||||||
|
public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType valueType, object value, string expansion)
|
||||||
|
: base(template, index, name, inherited)
|
||||||
|
{
|
||||||
|
Expansion = expansion;
|
||||||
|
ValueType = valueType;
|
||||||
|
Value = value;
|
||||||
|
//try
|
||||||
|
//{
|
||||||
|
// Codec.Compose(value, null);
|
||||||
|
// Value = value;
|
||||||
|
//}
|
||||||
|
//catch
|
||||||
|
//{
|
||||||
|
// throw new Exception($"Constant `{template.ClassName}.{name}` can't be serialized.");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Compose()
|
||||||
|
{
|
||||||
|
var name = base.Compose();
|
||||||
|
|
||||||
|
var hdr = Inherited ? (byte)0x80 : (byte)0;
|
||||||
|
|
||||||
|
|
||||||
|
if (Expansion != null)
|
||||||
|
{
|
||||||
|
var exp = DC.ToBytes(Expansion);
|
||||||
|
hdr |= 0x70;
|
||||||
|
return new BinaryList()
|
||||||
|
.AddUInt8(hdr)
|
||||||
|
.AddUInt8((byte)name.Length)
|
||||||
|
.AddUInt8Array(name)
|
||||||
|
.AddUInt8Array(ValueType.Compose())
|
||||||
|
.AddUInt8Array(Codec.Compose(Value, null))
|
||||||
|
.AddInt32(exp.Length)
|
||||||
|
.AddUInt8Array(exp)
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hdr |= 0x60;
|
||||||
|
|
||||||
|
return new BinaryList()
|
||||||
|
.AddUInt8(hdr)
|
||||||
|
.AddUInt8((byte)name.Length)
|
||||||
|
.AddUInt8Array(name)
|
||||||
|
.AddUInt8Array(ValueType.Compose())
|
||||||
|
.AddUInt8Array(Codec.Compose(Value, null))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
10
Esiur/Resource/Template/CustomEventOccurredEvent.cs
Normal file
10
Esiur/Resource/Template/CustomEventOccurredEvent.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Resource.Template
|
||||||
|
{
|
||||||
|
internal class CustomEventOccurredEvent
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -19,17 +19,23 @@ public class EventTemplate : MemberTemplate
|
|||||||
|
|
||||||
public EventInfo EventInfo { get; set; }
|
public EventInfo EventInfo { get; set; }
|
||||||
|
|
||||||
public TemplateDataType ArgumentType { get; set; }
|
public RepresentationType ArgumentType { get; set; }
|
||||||
|
|
||||||
public override byte[] Compose()
|
public override byte[] Compose()
|
||||||
{
|
{
|
||||||
var name = base.Compose();
|
var name = base.Compose();
|
||||||
|
|
||||||
|
var hdr = Inherited ? (byte)0x80 : (byte)0;
|
||||||
|
|
||||||
|
if (Listenable)
|
||||||
|
hdr |= 0x8;
|
||||||
|
|
||||||
if (Expansion != null)
|
if (Expansion != null)
|
||||||
{
|
{
|
||||||
var exp = DC.ToBytes(Expansion);
|
var exp = DC.ToBytes(Expansion);
|
||||||
|
hdr |= 0x50;
|
||||||
return new BinaryList()
|
return new BinaryList()
|
||||||
.AddUInt8(Listenable ? (byte)0x58 : (byte)0x50)
|
.AddUInt8(hdr)
|
||||||
.AddUInt8((byte)name.Length)
|
.AddUInt8((byte)name.Length)
|
||||||
.AddUInt8Array(name)
|
.AddUInt8Array(name)
|
||||||
.AddUInt8Array(ArgumentType.Compose())
|
.AddUInt8Array(ArgumentType.Compose())
|
||||||
@ -38,17 +44,17 @@ public class EventTemplate : MemberTemplate
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
hdr |= 0x40;
|
||||||
return new BinaryList()
|
return new BinaryList()
|
||||||
.AddUInt8(Listenable ? (byte)0x48 : (byte)0x40)
|
.AddUInt8(hdr)
|
||||||
.AddUInt8((byte)name.Length)
|
.AddUInt8((byte)name.Length)
|
||||||
.AddUInt8Array(name)
|
.AddUInt8Array(name)
|
||||||
.AddUInt8Array(ArgumentType.Compose())
|
.AddUInt8Array(ArgumentType.Compose())
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EventTemplate(TypeTemplate template, byte index, string name,bool inherited, RepresentationType argumentType, string expansion = null, bool listenable = false)
|
||||||
public EventTemplate(TypeTemplate template, byte index, string name, TemplateDataType argumentType, string expansion = null, bool listenable = false)
|
: base(template, index, name, inherited)
|
||||||
: base(template, MemberType.Property, index, name)
|
|
||||||
{
|
{
|
||||||
this.Expansion = expansion;
|
this.Expansion = expansion;
|
||||||
this.Listenable = listenable;
|
this.Listenable = listenable;
|
||||||
|
@ -22,7 +22,7 @@ public class FunctionTemplate : MemberTemplate
|
|||||||
// set;
|
// set;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public TemplateDataType ReturnType { get; set; }
|
public RepresentationType ReturnType { get; set; }
|
||||||
|
|
||||||
public ArgumentTemplate[] Arguments { get; set; }
|
public ArgumentTemplate[] Arguments { get; set; }
|
||||||
|
|
||||||
@ -54,17 +54,16 @@ public class FunctionTemplate : MemberTemplate
|
|||||||
var exp = DC.ToBytes(Expansion);
|
var exp = DC.ToBytes(Expansion);
|
||||||
bl.AddInt32(exp.Length)
|
bl.AddInt32(exp.Length)
|
||||||
.AddUInt8Array(exp);
|
.AddUInt8Array(exp);
|
||||||
bl.InsertUInt8(0, 0x10);
|
bl.InsertUInt8(0, Inherited ? (byte)0x90 : (byte)0x10);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bl.InsertUInt8(0, 0x0);
|
bl.InsertUInt8(0, Inherited ? (byte)0x80 : (byte)0x0);
|
||||||
|
|
||||||
return bl.ToArray();
|
return bl.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FunctionTemplate(TypeTemplate template, byte index, string name, bool inherited, ArgumentTemplate[] arguments, RepresentationType returnType, string expansion = null)
|
||||||
public FunctionTemplate(TypeTemplate template, byte index, string name, ArgumentTemplate[] arguments, TemplateDataType returnType, string expansion = null)
|
: base(template, index, name, inherited)
|
||||||
: base(template, MemberType.Property, index, name)
|
|
||||||
{
|
{
|
||||||
//this.IsVoid = isVoid;
|
//this.IsVoid = isVoid;
|
||||||
this.Arguments = arguments;
|
this.Arguments = arguments;
|
||||||
|
@ -8,34 +8,21 @@ using System.Threading.Tasks;
|
|||||||
namespace Esiur.Resource.Template;
|
namespace Esiur.Resource.Template;
|
||||||
public class MemberTemplate
|
public class MemberTemplate
|
||||||
{
|
{
|
||||||
public enum MemberType
|
|
||||||
|
public readonly byte Index;
|
||||||
|
public readonly string Name;
|
||||||
|
public readonly bool Inherited;
|
||||||
|
public readonly TypeTemplate Template;
|
||||||
|
|
||||||
|
public MemberTemplate(TypeTemplate template, byte index, string name, bool inherited)
|
||||||
{
|
{
|
||||||
Function = 0,
|
Template = template;
|
||||||
Property = 1,
|
Index = index;
|
||||||
Event = 2,
|
Name = name;
|
||||||
Attribute = 3
|
Inherited = inherited;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte Index => index;
|
public string Fullname => Template.ClassName + "." + Name;
|
||||||
public string Name => name;
|
|
||||||
public MemberType Type => type;
|
|
||||||
|
|
||||||
TypeTemplate template;
|
|
||||||
string name;
|
|
||||||
MemberType type;
|
|
||||||
byte index;
|
|
||||||
|
|
||||||
public TypeTemplate Template => template;
|
|
||||||
|
|
||||||
public MemberTemplate(TypeTemplate template, MemberType type, byte index, string name)
|
|
||||||
{
|
|
||||||
this.template = template;
|
|
||||||
this.type = type;
|
|
||||||
this.index = index;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Fullname => template.ClassName + "." + Name;
|
|
||||||
|
|
||||||
public virtual byte[] Compose()
|
public virtual byte[] Compose()
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@ public class PropertyTemplate : MemberTemplate
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TemplateDataType ValueType { get; set; }
|
public RepresentationType ValueType { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -40,6 +40,7 @@ public class PropertyTemplate : MemberTemplate
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsNullable { get; set; }
|
||||||
|
|
||||||
public bool Recordable
|
public bool Recordable
|
||||||
{
|
{
|
||||||
@ -79,6 +80,9 @@ public class PropertyTemplate : MemberTemplate
|
|||||||
var name = base.Compose();
|
var name = base.Compose();
|
||||||
var pv = ((byte)(Permission) << 1) | (Recordable ? 1 : 0);
|
var pv = ((byte)(Permission) << 1) | (Recordable ? 1 : 0);
|
||||||
|
|
||||||
|
if (Inherited)
|
||||||
|
pv |= 0x80;
|
||||||
|
|
||||||
if (WriteExpansion != null && ReadExpansion != null)
|
if (WriteExpansion != null && ReadExpansion != null)
|
||||||
{
|
{
|
||||||
var rexp = DC.ToBytes(ReadExpansion);
|
var rexp = DC.ToBytes(ReadExpansion);
|
||||||
@ -129,12 +133,14 @@ public class PropertyTemplate : MemberTemplate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PropertyTemplate(TypeTemplate template, byte index, string name, TemplateDataType valueType, string read = null, string write = null, bool recordable = false)
|
public PropertyTemplate(TypeTemplate template, byte index, string name, bool inherited,
|
||||||
: base(template, MemberType.Property, index, name)
|
RepresentationType valueType, string read = null, string write = null, bool recordable = false)
|
||||||
|
: base(template, index, name, inherited)
|
||||||
{
|
{
|
||||||
this.Recordable = recordable;
|
this.Recordable = recordable;
|
||||||
//this.Storage = storage;
|
//this.Storage = storage;
|
||||||
this.ReadExpansion = read;
|
if (read != null)
|
||||||
|
this.ReadExpansion = read;
|
||||||
this.WriteExpansion = write;
|
this.WriteExpansion = write;
|
||||||
this.ValueType = valueType;
|
this.ValueType = valueType;
|
||||||
}
|
}
|
||||||
|
@ -1,107 +1,131 @@
|
|||||||
using Esiur.Data;
|
//using Esiur.Data;
|
||||||
using System;
|
//using System;
|
||||||
using System.Collections.Generic;
|
//using System.Collections;
|
||||||
using System.Dynamic;
|
//using System.Collections.Generic;
|
||||||
using System.Text;
|
//using System.Dynamic;
|
||||||
|
//using System.Linq;
|
||||||
|
//using System.Text;
|
||||||
|
|
||||||
namespace Esiur.Resource.Template;
|
//namespace Esiur.Resource.Template;
|
||||||
public struct TemplateDataType
|
//public struct TemplateDataType
|
||||||
{
|
//{
|
||||||
public DataType Type { get; set; }
|
// public DataType Type { get; set; }
|
||||||
//public string TypeName { get; set; }
|
// //public string TypeName { get; set; }
|
||||||
public TypeTemplate TypeTemplate => TypeGuid == null ? null : Warehouse.GetTemplateByClassId((Guid)TypeGuid);
|
// public TypeTemplate TypeTemplate => TypeGuid == null ? null : Warehouse.GetTemplateByClassId((Guid)TypeGuid);
|
||||||
|
|
||||||
public Guid? TypeGuid { get; set; }
|
// public Guid? TypeGuid { get; set; }
|
||||||
//public TemplateDataType(DataType type, string typeName)
|
|
||||||
//{
|
// public bool IsNullable { get; set; }
|
||||||
// Type = type;
|
// //public TemplateDataType(DataType type, string typeName)
|
||||||
// TypeName = typeName;
|
// //{
|
||||||
//}
|
// // Type = type;
|
||||||
|
// // TypeName = typeName;
|
||||||
|
// //}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static TemplateDataType FromType(Type type)
|
// public static TemplateDataType FromType(Type type)
|
||||||
{
|
// {
|
||||||
|
|
||||||
var t = type switch
|
|
||||||
{
|
|
||||||
{ IsArray: true } => type.GetElementType(),
|
|
||||||
{ IsEnum: true } => type.GetEnumUnderlyingType(),
|
|
||||||
(_) => type
|
|
||||||
};
|
|
||||||
|
|
||||||
DataType dt = t switch
|
|
||||||
{
|
|
||||||
_ when t == typeof(bool) => DataType.Bool,
|
|
||||||
_ when t == typeof(char) => DataType.Char,
|
|
||||||
_ when t == typeof(byte) => DataType.UInt8,
|
|
||||||
_ when t == typeof(sbyte) => DataType.Int8,
|
|
||||||
_ when t == typeof(short) => DataType.Int16,
|
|
||||||
_ when t == typeof(ushort) => DataType.UInt16,
|
|
||||||
_ when t == typeof(int) => DataType.Int32,
|
|
||||||
_ when t == typeof(uint) => DataType.UInt32,
|
|
||||||
_ when t == typeof(long) => DataType.Int64,
|
|
||||||
_ when t == typeof(ulong) => DataType.UInt64,
|
|
||||||
_ when t == typeof(float) => DataType.Float32,
|
|
||||||
_ when t == typeof(double) => DataType.Float64,
|
|
||||||
_ when t == typeof(decimal) => DataType.Decimal,
|
|
||||||
_ when t == typeof(string) => DataType.String,
|
|
||||||
_ when t == typeof(DateTime) => DataType.DateTime,
|
|
||||||
_ when t == typeof(IResource) => DataType.Void, // Dynamic resource (unspecified type)
|
|
||||||
_ when t == typeof(IRecord) => DataType.Void, // Dynamic record (unspecified type)
|
|
||||||
_ when typeof(Structure).IsAssignableFrom(t) || t == typeof(ExpandoObject) => DataType.Structure,
|
|
||||||
_ when Codec.ImplementsInterface(t, typeof(IResource)) => DataType.Resource,
|
|
||||||
_ when Codec.ImplementsInterface(t, typeof(IRecord)) => DataType.Record,
|
|
||||||
_ => DataType.Void
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Guid? typeGuid = null;
|
// bool isList = typeof(ICollection).IsAssignableFrom(type);
|
||||||
|
|
||||||
if (dt == DataType.Resource || dt == DataType.Record)
|
// var t = type switch
|
||||||
typeGuid = TypeTemplate.GetTypeGuid(t);
|
// {
|
||||||
|
|
||||||
if (type.IsArray)
|
// { IsArray: true } => type.GetElementType(),
|
||||||
dt = (DataType)((byte)dt | 0x80);
|
// { IsEnum: true } => type.GetEnumUnderlyingType(),
|
||||||
|
// _ when isList => Codec.GetGenericListType(type),
|
||||||
|
// (_) => type
|
||||||
|
// };
|
||||||
|
|
||||||
return new TemplateDataType()
|
// DataType dt = t switch
|
||||||
{
|
// {
|
||||||
Type = dt,
|
// _ when t == typeof(bool) => DataType.Bool,
|
||||||
TypeGuid = typeGuid
|
// _ when t == typeof(char) => DataType.Char,
|
||||||
};
|
// _ when t == typeof(byte) => DataType.UInt8,
|
||||||
}
|
// _ when t == typeof(sbyte) => DataType.Int8,
|
||||||
|
// _ when t == typeof(short) => DataType.Int16,
|
||||||
public byte[] Compose()
|
// _ when t == typeof(ushort) => DataType.UInt16,
|
||||||
{
|
// _ when t == typeof(int) => DataType.Int32,
|
||||||
if (Type == DataType.Resource ||
|
// _ when t == typeof(uint) => DataType.UInt32,
|
||||||
Type == DataType.ResourceArray ||
|
// _ when t == typeof(long) => DataType.Int64,
|
||||||
Type == DataType.Record ||
|
// _ when t == typeof(ulong) => DataType.UInt64,
|
||||||
Type == DataType.RecordArray)
|
// _ when t == typeof(float) => DataType.Float32,
|
||||||
{
|
// _ when t == typeof(double) => DataType.Float64,
|
||||||
var guid = DC.ToBytes((Guid)TypeGuid);
|
// _ when t == typeof(decimal) => DataType.Decimal,
|
||||||
return new BinaryList()
|
// _ when t == typeof(string) => DataType.String,
|
||||||
.AddUInt8((byte)Type)
|
// _ when t == typeof(DateTime) => DataType.DateTime,
|
||||||
.AddUInt8Array(guid).ToArray();
|
// _ when t == typeof(IResource) => DataType.Void, // Dynamic resource (unspecified type)
|
||||||
}
|
// _ when t == typeof(IRecord) => DataType.Void, // Dynamic record (unspecified type)
|
||||||
else
|
// _ when typeof(Structure).IsAssignableFrom(t) || t == typeof(ExpandoObject) => DataType.Structure,
|
||||||
return new byte[] { (byte)Type };
|
// _ when Codec.ImplementsInterface(t, typeof(IResource)) => DataType.Resource,
|
||||||
}
|
// _ when Codec.ImplementsInterface(t, typeof(IRecord)) => DataType.Record,
|
||||||
|
// _ => DataType.Void
|
||||||
public override string ToString() => Type.ToString() + TypeTemplate != null ? "<" + TypeTemplate.ClassName + ">" : "";
|
// };
|
||||||
|
|
||||||
|
|
||||||
public static (uint, TemplateDataType) Parse(byte[] data, uint offset)
|
// Guid? typeGuid = null;
|
||||||
{
|
|
||||||
var type = (DataType)data[offset++];
|
// if (dt == DataType.Resource || dt == DataType.Record)
|
||||||
if (type == DataType.Resource ||
|
// typeGuid = TypeTemplate.GetTypeGuid(t);
|
||||||
type == DataType.ResourceArray ||
|
|
||||||
type == DataType.Record ||
|
// if (type.IsArray || isList)
|
||||||
type == DataType.RecordArray)
|
// dt = (DataType)((byte)dt | 0x80);
|
||||||
{
|
|
||||||
var guid = data.GetGuid(offset);
|
|
||||||
return (17, new TemplateDataType() { Type = type, TypeGuid = guid });
|
// return new TemplateDataType()
|
||||||
}
|
// {
|
||||||
else
|
// Type = dt,
|
||||||
return (1, new TemplateDataType() { Type = type });
|
// TypeGuid = typeGuid,
|
||||||
}
|
// IsNullable = Nullable.GetUnderlyingType(type) != null
|
||||||
}
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public byte[] Compose()
|
||||||
|
// {
|
||||||
|
// if (Type == DataType.Resource ||
|
||||||
|
// Type == DataType.ResourceArray ||
|
||||||
|
// Type == DataType.Record ||
|
||||||
|
// Type == DataType.RecordArray)
|
||||||
|
// {
|
||||||
|
// var guid = DC.ToBytes((Guid)TypeGuid);
|
||||||
|
// if (IsNullable)
|
||||||
|
// {
|
||||||
|
// return new BinaryList()
|
||||||
|
// .AddUInt8((byte)((byte)Type | 0x40))
|
||||||
|
// .AddUInt8Array(guid).ToArray();
|
||||||
|
// } else
|
||||||
|
// {
|
||||||
|
// return new BinaryList()
|
||||||
|
// .AddUInt8((byte)Type)
|
||||||
|
// .AddUInt8Array(guid).ToArray();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if (IsNullable)
|
||||||
|
// return new byte[] { (byte)((byte)Type | 0x40) };
|
||||||
|
// else
|
||||||
|
// return new byte[] { (byte)Type };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public override string ToString() => Type.ToString() + (IsNullable ? "?":"" )
|
||||||
|
// + TypeTemplate != null ? "<" + TypeTemplate.ClassName + ">" : "";
|
||||||
|
|
||||||
|
|
||||||
|
// public static (uint, TemplateDataType) Parse(byte[] data, uint offset)
|
||||||
|
// {
|
||||||
|
// bool isNullable = (data[offset] & 0x40) > 0;
|
||||||
|
// var type = (DataType)(data[offset++] & 0xBF);
|
||||||
|
|
||||||
|
// if (type == DataType.Resource ||
|
||||||
|
// type == DataType.ResourceArray ||
|
||||||
|
// type == DataType.Record ||
|
||||||
|
// type == DataType.RecordArray)
|
||||||
|
// {
|
||||||
|
// var guid = data.GetGuid(offset);
|
||||||
|
// return (17, new TemplateDataType() { Type = type, TypeGuid = guid , IsNullable = isNullable});
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// return (1, new TemplateDataType() { Type = type, IsNullable = isNullable });
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
@ -9,4 +9,5 @@ public enum TemplateType : byte
|
|||||||
Resource,
|
Resource,
|
||||||
Record,
|
Record,
|
||||||
Wrapper,
|
Wrapper,
|
||||||
|
Enum
|
||||||
}
|
}
|
||||||
|
@ -22,20 +22,26 @@ public class TypeTemplate
|
|||||||
{
|
{
|
||||||
|
|
||||||
protected Guid classId;
|
protected Guid classId;
|
||||||
protected string className;
|
protected Guid? parentId;
|
||||||
protected List<MemberTemplate> members = new List<MemberTemplate>();
|
|
||||||
protected List<FunctionTemplate> functions = new List<FunctionTemplate>();
|
string className;
|
||||||
protected List<EventTemplate> events = new List<EventTemplate>();
|
List<MemberTemplate> members = new List<MemberTemplate>();
|
||||||
protected List<PropertyTemplate> properties = new List<PropertyTemplate>();
|
List<FunctionTemplate> functions = new List<FunctionTemplate>();
|
||||||
protected List<AttributeTemplate> attributes = new List<AttributeTemplate>();
|
List<EventTemplate> events = new List<EventTemplate>();
|
||||||
protected int version;
|
List<PropertyTemplate> properties = new List<PropertyTemplate>();
|
||||||
protected TemplateType templateType;
|
List<AttributeTemplate> attributes = new List<AttributeTemplate>();
|
||||||
|
List<ConstantTemplate> constants = new();
|
||||||
|
int version;
|
||||||
|
TemplateType templateType;
|
||||||
|
|
||||||
|
|
||||||
// protected TemplateType
|
// protected TemplateType
|
||||||
//bool isReady;
|
//bool isReady;
|
||||||
|
|
||||||
protected byte[] content;
|
protected byte[] content;
|
||||||
|
|
||||||
|
public Guid? ParentId => parentId;
|
||||||
|
|
||||||
public byte[] Content
|
public byte[] Content
|
||||||
{
|
{
|
||||||
get { return content; }
|
get { return content; }
|
||||||
@ -45,9 +51,7 @@ public class TypeTemplate
|
|||||||
|
|
||||||
|
|
||||||
public Type DefinedType { get; set; }
|
public Type DefinedType { get; set; }
|
||||||
|
public Type ParentDefinedType { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//public MemberTemplate GetMemberTemplate(MemberInfo member)
|
//public MemberTemplate GetMemberTemplate(MemberInfo member)
|
||||||
//{
|
//{
|
||||||
@ -145,7 +149,7 @@ public class TypeTemplate
|
|||||||
get { return properties.ToArray(); }
|
get { return properties.ToArray(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConstantTemplate[] Constants => constants.ToArray();
|
||||||
|
|
||||||
public TypeTemplate()
|
public TypeTemplate()
|
||||||
{
|
{
|
||||||
@ -166,7 +170,7 @@ public class TypeTemplate
|
|||||||
static Type GetElementType(Type type) => type switch
|
static Type GetElementType(Type type) => type switch
|
||||||
{
|
{
|
||||||
{ IsArray: true } => type.GetElementType(),
|
{ IsArray: true } => type.GetElementType(),
|
||||||
{ IsEnum: true } => type.GetEnumUnderlyingType(),
|
// { IsEnum: true } => type.GetEnumUnderlyingType(),
|
||||||
(_) => type
|
(_) => type
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -177,8 +181,20 @@ public class TypeTemplate
|
|||||||
|
|
||||||
var list = new List<TypeTemplate>();
|
var list = new List<TypeTemplate>();
|
||||||
|
|
||||||
|
// Add self
|
||||||
list.Add(template);
|
list.Add(template);
|
||||||
|
|
||||||
|
// Add parents
|
||||||
|
var parentType = template.ParentDefinedType;
|
||||||
|
|
||||||
|
// Get parents
|
||||||
|
while (parentType != null)
|
||||||
|
{
|
||||||
|
var parentTemplate = Warehouse.GetTemplateByType(parentType);
|
||||||
|
list.Add(parentTemplate);
|
||||||
|
parentType = parentTemplate.ParentDefinedType;
|
||||||
|
}
|
||||||
|
|
||||||
Action<TypeTemplate, List<TypeTemplate>> getDependenciesFunc = null;
|
Action<TypeTemplate, List<TypeTemplate>> getDependenciesFunc = null;
|
||||||
|
|
||||||
getDependenciesFunc = (TypeTemplate tmp, List<TypeTemplate> bag) =>
|
getDependenciesFunc = (TypeTemplate tmp, List<TypeTemplate> bag) =>
|
||||||
@ -186,8 +202,8 @@ public class TypeTemplate
|
|||||||
if (template.DefinedType == null)
|
if (template.DefinedType == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
foreach (var f in tmp.functions)
|
foreach (var f in tmp.functions)
|
||||||
{
|
{
|
||||||
var frtt = Warehouse.GetTemplateByType(GetElementType(f.MethodInfo.ReturnType));
|
var frtt = Warehouse.GetTemplateByType(GetElementType(f.MethodInfo.ReturnType));
|
||||||
if (frtt != null)
|
if (frtt != null)
|
||||||
@ -214,8 +230,8 @@ public class TypeTemplate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip DistributedConnection argument
|
// skip DistributedConnection argument
|
||||||
if (args.Length > 0)
|
if (args.Length > 0)
|
||||||
{
|
{
|
||||||
var last = args.Last();
|
var last = args.Last();
|
||||||
if (last.ParameterType != typeof(DistributedConnection))
|
if (last.ParameterType != typeof(DistributedConnection))
|
||||||
@ -234,8 +250,8 @@ public class TypeTemplate
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// properties
|
// properties
|
||||||
foreach (var p in tmp.properties)
|
foreach (var p in tmp.properties)
|
||||||
{
|
{
|
||||||
var pt = Warehouse.GetTemplateByType(GetElementType(p.PropertyInfo.PropertyType));
|
var pt = Warehouse.GetTemplateByType(GetElementType(p.PropertyInfo.PropertyType));
|
||||||
if (pt != null)
|
if (pt != null)
|
||||||
@ -248,8 +264,8 @@ public class TypeTemplate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// events
|
// events
|
||||||
foreach (var e in tmp.events)
|
foreach (var e in tmp.events)
|
||||||
{
|
{
|
||||||
var et = Warehouse.GetTemplateByType(GetElementType(e.EventInfo.EventHandlerType.GenericTypeArguments[0]));
|
var et = Warehouse.GetTemplateByType(GetElementType(e.EventInfo.EventHandlerType.GenericTypeArguments[0]));
|
||||||
|
|
||||||
@ -268,6 +284,15 @@ public class TypeTemplate
|
|||||||
return list.ToArray();
|
return list.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetTypeAnnotationName(Type type)
|
||||||
|
{
|
||||||
|
var nullType = Nullable.GetUnderlyingType(type);
|
||||||
|
if (nullType == null)
|
||||||
|
return type.Name;
|
||||||
|
else
|
||||||
|
return type.Name + "?";
|
||||||
|
}
|
||||||
|
|
||||||
public TypeTemplate(Type type, bool addToWarehouse = false)
|
public TypeTemplate(Type type, bool addToWarehouse = false)
|
||||||
{
|
{
|
||||||
if (Codec.InheritsClass(type, typeof(DistributedResource)))
|
if (Codec.InheritsClass(type, typeof(DistributedResource)))
|
||||||
@ -276,6 +301,8 @@ public class TypeTemplate
|
|||||||
templateType = TemplateType.Resource;
|
templateType = TemplateType.Resource;
|
||||||
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
|
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
|
||||||
templateType = TemplateType.Record;
|
templateType = TemplateType.Record;
|
||||||
|
else if (type.IsEnum)
|
||||||
|
templateType = TemplateType.Enum;
|
||||||
else
|
else
|
||||||
throw new Exception("Type must implement IResource, IRecord or inherit from DistributedResource.");
|
throw new Exception("Type must implement IResource, IRecord or inherit from DistributedResource.");
|
||||||
|
|
||||||
@ -291,32 +318,56 @@ public class TypeTemplate
|
|||||||
|
|
||||||
className = type.FullName;
|
className = type.FullName;
|
||||||
|
|
||||||
//Console.WriteLine($"Creating {className}");
|
|
||||||
|
|
||||||
// set guid
|
// set guid
|
||||||
classId = GetTypeGuid(className);
|
classId = GetTypeGuid(className);
|
||||||
|
|
||||||
if (addToWarehouse)
|
if (addToWarehouse)
|
||||||
Warehouse.PutTemplate(this);
|
Warehouse.PutTemplate(this);
|
||||||
|
|
||||||
#if NETSTANDARD
|
|
||||||
PropertyInfo[] propsInfo = type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
|
||||||
EventInfo[] eventsInfo = type.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
|
||||||
MethodInfo[] methodsInfo = type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance); // | BindingFlags.DeclaredOnly);
|
|
||||||
|
|
||||||
#else
|
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
||||||
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
||||||
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); // | BindingFlags.DeclaredOnly);
|
||||||
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
|
FieldInfo[] constantsInfo = type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
bool classIsPublic = type.IsEnum || (type.GetCustomAttribute<PublicAttribute>() != null);
|
||||||
|
|
||||||
|
|
||||||
bool classIsPublic = type.GetCustomAttribute<PublicAttribute>() != null;
|
|
||||||
|
|
||||||
byte i = 0;
|
byte i = 0;
|
||||||
|
|
||||||
if (classIsPublic)
|
if (classIsPublic)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
foreach (var ci in constantsInfo)
|
||||||
|
{
|
||||||
|
var privateAttr = ci.GetCustomAttribute<PrivateAttribute>(true);
|
||||||
|
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
|
||||||
|
if (privateAttr != null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
var valueType = RepresentationType.FromType(ci.FieldType);
|
||||||
|
|
||||||
|
if (valueType == null)
|
||||||
|
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
|
||||||
|
|
||||||
|
var value = ci.GetValue(null);
|
||||||
|
|
||||||
|
if (templateType == TemplateType.Enum)
|
||||||
|
value = Convert.ChangeType(value, ci.FieldType.GetEnumUnderlyingType());
|
||||||
|
|
||||||
|
var ct = new ConstantTemplate(this, i++, ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation);
|
||||||
|
|
||||||
|
|
||||||
|
constants.Add(ct);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
foreach (var pi in propsInfo)
|
foreach (var pi in propsInfo)
|
||||||
{
|
{
|
||||||
var privateAttr = pi.GetCustomAttribute<PrivateAttribute>(true);
|
var privateAttr = pi.GetCustomAttribute<PrivateAttribute>(true);
|
||||||
@ -326,7 +377,12 @@ public class TypeTemplate
|
|||||||
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
||||||
|
|
||||||
var pt = new PropertyTemplate(this, i++, pi.Name, TemplateDataType.FromType(pi.PropertyType));
|
var attrType = RepresentationType.FromType(pi.PropertyType);
|
||||||
|
|
||||||
|
if (attrType == null)
|
||||||
|
throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`");
|
||||||
|
|
||||||
|
var pt = new PropertyTemplate(this, i++, pi.Name, pi.DeclaringType != type, attrType);
|
||||||
|
|
||||||
if (storageAttr != null)
|
if (storageAttr != null)
|
||||||
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
||||||
@ -334,7 +390,7 @@ public class TypeTemplate
|
|||||||
if (annotationAttr != null)
|
if (annotationAttr != null)
|
||||||
pt.ReadExpansion = annotationAttr.Annotation;
|
pt.ReadExpansion = annotationAttr.Annotation;
|
||||||
else
|
else
|
||||||
pt.ReadExpansion = pi.PropertyType.Name;
|
pt.ReadExpansion = GetTypeAnnotationName(pi.PropertyType);
|
||||||
|
|
||||||
pt.PropertyInfo = pi;
|
pt.PropertyInfo = pi;
|
||||||
//pt.Serilize = publicAttr.Serialize;
|
//pt.Serilize = publicAttr.Serialize;
|
||||||
@ -346,7 +402,7 @@ public class TypeTemplate
|
|||||||
if (attributeAttr != null)
|
if (attributeAttr != null)
|
||||||
{
|
{
|
||||||
var an = attributeAttr.Name ?? pi.Name;
|
var an = attributeAttr.Name ?? pi.Name;
|
||||||
var at = new AttributeTemplate(this, 0, an);
|
var at = new AttributeTemplate(this, 0, an, pi.DeclaringType != type);
|
||||||
at.PropertyInfo = pi;
|
at.PropertyInfo = pi;
|
||||||
attributes.Add(at);
|
attributes.Add(at);
|
||||||
}
|
}
|
||||||
@ -356,69 +412,109 @@ public class TypeTemplate
|
|||||||
if (templateType == TemplateType.Resource)
|
if (templateType == TemplateType.Resource)
|
||||||
{
|
{
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
foreach (var ei in eventsInfo)
|
foreach (var ei in eventsInfo)
|
||||||
{
|
{
|
||||||
var privateAttr = ei.GetCustomAttribute<PrivateAttribute>(true);
|
var privateAttr = ei.GetCustomAttribute<PrivateAttribute>(true);
|
||||||
if (privateAttr == null)
|
if (privateAttr != null)
|
||||||
{
|
continue;
|
||||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
|
||||||
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
|
||||||
|
|
||||||
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
var et = new EventTemplate(this, i++, ei.Name, TemplateDataType.FromType(argType));
|
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||||
et.EventInfo = ei;
|
|
||||||
|
|
||||||
if (annotationAttr != null)
|
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
||||||
et.Expansion = annotationAttr.Annotation;
|
var evtType = RepresentationType.FromType(argType);
|
||||||
|
|
||||||
if (listenableAttr != null)
|
if (evtType == null)
|
||||||
et.Listenable = true;
|
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");
|
||||||
|
|
||||||
events.Add(et);
|
var et = new EventTemplate(this, i++, ei.Name, ei.DeclaringType != type, evtType);
|
||||||
}
|
et.EventInfo = ei;
|
||||||
|
|
||||||
|
if (annotationAttr != null)
|
||||||
|
et.Expansion = annotationAttr.Annotation;
|
||||||
|
|
||||||
|
if (listenableAttr != null)
|
||||||
|
et.Listenable = true;
|
||||||
|
|
||||||
|
events.Add(et);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
foreach (MethodInfo mi in methodsInfo)
|
foreach (MethodInfo mi in methodsInfo)
|
||||||
{
|
{
|
||||||
var privateAttr = mi.GetCustomAttribute<PrivateAttribute>(true);
|
var privateAttr = mi.GetCustomAttribute<PrivateAttribute>(true);
|
||||||
if (privateAttr == null)
|
if (privateAttr != null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
|
||||||
|
var returnType = RepresentationType.FromType(mi.ReturnType);
|
||||||
|
|
||||||
|
if (returnType == null)
|
||||||
|
throw new Exception($"Unsupported type {mi.ReturnType} in method {type.Name}.{mi.Name} return");
|
||||||
|
|
||||||
|
var args = mi.GetParameters();
|
||||||
|
|
||||||
|
if (args.Length > 0)
|
||||||
{
|
{
|
||||||
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
if (args.Last().ParameterType == typeof(DistributedConnection))
|
||||||
|
args = args.Take(args.Count() - 1).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
var returnType = TemplateDataType.FromType(mi.ReturnType);
|
var arguments = args.Select(x =>
|
||||||
|
{
|
||||||
|
var argType = RepresentationType.FromType(x.ParameterType);
|
||||||
|
if (argType == null)
|
||||||
|
throw new Exception($"Unsupported type `{x.ParameterType}` in method `{type.Name}.{mi.Name}` parameter `{x.Name}`");
|
||||||
|
|
||||||
var args = mi.GetParameters();
|
return new ArgumentTemplate()
|
||||||
|
|
||||||
if (args.Length > 0)
|
|
||||||
{
|
|
||||||
if (args.Last().ParameterType == typeof(DistributedConnection))
|
|
||||||
args = args.Take(args.Count() - 1).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
var arguments = args.Select(x => new ArgumentTemplate()
|
|
||||||
{
|
{
|
||||||
Name = x.Name,
|
Name = x.Name,
|
||||||
Type = TemplateDataType.FromType(x.ParameterType),
|
Type = argType,
|
||||||
ParameterInfo = x
|
ParameterInfo = x,
|
||||||
}).ToArray();
|
Optional = x.IsOptional
|
||||||
|
};
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
var ft = new FunctionTemplate(this, i++, mi.Name, arguments, returnType);// mi.ReturnType == typeof(void));
|
var ft = new FunctionTemplate(this, i++, mi.Name, mi.DeclaringType != type, arguments, returnType);// mi.ReturnType == typeof(void));
|
||||||
|
|
||||||
if (annotationAttr != null)
|
if (annotationAttr != null)
|
||||||
ft.Expansion = annotationAttr.Annotation;
|
ft.Expansion = annotationAttr.Annotation;
|
||||||
else
|
else
|
||||||
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
|
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
|
||||||
|
|
||||||
ft.MethodInfo = mi;
|
ft.MethodInfo = mi;
|
||||||
functions.Add(ft);
|
functions.Add(ft);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
foreach (var ci in constantsInfo)
|
||||||
|
{
|
||||||
|
var publicAttr = ci.GetCustomAttribute<PublicAttribute>(true);
|
||||||
|
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
|
||||||
|
if (publicAttr == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
var valueType = RepresentationType.FromType(ci.FieldType);
|
||||||
|
|
||||||
|
if (valueType == null)
|
||||||
|
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
|
||||||
|
|
||||||
|
var value = ci.GetValue(null);
|
||||||
|
|
||||||
|
var ct = new ConstantTemplate(this, i++, ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation);
|
||||||
|
|
||||||
|
|
||||||
|
constants.Add(ct);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
foreach (var pi in propsInfo)
|
foreach (var pi in propsInfo)
|
||||||
{
|
{
|
||||||
@ -428,17 +524,22 @@ public class TypeTemplate
|
|||||||
{
|
{
|
||||||
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
|
||||||
var valueType = TemplateDataType.FromType(pi.PropertyType);
|
var valueType = RepresentationType.FromType(pi.PropertyType);
|
||||||
|
|
||||||
|
if (valueType == null)
|
||||||
|
throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`");
|
||||||
|
|
||||||
|
|
||||||
var pn = publicAttr.Name ?? pi.Name;
|
var pn = publicAttr.Name ?? pi.Name;
|
||||||
|
|
||||||
var pt = new PropertyTemplate(this, i++, pn, valueType);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
|
var pt = new PropertyTemplate(this, i++, pn, pi.DeclaringType != type, valueType);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
|
||||||
if (storageAttr != null)
|
if (storageAttr != null)
|
||||||
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
|
||||||
|
|
||||||
if (annotationAttr != null)
|
if (annotationAttr != null)
|
||||||
pt.ReadExpansion = annotationAttr.Annotation;
|
pt.ReadExpansion = annotationAttr.Annotation;
|
||||||
else
|
else
|
||||||
pt.ReadExpansion = pi.PropertyType.Name;
|
pt.ReadExpansion = GetTypeAnnotationName(pi.PropertyType);
|
||||||
|
|
||||||
pt.PropertyInfo = pi;
|
pt.PropertyInfo = pi;
|
||||||
//pt.Serilize = publicAttr.Serialize;
|
//pt.Serilize = publicAttr.Serialize;
|
||||||
@ -450,7 +551,7 @@ public class TypeTemplate
|
|||||||
if (attributeAttr != null)
|
if (attributeAttr != null)
|
||||||
{
|
{
|
||||||
var pn = attributeAttr.Name ?? pi.Name;
|
var pn = attributeAttr.Name ?? pi.Name;
|
||||||
var at = new AttributeTemplate(this, 0, pn);
|
var at = new AttributeTemplate(this, 0, pn, pi.DeclaringType != type);
|
||||||
at.PropertyInfo = pi;
|
at.PropertyInfo = pi;
|
||||||
attributes.Add(at);
|
attributes.Add(at);
|
||||||
}
|
}
|
||||||
@ -464,65 +565,85 @@ public class TypeTemplate
|
|||||||
foreach (var ei in eventsInfo)
|
foreach (var ei in eventsInfo)
|
||||||
{
|
{
|
||||||
var publicAttr = ei.GetCustomAttribute<PublicAttribute>(true);
|
var publicAttr = ei.GetCustomAttribute<PublicAttribute>(true);
|
||||||
if (publicAttr != null)
|
|
||||||
{
|
|
||||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
|
||||||
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
|
||||||
|
|
||||||
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
if (publicAttr == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
var en = publicAttr.Name ?? ei.Name;
|
|
||||||
|
|
||||||
var et = new EventTemplate(this, i++, en, TemplateDataType.FromType(argType));
|
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
et.EventInfo = ei;
|
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||||
|
|
||||||
if (annotationAttr != null)
|
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
||||||
et.Expansion = annotationAttr.Annotation;
|
|
||||||
|
|
||||||
if (listenableAttr != null)
|
var en = publicAttr.Name ?? ei.Name;
|
||||||
et.Listenable = true;
|
|
||||||
|
|
||||||
events.Add(et);
|
var evtType = RepresentationType.FromType(argType);
|
||||||
}
|
|
||||||
|
if (evtType == null)
|
||||||
|
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");
|
||||||
|
|
||||||
|
var et = new EventTemplate(this, i++, en, ei.DeclaringType != type, evtType);
|
||||||
|
et.EventInfo = ei;
|
||||||
|
|
||||||
|
if (annotationAttr != null)
|
||||||
|
et.Expansion = annotationAttr.Annotation;
|
||||||
|
|
||||||
|
if (listenableAttr != null)
|
||||||
|
et.Listenable = true;
|
||||||
|
|
||||||
|
events.Add(et);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
foreach (MethodInfo mi in methodsInfo)
|
foreach (MethodInfo mi in methodsInfo)
|
||||||
{
|
{
|
||||||
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
|
||||||
if (publicAttr != null)
|
if (publicAttr == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
var returnType = RepresentationType.FromType(mi.ReturnType);
|
||||||
|
|
||||||
|
if (returnType == null)
|
||||||
|
throw new Exception($"Unsupported type `{mi.ReturnType}` in method `{type.Name}.{mi.Name}` return");
|
||||||
|
|
||||||
|
var args = mi.GetParameters();
|
||||||
|
|
||||||
|
if (args.Length > 0)
|
||||||
{
|
{
|
||||||
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
if (args.Last().ParameterType == typeof(DistributedConnection))
|
||||||
var returnType = TemplateDataType.FromType(mi.ReturnType);
|
args = args.Take(args.Count() - 1).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
var args = mi.GetParameters();
|
var arguments = args.Select(x =>
|
||||||
|
{
|
||||||
|
var argType = RepresentationType.FromType(x.ParameterType);
|
||||||
|
if (argType == null)
|
||||||
|
throw new Exception($"Unsupported type `{x.ParameterType}` in method `{type.Name}.{mi.Name}` parameter `{x.Name}`");
|
||||||
|
|
||||||
if (args.Length > 0)
|
return new ArgumentTemplate()
|
||||||
{
|
|
||||||
if (args.Last().ParameterType == typeof(DistributedConnection))
|
|
||||||
args = args.Take(args.Count() - 1).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
var arguments = args.Select(x => new ArgumentTemplate()
|
|
||||||
{
|
{
|
||||||
Name = x.Name,
|
Name = x.Name,
|
||||||
Type = TemplateDataType.FromType(x.ParameterType),
|
Type = argType,
|
||||||
ParameterInfo = x
|
ParameterInfo = x,
|
||||||
})
|
Optional = x.IsOptional
|
||||||
.ToArray();
|
};
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
var fn = publicAttr.Name ?? mi.Name;
|
var fn = publicAttr.Name ?? mi.Name;
|
||||||
|
|
||||||
var ft = new FunctionTemplate(this, i++, fn, arguments, returnType);// mi.ReturnType == typeof(void));
|
var ft = new FunctionTemplate(this, i++, fn, mi.DeclaringType != type, arguments, returnType);// mi.ReturnType == typeof(void));
|
||||||
|
|
||||||
if (annotationAttr != null)
|
if (annotationAttr != null)
|
||||||
ft.Expansion = annotationAttr.Annotation;
|
ft.Expansion = annotationAttr.Annotation;
|
||||||
else
|
else
|
||||||
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
|
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
|
||||||
|
|
||||||
|
ft.MethodInfo = mi;
|
||||||
|
functions.Add(ft);
|
||||||
|
|
||||||
ft.MethodInfo = mi;
|
|
||||||
functions.Add(ft);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,15 +658,41 @@ public class TypeTemplate
|
|||||||
for (i = 0; i < properties.Count; i++)
|
for (i = 0; i < properties.Count; i++)
|
||||||
members.Add(properties[i]);
|
members.Add(properties[i]);
|
||||||
|
|
||||||
|
// append constants
|
||||||
|
for (i = 0; i < constants.Count; i++)
|
||||||
|
members.Add(constants[i]);
|
||||||
|
|
||||||
// bake it binarily
|
// bake it binarily
|
||||||
var b = new BinaryList();
|
var b = new BinaryList();
|
||||||
b.AddUInt8((byte)templateType)
|
|
||||||
.AddGuid(classId)
|
|
||||||
.AddUInt8((byte)className.Length)
|
|
||||||
.AddString(className)
|
|
||||||
.AddInt32(version)
|
|
||||||
.AddUInt16((ushort)members.Count);
|
|
||||||
|
|
||||||
|
// find the first parent type that implements IResource
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (HasParent(type))
|
||||||
|
{
|
||||||
|
// find the first parent type that implements IResource
|
||||||
|
var ParentDefinedType = ResourceProxy.GetBaseType(type.BaseType);
|
||||||
|
var parentId = GetTypeGuid(ParentDefinedType.FullName);
|
||||||
|
|
||||||
|
b.AddUInt8((byte)(0x80 | (byte)templateType))
|
||||||
|
.AddGuid(classId)
|
||||||
|
.AddUInt8((byte)className.Length)
|
||||||
|
.AddString(className)
|
||||||
|
.AddGuid(parentId)
|
||||||
|
.AddInt32(version)
|
||||||
|
.AddUInt16((ushort)members.Count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b.AddUInt8((byte)templateType)
|
||||||
|
.AddGuid(classId)
|
||||||
|
.AddUInt8((byte)className.Length)
|
||||||
|
.AddString(className)
|
||||||
|
.AddInt32(version)
|
||||||
|
.AddUInt16((ushort)members.Count);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var ft in functions)
|
foreach (var ft in functions)
|
||||||
b.AddUInt8Array(ft.Compose());
|
b.AddUInt8Array(ft.Compose());
|
||||||
@ -553,11 +700,32 @@ public class TypeTemplate
|
|||||||
b.AddUInt8Array(pt.Compose());
|
b.AddUInt8Array(pt.Compose());
|
||||||
foreach (var et in events)
|
foreach (var et in events)
|
||||||
b.AddUInt8Array(et.Compose());
|
b.AddUInt8Array(et.Compose());
|
||||||
|
foreach (var ct in constants)
|
||||||
|
b.AddUInt8Array(ct.Compose());
|
||||||
|
|
||||||
content = b.ToArray();
|
content = b.ToArray();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool HasParent (Type type)
|
||||||
|
{
|
||||||
|
var parent = type.BaseType;
|
||||||
|
|
||||||
|
if (parent == typeof(Resource)
|
||||||
|
|| parent == typeof(Record))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (parent != null)
|
||||||
|
{
|
||||||
|
if (parent.GetInterfaces().Contains(typeof(IResource))
|
||||||
|
|| parent.GetInterfaces().Contains(typeof(IRecord)))
|
||||||
|
return true;
|
||||||
|
parent = parent.BaseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static TypeTemplate Parse(byte[] data)
|
public static TypeTemplate Parse(byte[] data)
|
||||||
{
|
{
|
||||||
return Parse(data, 0, (uint)data.Length);
|
return Parse(data, 0, (uint)data.Length);
|
||||||
@ -576,17 +744,27 @@ public class TypeTemplate
|
|||||||
var od = new TypeTemplate();
|
var od = new TypeTemplate();
|
||||||
od.content = data.Clip(offset, contentLength);
|
od.content = data.Clip(offset, contentLength);
|
||||||
|
|
||||||
od.templateType = (TemplateType)data[offset++];
|
var hasParent = (data[offset] & 0x80) > 0;
|
||||||
|
od.templateType = (TemplateType)(data[offset++] & 0xF);
|
||||||
|
|
||||||
od.classId = data.GetGuid(offset);
|
od.classId = data.GetGuid(offset);
|
||||||
offset += 16;
|
offset += 16;
|
||||||
od.className = data.GetString(offset + 1, data[offset]);
|
od.className = data.GetString(offset + 1, data[offset]);
|
||||||
offset += (uint)data[offset] + 1;
|
offset += (uint)data[offset] + 1;
|
||||||
|
|
||||||
od.version = data.GetInt32(offset);
|
if (od.className == "Test.MyChildRecord")
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
if (hasParent)
|
||||||
|
{
|
||||||
|
od.parentId = data.GetGuid(offset);
|
||||||
|
offset += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
od.version = data.GetInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
ushort methodsCount = data.GetUInt16(offset);
|
ushort methodsCount = data.GetUInt16(offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
byte functionIndex = 0;
|
byte functionIndex = 0;
|
||||||
@ -595,7 +773,8 @@ public class TypeTemplate
|
|||||||
|
|
||||||
for (int i = 0; i < methodsCount; i++)
|
for (int i = 0; i < methodsCount; i++)
|
||||||
{
|
{
|
||||||
var type = data[offset] >> 5;
|
var inherited = (data[offset] & 0x80) > 0;
|
||||||
|
var type = (data[offset] >> 5) & 0x3;
|
||||||
|
|
||||||
if (type == 0) // function
|
if (type == 0) // function
|
||||||
{
|
{
|
||||||
@ -606,7 +785,7 @@ public class TypeTemplate
|
|||||||
offset += (uint)data[offset] + 1;
|
offset += (uint)data[offset] + 1;
|
||||||
|
|
||||||
// return type
|
// return type
|
||||||
var (rts, returnType) = TemplateDataType.Parse(data, offset);
|
var (rts, returnType) = RepresentationType.Parse(data, offset);
|
||||||
offset += rts;
|
offset += rts;
|
||||||
|
|
||||||
// arguments count
|
// arguments count
|
||||||
@ -615,7 +794,7 @@ public class TypeTemplate
|
|||||||
|
|
||||||
for (var a = 0; a < argsCount; a++)
|
for (var a = 0; a < argsCount; a++)
|
||||||
{
|
{
|
||||||
var (cs, argType) = ArgumentTemplate.Parse(data, offset);
|
var (cs, argType) = ArgumentTemplate.Parse(data, offset, a);
|
||||||
arguments.Add(argType);
|
arguments.Add(argType);
|
||||||
offset += cs;
|
offset += cs;
|
||||||
}
|
}
|
||||||
@ -623,13 +802,13 @@ public class TypeTemplate
|
|||||||
// arguments
|
// arguments
|
||||||
if (hasExpansion) // expansion ?
|
if (hasExpansion) // expansion ?
|
||||||
{
|
{
|
||||||
var cs = data.GetUInt32(offset);
|
var cs = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
expansion = data.GetString(offset, cs);
|
expansion = data.GetString(offset, cs);
|
||||||
offset += cs;
|
offset += cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ft = new FunctionTemplate(od, functionIndex++, name, arguments.ToArray(), returnType, expansion);
|
var ft = new FunctionTemplate(od, functionIndex++, name, inherited, arguments.ToArray(), returnType, expansion);
|
||||||
|
|
||||||
od.functions.Add(ft);
|
od.functions.Add(ft);
|
||||||
}
|
}
|
||||||
@ -646,13 +825,13 @@ public class TypeTemplate
|
|||||||
|
|
||||||
offset += (uint)data[offset] + 1;
|
offset += (uint)data[offset] + 1;
|
||||||
|
|
||||||
var (dts, valueType) = TemplateDataType.Parse(data, offset);
|
var (dts, valueType) = RepresentationType.Parse(data, offset);
|
||||||
|
|
||||||
offset += dts;
|
offset += dts;
|
||||||
|
|
||||||
if (hasReadExpansion) // expansion ?
|
if (hasReadExpansion) // expansion ?
|
||||||
{
|
{
|
||||||
var cs = data.GetUInt32(offset);
|
var cs = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
readExpansion = data.GetString(offset, cs);
|
readExpansion = data.GetString(offset, cs);
|
||||||
offset += cs;
|
offset += cs;
|
||||||
@ -660,13 +839,13 @@ public class TypeTemplate
|
|||||||
|
|
||||||
if (hasWriteExpansion) // expansion ?
|
if (hasWriteExpansion) // expansion ?
|
||||||
{
|
{
|
||||||
var cs = data.GetUInt32(offset);
|
var cs = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
writeExpansion = data.GetString(offset, cs);
|
writeExpansion = data.GetString(offset, cs);
|
||||||
offset += cs;
|
offset += cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pt = new PropertyTemplate(od, propertyIndex++, name, valueType, readExpansion, writeExpansion, recordable);
|
var pt = new PropertyTemplate(od, propertyIndex++, name, inherited, valueType, readExpansion, writeExpansion, recordable);
|
||||||
|
|
||||||
od.properties.Add(pt);
|
od.properties.Add(pt);
|
||||||
}
|
}
|
||||||
@ -680,23 +859,52 @@ public class TypeTemplate
|
|||||||
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
|
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
|
||||||
offset += (uint)data[offset] + 1;
|
offset += (uint)data[offset] + 1;
|
||||||
|
|
||||||
var (dts, argType) = TemplateDataType.Parse(data, offset);
|
var (dts, argType) = RepresentationType.Parse(data, offset);
|
||||||
|
|
||||||
offset += dts;
|
offset += dts;
|
||||||
|
|
||||||
if (hasExpansion) // expansion ?
|
if (hasExpansion) // expansion ?
|
||||||
{
|
{
|
||||||
var cs = data.GetUInt32(offset);
|
var cs = data.GetUInt32(offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
expansion = data.GetString(offset, cs);
|
expansion = data.GetString(offset, cs);
|
||||||
offset += cs;
|
offset += cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
var et = new EventTemplate(od, eventIndex++, name, argType, expansion, listenable);
|
var et = new EventTemplate(od, eventIndex++, name, inherited, argType, expansion, listenable);
|
||||||
|
|
||||||
od.events.Add(et);
|
od.events.Add(et);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// constant
|
||||||
|
else if (type == 3)
|
||||||
|
{
|
||||||
|
string expansion = null;
|
||||||
|
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
|
||||||
|
|
||||||
|
var name = data.GetString(offset + 1, data[offset]);
|
||||||
|
offset += (uint)data[offset] + 1;
|
||||||
|
|
||||||
|
var (dts, valueType) = RepresentationType.Parse(data, offset);
|
||||||
|
|
||||||
|
offset += dts;
|
||||||
|
|
||||||
|
(dts, var value) = Codec.Parse(data, offset, null);
|
||||||
|
|
||||||
|
offset += dts;
|
||||||
|
|
||||||
|
if (hasExpansion) // expansion ?
|
||||||
|
{
|
||||||
|
var cs = data.GetUInt32(offset, Endian.Little);
|
||||||
|
offset += 4;
|
||||||
|
expansion = data.GetString(offset, cs);
|
||||||
|
offset += cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ct = new ConstantTemplate(od, eventIndex++, name, inherited, valueType, value.Result, expansion);
|
||||||
|
|
||||||
|
od.constants.Add(ct);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// append signals
|
// append signals
|
||||||
@ -708,22 +916,9 @@ public class TypeTemplate
|
|||||||
// append properties
|
// append properties
|
||||||
for (int i = 0; i < od.properties.Count; i++)
|
for (int i = 0; i < od.properties.Count; i++)
|
||||||
od.members.Add(od.properties[i]);
|
od.members.Add(od.properties[i]);
|
||||||
|
// append constants
|
||||||
|
for (int i = 0; i < od.constants.Count; i++)
|
||||||
//od.isReady = true;
|
od.members.Add(od.constants[i]);
|
||||||
/*
|
|
||||||
var oo = owner.Socket.Engine.GetObjectDescription(od.GUID);
|
|
||||||
if (oo != null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Already there ! description");
|
|
||||||
return oo;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
owner.Socket.Engine.AddObjectDescription(od);
|
|
||||||
return od;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return od;
|
return od;
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,6 @@ public static class Warehouse
|
|||||||
|
|
||||||
static uint resourceCounter = 0;
|
static uint resourceCounter = 0;
|
||||||
|
|
||||||
//static KeyList<Guid, TypeTemplate> templates = new KeyList<Guid, TypeTemplate>();
|
|
||||||
//static KeyList<Guid, TypeTemplate> wrapperTemplates = new KeyList<Guid, TypeTemplate>();
|
|
||||||
|
|
||||||
static KeyList<TemplateType, KeyList<Guid, TypeTemplate>> templates
|
static KeyList<TemplateType, KeyList<Guid, TypeTemplate>> templates
|
||||||
= new KeyList<TemplateType, KeyList<Guid, TypeTemplate>>()
|
= new KeyList<TemplateType, KeyList<Guid, TypeTemplate>>()
|
||||||
@ -63,6 +61,7 @@ public static class Warehouse
|
|||||||
[TemplateType.Resource] = new KeyList<Guid, TypeTemplate>(),
|
[TemplateType.Resource] = new KeyList<Guid, TypeTemplate>(),
|
||||||
[TemplateType.Record] = new KeyList<Guid, TypeTemplate>(),
|
[TemplateType.Record] = new KeyList<Guid, TypeTemplate>(),
|
||||||
[TemplateType.Wrapper] = new KeyList<Guid, TypeTemplate>(),
|
[TemplateType.Wrapper] = new KeyList<Guid, TypeTemplate>(),
|
||||||
|
[TemplateType.Enum] = new KeyList<Guid, TypeTemplate>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool warehouseIsOpen = false;
|
static bool warehouseIsOpen = false;
|
||||||
@ -141,6 +140,12 @@ public static class Warehouse
|
|||||||
{
|
{
|
||||||
PutTemplate(new TypeTemplate(t));
|
PutTemplate(new TypeTemplate(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var enumsTypes = (Type[])generatedType.GetProperty("Enums").GetValue(null);
|
||||||
|
foreach (var t in recordTypes)
|
||||||
|
{
|
||||||
|
PutTemplate(new TypeTemplate(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -590,7 +595,7 @@ public static class Warehouse
|
|||||||
resource.Instance = new Instance(resourceCounter++, instanceName, resource, store, customTemplate, age);
|
resource.Instance = new Instance(resourceCounter++, instanceName, resource, store, customTemplate, age);
|
||||||
|
|
||||||
if (attributes != null)
|
if (attributes != null)
|
||||||
resource.Instance.SetAttributes(Structure.FromObject(attributes));
|
resource.Instance.SetAttributes(Map<string,object>.FromObject(attributes));
|
||||||
|
|
||||||
if (manager != null)
|
if (manager != null)
|
||||||
resource.Instance.Managers.Add(manager);
|
resource.Instance.Managers.Add(manager);
|
||||||
@ -686,7 +691,7 @@ public static class Warehouse
|
|||||||
|
|
||||||
if (properties != null)
|
if (properties != null)
|
||||||
{
|
{
|
||||||
var ps = Structure.FromObject(properties);
|
var ps = Map<string,object>.FromObject(properties);
|
||||||
|
|
||||||
foreach (var p in ps)
|
foreach (var p in ps)
|
||||||
{
|
{
|
||||||
@ -768,6 +773,8 @@ public static class Warehouse
|
|||||||
templateType = TemplateType.Resource;
|
templateType = TemplateType.Resource;
|
||||||
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
|
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
|
||||||
templateType = TemplateType.Record;
|
templateType = TemplateType.Record;
|
||||||
|
else if (type.IsEnum)
|
||||||
|
templateType = TemplateType.Enum;
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -781,7 +788,10 @@ public static class Warehouse
|
|||||||
|
|
||||||
// loaded ?
|
// loaded ?
|
||||||
if (template == null)
|
if (template == null)
|
||||||
|
{
|
||||||
template = new TypeTemplate(baseType, true);
|
template = new TypeTemplate(baseType, true);
|
||||||
|
TypeTemplate.GetDependencies(template);
|
||||||
|
}
|
||||||
|
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
@ -805,6 +815,12 @@ public static class Warehouse
|
|||||||
if (template != null)
|
if (template != null)
|
||||||
return template;
|
return template;
|
||||||
|
|
||||||
|
// look in enums
|
||||||
|
template = templates[TemplateType.Enum][classId];
|
||||||
|
if (template != null)
|
||||||
|
return template;
|
||||||
|
|
||||||
|
|
||||||
// look in wrappers
|
// look in wrappers
|
||||||
template = templates[TemplateType.Wrapper][classId];
|
template = templates[TemplateType.Wrapper][classId];
|
||||||
return template;
|
return template;
|
||||||
|
@ -53,11 +53,11 @@ public class CACertificate : Certificate
|
|||||||
|
|
||||||
uint oOffset = offset;
|
uint oOffset = offset;
|
||||||
|
|
||||||
this.id = DC.GetUInt64(data, offset);
|
this.id = DC.GetUInt64(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
this.issueDate = DC.GetDateTime(data, offset);
|
this.issueDate = DC.GetDateTime(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
this.expireDate = DC.GetDateTime(data, offset);
|
this.expireDate = DC.GetDateTime(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
this.hashFunction = (HashFunctionType)(data[offset++] >> 4);
|
this.hashFunction = (HashFunctionType)(data[offset++] >> 4);
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ public class CACertificate : Certificate
|
|||||||
|
|
||||||
offset += exponentLength;
|
offset += exponentLength;
|
||||||
|
|
||||||
uint keySize = DC.GetUInt16(data, offset);
|
uint keySize = DC.GetUInt16(data, offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
key.Modulus = DC.Clip(data, offset, keySize);
|
key.Modulus = DC.Clip(data, offset, keySize);
|
||||||
|
@ -79,19 +79,19 @@ public class DomainCertificate : Certificate
|
|||||||
{
|
{
|
||||||
var oOffset = offset;
|
var oOffset = offset;
|
||||||
|
|
||||||
this.id = DC.GetUInt64(data, offset);
|
this.id = DC.GetUInt64(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
// load IPs
|
// load IPs
|
||||||
this.ip = DC.GetUInt32(data, offset);
|
this.ip = DC.GetUInt32(data, offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
this.ip6 = DC.Clip(data, offset, 16);
|
this.ip6 = DC.Clip(data, offset, 16);
|
||||||
|
|
||||||
offset += 16;
|
offset += 16;
|
||||||
|
|
||||||
this.issueDate = DC.GetDateTime(data, offset);
|
this.issueDate = DC.GetDateTime(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
this.expireDate = DC.GetDateTime(data, offset);
|
this.expireDate = DC.GetDateTime(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
this.domain = Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
|
this.domain = Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
|
||||||
@ -100,7 +100,7 @@ public class DomainCertificate : Certificate
|
|||||||
this.authorityName = (Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]));
|
this.authorityName = (Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]));
|
||||||
offset += (uint)data[offset] + 1;
|
offset += (uint)data[offset] + 1;
|
||||||
|
|
||||||
caId = DC.GetUInt64(data, offset);
|
caId = DC.GetUInt64(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
var aea = (AsymetricEncryptionAlgorithmType)(data[offset] >> 5);
|
var aea = (AsymetricEncryptionAlgorithmType)(data[offset] >> 5);
|
||||||
@ -113,7 +113,7 @@ public class DomainCertificate : Certificate
|
|||||||
key.Exponent = DC.Clip(data, offset, exponentLength);
|
key.Exponent = DC.Clip(data, offset, exponentLength);
|
||||||
offset += exponentLength;
|
offset += exponentLength;
|
||||||
|
|
||||||
uint keySize = DC.GetUInt16(data, offset);
|
uint keySize = DC.GetUInt16(data, offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
key.Modulus = DC.Clip(data, offset, keySize);
|
key.Modulus = DC.Clip(data, offset, keySize);
|
||||||
|
@ -79,21 +79,21 @@ public class UserCertificate : Certificate
|
|||||||
{
|
{
|
||||||
var oOffset = offset;
|
var oOffset = offset;
|
||||||
|
|
||||||
this.id = DC.GetUInt64(data, offset);
|
this.id = DC.GetUInt64(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
// load IPs
|
// load IPs
|
||||||
this.ip = DC.GetUInt32(data, offset);
|
this.ip = DC.GetUInt32(data, offset, Endian.Little);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
ip6 = DC.Clip(data, offset, 16);
|
ip6 = DC.Clip(data, offset, 16);
|
||||||
offset += 16;
|
offset += 16;
|
||||||
|
|
||||||
this.issueDate = DC.GetDateTime(data, offset);
|
this.issueDate = DC.GetDateTime(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
this.expireDate = DC.GetDateTime(data, offset);
|
this.expireDate = DC.GetDateTime(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
this.domainId = DC.GetUInt64(data, offset);
|
this.domainId = DC.GetUInt64(data, offset, Endian.Little);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
this.domain = Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
|
this.domain = Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
|
||||||
@ -119,7 +119,7 @@ public class UserCertificate : Certificate
|
|||||||
offset += exponentLength;
|
offset += exponentLength;
|
||||||
|
|
||||||
|
|
||||||
uint keySize = DC.GetUInt16(data, offset);
|
uint keySize = DC.GetUInt16(data, offset, Endian.Little);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
key.Modulus = DC.Clip(data, offset, keySize);
|
key.Modulus = DC.Clip(data, offset, keySize);
|
||||||
|
@ -76,7 +76,7 @@ public static class SHA256
|
|||||||
|
|
||||||
var w = new uint[64];
|
var w = new uint[64];
|
||||||
for (var i = 0; i < 16; i++)
|
for (var i = 0; i < 16; i++)
|
||||||
w[i] = data.GetUInt32((uint)(chunk + (i * 4)));
|
w[i] = data.GetUInt32((uint)(chunk + (i * 4)), Endian.Big);
|
||||||
|
|
||||||
//for(var i = 16; i < 64; i++)
|
//for(var i = 16; i < 64; i++)
|
||||||
// w[i] = 0;
|
// w[i] = 0;
|
||||||
|
@ -49,7 +49,7 @@ public interface IPermissionsManager
|
|||||||
/// <returns>Allowed or denined.</returns>
|
/// <returns>Allowed or denined.</returns>
|
||||||
Ruling Applicable(IResource resource, Session session, ActionType action, MemberTemplate member, object inquirer = null);
|
Ruling Applicable(IResource resource, Session session, ActionType action, MemberTemplate member, object inquirer = null);
|
||||||
|
|
||||||
bool Initialize(Structure settings, IResource resource);
|
bool Initialize(Map<string, object> settings, IResource resource);
|
||||||
|
|
||||||
Structure Settings { get; }
|
Map<string, object> Settings { get; }
|
||||||
}
|
}
|
||||||
|
@ -35,16 +35,16 @@ namespace Esiur.Security.Permissions;
|
|||||||
|
|
||||||
public class StorePermissionsManager : IPermissionsManager
|
public class StorePermissionsManager : IPermissionsManager
|
||||||
{
|
{
|
||||||
Structure settings;
|
Map<string, object> settings;
|
||||||
|
|
||||||
public Structure Settings => settings;
|
public Map<string,object> Settings => settings;
|
||||||
|
|
||||||
public Ruling Applicable(IResource resource, Session session, ActionType action, MemberTemplate member, object inquirer = null)
|
public Ruling Applicable(IResource resource, Session session, ActionType action, MemberTemplate member, object inquirer = null)
|
||||||
{
|
{
|
||||||
return resource.Instance.Store.Instance.Applicable(session, action, member, inquirer);
|
return resource.Instance.Store.Instance.Applicable(session, action, member, inquirer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Initialize(Structure settings, IResource resource)
|
public bool Initialize(Map<string,object> settings, IResource resource)
|
||||||
{
|
{
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
return true;
|
return true;
|
||||||
|
@ -36,18 +36,18 @@ namespace Esiur.Security.Permissions;
|
|||||||
public class UserPermissionsManager : IPermissionsManager
|
public class UserPermissionsManager : IPermissionsManager
|
||||||
{
|
{
|
||||||
IResource resource;
|
IResource resource;
|
||||||
Structure settings;
|
Map<string, object> settings;
|
||||||
|
|
||||||
public Structure Settings => settings;
|
public Map<string,object> Settings => settings;
|
||||||
|
|
||||||
public Ruling Applicable(IResource resource, Session session, ActionType action, MemberTemplate member, object inquirer)
|
public Ruling Applicable(IResource resource, Session session, ActionType action, MemberTemplate member, object inquirer)
|
||||||
{
|
{
|
||||||
Structure userPermissions = null;
|
Map<string,object> userPermissions = null;
|
||||||
|
|
||||||
if (settings.ContainsKey(session.RemoteAuthentication.FullName))
|
if (settings.ContainsKey(session.RemoteAuthentication.FullName))
|
||||||
userPermissions = settings[session.RemoteAuthentication.FullName] as Structure;
|
userPermissions = settings[session.RemoteAuthentication.FullName] as Map<string, object>;
|
||||||
else if (settings.ContainsKey("public"))
|
else if (settings.ContainsKey("public"))
|
||||||
userPermissions = settings["public"] as Structure;
|
userPermissions = settings["public"] as Map<string,object>;
|
||||||
else
|
else
|
||||||
return Ruling.Denied;
|
return Ruling.Denied;
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ public class UserPermissionsManager : IPermissionsManager
|
|||||||
}
|
}
|
||||||
else if (userPermissions.ContainsKey(member?.Name))
|
else if (userPermissions.ContainsKey(member?.Name))
|
||||||
{
|
{
|
||||||
Structure methodPermissions = userPermissions[member.Name] as Structure;
|
Map<string,object> methodPermissions = userPermissions[member.Name] as Map<string,object>;
|
||||||
if ((string)methodPermissions[action.ToString()] != "yes")
|
if ((string)methodPermissions[action.ToString()] != "yes")
|
||||||
return Ruling.Denied;
|
return Ruling.Denied;
|
||||||
}
|
}
|
||||||
@ -111,12 +111,12 @@ public class UserPermissionsManager : IPermissionsManager
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserPermissionsManager(Structure settings)
|
public UserPermissionsManager(Map<string, object> settings)
|
||||||
{
|
{
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Initialize(Structure settings, IResource resource)
|
public bool Initialize(Map<string, object> settings, IResource resource)
|
||||||
{
|
{
|
||||||
this.resource = resource;
|
this.resource = resource;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
@ -16,6 +16,7 @@ public class MemoryStore : IStore
|
|||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
|
|
||||||
KeyList<uint, IResource> resources = new KeyList<uint, IResource>();
|
KeyList<uint, IResource> resources = new KeyList<uint, IResource>();
|
||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
@ -69,7 +70,7 @@ public class MemoryStore : IStore
|
|||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
@ -85,7 +86,7 @@ public class MemoryStore : IStore
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ public class TemporaryStore : IStore
|
|||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ public class TemporaryStore : IStore
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
|
public bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
3
Esiur/TODO
Normal file
3
Esiur/TODO
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
1- Bin
|
||||||
|
2- clean
|
21
Test.Client/Program.cs
Normal file
21
Test.Client/Program.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using Esiur.Resource;
|
||||||
|
|
||||||
|
namespace Test.Client;
|
||||||
|
|
||||||
|
public class App
|
||||||
|
{
|
||||||
|
static async Task Main(string[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
var remote = await Warehouse.Get<MyService>("iip://localhost/mem/service");
|
||||||
|
var (i, s) = await remote.Tuple2(22, "ZZZZ");
|
||||||
|
remote.ArrayEvent += (x) => Console.WriteLine(x);
|
||||||
|
remote.StringEvent += (x)=>Console.WriteLine(x);
|
||||||
|
await remote.InvokeEvents("Client");
|
||||||
|
|
||||||
|
Console.WriteLine(remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
Test.Client/Test.Client.csproj
Normal file
14
Test.Client/Test.Client.csproj
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Esiur" Version="2.1.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
25
Test.Client/Test.Client.sln
Normal file
25
Test.Client/Test.Client.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31919.166
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test.Client", "Test.Client.csproj", "{EDDCB21B-5929-4218-912A-64B115CBF625}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{EDDCB21B-5929-4218-912A-64B115CBF625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{EDDCB21B-5929-4218-912A-64B115CBF625}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{EDDCB21B-5929-4218-912A-64B115CBF625}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{EDDCB21B-5929-4218-912A-64B115CBF625}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {E70DC657-E2B7-466C-BC0E-9ADC92F62831}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
8
Test.Client/localhost/Esiur.Generated.cs
Normal file
8
Test.Client/localhost/Esiur.Generated.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
namespace Esiur {
|
||||||
|
public static class Generated {
|
||||||
|
public static Type[] Resources {get;} = new Type[] { typeof(Test.MyService),typeof(Test.MyResource),typeof(Test.MyChildResource),typeof(Test.MyService) };
|
||||||
|
public static Type[] Records { get; } = new Type[] { typeof(Test.MyRecord) };
|
||||||
|
public static Type[] Enums { get; } = new Type[] { typeof(Test.SizeEnum) };
|
||||||
|
}
|
||||||
|
}
|
23
Test.Client/localhost/Test.MyChildResource.Generated.cs
Normal file
23
Test.Client/localhost/Test.MyChildResource.Generated.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using Esiur.Core;
|
||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
|
namespace Test {
|
||||||
|
public class MyChildResource : Test.MyResource {
|
||||||
|
public MyChildResource(DistributedConnection connection, uint instanceId, ulong age, string link) : base(connection, instanceId, age, link) {}
|
||||||
|
public MyChildResource() {}
|
||||||
|
public AsyncReply<int> ChildMethod(string childName) {
|
||||||
|
var rt = new AsyncReply<int>();
|
||||||
|
_InvokeByArrayArguments(0, new object[] { childName })
|
||||||
|
.Then(x => rt.Trigger((int)x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public string ChildName {
|
||||||
|
get => (string)properties[0];
|
||||||
|
set => _Set(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
16
Test.Client/localhost/Test.MyRecord.Generated.cs
Normal file
16
Test.Client/localhost/Test.MyRecord.Generated.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using Esiur.Core;
|
||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
|
namespace Test {
|
||||||
|
[Public] public class MyRecord : IRecord {
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public double Score { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
20
Test.Client/localhost/Test.MyResource.Generated.cs
Normal file
20
Test.Client/localhost/Test.MyResource.Generated.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using Esiur.Core;
|
||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
|
namespace Test {
|
||||||
|
public class MyResource : DistributedResource {
|
||||||
|
public MyResource(DistributedConnection connection, uint instanceId, ulong age, string link) : base(connection, instanceId, age, link) {}
|
||||||
|
public MyResource() {}
|
||||||
|
public string Description {
|
||||||
|
get => (string)properties[0];
|
||||||
|
set => _Set(0, value);
|
||||||
|
}
|
||||||
|
public int CategoryId {
|
||||||
|
get => (int)properties[1];
|
||||||
|
set => _Set(1, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
257
Test.Client/localhost/Test.MyService.Generated.cs
Normal file
257
Test.Client/localhost/Test.MyService.Generated.cs
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
using System;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using Esiur.Core;
|
||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
|
namespace Test {
|
||||||
|
public class MyService : DistributedResource {
|
||||||
|
public MyService(DistributedConnection connection, uint instanceId, ulong age, string link) : base(connection, instanceId, age, link) {}
|
||||||
|
public MyService() {}
|
||||||
|
public AsyncReply<object> Void() {
|
||||||
|
var rt = new AsyncReply<object>();
|
||||||
|
_InvokeByArrayArguments(0, new object[] { })
|
||||||
|
.Then(x => rt.Trigger((object)x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public AsyncReply<object> InvokeEvents(string msg) {
|
||||||
|
var rt = new AsyncReply<object>();
|
||||||
|
_InvokeByArrayArguments(1, new object[] { msg })
|
||||||
|
.Then(x => rt.Trigger((object)x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public AsyncReply<double> Optional(object a1,int a2,string a3) {
|
||||||
|
var rt = new AsyncReply<double>();
|
||||||
|
_InvokeByArrayArguments(2, new object[] { a1, a2, a3 })
|
||||||
|
.Then(x => rt.Trigger((double)x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public AsyncReply<object> Connection(object a1,int a2) {
|
||||||
|
var rt = new AsyncReply<object>();
|
||||||
|
_InvokeByArrayArguments(3, new object[] { a1, a2 })
|
||||||
|
.Then(x => rt.Trigger((object)x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public AsyncReply<object> ConnectionOptional(object a1,int a2,string a3) {
|
||||||
|
var rt = new AsyncReply<object>();
|
||||||
|
_InvokeByArrayArguments(4, new object[] { a1, a2, a3 })
|
||||||
|
.Then(x => rt.Trigger((object)x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public AsyncReply<(int,string)> Tuple2(int a1,string a2) {
|
||||||
|
var rt = new AsyncReply<(int,string)>();
|
||||||
|
_InvokeByArrayArguments(5, new object[] { a1, a2 })
|
||||||
|
.Then(x => rt.Trigger(((int,string))x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public AsyncReply<(int,string,double)> Tuple3(int a1,string a2,double a3) {
|
||||||
|
var rt = new AsyncReply<(int,string,double)>();
|
||||||
|
_InvokeByArrayArguments(6, new object[] { a1, a2, a3 })
|
||||||
|
.Then(x => rt.Trigger(((int,string,double))x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public AsyncReply<(int,string,double,bool)> Tuple4(int a1,string a2,double a3,bool a4) {
|
||||||
|
var rt = new AsyncReply<(int,string,double,bool)>();
|
||||||
|
_InvokeByArrayArguments(7, new object[] { a1, a2, a3, a4 })
|
||||||
|
.Then(x => rt.Trigger(((int,string,double,bool))x))
|
||||||
|
.Error(x => rt.TriggerError(x))
|
||||||
|
.Chunk(x => rt.TriggerChunk(x));
|
||||||
|
return rt; }
|
||||||
|
public int PropertyContext {
|
||||||
|
get => (int)properties[0];
|
||||||
|
set => _Set(0, value);
|
||||||
|
}
|
||||||
|
public Test.SizeEnum Enum {
|
||||||
|
get => (Test.SizeEnum)properties[1];
|
||||||
|
set => _Set(1, value);
|
||||||
|
}
|
||||||
|
public Test.MyRecord Record {
|
||||||
|
get => (Test.MyRecord)properties[2];
|
||||||
|
set => _Set(2, value);
|
||||||
|
}
|
||||||
|
public int[] IntList {
|
||||||
|
get => (int[])properties[3];
|
||||||
|
set => _Set(3, value);
|
||||||
|
}
|
||||||
|
public IRecord[] RecordsArray {
|
||||||
|
get => (IRecord[])properties[4];
|
||||||
|
set => _Set(4, value);
|
||||||
|
}
|
||||||
|
public Test.MyRecord[] RecordsList {
|
||||||
|
get => (Test.MyRecord[])properties[5];
|
||||||
|
set => _Set(5, value);
|
||||||
|
}
|
||||||
|
public Test.MyResource Resource {
|
||||||
|
get => (Test.MyResource)properties[6];
|
||||||
|
set => _Set(6, value);
|
||||||
|
}
|
||||||
|
public Test.MyChildResource Child {
|
||||||
|
get => (Test.MyChildResource)properties[7];
|
||||||
|
set => _Set(7, value);
|
||||||
|
}
|
||||||
|
public IResource[] Resources {
|
||||||
|
get => (IResource[])properties[8];
|
||||||
|
set => _Set(8, value);
|
||||||
|
}
|
||||||
|
public Test.MyService Me {
|
||||||
|
get => (Test.MyService)properties[9];
|
||||||
|
set => _Set(9, value);
|
||||||
|
}
|
||||||
|
public bool Boolean {
|
||||||
|
get => (bool)properties[10];
|
||||||
|
set => _Set(10, value);
|
||||||
|
}
|
||||||
|
public bool[] BooleanArray {
|
||||||
|
get => (bool[])properties[11];
|
||||||
|
set => _Set(11, value);
|
||||||
|
}
|
||||||
|
public byte UInt8 {
|
||||||
|
get => (byte)properties[12];
|
||||||
|
set => _Set(12, value);
|
||||||
|
}
|
||||||
|
public byte? UInt8Null {
|
||||||
|
get => (byte?)properties[13];
|
||||||
|
set => _Set(13, value);
|
||||||
|
}
|
||||||
|
public byte[] UInt8Array {
|
||||||
|
get => (byte[])properties[14];
|
||||||
|
set => _Set(14, value);
|
||||||
|
}
|
||||||
|
public byte?[] UInt8ArrayNull {
|
||||||
|
get => (byte?[])properties[15];
|
||||||
|
set => _Set(15, value);
|
||||||
|
}
|
||||||
|
public sbyte Int8 {
|
||||||
|
get => (sbyte)properties[16];
|
||||||
|
set => _Set(16, value);
|
||||||
|
}
|
||||||
|
public sbyte[] Int8Array {
|
||||||
|
get => (sbyte[])properties[17];
|
||||||
|
set => _Set(17, value);
|
||||||
|
}
|
||||||
|
public char Char16 {
|
||||||
|
get => (char)properties[18];
|
||||||
|
set => _Set(18, value);
|
||||||
|
}
|
||||||
|
public char[] Char16Array {
|
||||||
|
get => (char[])properties[19];
|
||||||
|
set => _Set(19, value);
|
||||||
|
}
|
||||||
|
public short Int16 {
|
||||||
|
get => (short)properties[20];
|
||||||
|
set => _Set(20, value);
|
||||||
|
}
|
||||||
|
public short[] Int16Array {
|
||||||
|
get => (short[])properties[21];
|
||||||
|
set => _Set(21, value);
|
||||||
|
}
|
||||||
|
public ushort UInt16 {
|
||||||
|
get => (ushort)properties[22];
|
||||||
|
set => _Set(22, value);
|
||||||
|
}
|
||||||
|
public ushort[] UInt16Array {
|
||||||
|
get => (ushort[])properties[23];
|
||||||
|
set => _Set(23, value);
|
||||||
|
}
|
||||||
|
public int Int32 {
|
||||||
|
get => (int)properties[24];
|
||||||
|
set => _Set(24, value);
|
||||||
|
}
|
||||||
|
public int[] Int32Array {
|
||||||
|
get => (int[])properties[25];
|
||||||
|
set => _Set(25, value);
|
||||||
|
}
|
||||||
|
public uint UInt32 {
|
||||||
|
get => (uint)properties[26];
|
||||||
|
set => _Set(26, value);
|
||||||
|
}
|
||||||
|
public uint[] UInt32Array {
|
||||||
|
get => (uint[])properties[27];
|
||||||
|
set => _Set(27, value);
|
||||||
|
}
|
||||||
|
public long Int64 {
|
||||||
|
get => (long)properties[28];
|
||||||
|
set => _Set(28, value);
|
||||||
|
}
|
||||||
|
public long[] Int64Array {
|
||||||
|
get => (long[])properties[29];
|
||||||
|
set => _Set(29, value);
|
||||||
|
}
|
||||||
|
public ulong UInt64 {
|
||||||
|
get => (ulong)properties[30];
|
||||||
|
set => _Set(30, value);
|
||||||
|
}
|
||||||
|
public ulong[] UInt64Array {
|
||||||
|
get => (ulong[])properties[31];
|
||||||
|
set => _Set(31, value);
|
||||||
|
}
|
||||||
|
public float Float32 {
|
||||||
|
get => (float)properties[32];
|
||||||
|
set => _Set(32, value);
|
||||||
|
}
|
||||||
|
public float[] Float32Array {
|
||||||
|
get => (float[])properties[33];
|
||||||
|
set => _Set(33, value);
|
||||||
|
}
|
||||||
|
public double Float64 {
|
||||||
|
get => (double)properties[34];
|
||||||
|
set => _Set(34, value);
|
||||||
|
}
|
||||||
|
public double[] Float64Array {
|
||||||
|
get => (double[])properties[35];
|
||||||
|
set => _Set(35, value);
|
||||||
|
}
|
||||||
|
public decimal Float128 {
|
||||||
|
get => (decimal)properties[36];
|
||||||
|
set => _Set(36, value);
|
||||||
|
}
|
||||||
|
public decimal[] Float128Array {
|
||||||
|
get => (decimal[])properties[37];
|
||||||
|
set => _Set(37, value);
|
||||||
|
}
|
||||||
|
public string String {
|
||||||
|
get => (string)properties[38];
|
||||||
|
set => _Set(38, value);
|
||||||
|
}
|
||||||
|
public string[] StringArray {
|
||||||
|
get => (string[])properties[39];
|
||||||
|
set => _Set(39, value);
|
||||||
|
}
|
||||||
|
public DateTime DateTime {
|
||||||
|
get => (DateTime)properties[40];
|
||||||
|
set => _Set(40, value);
|
||||||
|
}
|
||||||
|
public Map<string,object> StringMap {
|
||||||
|
get => (Map<string,object>)properties[41];
|
||||||
|
set => _Set(41, value);
|
||||||
|
}
|
||||||
|
public Map<int,string> IntStringMap {
|
||||||
|
get => (Map<int,string>)properties[42];
|
||||||
|
set => _Set(42, value);
|
||||||
|
}
|
||||||
|
public object Object {
|
||||||
|
get => (object)properties[43];
|
||||||
|
set => _Set(43, value);
|
||||||
|
}
|
||||||
|
public object[] ObjectArray {
|
||||||
|
get => (object[])properties[44];
|
||||||
|
set => _Set(44, value);
|
||||||
|
}
|
||||||
|
public const double PI = 3.14159265358979;
|
||||||
|
protected override void _EmitEventByIndex(byte index, object args) {
|
||||||
|
switch (index) {
|
||||||
|
case 0: StringEvent?.Invoke((string)args); break;
|
||||||
|
case 1: ArrayEvent?.Invoke((object[])args); break;
|
||||||
|
}}
|
||||||
|
public event ResourceEventHandler<string> StringEvent;
|
||||||
|
public event ResourceEventHandler<object[]> ArrayEvent;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
15
Test.Client/localhost/Test.SizeEnum.Generated.cs
Normal file
15
Test.Client/localhost/Test.SizeEnum.Generated.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using Esiur.Core;
|
||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Net.IIP;
|
||||||
|
namespace Test {
|
||||||
|
[Public] public enum SizeEnum {
|
||||||
|
xSmall=-11,
|
||||||
|
Small=-10,
|
||||||
|
Medium=0,
|
||||||
|
Large=1,
|
||||||
|
XLarge=22
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
15
Test/MyChildRecord.cs
Normal file
15
Test/MyChildRecord.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using Esiur.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
[Public]
|
||||||
|
public class MyChildRecord : MyRecord
|
||||||
|
{
|
||||||
|
public string ChildName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
16
Test/MyChildResource.cs
Normal file
16
Test/MyChildResource.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using Esiur.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
[Resource]
|
||||||
|
public partial class MyChildResource : MyResource
|
||||||
|
{
|
||||||
|
[Public] string childName;
|
||||||
|
[Public] public int ChildMethod(string childName) => 111;
|
||||||
|
}
|
||||||
|
}
|
@ -1,51 +0,0 @@
|
|||||||
using Esiur.Data;
|
|
||||||
using Esiur.Core;
|
|
||||||
using Esiur.Resource;
|
|
||||||
using Esiur.Security.Authority;
|
|
||||||
using Esiur.Security.Membership;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Test
|
|
||||||
{
|
|
||||||
public class MyMembership : IMembership
|
|
||||||
{
|
|
||||||
public Instance Instance { get; set; }
|
|
||||||
|
|
||||||
public event DestroyedEvent OnDestroy;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void Destroy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<byte[]> GetPassword(string username, string domain)
|
|
||||||
{
|
|
||||||
return new AsyncReply<byte[]>(DC.ToBytes("1234"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<bool> Login(Session session)
|
|
||||||
{
|
|
||||||
return new AsyncReply<bool>(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<bool> Logout(Session session)
|
|
||||||
{
|
|
||||||
return new AsyncReply<bool>(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
|
|
||||||
{
|
|
||||||
return new AsyncReply<bool>(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public AsyncReply<bool> UserExists(string username, string domain)
|
|
||||||
{
|
|
||||||
return new AsyncReply<bool>(username == "demo");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user