mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-07 20:12:57 +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
|
||||||
|
@ -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)
|
||||||
|
{
|
||||||
|
if (ArrayType != null)
|
||||||
|
{
|
||||||
|
var ar = Array.CreateInstance(ArrayType, 0);
|
||||||
|
Trigger(ar);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Trigger(new object[0]);
|
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,17 +96,25 @@ 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)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// @TODO: Safe casting check
|
||||||
var ar = Array.CreateInstance(ArrayType, count);
|
var ar = Array.CreateInstance(ArrayType, count);
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
ar.SetValue(results[i], i);
|
ar.SetValue(results[i], i);
|
||||||
Trigger(ar);
|
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,19 +156,6 @@ public class BinaryList
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryList AddCharArray(char[] value)
|
|
||||||
{
|
|
||||||
list.AddRange(DC.ToBytes(value));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BinaryList InsertCharArray(int position, char[] value)
|
|
||||||
{
|
|
||||||
list.InsertRange(position, DC.ToBytes(value));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public BinaryList AddBoolean(bool value)
|
public BinaryList AddBoolean(bool value)
|
||||||
{
|
{
|
||||||
list.AddRange(DC.ToBytes(value));
|
list.AddRange(DC.ToBytes(value));
|
||||||
@ -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,9 +243,18 @@ 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];
|
||||||
|
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((int*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
byte* p = (byte*)&value;
|
byte* p = (byte*)&value;
|
||||||
|
|
||||||
rt[0] = *(p + 3);
|
rt[0] = *(p + 3);
|
||||||
@ -374,31 +262,49 @@ public static class DC // Data Converter
|
|||||||
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 short value)
|
|
||||||
|
|
||||||
|
public static unsafe byte[] ToBytes(this short value, Endian endian)
|
||||||
{
|
{
|
||||||
var rt = new byte[2];
|
var rt = new byte[2];
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((short*)ptr) = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
byte* p = (byte*)&value;
|
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;
|
{
|
||||||
|
fixed (byte* ptr = rt)
|
||||||
|
*((float*)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);
|
rt[3] = *(p);
|
||||||
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
@ -406,15 +312,27 @@ 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[0] = *(p + 7);
|
||||||
@ -425,14 +343,21 @@ public static class DC // Data Converter
|
|||||||
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 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[0] = *(p + 7);
|
||||||
@ -443,36 +368,31 @@ public static class DC // Data Converter
|
|||||||
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 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;
|
||||||
|
|
||||||
@ -484,14 +404,21 @@ public static class DC // Data Converter
|
|||||||
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;
|
||||||
|
|
||||||
@ -499,29 +426,39 @@ public static class DC // Data Converter
|
|||||||
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[0] = *(p + 1);
|
||||||
rt[1] = *(p);
|
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,92 +564,85 @@ 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;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public static Int16 GetInt16(this byte[] data, uint offset)
|
|
||||||
{
|
{
|
||||||
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)
|
|
||||||
|
|
||||||
|
public static unsafe ushort GetUInt16(this byte[] data, uint offset, Endian endian)
|
||||||
|
{
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return *(ushort*)ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return (UInt16)((data[offset] << 8) | data[offset + 1]);
|
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)
|
public static unsafe int GetInt32(this byte[] data, uint offset, Endian endian)
|
||||||
|
{
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return *(int*)ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return (Int32)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]);
|
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)
|
public static unsafe uint GetUInt32(this byte[] data, uint offset, Endian endian)
|
||||||
{
|
{
|
||||||
return (UInt32)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]);
|
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return *(uint*)ptr;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public static UInt32[] GetUInt32Array(this byte[] data, uint offset, uint length)
|
|
||||||
{
|
{
|
||||||
var j = 0; var end = offset + length;
|
return (uint)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]);
|
||||||
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 ulong GetUInt64(this byte[] data, uint offset, Endian endian)
|
||||||
|
{
|
||||||
|
if (endian == Endian.Little)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = &data[offset])
|
||||||
|
return *(ulong*)ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
UInt64 rt = 0;
|
UInt64 rt = 0;
|
||||||
byte* p = (byte*)&rt;
|
byte* p = (byte*)&rt;
|
||||||
@ -739,21 +657,18 @@ public static class DC // Data Converter
|
|||||||
*(p) = data[offset++];
|
*(p) = data[offset++];
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64[] GetInt64Array(this byte[] data, uint offset, uint length)
|
|
||||||
|
public static unsafe long GetInt64(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 *(long*)ptr;
|
||||||
rt[j++] = GetInt64(data, i);
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public static unsafe Int64 GetInt64(this byte[] data, uint offset)
|
|
||||||
{
|
{
|
||||||
Int64 rt = 0;
|
Int64 rt = 0;
|
||||||
byte* p = (byte*)&rt;
|
byte* p = (byte*)&rt;
|
||||||
@ -769,32 +684,17 @@ public static class DC // Data Converter
|
|||||||
|
|
||||||
return rt;
|
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 float GetFloat32(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])
|
||||||
for (var i = offset; i < end; i += 8)
|
return *(float*)ptr;
|
||||||
rt[j++] = GetUInt64(data, i);
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public static unsafe float GetFloat32(this byte[] data, uint offset)
|
|
||||||
{
|
{
|
||||||
float rt = 0;
|
float rt = 0;
|
||||||
byte* p = (byte*)&rt;
|
byte* p = (byte*)&rt;
|
||||||
@ -803,20 +703,19 @@ public static class DC // Data Converter
|
|||||||
*(p + 2) = data[offset + 1];
|
*(p + 2) = data[offset + 1];
|
||||||
*(p + 3) = data[offset];
|
*(p + 3) = data[offset];
|
||||||
return rt;
|
return rt;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float[] GetFloat32Array(this byte[] data, uint offset, uint length)
|
|
||||||
|
public static unsafe double GetFloat64(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])
|
||||||
for (var i = offset; i < end; i += 4)
|
return *(double*)ptr;
|
||||||
rt[j++] = GetFloat32(data, i);
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public static unsafe double GetFloat64(this byte[] data, uint offset)
|
|
||||||
{
|
{
|
||||||
double rt = 0;
|
double rt = 0;
|
||||||
byte* p = (byte*)&rt;
|
byte* p = (byte*)&rt;
|
||||||
@ -832,47 +731,19 @@ public static class DC // Data Converter
|
|||||||
|
|
||||||
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
|
||||||
|
}
|
||||||
|
}
|
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)
|
||||||
{
|
{
|
||||||
@ -686,7 +767,18 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (Server.Membership == null)
|
||||||
|
{
|
||||||
|
SendParams()
|
||||||
|
.AddUInt8(0xc0)
|
||||||
|
.AddUInt8((byte)ExceptionCode.UserOrTokenNotFound)
|
||||||
|
.AddUInt16(15)
|
||||||
|
.AddString("Token not found")
|
||||||
|
.Done();
|
||||||
|
}
|
||||||
// Check if user and token exists
|
// Check if user and token exists
|
||||||
|
else
|
||||||
|
{
|
||||||
Server.Membership.TokenExists(authPacket.RemoteTokenIndex, authPacket.Domain).Then(x =>
|
Server.Membership.TokenExists(authPacket.RemoteTokenIndex, authPacket.Domain).Then(x =>
|
||||||
{
|
{
|
||||||
if (x != null)
|
if (x != null)
|
||||||
@ -712,6 +804,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var errMsg = DC.ToBytes(ex.Message);
|
var errMsg = DC.ToBytes(ex.Message);
|
||||||
@ -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;
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (NotEnough(offset, ends, (uint)size))
|
|
||||||
return -dataLengthNeeded;
|
|
||||||
|
|
||||||
Content = data.Clip(offset - 1, (uint)size + 1);
|
|
||||||
offset += (uint)size;
|
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))
|
|
||||||
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;
|
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 += 4;
|
|
||||||
|
|
||||||
if (NotEnough(offset, ends, cl))
|
|
||||||
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;
|
offset += (uint)size;
|
||||||
}
|
|
||||||
|
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
|
||||||
}
|
}
|
||||||
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))
|
|
||||||
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;
|
offset += (uint)size;
|
||||||
}
|
|
||||||
|
//Content = data.Clip(DataType.Value.Offset, (uint)DataType.Value.ContentLength);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,8 +29,9 @@ 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();
|
||||||
|
|
||||||
|
foreach(var url in urls)
|
||||||
if (!Imports.Contains(url))
|
if (!Imports.Contains(url))
|
||||||
Imports.Add(url);
|
Imports.Add(url);
|
||||||
}
|
}
|
||||||
@ -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('.');
|
||||||
|
|
||||||
|
var nameSpace = string.Join(".", cls.Take(cls.Length - 1));
|
||||||
|
var className = cls.Last();
|
||||||
|
|
||||||
|
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
|
||||||
{
|
{
|
||||||
|
|
||||||
if (templateDataType.Type == DataType.Resource)
|
name = representationType.Identifier switch
|
||||||
return templates.First(x => x.ClassId == templateDataType.TypeGuid && (x.Type == TemplateType.Resource || x.Type == TemplateType.Wrapper)).ClassName;
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
DataType.Bool => "bool",
|
RepresentationTypeIdentifier.Dynamic => "object",
|
||||||
DataType.BoolArray => "bool[]",
|
RepresentationTypeIdentifier.Bool => "bool",
|
||||||
DataType.Char => "char",
|
RepresentationTypeIdentifier.Char => "char",
|
||||||
DataType.CharArray => "char[]",
|
RepresentationTypeIdentifier.DateTime => "DateTime",
|
||||||
DataType.DateTime => "DateTime",
|
RepresentationTypeIdentifier.Decimal => "decimal",
|
||||||
DataType.DateTimeArray => "DateTime[]",
|
RepresentationTypeIdentifier.Float32 => "float",
|
||||||
DataType.Decimal => "decimal",
|
RepresentationTypeIdentifier.Float64 => "double",
|
||||||
DataType.DecimalArray => "decimal[]",
|
RepresentationTypeIdentifier.Int16 => "short",
|
||||||
DataType.Float32 => "float",
|
RepresentationTypeIdentifier.Int32 => "int",
|
||||||
DataType.Float32Array => "float[]",
|
RepresentationTypeIdentifier.Int64 => "long",
|
||||||
DataType.Float64 => "double",
|
RepresentationTypeIdentifier.Int8 => "sbyte",
|
||||||
DataType.Float64Array => "double[]",
|
RepresentationTypeIdentifier.String => "string",
|
||||||
DataType.Int16 => "short",
|
RepresentationTypeIdentifier.Map => "Map<object, object>",
|
||||||
DataType.Int16Array => "short[]",
|
RepresentationTypeIdentifier.UInt16 => "ushort",
|
||||||
DataType.Int32 => "int",
|
RepresentationTypeIdentifier.UInt32 => "uint",
|
||||||
DataType.Int32Array => "int[]",
|
RepresentationTypeIdentifier.UInt64 => "ulong",
|
||||||
DataType.Int64 => "long",
|
RepresentationTypeIdentifier.UInt8 => "byte",
|
||||||
DataType.Int64Array => "long[]",
|
RepresentationTypeIdentifier.List => "object[]",
|
||||||
DataType.Int8 => "sbyte",
|
RepresentationTypeIdentifier.Resource => "IResource",
|
||||||
DataType.Int8Array => "sbyte[]",
|
RepresentationTypeIdentifier.Record => "IRecord",
|
||||||
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"
|
_ => "object"
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return name;
|
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} {{");
|
||||||
|
|
||||||
|
// extends
|
||||||
|
if (template.ParentId == null)
|
||||||
rt.AppendLine($"public class {className} : DistributedResource {{");
|
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,11 +133,13 @@ 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;
|
||||||
|
if (read != null)
|
||||||
this.ReadExpansion = read;
|
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) =>
|
||||||
@ -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);
|
||||||
#endif
|
FieldInfo[] constantsInfo = type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||||
|
|
||||||
|
|
||||||
|
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,17 +412,22 @@ 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 annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||||
|
|
||||||
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
var argType = ei.EventHandlerType.GenericTypeArguments[0];
|
||||||
var et = new EventTemplate(this, i++, ei.Name, TemplateDataType.FromType(argType));
|
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++, ei.Name, ei.DeclaringType != type, evtType);
|
||||||
et.EventInfo = ei;
|
et.EventInfo = ei;
|
||||||
|
|
||||||
if (annotationAttr != null)
|
if (annotationAttr != null)
|
||||||
@ -377,17 +438,20 @@ public class TypeTemplate
|
|||||||
|
|
||||||
events.Add(et);
|
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 annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
|
|
||||||
var returnType = TemplateDataType.FromType(mi.ReturnType);
|
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();
|
var args = mi.GetParameters();
|
||||||
|
|
||||||
@ -397,14 +461,22 @@ public class TypeTemplate
|
|||||||
args = args.Take(args.Count() - 1).ToArray();
|
args = args.Take(args.Count() - 1).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
var arguments = args.Select(x => new ArgumentTemplate()
|
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}`");
|
||||||
|
|
||||||
|
return 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 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;
|
||||||
@ -414,11 +486,35 @@ public class TypeTemplate
|
|||||||
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,8 +565,11 @@ 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)
|
|
||||||
{
|
if (publicAttr == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
|
||||||
|
|
||||||
@ -473,7 +577,12 @@ public class TypeTemplate
|
|||||||
|
|
||||||
var en = publicAttr.Name ?? ei.Name;
|
var en = publicAttr.Name ?? ei.Name;
|
||||||
|
|
||||||
var et = new EventTemplate(this, i++, en, TemplateDataType.FromType(argType));
|
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;
|
et.EventInfo = ei;
|
||||||
|
|
||||||
if (annotationAttr != null)
|
if (annotationAttr != null)
|
||||||
@ -484,16 +593,20 @@ public class TypeTemplate
|
|||||||
|
|
||||||
events.Add(et);
|
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 annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
|
||||||
var returnType = TemplateDataType.FromType(mi.ReturnType);
|
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();
|
var args = mi.GetParameters();
|
||||||
|
|
||||||
@ -503,17 +616,25 @@ public class TypeTemplate
|
|||||||
args = args.Take(args.Count() - 1).ToArray();
|
args = args.Take(args.Count() - 1).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
var arguments = args.Select(x => new ArgumentTemplate()
|
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}`");
|
||||||
|
|
||||||
|
return 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;
|
||||||
@ -522,7 +643,7 @@ public class TypeTemplate
|
|||||||
|
|
||||||
ft.MethodInfo = mi;
|
ft.MethodInfo = mi;
|
||||||
functions.Add(ft);
|
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();
|
||||||
|
|
||||||
|
// 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)
|
b.AddUInt8((byte)templateType)
|
||||||
.AddGuid(classId)
|
.AddGuid(classId)
|
||||||
.AddUInt8((byte)className.Length)
|
.AddUInt8((byte)className.Length)
|
||||||
.AddString(className)
|
.AddString(className)
|
||||||
.AddInt32(version)
|
.AddInt32(version)
|
||||||
.AddUInt16((ushort)members.Count);
|
.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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
156
Test/MyObject.cs
156
Test/MyObject.cs
@ -1,156 +0,0 @@
|
|||||||
using Esiur.Data;
|
|
||||||
using Esiur.Core;
|
|
||||||
using Esiur.Net.IIP;
|
|
||||||
using Esiur.Resource;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Test
|
|
||||||
{
|
|
||||||
public class MyObject : EntryPoint
|
|
||||||
{
|
|
||||||
|
|
||||||
[ResourceEvent]
|
|
||||||
public event ResourceEventHanlder LevelUp;
|
|
||||||
[ResourceEvent]
|
|
||||||
public event ResourceEventHanlder LevelDown;
|
|
||||||
|
|
||||||
public MyObject()
|
|
||||||
{
|
|
||||||
Info = new Structure();
|
|
||||||
Info["size"] = 200;
|
|
||||||
Info["age"] = 28;
|
|
||||||
Info["name"] = "Esiur";
|
|
||||||
Name = "Esiur Project";
|
|
||||||
Level = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[ResourceFunction]
|
|
||||||
public int Add(int? value)
|
|
||||||
{
|
|
||||||
Level += (int)value;
|
|
||||||
LevelUp?.Invoke(null, "going up", value);
|
|
||||||
return Level;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ResourceFunction("Divide takes two arguments nominator and denominator")]
|
|
||||||
public double Divide(float n, float d, DistributedConnection sender)
|
|
||||||
{
|
|
||||||
return n / d;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ResourceFunction]
|
|
||||||
public int Subtract(int value)
|
|
||||||
{
|
|
||||||
Level -= value;
|
|
||||||
LevelDown?.Invoke(null, "going down", value);
|
|
||||||
return Level;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ResourceFunction("use it with next()")]
|
|
||||||
public IEnumerable<string> Enum(int count)
|
|
||||||
{
|
|
||||||
var msg = new string[] { "Have you throught what if a function has multiple returns ?", "So you can return chunks of IO operation that not yet finished.", "Also, what about the progress ?", "This is an example of both.", "Use it anyway you like" };
|
|
||||||
|
|
||||||
for (var i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
Thread.Sleep(2000);
|
|
||||||
yield return msg[(int)(i % msg.Length)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ResourceFunction("Stream returns progress")]
|
|
||||||
public AsyncReply<string> Stream(int count)
|
|
||||||
{
|
|
||||||
var reply = new AsyncReply<string>();
|
|
||||||
var msg = new object[] { "Have you throught what if a function has multiple returns ?", "So you can return chunks of IO operation that not yet finished.", "Also, what about the progress ?", "This is an example of both.", "Use it anyway you like" };
|
|
||||||
Timer timer = null;
|
|
||||||
var msgCounter = 0;
|
|
||||||
|
|
||||||
timer = new Timer((x) =>
|
|
||||||
{
|
|
||||||
|
|
||||||
reply.TriggerProgress(ProgressType.Execution, count, 22);
|
|
||||||
|
|
||||||
if (count % 2 == 0 && msgCounter < msg.Length)
|
|
||||||
reply.TriggerChunk(msg[msgCounter++]);
|
|
||||||
|
|
||||||
count--;
|
|
||||||
if (count <= 0)
|
|
||||||
{
|
|
||||||
timer.Dispose();
|
|
||||||
reply.Trigger("Done");
|
|
||||||
}
|
|
||||||
|
|
||||||
}, null, 10, 3000);
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override AsyncReply<IResource[]> Query(string path, DistributedConnection sender)
|
|
||||||
{
|
|
||||||
return new AsyncReply<IResource[]>(new IResource[] { this });
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Create()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ResourceProperty]
|
|
||||||
public Structure Info
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ResourceProperty]
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ResourceProperty]
|
|
||||||
public MyObject Me
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
int level;
|
|
||||||
[ResourceProperty]
|
|
||||||
public int Level
|
|
||||||
{
|
|
||||||
get { return level; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
level = value;
|
|
||||||
Instance?.Modified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
[ResourceProperty]
|
|
||||||
public virtual int Level
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ResourceProperty]
|
|
||||||
public int Level3
|
|
||||||
{
|
|
||||||
get => 0;
|
|
||||||
set => Instance?.Modified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
20
Test/MyRecord.cs
Normal file
20
Test/MyRecord.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using Esiur.Data;
|
||||||
|
using Esiur.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
[Public]
|
||||||
|
public class MyRecord:IRecord
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public double Score { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
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