2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-26 13:03:13 +00:00

Updated to support IIP v3.3

This commit is contained in:
2019-05-24 05:38:53 +03:00
parent d215e48761
commit 08e95bd4dc
106 changed files with 6643 additions and 1179 deletions

View File

@ -7,6 +7,10 @@ using MongoDB.Bson;
using Esiur.Data;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Esiur.Resource.Template;
using System.Linq;
using Esiur.Security.Permissions;
namespace Esiur.Stores.MongoDB
{
@ -17,6 +21,7 @@ namespace Esiur.Stores.MongoDB
public event DestroyedEvent OnDestroy;
MongoClient client;
IMongoDatabase database;
IMongoCollection<BsonDocument> resourcesCollection;
Dictionary<string, IResource> resources = new Dictionary<string, IResource>();
@ -25,28 +30,70 @@ namespace Esiur.Stores.MongoDB
{
get { return resources.Count; }
}
public void Destroy()
{
}
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime date)
{
var objectId = resource.Instance.Attributes["objectId"].ToString();
//var bsonObjectId = new BsonObjectId(new ObjectId(objectId));
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
record.InsertOne(new BsonDocument()
{
{"property", propertyName}, {"age", BsonValue.Create(age) }, {"date", date}, {"value", Compose(value) }
});
var col = this.database.GetCollection<BsonDocument>("resources");
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(objectId)));
var update = Builders<BsonDocument>.Update
.Set("values." + propertyName, new BsonDocument { { "age", BsonValue.Create(age) },
{ "modification", date },
{ "value", Compose(value) } });
col.UpdateOne(filter, update);
return true;
}
public MongoDBStore()
{
client = new MongoClient();
this.database = client.GetDatabase("esiur");
this.resourcesCollection = this.database.GetCollection<BsonDocument>("resources");
}
public MongoDBStore(string connectionString, string database)
{
client = new MongoClient(connectionString);
this.database = client.GetDatabase(database);
this.resourcesCollection = this.database.GetCollection<BsonDocument>("resources");
}
public bool Remove(IResource resource)
{
var objectId = resource.Instance.Attributes["objectId"].ToString();
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(objectId)));
this.database.DropCollection("record_" + objectId);
resourcesCollection.DeleteOne(filter);
return true;
}
AsyncReply<IResource> Fetch(string id)
{
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(id)));
var list = this.database.GetCollection<BsonDocument>("resources").Find(filter).ToList();
var list = resourcesCollection.Find(filter).ToList();
if (list.Count == 0)
return new AsyncReply<IResource>(null);
var document = list[0];
@ -60,6 +107,11 @@ namespace Esiur.Stores.MongoDB
var parents = document["parents"].AsBsonArray;
var children = document["children"].AsBsonArray;
//var managers = document["managers"].AsBsonArray;
var attributes = Parse(document["attributes"]).Then(x=> {
resource.Instance.SetAttributes(x as Structure);
});
var bag = new AsyncBag<object>();
@ -69,6 +121,7 @@ namespace Esiur.Stores.MongoDB
bag.Add(ap);
ap.Then((x) =>
{
if (!resource.Instance.Parents.Contains(x))
resource.Instance.Parents.Add(x);
});
}
@ -80,28 +133,41 @@ namespace Esiur.Stores.MongoDB
bag.Add(ac);
ac.Then((x) =>
{
if (!resource.Instance.Children.Contains(x))
resource.Instance.Children.Add(x);
});
}
/*
// load managers
foreach(var m in managers)
{
IPermissionsManager pm = (IPermissionsManager)Activator.CreateInstance(Type.GetType(m["classname"].AsString));
var sr = Parse(m["settings"]);
bag.Add(sr);
sr.Then((x) =>
{
pm.Initialize((Structure)x, resource);
resource.Instance.Managers.Add(pm);
});
}
*/
// Load values
var values = document["values"].AsBsonDocument;
foreach (var v in values)
{
#if NETSTANDARD1_5
var pi = resource.GetType().GetTypeInfo().GetProperty(v.Name);
#else
var pi = resource.GetType().GetProperty(pt.Name);
#endif
var av = Parse(v.Value);
var valueInfo = v.Value as BsonDocument;
var av = Parse(valueInfo["value"]);
bag.Add(av);
av.Then((x) =>
{
if (pi.CanWrite)
pi.SetValue(resource, DC.CastConvert(x, pi.PropertyType));
resource.Instance.LoadProperty(v.Name, (ulong)valueInfo["age"].AsInt64, valueInfo["modification"].ToUniversalTime(), x);
});
}
@ -163,8 +229,13 @@ namespace Esiur.Stores.MongoDB
return bag;
}
else if (value.BsonType == BsonType.DateTime)
{
return new AsyncReply(value.ToUniversalTime());
}
else
{
return new AsyncReply(value.RawValue);
}
}
@ -194,6 +265,8 @@ namespace Esiur.Stores.MongoDB
public bool Put(IResource resource)
{
var attrs = resource.Instance.GetAttributes();
foreach (var kv in resources)
if (kv.Value == resource)
{
@ -203,6 +276,7 @@ namespace Esiur.Stores.MongoDB
var parents = new BsonArray();
var children = new BsonArray();
var template = resource.Instance.Template;
foreach (IResource c in resource.Instance.Children)
@ -211,20 +285,11 @@ namespace Esiur.Stores.MongoDB
foreach (IResource p in resource.Instance.Parents)
parents.Add(p.Instance.Link);
var document = new BsonDocument
{
{ "parents", parents },
{ "children", children },
{ "classname", resource.GetType().AssemblyQualifiedName },
{ "name", resource.Instance.Name }
};
var attrsDoc = ComposeStructure(attrs);
var col = this.database.GetCollection<BsonDocument>("resources");
col.InsertOne(document);
resource.Instance.Attributes["objectId"] = document["_id"].ToString();
var values = new BsonDocument();
@ -237,18 +302,33 @@ namespace Esiur.Stores.MongoDB
#endif
var rt = pi.GetValue(resource, null);
values.Add(pt.Name, Compose(rt));
values.Add(pt.Name,
new BsonDocument { { "age", BsonValue.Create(resource.Instance.GetAge(pt.Index)) },
{ "modification", resource.Instance.GetModificationDate(pt.Index) },
{ "value", Compose(rt) } });
}
var filter = Builders<BsonDocument>.Filter.Eq("_id", document["_id"]);
var update = Builders<BsonDocument>.Update
.Set("values", values);
// var filter = Builders<BsonDocument>.Filter.Eq("_id", document["_id"]);
// var update = Builders<BsonDocument>.Update
// .Set("values", values);
// col.UpdateOne(filter, update);
col.UpdateOne(filter, update);
//document.Add("values", values);
var document = new BsonDocument
{
{ "parents", parents },
{ "children", children },
{ "attributes", attrsDoc },
{ "classname", resource.GetType().FullName + "," + resource.GetType().GetTypeInfo().Assembly.GetName().Name },
{ "name", resource.Instance.Name },
{ "values", values }
};
resourcesCollection.InsertOne(document);
resource.Instance.Attributes["objectId"] = document["_id"].ToString();
//col.ReplaceOne(document, document);
return true;
}
@ -356,17 +436,19 @@ namespace Esiur.Stores.MongoDB
{
var filter = new BsonDocument();
var list = this.database.GetCollection<BsonDocument>("resources").Find(filter).ToList();
var list = resourcesCollection.Find(filter).ToList();
Console.WriteLine(list.Count);
// if (list.Count == 0)
// return new AsyncBag<IResource>(new IResource[0]);
var bag = new AsyncBag<IResource>();
foreach (var r in list)
for(var i = 0; i < list.Count; i++)
{
bag.Add(Get("id/" + r["_id"].AsObjectId.ToString()));
Console.WriteLine("Loading {0}/{1}", i, list.Count);
bag.Add(Get("id/" + list[i]["_id"].AsObjectId.ToString()));
}
bag.Seal();
@ -392,6 +474,8 @@ namespace Esiur.Stores.MongoDB
public void SaveResource(IResource resource)
{
var attrs = resource.Instance.GetAttributes();
var parents = new BsonArray();
var children = new BsonArray();
var template = resource.Instance.Template;
@ -402,6 +486,7 @@ namespace Esiur.Stores.MongoDB
foreach (IResource p in resource.Instance.Parents)
parents.Add(p.Instance.Link);
var values = new BsonDocument();
foreach (var pt in template.Properties)
@ -413,28 +498,182 @@ namespace Esiur.Stores.MongoDB
#endif
var rt = pi.GetValue(resource, null);
values.Add(pt.Name, Compose(rt));
values.Add(pt.Name,
new BsonDocument { { "age", BsonValue.Create(resource.Instance.GetAge(pt.Index)) },
{ "modification", resource.Instance.GetModificationDate(pt.Index) },
{ "value", Compose(rt) } });
}
var attrsDoc = ComposeStructure(attrs);
var document = new BsonDocument
{
{ "parents", parents },
{ "children", children },
{ "classname", resource.GetType().AssemblyQualifiedName },
{"attributes", attrsDoc },
{ "classname", resource.GetType().FullName + "," + resource.GetType().GetTypeInfo().Assembly.GetName().Name },
{ "name", resource.Instance.Name },
{ "_id", new BsonObjectId(new ObjectId(resource.Instance.Attributes["objectId"].ToString())) },
{"values", values }
};
var col = this.database.GetCollection<BsonDocument>("resources");
var filter = Builders<BsonDocument>.Filter.Eq("_id", document["_id"]);
/*
var update = Builders<BsonDocument>.Update
.Set("values", values);
var update = Builders<BsonDocument>.Update.Set("values", values).Set("parents", parents;
col.UpdateOne(filter, update);
*/
resourcesCollection.ReplaceOne(filter, document);
}
public AsyncReply<PropertyValue[]> GetPropertyRecordByAge(IResource resource, string propertyName, ulong fromAge, ulong toAge)
{
var objectId = resource.Instance.Attributes["objectId"].ToString();
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Gte("age", fromAge) & builder.Lte("age", toAge) & builder.Eq("property", propertyName);
var reply = new AsyncReply<PropertyValue[]>();
record.FindAsync(filter).ContinueWith((x) =>
{
var values = ((Task<IAsyncCursor<BsonDocument>>)x).Result.ToList();
var bag = new AsyncBag<object>();
foreach(var v in values)
bag.Add(Parse(v["value"]));
bag.Seal();
bag.Then((results) =>
{
var list = new List<PropertyValue>();
for(var i = 0; i < results.Length; i++)
list.Add(new PropertyValue(results[i], (ulong)values[i]["age"].AsInt64, values[i]["date"].ToUniversalTime()));
reply.Trigger(list.ToArray());
});
});
return reply;
}
public AsyncReply<PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate)
{
var objectId = resource.Instance.Attributes["objectId"].ToString();
var record = this.database.GetCollection<BsonDocument>("record_" + objectId);
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Gte("date", fromDate) & builder.Lte("date", toDate) & builder.Eq("property", propertyName);
var reply = new AsyncReply<PropertyValue[]>();
record.FindAsync(filter).ContinueWith((x) =>
{
var values = ((Task<IAsyncCursor<BsonDocument>>)x).Result.ToList();
var bag = new AsyncBag<object>();
foreach (var v in values)
bag.Add(Parse(v["value"]));
bag.Seal();
bag.Then((results) =>
{
var list = new List<PropertyValue>();
for (var i = 0; i < results.Length; i++)
list.Add(new PropertyValue(results[i], (ulong)values[i]["age"].AsInt64, values[i]["date"].ToUniversalTime()));
reply.Trigger(list.ToArray());
});
});
return reply;
}
AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecordByAge(IResource resource, ulong fromAge, ulong toAge)
{
var properties = resource.Instance.Template.Properties.Where(x => x.Storage == StorageMode.Recordable).ToList();
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
AsyncBag<PropertyValue> bag = new AsyncBag<PropertyValue>();
foreach (var p in properties)
bag.Add(GetPropertyRecordByAge(resource, p.Name, fromAge, toAge));
bag.Seal();
bag.Then(x =>
{
var list = new KeyList<PropertyTemplate, PropertyValue>();
for (var i = 0; i < x.Length; i++)
list.Add(properties[i], x[i]);
reply.Trigger(list);
});
return reply;
}
public AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, DateTime fromDate, DateTime toDate)
{
var properties = resource.Instance.Template.Properties.Where(x => x.Storage == StorageMode.Recordable).ToList();
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
AsyncBag<PropertyValue[]> bag = new AsyncBag<PropertyValue[]>();
foreach (var p in properties)
bag.Add(GetPropertyRecordByDate(resource, p.Name, fromDate, toDate));
bag.Seal();
bag.Then(x =>
{
var list = new KeyList<PropertyTemplate, PropertyValue[]>();
for (var i = 0; i < x.Length; i++)
list.Add(properties[i], x[i]);
reply.Trigger(list);
});
return reply;
}
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
{
var objectId = resource.Instance.Attributes["objectId"].ToString();
var filter = Builders<BsonDocument>.Filter.Eq("_id", new BsonObjectId(new ObjectId(objectId)));
var update = Builders<BsonDocument>.Update
.Set("values." + propertyName, new BsonDocument { { "age", BsonValue.Create(age) },
{ "modification", dateTime },
{ "value", Compose(value) } });
resourcesCollection.UpdateOne(filter, update);
return true;
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,7 +32,7 @@ using System.Reflection;
namespace Esiur.Data
{
public class AutoList<T, ST> : IEnumerable
public class AutoList<T, ST> : IEnumerable<T>
{
private readonly object syncRoot = new object();
@ -45,6 +69,10 @@ namespace Esiur.Data
list.Sort(comparer);
}
public void Sort(Comparison<T> comparison)
{
list.Sort(comparison);
}
public IEnumerable<T> Where(Func<T, bool> predicate)
{
@ -80,9 +108,9 @@ namespace Esiur.Data
/// </summary>
/// <param name="values">Populate the list with items</param>
/// <returns></returns>
public AutoList(T[] values)
public AutoList(ST state, T[] values)
{
this.state = state;
#if NETSTANDARD1_5
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
#else
@ -168,11 +196,6 @@ namespace Esiur.Data
Remove((T)sender);
}
public IEnumerator GetEnumerator()
{
return list.GetEnumerator();
}
/// <summary>
/// Clear the list
/// </summary>
@ -249,5 +272,15 @@ namespace Esiur.Data
return true;
return false;
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)list).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<T>)list).GetEnumerator();
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Misc;
@ -9,6 +33,7 @@ using Esiur.Net.IIP;
using Esiur.Resource;
using System.Linq;
using System.Reflection;
using Esiur.Resource.Template;
namespace Esiur.Data
{
@ -98,13 +123,13 @@ namespace Esiur.Data
public static byte[] ComposeStructureArray(Structure[] structures, DistributedConnection connection, bool prependLength = false)
{
if (structures == null || structures?.Length == 0)
return new byte[0];
return prependLength ? new byte[] { 0, 0, 0, 0 } : new byte[0];
var rt = new BinaryList();
var comparsion = StructureComparisonResult.Structure;
rt.Append((byte)comparsion);
rt.Append(ComposeStructure(structures[0], connection));
rt.Append(ComposeStructure(structures[0], connection, true, true, true));
for (var i = 1; i < structures.Length; i++)
{
@ -112,11 +137,11 @@ namespace Esiur.Data
rt.Append((byte)comparsion);
if (comparsion == StructureComparisonResult.Structure)
rt.Append(ComposeStructure(structures[i], connection));
rt.Append(ComposeStructure(structures[i], connection, true, true, true));
else if (comparsion == StructureComparisonResult.StructureSameKeys)
rt.Append(ComposeStructure(structures[i], connection, false));
rt.Append(ComposeStructure(structures[i], connection, false, true, true));
else if (comparsion == StructureComparisonResult.StructureSameTypes)
rt.Append(ComposeStructure(structures[i], connection, false, false));
rt.Append(ComposeStructure(structures[i], connection, false, false, true));
}
if (prependLength)
@ -147,9 +172,10 @@ namespace Esiur.Data
var result = (StructureComparisonResult)data[offset++];
AsyncReply previous = null;
string[] previousKeys = null;
DataType[] previousTypes = null;
// string[] previousKeys = null;
// DataType[] previousTypes = null;
Structure.StructureMetadata metadata = new Structure.StructureMetadata();
if (result == StructureComparisonResult.Null)
@ -157,8 +183,8 @@ namespace Esiur.Data
else if (result == StructureComparisonResult.Structure)
{
uint cs = data.GetUInt32(offset);
cs += 4;
previous = ParseStructure(data, offset, cs, connection, out previousKeys, out previousTypes);
offset += 4;
previous = ParseStructure(data, offset, cs, connection, out metadata);
offset += cs;
}
@ -174,22 +200,22 @@ namespace Esiur.Data
else if (result == StructureComparisonResult.Structure)
{
uint cs = data.GetUInt32(offset);
cs += 4;
previous = ParseStructure(data, offset, cs, connection, out previousKeys, out previousTypes);
offset += 4;
previous = ParseStructure(data, offset, cs, connection, out metadata);// out previousKeys, out previousTypes);
offset += cs;
}
else if (result == StructureComparisonResult.StructureSameKeys)
{
uint cs = data.GetUInt32(offset);
cs += 4;
previous = ParseStructure(data, offset, cs, connection, out previousKeys, out previousTypes, previousKeys);
offset += 4;
previous = ParseStructure(data, offset, cs, connection, out metadata, metadata.Keys);
offset += cs;
}
else if (result == StructureComparisonResult.StructureSameTypes)
{
uint cs = data.GetUInt32(offset);
cs += 4;
previous = ParseStructure(data, offset, cs, connection, out previousKeys, out previousTypes, previousKeys, previousTypes);
offset += 4;
previous = ParseStructure(data, offset, cs, connection, out metadata, metadata.Keys, metadata.Types);
offset += cs;
}
@ -243,9 +269,8 @@ namespace Esiur.Data
/// <returns>Value</returns>
public static AsyncReply<Structure> ParseStructure(byte[] data, uint offset, uint contentLength, DistributedConnection connection)
{
string[] pk;
DataType[] pt;
return ParseStructure(data, offset, contentLength, connection, out pk, out pt);
Structure.StructureMetadata metadata;
return ParseStructure(data, offset, contentLength, connection, out metadata);
}
/// <summary>
@ -260,7 +285,7 @@ namespace Esiur.Data
/// <param name="keys">Array of keys, in case the data doesn't include keys</param>
/// <param name="types">Array of DataTypes, in case the data doesn't include DataTypes</param>
/// <returns>Structure</returns>
public static AsyncReply<Structure> ParseStructure(byte[] data, uint offset, uint length, DistributedConnection connection, out string[] parsedKeys, out DataType[] parsedTypes, string[] keys = null, DataType[] types = null)
public static AsyncReply<Structure> ParseStructure(byte[] data, uint offset, uint length, DistributedConnection connection, out Structure.StructureMetadata metadata, string[] keys = null, DataType[] types = null)// out string[] parsedKeys, out DataType[] parsedTypes, string[] keys = null, DataType[] types = null)
{
var reply = new AsyncReply<Structure>();
var bag = new AsyncBag<object>();
@ -293,8 +318,8 @@ namespace Esiur.Data
uint rt;
bag.Add(Codec.Parse(data, offset, out rt, connection));
length -= rt + 1;
offset += rt + 1;
length -= rt;
offset += rt;
}
}
else
@ -324,8 +349,8 @@ namespace Esiur.Data
reply.Trigger(s);
});
parsedKeys = keylist.ToArray();
parsedTypes = typelist.ToArray();
metadata = new Structure.StructureMetadata() { Keys = keylist.ToArray(), Types = typelist.ToArray() };
return reply;
}
@ -544,7 +569,6 @@ namespace Esiur.Data
{
Null,
Distributed,
DistributedSameClass,
Local,
Same
}
@ -585,21 +609,12 @@ namespace Esiur.Data
{
if (next == null)
return ResourceComparisonResult.Null;
if (next == initial)
else if (next == initial)
return ResourceComparisonResult.Same;
if (IsLocalResource(next, connection))
else if (IsLocalResource(next, connection))
return ResourceComparisonResult.Local;
if (initial == null)
else
return ResourceComparisonResult.Distributed;
if (initial.Instance.Template.ClassId == next.Instance.Template.ClassId)
return ResourceComparisonResult.DistributedSameClass;
return ResourceComparisonResult.Distributed;
}
/// <summary>
@ -629,7 +644,7 @@ namespace Esiur.Data
public static byte[] ComposeResourceArray(IResource[] resources, DistributedConnection connection, bool prependLength = false)
{
if (resources == null || resources?.Length == 0)
return new byte[0];
return prependLength ? new byte[] { 0, 0, 0, 0 } : new byte[0];
var rt = new BinaryList();
var comparsion = Compare(null, resources[0], connection);
@ -639,26 +654,16 @@ namespace Esiur.Data
if (comparsion == ResourceComparisonResult.Local)
rt.Append((resources[0] as DistributedResource).Id);
else if (comparsion == ResourceComparisonResult.Distributed)
{
rt.Append(resources[0].Instance.Template.ClassId);
rt.Append(resources[0].Instance.Id);
}
for (var i = 1; i < resources.Length; i++)
{
comparsion = Compare(resources[i - 1], resources[i], connection);
rt.Append((byte)comparsion);
if (comparsion == ResourceComparisonResult.Local)
rt.Append((resources[0] as DistributedResource).Id);
rt.Append((resources[i] as DistributedResource).Id);
else if (comparsion == ResourceComparisonResult.Distributed)
{
rt.Append(resources[0].Instance.Template.ClassId);
rt.Append(resources[0].Instance.Id);
}
else if (comparsion == ResourceComparisonResult.DistributedSameClass)
{
rt.Append(resources[0].Instance.Id);
}
rt.Append(resources[i].Instance.Id);
}
if (prependLength)
@ -690,7 +695,6 @@ namespace Esiur.Data
var result = (ResourceComparisonResult)data[offset++];
AsyncReply previous = null;
Guid previousGuid = Guid.Empty;
if (result == ResourceComparisonResult.Null)
previous = new AsyncReply<IResource>(null);
@ -701,9 +705,7 @@ namespace Esiur.Data
}
else if (result == ResourceComparisonResult.Distributed)
{
previousGuid = data.GetGuid(offset);
offset += 16;
//previous = connection.Fetch(previousGuid, data.GetUInt32(offset));
previous = connection.Fetch(data.GetUInt32(offset));
offset += 4;
}
@ -714,32 +716,30 @@ namespace Esiur.Data
{
result = (ResourceComparisonResult)data[offset++];
AsyncReply current = null;
if (result == ResourceComparisonResult.Null)
previous = new AsyncReply<IResource>(null);
//else if (result == ResourceComparisonResult.Same)
// reply.Add(previous);
{
current = new AsyncReply<IResource>(null);
}
else if (result == ResourceComparisonResult.Same)
{
current = previous;
}
else if (result == ResourceComparisonResult.Local)
{
// overwrite previous
previous = Warehouse.Get(data.GetUInt32(offset));
current = Warehouse.Get(data.GetUInt32(offset));
offset += 4;
}
else if (result == ResourceComparisonResult.Distributed)
{
// overwrite previous
previousGuid = data.GetGuid(offset);
offset += 16;
//previous = connection.Fetch(previousGuid, data.GetUInt32(offset));
offset += 4;
}
else if (result == ResourceComparisonResult.DistributedSameClass)
{
// overwrite previous
//previous = connection.Fetch(previousGuid, data.GetUInt32(offset));
current = connection.Fetch(data.GetUInt32(offset));
offset += 4;
}
reply.Add(previous);
reply.Add(current);
previous = current;
}
reply.Seal();
@ -763,7 +763,12 @@ namespace Esiur.Data
rt.InsertRange(0, DC.ToBytes(rt.Count));
return rt.ToArray();
}
/// <summary>
/// Parse an array of variables.
/// </summary>
/// <param name="data">Array of bytes.</param>
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
/// <returns>Array of variables.</returns>
public static AsyncBag<object> ParseVarArray(byte[] data, DistributedConnection connection)
{
return ParseVarArray(data, 0, (uint)data.Length, connection);
@ -801,6 +806,180 @@ namespace Esiur.Data
return rt;
}
/// <summary>
/// Compose an array of property values.
/// </summary>
/// <param name="array">PropertyValue array.</param>
/// <param name="connection">DistributedConnection is required to check locality.</param>
/// <param name="prependLength">If True, prepend the length as UInt32 at the beginning of the output.</param>
/// <returns>Array of bytes in the network byte order.</returns>
/// //, bool includeAge = true
public static byte[] ComposePropertyValueArray(PropertyValue[] array, DistributedConnection connection, bool prependLength = false)
{
var rt = new List<byte>();
for (var i = 0; i < array.Length; i++)
rt.AddRange(ComposePropertyValue(array[i], connection));
if (prependLength)
rt.InsertRange(0, DC.ToBytes(rt.Count));
return rt.ToArray();
}
/// <summary>
/// Compose a property value.
/// </summary>
/// <param name="propertyValue">Property value</param>
/// <param name="connection">DistributedConnection is required to check locality.</param>
/// <returns>Array of bytes in the network byte order.</returns>
public static byte[] ComposePropertyValue(PropertyValue propertyValue, DistributedConnection connection)//, bool includeAge = true)
{
// age, date, value
//if (includeAge)
return BinaryList.ToBytes(propertyValue.Age, propertyValue.Date, Compose(propertyValue.Value, connection));
//else
// return BinaryList.ToBytes(propertyValue.Date, Compose(propertyValue.Value, connection));
}
/// <summary>
/// Parse property value.
/// </summary>
/// <param name="data">Array of bytes.</param>
/// <param name="offset">Zero-indexed offset.</param>
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
/// <param name="cs">Output content size.</param>
/// <returns>PropertyValue.</returns>
public static AsyncReply<PropertyValue> ParsePropertyValue(byte[] data, uint offset, out uint cs, DistributedConnection connection)//, bool ageIncluded = true)
{
var reply = new AsyncReply<PropertyValue>();
var age = data.GetUInt64(offset);
offset += 8;
DateTime date = data.GetDateTime(offset);
offset += 8;
uint valueSize;
Parse(data, offset, out valueSize, connection).Then(value =>
{
reply.Trigger(new PropertyValue(value, age, date));
});
cs = 16 + valueSize;
return reply;
}
/// <summary>
/// Parse an array of PropertyValue.
/// </summary>
/// <param name="data">Array of bytes.</param>
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
/// <returns>Array of variables.</returns>
public static AsyncBag<PropertyValue> ParsePropertyValueArray(byte[] data, DistributedConnection connection)
{
return ParsePropertyValueArray(data, 0, (uint)data.Length, connection);
}
/// <summary>
/// Parse resource history
/// </summary>
/// <param name="data">Array of bytes.</param>
/// <param name="offset">Zero-indexed offset.</param>
/// <param name="length">Number of bytes to parse.</param>
/// <param name="resource">Resource</param>
/// <param name="fromAge">Starting age.</param>
/// <param name="toAge">Ending age.</param>
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
/// <returns></returns>
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> ParseHistory(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.GetPropertyTemplate(index);
list.Add(pt, null);
var cs = DC.GetUInt32(data, offset);
offset += 4;
bagOfBags.Add(ParsePropertyValueArray(data, offset, cs, connection));
offset += cs;
}
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;
}
/// <summary>
/// Compose resource history
/// </summary>
/// <param name="history">History</param>
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
/// <returns></returns>
public static byte[] ComposeHistory(KeyList<PropertyTemplate, PropertyValue[]> history, DistributedConnection connection, bool prependLength = false)
{
var rt = new BinaryList();
for (var i = 0; i < history.Count; i++)
rt.Append((byte)history.Keys.ElementAt(i).Index,
ComposePropertyValueArray(history.Values.ElementAt(i), connection, true));
if (prependLength)
rt.Insert(0, (uint)rt.Length);
return rt.ToArray();
}
/// <summary>
/// Parse an array of PropertyValue.
/// </summary>
/// <param name="data">Array of bytes.</param>
/// <param name="offset">Zero-indexed offset.</param>
/// <param name="length">Number of bytes to parse.</param>
/// <param name="connection">DistributedConnection is required to fetch resources.</param>
/// <param name="ageIncluded">Whether property age is represented in the data.</param>
/// <returns></returns>
public static AsyncBag<PropertyValue> ParsePropertyValueArray(byte[] data, uint offset, uint length, DistributedConnection connection)//, bool ageIncluded = true)
{
var rt = new AsyncBag<PropertyValue>();
while (length > 0)
{
uint cs;
rt.Add(ParsePropertyValue(data, offset, out cs, connection));//, ageIncluded));
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing ValueInfo structured data");
}
rt.Seal();
return rt;
}
/// <summary>
/// Compose a variable
/// </summary>
@ -811,6 +990,11 @@ namespace Esiur.Data
public static byte[] Compose(object value, DistributedConnection connection, bool prependType = true)
{
if (value is Func<DistributedConnection, object>)
value = (value as Func<DistributedConnection, object>)(connection);
else if (value is DistributedPropertyContext)
value = (value as DistributedPropertyContext).Method(connection);
var type = GetDataType(value, connection);
var rt = new BinaryList();
@ -873,11 +1057,15 @@ namespace Esiur.Data
/// <param name="type">Sub-class type.</param>
/// <param name="iface">Super-interface type.</param>
/// <returns>True, if <paramref name="type"/> implements <paramref name="iface"/>.</returns>
private static bool ImplementsInterface(Type type, Type iface)
public static bool ImplementsInterface(Type type, Type iface)
{
while (type != null)
{
if (type == iface)
return true;
#if NETSTANDARD1_5
if (type.GetTypeInfo().GetInterfaces().Contains(iface))
return true;
@ -977,7 +1165,7 @@ namespace Esiur.Data
}
}
else
return DataType.Void;
type = DataType.Void;
if (isArray)

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -225,14 +249,14 @@ namespace Esiur.Data
UInt64 rt = 0;
byte* p = (byte*)&rt;
*(p + 7) = data[0];
*(p + 6) = data[1];
*(p + 5) = data[2];
*(p + 4) = data[3];
*(p + 3) = data[4];
*(p + 2) = data[5];
*(p + 1) = data[6];
*(p) = data[7];
*(p + 7) = data[offset++];
*(p + 6) = data[offset++];
*(p + 5) = data[offset++];
*(p + 4) = data[offset++];
*(p + 3) = data[offset++];
*(p + 2) = data[offset++];
*(p + 1) = data[offset++];
*(p) = data[offset++];
return rt;
@ -252,14 +276,14 @@ namespace Esiur.Data
Int64 rt = 0;
byte* p = (byte*)&rt;
*(p + 7) = data[0];
*(p + 6) = data[1];
*(p + 5) = data[2];
*(p + 4) = data[3];
*(p + 3) = data[4];
*(p + 2) = data[5];
*(p + 1) = data[6];
*(p) = data[7];
*(p + 7) = data[offset++];
*(p + 6) = data[offset++];
*(p + 5) = data[offset++];
*(p + 4) = data[offset++];
*(p + 3) = data[offset++];
*(p + 2) = data[offset++];
*(p + 1) = data[offset++];
*(p) = data[offset++];
return rt;
@ -311,14 +335,14 @@ namespace Esiur.Data
double rt = 0;
byte* p = (byte*)&rt;
*(p + 7) = data[0];
*(p + 6) = data[1];
*(p + 5) = data[2];
*(p + 4) = data[3];
*(p + 3) = data[4];
*(p + 2) = data[5];
*(p + 1) = data[6];
*(p) = data[7];
*(p + 7) = data[offset++];
*(p + 6) = data[offset++];
*(p + 5) = data[offset++];
*(p + 4) = data[offset++];
*(p + 3) = data[offset++];
*(p + 2) = data[offset++];
*(p + 1) = data[offset++];
*(p) = data[offset++];
return rt;
}
@ -792,33 +816,48 @@ namespace Esiur.Data
return rt.ToArray();
}
public static byte[] ToBytes(int value)
public static unsafe byte[] ToBytes(int value)
{
byte[] ret = BitConverter.GetBytes(value);
var rt = new byte[4];
byte* p = (byte*)&value;
Array.Reverse(ret);
rt[0] = *(p + 3);
rt[1] = *(p + 2);
rt[2] = *(p + 1);
rt[3] = *(p + 0);
return ret;
return rt;
}
public static byte[] ToBytes(short value)
public static unsafe byte[] ToBytes(short value)
{
byte[] ret = BitConverter.GetBytes(value);
var rt = new byte[2];
byte* p = (byte*)&value;
Array.Reverse(ret);
rt[0] = *(p + 1);
rt[1] = *(p + 0);
return ret;
return rt;
}
public static byte[] ToBytes(float value)
public static unsafe byte[] ToBytes(float value)
{
byte[] ret = BitConverter.GetBytes(value);
var rt = new byte[4];
Array.Reverse(ret);
//float rt = 0;
byte* p = (byte*)&value;
rt[0] = *(p + 3);
rt[1] = *(p + 2);
rt[2] = *(p + 1);
rt[3] = *(p);
return ret;
return rt;
}
/*
public static byte[] ToBytes(Structure[] values)
{
@ -888,58 +927,108 @@ namespace Esiur.Data
return Encoding.UTF8.GetBytes(value);
}
public static byte[] ToBytes(double value)
public unsafe static byte[] ToBytes(double value)
{
byte[] ret = BitConverter.GetBytes(value);
var rt = new byte[8];
Array.Reverse(ret);
byte* p = (byte*)&value;
return ret;
rt[0] = *(p + 7);
rt[1] = *(p + 6);
rt[2] = *(p + 5);
rt[3] = *(p + 4);
rt[4] = *(p + 3);
rt[5] = *(p + 2);
rt[6] = *(p + 1);
rt[7] = *(p + 0);
return rt;
}
public static byte[] ToBytes(long value)
public static unsafe byte[] ToBytes(long value)
{
byte[] ret = BitConverter.GetBytes(value);
var rt = new byte[8];
Array.Reverse(ret);
byte* p = (byte*)&value;
rt[0] = *(p + 7);
rt[1] = *(p + 6);
rt[2] = *(p + 5);
rt[3] = *(p + 4);
rt[4] = *(p + 3);
rt[5] = *(p + 2);
rt[6] = *(p + 1);
rt[7] = *(p + 0);
return rt;
return ret;
}
public static byte[] ToBytes(DateTime value)
public static unsafe byte[] ToBytes(DateTime value)
{
byte[] ret = BitConverter.GetBytes(value.ToUniversalTime().Ticks);
Array.Reverse(ret);
return ret;
var rt = new byte[8];
var v = value.ToUniversalTime().Ticks;
byte* p = (byte*)&v;
rt[0] = *(p + 7);
rt[1] = *(p + 6);
rt[2] = *(p + 5);
rt[3] = *(p + 4);
rt[4] = *(p + 3);
rt[5] = *(p + 2);
rt[6] = *(p + 1);
rt[7] = *(p + 0);
return rt;
}
public static byte[] ToBytes(ulong value)
public static unsafe byte[] ToBytes(ulong value)
{
byte[] ret = BitConverter.GetBytes(value);
var rt = new byte[8];
Array.Reverse(ret);
byte* p = (byte*)&value;
return ret;
rt[0] = *(p + 7);
rt[1] = *(p + 6);
rt[2] = *(p + 5);
rt[3] = *(p + 4);
rt[4] = *(p + 3);
rt[5] = *(p + 2);
rt[6] = *(p + 1);
rt[7] = *(p + 0);
return rt;
}
public static byte[] ToBytes(uint value)
public static unsafe byte[] ToBytes(uint value)
{
byte[] ret = BitConverter.GetBytes(value);
var rt = new byte[4];
Array.Reverse(ret);
byte* p = (byte*)&value;
return ret;
rt[0] = *(p + 3);
rt[1] = *(p + 2);
rt[2] = *(p + 1);
rt[3] = *(p + 0);
return rt;
}
public static byte[] ToBytes(ushort value)
public static unsafe byte[] ToBytes(ushort value)
{
byte[] ret = BitConverter.GetBytes(value);
var rt = new byte[2];
Array.Reverse(ret);
byte* p = (byte*)&value;
return ret;
rt[0] = *(p + 1);
rt[1] = *(p);
return rt;
}
public static byte[] ToBytes(decimal value)

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Collections;
using System.Security.Cryptography;
@ -17,10 +41,10 @@ namespace Esiur.Data
private readonly object syncRoot = new object();
private Dictionary<KT, T> dic;
public delegate void Modified(KT key, T oldValue, T newValue);
public delegate void Added(T value);
public delegate void Removed(KT key, T value);
public delegate void Cleared();
public delegate void Modified(KT key, T oldValue, T newValue, KeyList<KT, T> sender);
public delegate void Added(T value, KeyList<KT, T> sender);
public delegate void Removed(KT key, T value, KeyList<KT, T> sender);
public delegate void Cleared(KeyList<KT, T> sender);
public event Modified OnModified;
public event Removed OnRemoved;
@ -77,14 +101,14 @@ namespace Esiur.Data
((IDestructible)oldValue).OnDestroy -= ItemDestroyed;
dic[key] = value;
if (OnModified != null)
OnModified(key, oldValue, value);
OnModified(key, oldValue, value, this);
}
else
{
dic.Add(key, value);
if (OnAdd != null)
OnAdd(value);
OnAdd(value, this);
}
}
}
@ -136,7 +160,7 @@ namespace Esiur.Data
dic.Clear();
if (OnCleared != null)
OnCleared();
OnCleared(this);
}
public Dictionary<KT, T>.KeyCollection Keys
@ -167,7 +191,13 @@ namespace Esiur.Data
dic.Remove(key);
if (OnRemoved != null)
OnRemoved(key, value);
OnRemoved(key, value, this);
}
public object Owner
{
get;
set;
}
public int Count
@ -187,7 +217,8 @@ namespace Esiur.Data
return dic.ContainsValue(Value);
}
public KeyList()
public KeyList(object owner = null)
{
#if NETSTANDARD1_5
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
@ -195,6 +226,8 @@ namespace Esiur.Data
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
#endif
this.Owner = owner;
if (typeof(KT) == typeof(string))
dic = (Dictionary<KT, T>)(object)new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
else

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Data
{
public class PropertyValue
{
/// <summary>
/// Get or set the value.
/// </summary>
public object Value { get; set; }
/// <summary>
/// Get or set date of modification or occurrence.
/// </summary>
public DateTime Date { get; set; }
/// <summary>
/// Get or set property age.
/// </summary>
public ulong Age { get; set; }
/// <summary>
/// Create an instance of PropertyValue.
/// </summary>
/// <param name="value">Value.</param>
/// <param name="age">Age.</param>
/// <param name="date">Date.</param>
public PropertyValue(object value, ulong age, DateTime date)
{
Value = value;
Age = age;
Date = date;
}
}
}

View File

@ -1,10 +1,35 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Reflection;
using System.Linq;
namespace Esiur.Data
{
@ -64,15 +89,16 @@ namespace Esiur.Data
{
var key = Key.ToLower();
if (OnModified != null)
OnModified(Key, value);
var toRemove = m_Variables.Where(x => x.Key.ToLower() == key);
foreach (var item in toRemove)
m_Variables.Remove(item);
foreach (var kv in m_Variables)
if (kv.Key.ToLower() == key)
m_Variables.Remove(kv);
m_Variables.Add(new KeyValuePair<string, string>(Key, value));
OnModified?.Invoke(Key, value);
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
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;
@ -13,6 +37,12 @@ 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();
@ -56,10 +86,10 @@ namespace Esiur.Data
get { return syncRoot; }
}
public string[] GetKeys()
{
return dic.Keys.ToArray();
}
public string[] GetKeys() => dic.Keys.ToArray();//GetKeys()
//{
// return dic.Keys.ToArray();
//}
public object this[string index]
{

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,17 +32,25 @@ namespace Esiur.Engine
{
public class AsyncBag<T>:AsyncReply
{
Dictionary<AsyncReply, T> results = new Dictionary<AsyncReply, T>();
//Dictionary<AsyncReply, T> results = new Dictionary<AsyncReply, T>();
List<AsyncReply> replies = new List<AsyncReply>();
List<T> results = new List<T>();
int count = 0;
bool sealedBag = false;
public void Then(Action<T[]> callback)
public AsyncBag<T> Then(Action<T[]> callback)
{
base.Then(new Action<object>(o => callback((T[])o)));
return this;
}
public void Seal()
{
if (sealedBag)
return;
sealedBag = true;
if (results.Count == 0)
@ -26,18 +58,28 @@ namespace Esiur.Engine
for (var i = 0; i < results.Count; i++)
//foreach(var reply in results.Keys)
results.Keys.ElementAt(i).Then((r) => {
results[results.Keys.ElementAt(i)] = (T)r;
{
var k = replies[i];// results.Keys.ElementAt(i);
var index = i;
k.Then((r) =>
{
results[index] = (T)r;
count++;
if (count == results.Count)
Trigger(results.Values.ToArray());
Trigger(results.ToArray());
});
}
}
public void Add(AsyncReply reply)
{
if (!sealedBag)
results.Add(reply, default(T));
{
results.Add(default(T));
replies.Add(reply);
}
//results.Add(reply, default(T));
}
public AsyncBag()

View File

@ -0,0 +1,85 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Engine
{
public enum ExceptionCode : ushort
{
HostNotReachable,
AccessDenied,
ResourceNotFound,
AttachDenied,
InvalidMethod,
InvokeDenied,
CreateDenied,
AddParentDenied,
AddChildDenied,
ViewAttributeDenied,
UpdateAttributeDenied,
StoreNotFound,
ParentNotFound,
ChildNotFound,
ResourceIsNotStore,
DeleteDenied,
DeleteFailed,
UpdateAttributeFailed,
GetAttributesFailed,
ClearAttributesFailed,
TemplateNotFound,
RenameDenied,
ClassNotFound,
MethodNotFound,
PropertyNotFound,
SetPropertyDenied,
ReadOnlyProperty
}
public class AsyncException: Exception
{
AsyncReply.ErrorType type;
ExceptionCode code;
public AsyncReply.ErrorType Type => type;
public ExceptionCode Code => code;
public AsyncException(AsyncReply.ErrorType type, ushort code, string message)
: base(type == AsyncReply.ErrorType.Management ? ((ExceptionCode)code).ToString() : message)
{
this.type = type;
this.code = (ExceptionCode)code;
}
public override string ToString()
{
return code.ToString() + ": " + Message;
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -12,9 +36,11 @@ namespace Esiur.Engine
//Action<T> callback;
object queueLock = new object();
public void Then(Action<T> callback)
public AsyncQueue<T> Then(Action<T> callback)
{
base.Then(new Action<object>(o => callback((T)o)));
return this;
}
public void Add(AsyncReply<T> reply)

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,12 +32,34 @@ namespace Esiur.Engine
{
public class AsyncReply
{
public enum ErrorType
{
Management,
Exception
}
public enum ProgressType
{
Execution,
Network,
}
protected List<Action<object>> callbacks = new List<Action<object>>();
protected object result;
protected List<Action<AsyncException>> errorCallbacks = new List<Action<AsyncException>>();
protected List<Action<ProgressType, int, int>> progressCallbacks = new List<Action<ProgressType, int, int>>();
protected List<Action<object>> chunkCallbacks = new List<Action<object>>();
object callbacksLock = new object();
//bool fired = false;
protected bool resultReady = false;
AsyncException exception;
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
public bool Ready
{
@ -25,40 +71,111 @@ namespace Esiur.Engine
get { return result; }
}
public void Then(Action<object> callback)
public AsyncReply Then(Action<object> callback)
{
callbacks.Add(callback);
if (resultReady)
callback(result);
// Trigger(this.result);
return this;
}
public AsyncReply Error(Action<AsyncException> callback)
{
errorCallbacks.Add(callback);
if (exception != null)
{
callback(exception);
tcs.SetException(exception);
}
return this;
}
public AsyncReply Progress(Action<ProgressType, int, int> callback)
{
progressCallbacks.Add(callback);
return this;
}
public AsyncReply Chunk(Action<object> callback)
{
chunkCallbacks.Add(callback);
return this;
}
public void Trigger(object result)
{
//if (!fired)
//{
this.result = result;
resultReady = true;
lock (callbacksLock)
{
if (resultReady)
return;
this.result = result;
resultReady = true;
foreach (var cb in callbacks)
cb(result);
//callbacks.Clear();
tcs.TrySetResult(result);
}
/*
if (callback == null)
}
public void TriggerError(AsyncException exception)
{
fireAtChance = true;
}
else
if (resultReady)
return;
this.exception = exception;
lock (callbacksLock)
{
callback(result);
fired = true;
foreach (var cb in errorCallbacks)
cb(exception);
}
tcs.TrySetException(exception);
}
public void TriggerProgress(ProgressType type, int value, int max)
{
if (resultReady)
return;
lock (callbacksLock)
{
foreach (var cb in progressCallbacks)
cb(type, value, max);
}
}
public void TriggerChunk(object value)
{
if (resultReady)
return;
lock (callbacksLock)
{
foreach (var cb in chunkCallbacks)
cb(value);
}
}
public Task Task
{
get
{
return tcs.Task;
}
*/
//}
}
public AsyncReply()
@ -69,6 +186,7 @@ namespace Esiur.Engine
public AsyncReply(object result)
{
resultReady = true;
tcs.SetResult(result);
this.result = result;
}
}

View File

@ -1,17 +1,44 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Esiur.Resource;
using System.Reflection;
namespace Esiur.Engine
{
public class AsyncReply<T>: AsyncReply
{
public void Then(Action<T> callback)
public AsyncReply<T> Then(Action<T> callback)
{
base.Then(new Action<object>(o => callback((T)o)));
return this;
}
public void Trigger(T result)
@ -24,6 +51,22 @@ namespace Esiur.Engine
}
public new Task<T> Task
{
get
{
return base.Task.ContinueWith<T>((t) =>
{
#if NETSTANDARD1_5
return (T)t.GetType().GetTypeInfo().GetProperty("Result").GetValue(t);
#else
return (T)t.GetType().GetProperty("Result").GetValue(t);
#endif
});
}
}
public AsyncReply(T result)
: base(result)
{

View File

@ -1,4 +1,27 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,29 @@
using System;

/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -6,7 +6,7 @@
<Copyright>Ahmed Kh. Zamil</Copyright>
<PackageLicenseUrl>https://github.com/esiur/esiur-dotnet/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<Version>1.0.0</Version>
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
<Authors>Ahmed Kh. Zamil</Authors>

View File

@ -1,3 +1,27 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Collections;
@ -31,7 +55,7 @@ namespace Esiur.Misc
public delegate void LogEvent(string service, LogType type, string message);
public static LogEvent SystemLog;
public static event LogEvent SystemLog;
static Random random = new Random();
@ -88,8 +112,7 @@ namespace Esiur.Misc
//if (type != LogType.Debug)
Console.WriteLine(service + " " + message);
if (SystemLog != null)
SystemLog(service, type, message);
SystemLog?.Invoke(service, type, message);
}
/*
@ -398,8 +421,8 @@ namespace Esiur.Misc
Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)])
.ToArray());
if (result.Length < length)
Console.WriteLine();
//if (result.Length < length)
// Console.WriteLine();
return result;
/*
int len = 0;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using Esiur.Net.Packets;
/*
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 Esiur.Net.Packets;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -1,4 +1,28 @@
using System;
/*
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.Diagnostics;
using System.IO;
using System.Net.Sockets;

View File

@ -1,4 +1,28 @@
using System;
/*
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.Diagnostics;
using System.IO;
using System.Net.Sockets;

View File

@ -1,3 +1,27 @@
/*
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.Diagnostics;
using System.IO;
@ -157,7 +181,7 @@ namespace Esiur.Net.HTTP
protected override void ClientDisconnected(HTTPConnection sender)
{
Console.WriteLine("OUT: " + this.Connections.Count);
//Console.WriteLine("OUT: " + this.Connections.Count);
foreach (IResource resource in Instance.Children)
{
@ -369,7 +393,7 @@ namespace Esiur.Net.HTTP
//sender.SessionEnded += SessionExpired;
sender.SetParent(this);
Console.WriteLine("IN: " + this.Connections.Count);
//Console.WriteLine("IN: " + this.Connections.Count);
foreach (IResource resource in Instance.Children)
{

View File

@ -1,4 +1,28 @@
using System;
/*
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.Diagnostics;
using System.IO;
using System.Net.Sockets;
@ -61,7 +85,7 @@ namespace Esiur.Net.HTTP
OnEnd?.Invoke(this);
}
void VariablesModified(string key, object oldValue, object newValue)
void VariablesModified(string key, object oldValue, object newValue, KeyList<string, object> sender)
{
OnModify?.Invoke(this, key, oldValue, newValue);
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -27,11 +51,21 @@ namespace Esiur.Net.HTTP
var httpServer = sender.Parent;
var iipServer = r as DistributedServer;
var tcpSocket = sender.Unassign();
if (tcpSocket == null)
return;
var wsSocket = new WSSocket(tcpSocket);
httpServer.Connections.Remove(sender);
httpServer.RemoveConnection(sender);
//httpServer.Connections.Remove(sender);
var iipConnection = new DistributedConnection();
iipConnection.Server = iipServer;
// iipConnection.OnReady += IipConnection_OnReady;
// iipConnection.Server = iipServer;
// iipConnection.Assign(wsSocket);
iipServer.AddConnection(iipConnection);
iipConnection.Assign(wsSocket);
wsSocket.Begin();
}
});
@ -41,6 +75,11 @@ namespace Esiur.Net.HTTP
return false;
}
private void IipConnection_OnReady(DistributedConnection sender)
{
Warehouse.Put(sender, sender.RemoteUsername, null, sender.Server);
}
public override AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
return new AsyncReply<bool>(true);

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
@ -14,6 +38,7 @@ using Esiur.Security.Authority;
using Esiur.Resource.Template;
using System.Linq;
using System.Diagnostics;
using static Esiur.Net.Packets.IIPPacket;
namespace Esiur.Net.IIP
{
@ -35,35 +60,36 @@ namespace Esiur.Net.IIP
IIPPacket packet = new IIPPacket();
IIPAuthPacket authPacket = new IIPAuthPacket();
byte[] sessionId;
AuthenticationType hostType;
string domain;
string localUsername, remoteUsername;
byte[] localPassword;
Session session;
byte[] localPassword;
byte[] localNonce, remoteNonce;
bool ready, readyToEstablish;
DateTime loginDate;
KeyList<string, object> variables = new KeyList<string, object>();
/// <summary>
/// Local username to authenticate ourselves.
/// </summary>
public string LocalUsername { get; set; }
public string LocalUsername => session.LocalAuthentication.Username;// { get; set; }
/// <summary>
/// Peer's username.
/// </summary>
public string RemoteUsername { get; set; }
public string RemoteUsername => session.RemoteAuthentication.Username;// { get; set; }
/// <summary>
/// Working domain.
/// </summary>
public string Domain { get { return domain; } }
//public string Domain { get { return domain; } }
/// <summary>
/// The session related to this connection.
/// </summary>
public Session Session => session;
/// <summary>
/// Distributed server responsible for this connection, usually for incoming connections.
/// </summary>
@ -73,14 +99,50 @@ namespace Esiur.Net.IIP
set;
}
public bool Remove(IResource resource)
{
// nothing to do
return true;
}
/// <summary>
/// Send data to the other end as parameters
/// </summary>
/// <param name="values">Values will be converted to bytes then sent.</param>
internal void SendParams(params object[] values)
{
var ar = BinaryList.ToBytes(values);
Send(ar);
var data = BinaryList.ToBytes(values);
if (ready)
{
var cmd = (IIPPacketCommand)(data[0] >> 6);
if (cmd == IIPPacketCommand.Event)
{
var evt = (IIPPacketEvent)(data[0] & 0x3f);
//Console.Write("Sent: " + cmd.ToString() + " " + evt.ToString());
}
else if (cmd == IIPPacketCommand.Report)
{
var r = (IIPPacketReport)(data[0] & 0x3f);
//Console.Write("Sent: " + cmd.ToString() + " " + r.ToString());
}
else
{
var act = (IIPPacketAction)(data[0] & 0x3f);
//Console.Write("Sent: " + cmd.ToString() + " " + act.ToString());
}
//foreach (var param in values)
// Console.Write(", " + param);
//Console.WriteLine();
}
Send(data);
//StackTrace stackTrace = new StackTrace(;
@ -104,13 +166,7 @@ namespace Esiur.Net.IIP
/// <summary>
/// KeyList to store user variables related to this connection.
/// </summary>
public KeyList<string, object> Variables
{
get
{
return variables;
}
}
public KeyList<string, object> Variables { get; } = new KeyList<string, object>();
/// <summary>
/// IResource interface.
@ -129,12 +185,17 @@ namespace Esiur.Net.IIP
{
base.Assign(socket);
session.RemoteAuthentication.Source.Attributes.Add(SourceAttributeType.IPv4, socket.RemoteEndPoint.Address);
session.RemoteAuthentication.Source.Attributes.Add(SourceAttributeType.Port, socket.RemoteEndPoint.Port);
session.LocalAuthentication.Source.Attributes.Add(SourceAttributeType.IPv4, socket.LocalEndPoint.Address);
session.LocalAuthentication.Source.Attributes.Add(SourceAttributeType.Port, socket.LocalEndPoint.Port);
if (hostType == AuthenticationType.Client)
if (session.LocalAuthentication.Type == AuthenticationType.Client)
{
// declare (Credentials -> No Auth, No Enctypt)
var un = DC.ToBytes(localUsername);
var dmn = DC.ToBytes(domain);
var un = DC.ToBytes(session.LocalAuthentication.Username);
var dmn = DC.ToBytes(session.LocalAuthentication.Domain);// domain);
if (socket.State == SocketState.Established)
{
@ -160,10 +221,14 @@ namespace Esiur.Net.IIP
/// <param name="password">Password.</param>
public DistributedConnection(ISocket socket, string domain, string username, string password)
{
this.session = new Session( new ClientAuthentication()
, new HostAuthentication());
//Instance.Name = Global.GenerateCode(12);
this.hostType = AuthenticationType.Client;
this.domain = domain;
this.localUsername = username;
//this.hostType = AuthenticationType.Client;
//this.domain = domain;
//this.localUsername = username;
session.LocalAuthentication.Domain = domain;
session.LocalAuthentication.Username = username;
this.localPassword = DC.ToBytes(password);
init();
@ -178,6 +243,7 @@ namespace Esiur.Net.IIP
{
//myId = Global.GenerateCode(12);
// localParams.Host = DistributedParameters.HostType.Host;
session = new Session(new HostAuthentication(), new ClientAuthentication());
init();
}
@ -185,7 +251,7 @@ namespace Esiur.Net.IIP
public string Link(IResource resource)
{
if (resource is DistributedConnection)
if (resource is DistributedResource)
{
var r = resource as DistributedResource;
if (r.Instance.Store == this)
@ -203,7 +269,7 @@ namespace Esiur.Net.IIP
if (x.Type == DistributedResourceQueueItem.DistributedResourceQueueItemType.Event)
x.Resource._EmitEventByIndex(x.Index, (object[])x.Value);
else
x.Resource.UpdatePropertyByIndex(x.Index, x.Value);
x.Resource._UpdatePropertyByIndex(x.Index, x.Value);
});
var r = new Random();
@ -213,22 +279,39 @@ namespace Esiur.Net.IIP
protected override void DataReceived(NetworkBuffer data)
{
// Console.WriteLine("DR " + hostType + " " + data.Available + " " + RemoteEndPoint.ToString());
var msg = data.Read();
uint offset = 0;
uint ends = (uint)msg.Length;
while (offset < ends)
private uint processPacket(byte[] msg, uint offset, uint ends, NetworkBuffer data, int chunkId)
{
var packet = new IIPPacket();
// packets++;
if (ready)
{
var rt = packet.Parse(msg, offset, ends);
//Console.WriteLine("Rec: " + chunkId + " " + packet.ToString());
/*
if (packet.Command == IIPPacketCommand.Event)
Console.WriteLine("Rec: " + packet.Command.ToString() + " " + packet.Event.ToString());
else if (packet.Command == IIPPacketCommand.Report)
Console.WriteLine("Rec: " + packet.Command.ToString() + " " + packet.Report.ToString());
else
Console.WriteLine("Rec: " + packet.Command.ToString() + " " + packet.Action.ToString() + " " + packet.ResourceId + " " + offset + "/" + ends);
*/
//packs.Add(packet.Command.ToString() + " " + packet.Action.ToString() + " " + packet.Event.ToString());
//if (packs.Count > 1)
// Console.WriteLine("P2");
if (rt <= 0)
{
data.HoldFor(msg, offset, ends - offset, (uint)(-rt));
return;
var size = ends - offset;
data.HoldFor(msg, offset, size, size + (uint)(-rt));
return ends;
}
else
{
@ -247,8 +330,21 @@ namespace Esiur.Net.IIP
case IIPPacket.IIPPacketEvent.PropertyUpdated:
IIPEventPropertyUpdated(packet.ResourceId, packet.MethodIndex, packet.Content);
break;
case IIPPacket.IIPPacketEvent.EventOccured:
IIPEventEventOccured(packet.ResourceId, packet.MethodIndex, packet.Content);
case IIPPacket.IIPPacketEvent.EventOccurred:
IIPEventEventOccurred(packet.ResourceId, packet.MethodIndex, packet.Content);
break;
case IIPPacketEvent.ChildAdded:
IIPEventChildAdded(packet.ResourceId, packet.ChildId);
break;
case IIPPacketEvent.ChildRemoved:
IIPEventChildRemoved(packet.ResourceId, packet.ChildId);
break;
case IIPPacketEvent.Renamed:
IIPEventRenamed(packet.ResourceId, packet.Content);
break;
case IIPPacketEvent.AttributesUpdated:
IIPEventAttributesUpdated(packet.ResourceId, packet.Content);
break;
}
}
@ -256,6 +352,7 @@ namespace Esiur.Net.IIP
{
switch (packet.Action)
{
// Manage
case IIPPacket.IIPPacketAction.AttachResource:
IIPRequestAttachResource(packet.CallbackId, packet.ResourceId);
break;
@ -266,26 +363,47 @@ namespace Esiur.Net.IIP
IIPRequestDetachResource(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.CreateResource:
IIPRequestCreateResource(packet.CallbackId, packet.ClassName);
IIPRequestCreateResource(packet.CallbackId, packet.StoreId, packet.ResourceId, packet.Content);
break;
case IIPPacket.IIPPacketAction.DeleteResource:
IIPRequestDeleteResource(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketAction.AddChild:
IIPRequestAddChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
break;
case IIPPacketAction.RemoveChild:
IIPRequestRemoveChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
break;
case IIPPacketAction.RenameResource:
IIPRequestRenameResource(packet.CallbackId, packet.ResourceId, packet.Content);
break;
// Inquire
case IIPPacket.IIPPacketAction.TemplateFromClassName:
IIPRequestTemplateFromClassName(packet.CallbackId, packet.ClassName);
break;
case IIPPacket.IIPPacketAction.TemplateFromClassId:
IIPRequestTemplateFromClassId(packet.CallbackId, packet.ClassId);
break;
case IIPPacket.IIPPacketAction.TemplateFromResourceLink:
IIPRequestTemplateFromResourceLink(packet.CallbackId, packet.ResourceLink);
break;
case IIPPacket.IIPPacketAction.TemplateFromResourceId:
IIPRequestTemplateFromResourceId(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.ResourceIdFromResourceLink:
IIPRequestResourceIdFromResourceLink(packet.CallbackId, packet.ResourceLink);
case IIPPacketAction.QueryLink:
IIPRequestQueryResources(packet.CallbackId, packet.ResourceLink);
break;
case IIPPacketAction.ResourceChildren:
IIPRequestResourceChildren(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketAction.ResourceParents:
IIPRequestResourceParents(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.ResourceHistory:
IIPRequestInquireResourceHistory(packet.CallbackId, packet.ResourceId, packet.FromDate, packet.ToDate);
break;
// Invoke
case IIPPacket.IIPPacketAction.InvokeFunction:
IIPRequestInvokeFunction(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
break;
@ -298,103 +416,163 @@ namespace Esiur.Net.IIP
case IIPPacket.IIPPacketAction.SetProperty:
IIPRequestSetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
break;
// Attribute
case IIPPacketAction.GetAllAttributes:
IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
break;
case IIPPacketAction.UpdateAllAttributes:
IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
break;
case IIPPacketAction.ClearAllAttributes:
IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
break;
case IIPPacketAction.GetAttributes:
IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
break;
case IIPPacketAction.UpdateAttributes:
IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
break;
case IIPPacketAction.ClearAttributes:
IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
break;
}
}
else if (packet.Command == IIPPacket.IIPPacketCommand.Reply)
{
switch (packet.Action)
{
// Manage
case IIPPacket.IIPPacketAction.AttachResource:
IIPReply(packet.CallbackId, packet.ClassId, packet.ResourceAge, packet.ResourceLink, packet.Content);
//IIPReplyAttachResource(packet.CallbackId, packet.ResourceAge, Codec.ParseValues(packet.Content));
break;
case IIPPacket.IIPPacketAction.ReattachResource:
//IIPReplyReattachResource(packet.CallbackId, packet.ResourceAge, Codec.ParseValues(packet.Content));
IIPReply(packet.CallbackId, packet.ResourceAge, packet.Content);
break;
case IIPPacket.IIPPacketAction.DetachResource:
//IIPReplyDetachResource(packet.CallbackId);
IIPReply(packet.CallbackId);
break;
case IIPPacket.IIPPacketAction.CreateResource:
//IIPReplyCreateResource(packet.CallbackId, packet.ClassId, packet.ResourceId);
IIPReply(packet.CallbackId, packet.ClassId, packet.ResourceId);
IIPReply(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.DeleteResource:
//IIPReplyDeleteResource(packet.CallbackId);
case IIPPacketAction.AddChild:
case IIPPacketAction.RemoveChild:
case IIPPacketAction.RenameResource:
IIPReply(packet.CallbackId);
break;
// Inquire
case IIPPacket.IIPPacketAction.TemplateFromClassName:
//IIPReplyTemplateFromClassName(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
IIPReply(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
break;
case IIPPacket.IIPPacketAction.TemplateFromClassId:
//IIPReplyTemplateFromClassId(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
IIPReply(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
break;
case IIPPacket.IIPPacketAction.TemplateFromResourceLink:
//IIPReplyTemplateFromResourceLink(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
IIPReply(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
break;
case IIPPacket.IIPPacketAction.TemplateFromResourceId:
//IIPReplyTemplateFromResourceId(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
IIPReply(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
break;
case IIPPacket.IIPPacketAction.ResourceIdFromResourceLink:
//IIPReplyResourceIdFromResourceLink(packet.CallbackId, packet.ClassId, packet.ResourceId, packet.ResourceAge);
IIPReply(packet.CallbackId, packet.ClassId, packet.ResourceId, packet.ResourceAge);
break;
case IIPPacket.IIPPacketAction.InvokeFunction:
//IIPReplyInvokeFunction(packet.CallbackId, Codec.Parse(packet.Content, 0));
case IIPPacketAction.QueryLink:
case IIPPacketAction.ResourceChildren:
case IIPPacketAction.ResourceParents:
case IIPPacketAction.ResourceHistory:
IIPReply(packet.CallbackId, packet.Content);
break;
// Invoke
case IIPPacket.IIPPacketAction.InvokeFunction:
IIPReplyInvoke(packet.CallbackId, packet.Content);
break;
case IIPPacket.IIPPacketAction.GetProperty:
//IIPReplyGetProperty(packet.CallbackId, Codec.Parse(packet.Content, 0));
IIPReply(packet.CallbackId, packet.Content);
break;
case IIPPacket.IIPPacketAction.GetPropertyIfModified:
//IIPReplyGetPropertyIfModifiedSince(packet.CallbackId, Codec.Parse(packet.Content, 0));
IIPReply(packet.CallbackId, packet.Content);
break;
case IIPPacket.IIPPacketAction.SetProperty:
//IIPReplySetProperty(packet.CallbackId);
IIPReply(packet.CallbackId);
break;
}
// Attribute
case IIPPacketAction.GetAllAttributes:
case IIPPacketAction.GetAttributes:
IIPReply(packet.CallbackId, packet.Content);
break;
case IIPPacketAction.UpdateAllAttributes:
case IIPPacketAction.UpdateAttributes:
case IIPPacketAction.ClearAllAttributes:
case IIPPacketAction.ClearAttributes:
IIPReply(packet.CallbackId);
break;
}
}
else if (packet.Command == IIPPacketCommand.Report)
{
switch (packet.Report)
{
case IIPPacketReport.ManagementError:
IIPReportError(packet.CallbackId, AsyncReply.ErrorType.Management, packet.ErrorCode, null);
break;
case IIPPacketReport.ExecutionError:
IIPReportError(packet.CallbackId, AsyncReply.ErrorType.Exception, packet.ErrorCode, packet.ErrorMessage);
break;
case IIPPacketReport.ProgressReport:
IIPReportProgress(packet.CallbackId, AsyncReply.ProgressType.Execution, packet.ProgressValue, packet.ProgressMax);
break;
case IIPPacketReport.ChunkStream:
IIPReportChunk(packet.CallbackId, packet.Content);
break;
}
}
}
}
else
{
var rt = authPacket.Parse(msg, offset, ends);
Console.WriteLine(hostType.ToString() + " " + offset + " " + ends + " " + rt + " " + authPacket.ToString());
//Console.WriteLine(session.LocalAuthentication.Type.ToString() + " " + offset + " " + ends + " " + rt + " " + authPacket.ToString());
if (rt <= 0)
{
data.HoldFor(msg, ends + (uint)(-rt));
return;
return ends;
}
else
{
offset += (uint)rt;
if (hostType == AuthenticationType.Host)
if (session.LocalAuthentication.Type == AuthenticationType.Host)
{
if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Declare)
{
if (authPacket.RemoteMethod == IIPAuthPacket.IIPAuthPacketMethod.Credentials && authPacket.LocalMethod == IIPAuthPacket.IIPAuthPacketMethod.None)
{
remoteUsername = authPacket.RemoteUsername;
Server.Membership.UserExists(authPacket.RemoteUsername, authPacket.Domain).Then(x =>
{
if (x)
{
session.RemoteAuthentication.Username = authPacket.RemoteUsername;
remoteNonce = authPacket.RemoteNonce;
domain = authPacket.Domain;
session.RemoteAuthentication.Domain = authPacket.Domain;
SendParams((byte)0xa0, localNonce);
}
else
{
//Console.WriteLine("User not found");
SendParams((byte)0xc0, (byte)1, (ushort)14, DC.ToBytes("User not found"));
}
});
}
}
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Action)
{
@ -402,10 +580,9 @@ namespace Esiur.Net.IIP
{
var remoteHash = authPacket.Hash;
Server.Membership.GetPassword(remoteUsername, domain).Then((pw) =>
Server.Membership.GetPassword(session.RemoteAuthentication.Username,
session.RemoteAuthentication.Domain).Then((pw) =>
{
if (pw != null)
{
var hashFunc = SHA256.Create();
@ -421,7 +598,8 @@ namespace Esiur.Net.IIP
}
else
{
Console.WriteLine("Incorrect password");
Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:DENIED");
//Console.WriteLine("Incorrect password");
SendParams((byte)0xc0, (byte)1, (ushort)5, DC.ToBytes("Error"));
}
}
@ -432,16 +610,20 @@ namespace Esiur.Net.IIP
if (readyToEstablish)
{
var r = new Random();
sessionId = new byte[32];
r.NextBytes(sessionId);
SendParams((byte)0x28, sessionId);
session.Id = new byte[32];
r.NextBytes(session.Id);
SendParams((byte)0x28, session.Id);
ready = true;
OnReady?.Invoke(this);
Server.Membership.Login(session);
Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:AUTH");
}
}
}
}
else if (hostType == AuthenticationType.Client)
else if (session.LocalAuthentication.Type == AuthenticationType.Client)
{
if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Acknowledge)
{
@ -473,9 +655,11 @@ namespace Esiur.Net.IIP
}
else if (authPacket.Action == IIPAuthPacket.IIPAuthPacketAction.ConnectionEstablished)
{
sessionId = authPacket.SessionId;
session.Id = authPacket.SessionId;
ready = true;
OnReady?.Invoke(this);
}
}
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Error)
@ -486,6 +670,29 @@ namespace Esiur.Net.IIP
}
}
}
return offset;
//if (offset < ends)
// processPacket(msg, offset, ends, data, chunkId);
}
protected override void DataReceived(NetworkBuffer data)
{
// Console.WriteLine("DR " + hostType + " " + data.Available + " " + RemoteEndPoint.ToString());
var msg = data.Read();
uint offset = 0;
uint ends = (uint)msg.Length;
var packs = new List<string>();
var chunkId = (new Random()).Next(1000, 1000000);
while (offset < ends)
{
offset = processPacket(msg, offset, ends, data, chunkId);
}
}
@ -510,5 +717,17 @@ namespace Esiur.Net.IIP
resources.Add(Convert.ToUInt32(resource.Instance.Name), (DistributedResource)resource);
return true;
}
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
{
// nothing to do
return true;
}
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
{
// nothing to do
return true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
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)
{
this.Value = value;
this.Connection = connection;
}
public DistributedPropertyContext(Func<DistributedConnection, object> method)
{
this.Method = method;
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
@ -41,12 +65,12 @@ namespace Esiur.Net.IIP
//Structure properties = new Structure();
string link;
uint age;
uint[] ages;
//ulong age;
//ulong[] ages;
object[] properties;
DistributedResourceEvent[] events;
ResourceTemplate template;
//ResourceTemplate template;
//DistributedResourceStack stack;
@ -54,13 +78,23 @@ namespace Esiur.Net.IIP
bool destroyed;
/*
Dictionary<AsyncReply, object> afterAttachmentTriggers = new Dictionary<AsyncReply, object>();
internal void AddAfterAttachement(AsyncReply trigger, object value)
{
afterAttachmentTriggers.Add(trigger, value);
}
*/
/// <summary>
/// Resource template for the remotely located resource.
/// </summary>
public ResourceTemplate Template
{
get { return template; }
}
//public ResourceTemplate Template
//{
// get { return template; }
//}
/// <summary>
@ -132,13 +166,15 @@ namespace Esiur.Net.IIP
/// <param name="template">Resource template.</param>
/// <param name="instanceId">Instance Id given by the other end.</param>
/// <param name="age">Resource age.</param>
public DistributedResource(DistributedConnection connection, ResourceTemplate template, uint instanceId, uint age, string link)
public DistributedResource(DistributedConnection connection, uint instanceId, ulong age, string link)
{
this.link = link;
this.connection = connection;
this.instanceId = instanceId;
this.template = template;
this.age = age;
//this.Instance.Template = template;
//this.Instance.Age = age;
//this.template = template;
//this.age = age;
}
internal void _Ready()
@ -146,26 +182,56 @@ namespace Esiur.Net.IIP
isReady = true;
}
internal bool _Attached(object[] properties)
/// <summary>
/// Export all properties with ResourceProperty attributed as bytes array.
/// </summary>
/// <returns></returns>
internal PropertyValue[] _Serialize()
{
var props = new PropertyValue[properties.Length];
for (byte i = 0; i < properties.Length; i++)
props[i] = new PropertyValue(properties[i], Instance.GetAge(i), Instance.GetModificationDate(i));
return props;
}
internal bool _Attached(PropertyValue[] properties)
{
if (isAttached)
return false;
else
{
this.properties = properties;
ages = new uint[properties.Length];
this.events = new DistributedResourceEvent[template.Events.Length];
this.properties = new object[properties.Length];
this.events = new DistributedResourceEvent[Instance.Template.Events.Length];
for (byte i = 0; i < properties.Length; i++)
{
Instance.SetAge(i, properties[i].Age);
Instance.SetModificationDate(i, properties[i].Date);
this.properties[i] = properties[i].Value;
}
// trigger holded events/property updates.
//foreach (var r in afterAttachmentTriggers)
// r.Key.Trigger(r.Value);
//afterAttachmentTriggers.Clear();
isAttached = true;
}
return true;
}
internal void _EmitEventByIndex(byte index, object[] args)
{
var et = template.GetEventTemplate(index);
var et = Instance.Template.GetEventTemplate(index);
events[index]?.Invoke(this, args);
Instance.EmitResourceEvent(et.Name, null, args);
Instance.EmitResourceEvent(null, null, et.Name, args);
}
public AsyncReply _Invoke(byte index, object[] args)
@ -173,29 +239,37 @@ namespace Esiur.Net.IIP
if (destroyed)
throw new Exception("Trying to access destroyed object");
if (index >= template.Functions.Length)
if (index >= Instance.Template.Functions.Length)
throw new Exception("Function index is incorrect");
var reply = new AsyncReply();
// var reply = new AsyncReply();
var parameters = Codec.ComposeVarArray(args, connection, true);
connection.SendRequest(Packets.IIPPacket.IIPPacketAction.InvokeFunction, instanceId, index, parameters).Then((res) =>
return connection.SendInvoke(instanceId, index, args);
//var parameters = Codec.ComposeVarArray(args, connection, true);
//return connection.SendRequest(Packets.IIPPacket.IIPPacketAction.InvokeFunction, instanceId, index, parameters);
/*.Then((res) =>
{
Codec.Parse((byte[])res[0], 0, connection).Then((rt) =>
{
reply.Trigger(rt);
});
});
}).Error((ex) => {
reply.TriggerError(ex);
}).Progress((t, pv, pm)=> {
reply.TriggerProgress(t, pv, pm);
}).Chunk(v => reply.TriggerChunk(v));
return reply;
*/
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var ft = template.GetFunctionTemplate(binder.Name);
var ft = Instance.Template.GetFunctionTemplate(binder.Name);
var reply = new AsyncReply();
@ -233,7 +307,7 @@ namespace Esiur.Net.IIP
if (!isAttached)
return false;
var pt = template.GetPropertyTemplate(binder.Name);
var pt = Instance.Template.GetPropertyTemplate(binder.Name);
if (pt != null)
{
@ -242,7 +316,7 @@ namespace Esiur.Net.IIP
}
else
{
var et = template.GetEventTemplate(binder.Name);
var et = Instance.Template.GetEventTemplate(binder.Name);
if (et == null)
return false;
@ -253,11 +327,11 @@ namespace Esiur.Net.IIP
}
internal void UpdatePropertyByIndex(byte index, object value)
internal void _UpdatePropertyByIndex(byte index, object value)
{
var pt = template.GetPropertyTemplate(index);
var pt = Instance.Template.GetPropertyTemplate(index);
properties[index] = value;
Instance.Modified(pt.Name, value);
Instance.EmitModification(pt, value);
}
/// <summary>
@ -277,9 +351,8 @@ namespace Esiur.Net.IIP
connection.SendRequest(Packets.IIPPacket.IIPPacketAction.SetProperty, instanceId, index, parameters).Then((res) =>
{
// not really needed, server will always send property modified, this only happens if the programmer forgot to emit in property setter
//Update(index, value);
properties[index] = value;
reply.Trigger(null);
// nothing to do here
});
return reply;
@ -293,8 +366,7 @@ namespace Esiur.Net.IIP
if (!isAttached)
return false;
var pt = template.GetPropertyTemplate(binder.Name);
var pt = Instance.Template.GetPropertyTemplate(binder.Name);
if (pt != null)
{
@ -303,7 +375,7 @@ namespace Esiur.Net.IIP
}
else
{
var et = template.GetEventTemplate(binder.Name);
var et = Instance.Template.GetEventTemplate(binder.Name);
if (et == null)
return false;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -16,39 +40,40 @@ namespace Esiur.Net.IIP
public class DistributedServer : NetworkServer<DistributedConnection>, IResource
{
[Storable]
[ResourceProperty]
//[Storable]
//[ResourceProperty]
public string ip
{
get;
set;
}
[Storable]
[ResourceProperty]
//[Storable]
//[ResourceProperty]
public IMembership Membership
{
get;
set;
}
[Storable]
[ResourceProperty]
//[Storable]
//[ResourceProperty]
public ushort port
{
get;
set;
}
[Storable]
[ResourceProperty]
//[Storable]
//[ResourceProperty]
public uint timeout
{
get;
set;
}
[Storable]
[ResourceProperty]
//[Storable]
//[ResourceProperty]
public uint clock
{
get;
@ -101,17 +126,38 @@ namespace Esiur.Net.IIP
}
protected override void ClientConnected(DistributedConnection sender)
{
Console.WriteLine("DistributedConnection Client Connected");
sender.Server = this;
//Console.WriteLine("DistributedConnection Client Connected");
}
private void Sender_OnReady(DistributedConnection sender)
{
Warehouse.Put(sender, sender.LocalUsername, null, this);
}
public override void RemoveConnection(DistributedConnection connection)
{
connection.OnReady -= Sender_OnReady;
//connection.Server = null;
base.RemoveConnection(connection);
}
public override void AddConnection(DistributedConnection connection)
{
connection.OnReady += Sender_OnReady;
connection.Server = this;
base.AddConnection(connection);
}
protected override void ClientDisconnected(DistributedConnection sender)
{
Console.WriteLine("DistributedConnection Client Disconnected");
sender.Destroy();
Warehouse.Remove(sender);
//Console.WriteLine("DistributedConnection Client Disconnected");
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Net.Sockets;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -14,6 +38,13 @@ namespace Esiur.Net
uint neededDataLength = 0;
//bool trim;
object syncLock = new object();
//public object SyncLock
//{
// get { return syncLock; }
//}
public NetworkBuffer()
{
data = new byte[0];
@ -61,6 +92,8 @@ namespace Esiur.Net
public void HoldFor(byte[] src, uint offset, uint size, uint needed)
{
lock (syncLock)
{
if (size >= needed)
throw new Exception("Size >= Needed !");
@ -71,7 +104,8 @@ namespace Esiur.Net
// Console.WriteLine("Hold StackTrace: '{0}'", Environment.StackTrace);
Console.WriteLine("Holded {0} {1} {2} {3} - {4}", offset, size, needed, data.Length, GetHashCode());
//Console.WriteLine("Holded {0} {1} {2} {3} - {4}", offset, size, needed, data.Length, GetHashCode());
}
}
public void HoldFor(byte[] src, uint needed)
@ -104,6 +138,10 @@ namespace Esiur.Net
public void Write(byte[] src, uint offset, uint length)
{
//if (data.Length > 0)
// Console.WriteLine();
lock(syncLock)
DC.Append(ref data, src, offset, length);
}
@ -121,6 +159,8 @@ namespace Esiur.Net
}
public byte[] Read()
{
lock (syncLock)
{
if (data.Length == 0)
return null;
@ -165,3 +205,4 @@ namespace Esiur.Net
}
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
@ -29,7 +53,9 @@ namespace Esiur.Net
public event DataReceivedEvent OnDataReceived;
public event ConnectionClosedEvent OnClose;
public event DestroyedEvent OnDestroy;
object receivingLock = new object();
bool processing = false;
public void Destroy()
@ -62,8 +88,8 @@ namespace Esiur.Net
socket.OnReceive += Socket_OnReceive;
socket.OnClose += Socket_OnClose;
socket.OnConnect += Socket_OnConnect;
if (socket.State == SocketState.Established)
socket.Begin();
//if (socket.State == SocketState.Established)
// socket.Begin();
}
private void Socket_OnConnect()
@ -90,8 +116,23 @@ namespace Esiur.Net
lastAction = DateTime.Now;
if (!processing)
{
processing = true;
try
{
//lock(buffer.SyncLock)
while (buffer.Available > 0 && !buffer.Protected)
DataReceived(buffer);
}
catch
{
}
processing = false;
}
}
catch (Exception ex)
@ -234,9 +275,9 @@ namespace Esiur.Net
sock.Send(msg);
}
}
catch
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}

View File

@ -1,3 +1,27 @@
/*
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.Threading;
using System.Collections.Generic;
@ -10,7 +34,6 @@ using System.Threading.Tasks;
namespace Esiur.Net
{
//public abstract class NetworkServer<TConnection, TSession> : IResource where TSession : NetworkSession, new() where TConnection : NetworkConnection<TSession>, new()
public abstract class NetworkServer<TConnection>: IDestructible where TConnection : NetworkConnection, new()
{
@ -25,8 +48,6 @@ namespace Esiur.Net
protected abstract void ClientConnected(TConnection sender);
protected abstract void ClientDisconnected(TConnection sender);
// private int port;
// private IPAddress ip = null;
private uint timeout;
private Timer timer;
@ -201,7 +222,7 @@ namespace Esiur.Net
// Thread.Sleep(100);
//}
Console.WriteLine("Listener stopped");
//Console.WriteLine("Listener stopped");
var cons = connections.ToArray();
@ -211,14 +232,13 @@ namespace Esiur.Net
con.Close();
//}
Console.WriteLine("Sockets Closed");
while (connections.Count > 0)
{
Console.WriteLine("Waiting... " + connections.Count);
//Console.WriteLine("Sockets Closed");
//while (connections.Count > 0)
//{
// Console.WriteLine("Waiting... " + connections.Count);
// Thread.Sleep(1000);
}
//}
}
finally
@ -228,6 +248,21 @@ namespace Esiur.Net
}
public virtual void RemoveConnection(TConnection connection)
{
connection.OnDataReceived -= OnDataReceived;
connection.OnConnect -= OnClientConnect;
connection.OnClose -= OnClientClose;
connections.Remove(connection);
}
public virtual void AddConnection(TConnection connection)
{
connection.OnDataReceived += OnDataReceived;
connection.OnConnect += OnClientConnect;
connection.OnClose += OnClientClose;
connections.Add(connection);
}
private void NewConnection(ISocket sock)
{
@ -246,20 +281,17 @@ namespace Esiur.Net
if (sock == null)
{
Console.Write("sock == null");
//Console.Write("sock == null");
return;
}
//sock.ReceiveBufferSize = 102400;
//sock.SendBufferSize = 102400;
TConnection c = new TConnection();
c.OnDataReceived += OnDataReceived;
c.OnConnect += OnClientConnect;
c.OnClose += OnClientClose;
AddConnection(c);
connections.Add(c);
c.Assign(sock);
ClientConnected(c);
@ -267,13 +299,14 @@ namespace Esiur.Net
// Accept more
listener.Accept().Then(NewConnection);
sock.Begin();
}
catch (Exception ex)
{
Console.WriteLine("TSERVER " + ex.ToString());
Global.Log("TServer", LogType.Error, ex.ToString());
//Console.WriteLine("TSERVER " + ex.ToString());
Global.Log("NetworkServer", LogType.Error, ex.ToString());
}
//isRunning = false;
@ -317,6 +350,7 @@ namespace Esiur.Net
try
{
sender.Destroy();
RemoveConnection((TConnection)sender);
ClientDisconnected((TConnection)sender);
}
catch (Exception ex)

View File

@ -1,4 +1,28 @@
using System;
/*
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.Diagnostics;
using System.IO;
using System.Net.Sockets;
@ -61,7 +85,7 @@ namespace Esiur.Net
OnEnd?.Invoke(this);
}
void VariablesModified(string key, object oldValue, object newValue)
void VariablesModified(string key, object oldValue, object newValue, KeyList<string, object> sender)
{
OnModify?.Invoke(this, key, oldValue, newValue);
}

View File

@ -1,4 +1,29 @@
using System;

/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -218,7 +243,7 @@ namespace Esiur.Net.Packets
return postSize - (data.Length - headerSize);
if (Headers["content-type"] == "application/x-www-form-urlencoded"
if (Headers["content-type"].StartsWith("application/x-www-form-urlencoded")
|| Headers["content-type"] == ""
|| Headers["content-type"] == null)
{

View File

@ -1,4 +1,27 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
 using Esiur.Data;
/*
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 Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -1,4 +1,28 @@
 using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Engine;
using Esiur.Misc;
using Esiur.Net.Packets;
@ -12,12 +36,39 @@ namespace Esiur.Net.Packets
{
class IIPPacket : Packet
{
public override string ToString()
{
var rt = Command.ToString();
if (Command == IIPPacketCommand.Event)
{
rt += " " + Event.ToString();
//if (Event == IIPPacketEvent.AttributesUpdated)
// rt +=
}
else if (Command == IIPPacketCommand.Request)
{
rt += " " + Action.ToString();
if (Action == IIPPacketAction.AttachResource)
{
rt += " CID: " + CallbackId + " RID: " + ResourceId;
}
}
else if (Command == IIPPacketCommand.Reply)
rt += " " + Action.ToString();
else if (Command == IIPPacketCommand.Report)
rt += " " + Report.ToString();
return rt;
}
public enum IIPPacketCommand : byte
{
Event = 0,
Request,
Reply,
Error,
Report,
}
public enum IIPPacketEvent: byte
@ -25,10 +76,15 @@ namespace Esiur.Net.Packets
// Event Manage
ResourceReassigned = 0,
ResourceDestroyed,
ChildAdded,
ChildRemoved,
Renamed,
// Event Invoke
PropertyUpdated = 0x10,
EventOccured,
EventOccurred,
// Attribute
AttributesUpdated = 0x18
}
public enum IIPPacketAction : byte
@ -39,21 +95,48 @@ namespace Esiur.Net.Packets
DetachResource,
CreateResource,
DeleteResource,
AddChild,
RemoveChild,
RenameResource,
// Request Inquire
TemplateFromClassName = 0x8,
TemplateFromClassId,
TemplateFromResourceLink,
TemplateFromResourceId,
ResourceIdFromResourceLink,
QueryLink,
ResourceHistory,
ResourceChildren,
ResourceParents,
// Request Invoke
InvokeFunction = 0x10,
GetProperty,
GetPropertyIfModified,
SetProperty,
// Request Attribute
GetAllAttributes = 0x18,
UpdateAllAttributes,
ClearAllAttributes,
GetAttributes,
UpdateAttributes,
ClearAttributes
}
public enum IIPPacketReport: byte
{
ManagementError,
ExecutionError,
ProgressReport = 0x8,
ChunkStream = 0x9
}
public IIPPacketReport Report
{
get;
set;
}
public IIPPacketCommand Command
{
@ -72,13 +155,33 @@ namespace Esiur.Net.Packets
set;
}
public IIPPacketCommand PreviousCommand
{
get;
set;
}
public IIPPacketAction PreviousAction
{
get;
set;
}
public IIPPacketEvent PreviousEvent
{
get;
set;
}
public uint ResourceId { get; set; }
public uint NewResourceId { get; set; }
//public uint ParentId { get; set; }
public uint ChildId { get; set; }
public uint StoreId { get; set; }
public uint ResourceAge { get; set; }
public ulong ResourceAge { get; set; }
public byte[] Content { get; set; }
public byte ErrorCode { get; set; }
public ushort ErrorCode { get; set; }
public string ErrorMessage { get; set; }
public string ClassName { get; set; }
public string ResourceLink { get; set; }
@ -86,8 +189,15 @@ namespace Esiur.Net.Packets
public byte MethodIndex { get; set; }
public string MethodName { get; set; }
public uint CallbackId { get; set; }
public int ProgressValue { get; set; }
public int ProgressMax { get; set; }
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; }
public ulong FromAge { get; set; }
public ulong ToAge { get; set; }
private uint dataLengthNeeded;
private uint originalOffset;
public override bool Compose()
{
@ -98,7 +208,9 @@ namespace Esiur.Net.Packets
{
if (offset + needed > ends)
{
dataLengthNeeded = needed - (ends - offset);
//dataLengthNeeded = needed - (ends - offset);
dataLengthNeeded = needed - (ends - originalOffset);
return true;
}
else
@ -107,11 +219,13 @@ namespace Esiur.Net.Packets
public override long Parse(byte[] data, uint offset, uint ends)
{
var oOffset = offset;
originalOffset = offset;
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
PreviousCommand = Command;
Command = (IIPPacketCommand)(data[offset] >> 6);
if (Command == IIPPacketCommand.Event)
@ -124,8 +238,19 @@ namespace Esiur.Net.Packets
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Command == IIPPacketCommand.Report)
{
Report = (IIPPacketReport)(data[offset++] & 0x3f);
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
CallbackId = data.GetUInt32(offset);
offset += 4;
}
else
{
PreviousAction = Action;
Action = (IIPPacketAction)(data[offset++] & 0x3f);
if (NotEnough(offset, ends, 4))
@ -150,6 +275,30 @@ namespace Esiur.Net.Packets
{
// nothing to parse
}
else if (Event == IIPPacketEvent.ChildAdded
|| Event == IIPPacketEvent.ChildRemoved)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ChildId = data.GetUInt32(offset);
offset += 4;
}
else if(Event == IIPPacketEvent.Renamed)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Event == IIPPacketEvent.PropertyUpdated)
{
if (NotEnough(offset, ends, 2))
@ -183,7 +332,7 @@ namespace Esiur.Net.Packets
offset += (uint)size;
}
}
else if (Event == IIPPacketEvent.EventOccured)
else if (Event == IIPPacketEvent.EventOccurred)
{
if (NotEnough(offset, ends, 5))
return -dataLengthNeeded;
@ -197,6 +346,22 @@ namespace Esiur.Net.Packets
offset += cl;
}
// Attribute
else if (Event == IIPPacketEvent.AttributesUpdated)
{
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, cl);
offset += cl;
}
}
else if (Command == IIPPacketCommand.Request)
{
@ -210,14 +375,14 @@ namespace Esiur.Net.Packets
}
else if (Action == IIPPacketAction.ReattachResource)
{
if (NotEnough(offset, ends, 8))
if (NotEnough(offset, ends, 12))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
ResourceAge = data.GetUInt32(offset);
offset += 4;
ResourceAge = data.GetUInt64(offset);
offset += 8;
}
else if (Action == IIPPacketAction.DetachResource)
@ -231,16 +396,21 @@ namespace Esiur.Net.Packets
}
else if (Action == IIPPacketAction.CreateResource)
{
if (NotEnough(offset, ends, 1))
if (NotEnough(offset, ends, 12))
return -dataLengthNeeded;
var cl = data[offset++];
StoreId = data.GetUInt32(offset);
offset += 4;
ResourceId = data.GetUInt32(offset);
offset += 4;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ClassName = data.GetString(offset, cl);
offset += cl;
this.Content = data.Clip(offset, cl);
}
else if (Action == IIPPacketAction.DeleteResource)
{
@ -251,6 +421,33 @@ namespace Esiur.Net.Packets
offset += 4;
}
else if (Action == IIPPacketAction.AddChild
|| Action == IIPPacketAction.RemoveChild)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
ChildId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.RenameResource)
{
if (NotEnough(offset, ends, 6))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.TemplateFromClassName)
{
if (NotEnough(offset, ends, 1))
@ -274,20 +471,6 @@ namespace Esiur.Net.Packets
offset += 16;
}
else if (Action == IIPPacketAction.TemplateFromResourceLink)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceLink = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.TemplateFromResourceId)
{
if (NotEnough(offset, ends, 4))
@ -296,7 +479,7 @@ namespace Esiur.Net.Packets
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.ResourceIdFromResourceLink)
else if (Action == IIPPacketAction.QueryLink)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
@ -310,6 +493,30 @@ namespace Esiur.Net.Packets
ResourceLink = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.ResourceChildren
|| Action == IIPPacketAction.ResourceParents)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.ResourceHistory)
{
if (NotEnough(offset, ends, 20))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
FromDate = data.GetDateTime(offset);
offset += 8;
ToDate = data.GetDateTime(offset);
offset += 8;
}
else if (Action == IIPPacketAction.InvokeFunction)
{
if (NotEnough(offset, ends, 9))
@ -351,8 +558,8 @@ namespace Esiur.Net.Packets
MethodIndex = data[offset++];
ResourceAge = data.GetUInt32(offset);
offset += 4;
ResourceAge = data.GetUInt64(offset);
offset += 8;
}
else if (Action == IIPPacketAction.SetProperty)
@ -392,6 +599,26 @@ namespace Esiur.Net.Packets
offset += (uint)size;
}
}
// Attributes
else if (Action == IIPPacketAction.UpdateAllAttributes
|| Action == IIPPacketAction.GetAttributes
|| Action == IIPPacketAction.UpdateAttributes
|| Action == IIPPacketAction.ClearAttributes)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
}
else if (Command == IIPPacketCommand.Reply)
{
@ -405,8 +632,8 @@ namespace Esiur.Net.Packets
ClassId = data.GetGuid(offset);
offset += 16;
ResourceAge = data.GetUInt32(offset);
offset += 4;
ResourceAge = data.GetUInt64(offset);
offset += 8;
uint cl = data.GetUInt16(offset);
offset += 2;
@ -438,8 +665,8 @@ namespace Esiur.Net.Packets
if (NotEnough(offset, ends, 20))
return -dataLengthNeeded;
ClassId = data.GetGuid(offset);
offset += 16;
//ClassId = data.GetGuid(offset);
//offset += 16;
ResourceId = data.GetUInt32(offset);
offset += 4;
@ -449,10 +676,17 @@ namespace Esiur.Net.Packets
{
// nothing to do
}
// Inquire
else if (Action == IIPPacketAction.TemplateFromClassName
|| Action == IIPPacketAction.TemplateFromClassId
|| Action == IIPPacketAction.TemplateFromResourceLink
|| Action == IIPPacketAction.TemplateFromResourceId)
|| Action == IIPPacketAction.TemplateFromResourceId
|| Action == IIPPacketAction.QueryLink
|| Action == IIPPacketAction.ResourceChildren
|| Action == IIPPacketAction.ResourceParents
|| Action == IIPPacketAction.ResourceHistory
// Attribute
|| Action == IIPPacketAction.GetAllAttributes
|| Action == IIPPacketAction.GetAttributes)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
@ -466,20 +700,6 @@ namespace Esiur.Net.Packets
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.ResourceIdFromResourceLink)
{
if (NotEnough(offset, ends, 24))
return -dataLengthNeeded;
ClassId = data.GetGuid(offset);
offset += 16;
ResourceId = data.GetUInt32(offset);
offset += 4;
ResourceAge = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.InvokeFunction
|| Action == IIPPacketAction.GetProperty
|| Action == IIPPacketAction.GetPropertyIfModified)
@ -518,19 +738,56 @@ namespace Esiur.Net.Packets
// nothing to do
}
}
else if (Command == IIPPacketCommand.Error)
else if (Command == IIPPacketCommand.Report)
{
// Error
if (NotEnough(offset, ends, 4))
if (Report == IIPPacketReport.ManagementError)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
CallbackId = data.GetUInt32(offset);
ErrorCode = data.GetUInt16(offset);
offset += 2;
}
else if (Report == IIPPacketReport.ExecutionError)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
ErrorCode = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ErrorMessage = data.GetString(offset, cl);
offset += cl;
}
else if (Report == IIPPacketReport.ProgressReport)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ProgressValue = data.GetInt32(offset);
offset += 4;
ProgressMax = data.GetInt32(offset);
offset += 4;
}
else if (Report == IIPPacketReport.ChunkStream)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
ErrorCode = data[offset++];
var dt = (DataType)data[offset++];
var size = dt.Size();// Codec.SizeOf(dt);
if (size < 0)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
@ -540,11 +797,21 @@ namespace Esiur.Net.Packets
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ErrorMessage = data.GetString(offset, cl);
Content = data.Clip(offset - 5, cl + 5);
offset += cl;
}
else
{
if (NotEnough(offset, ends, (uint)size))
return -dataLengthNeeded;
return offset - oOffset;
Content = data.Clip(offset - 1, (uint)size + 1);
offset += (uint)size;
}
}
}
return offset - originalOffset;
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -138,6 +162,7 @@ namespace Esiur.Net.Packets
offset += 8;
}
/*
if (Mask)
{
MaskKey = new byte[4];
@ -149,6 +174,7 @@ namespace Esiur.Net.Packets
//MaskKey = DC.GetUInt32(data, offset);
//offset += 4;
}
*/
needed += PayloadLength;
if (length < needed)
@ -156,23 +182,26 @@ namespace Esiur.Net.Packets
//Console.WriteLine("stage 4");
return length - needed;
}
// if ((int)PayloadLength > (ends - offset))
// {
// return -((int)PayloadLength - (ends - offset));
// }
else
{
Message = DC.Clip(data, offset, (uint)PayloadLength);
if (Mask)
{
MaskKey = new byte[4];
MaskKey[0] = data[offset++];
MaskKey[1] = data[offset++];
MaskKey[2] = data[offset++];
MaskKey[3] = data[offset++];
Message = DC.Clip(data, offset, (uint)PayloadLength);
//var aMask = BitConverter.GetBytes(MaskKey);
for (int i = 0; i < Message.Length; i++)
{
Message[i] = (byte)(Message[i] ^ MaskKey[i % 4]);
}
}
else
Message = DC.Clip(data, offset, (uint)PayloadLength);
return (offset - oOffset) + (int)PayloadLength;
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -27,7 +51,7 @@ namespace Esiur.Net.Sockets
Queue<byte[]> sendBufferQueue = new Queue<byte[]>();
bool asyncSending;
bool began = false;
SocketState state = SocketState.Initial;
@ -36,6 +60,7 @@ namespace Esiur.Net.Sockets
public event ISocketCloseEvent OnClose;
public event DestroyedEvent OnDestroy;
SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs();
private void Connected(Task t)
{
@ -46,7 +71,18 @@ namespace Esiur.Net.Sockets
public bool Begin()
{
sock.ReceiveAsync(receiveBufferSegment, SocketFlags.None).ContinueWith(DataReceived);
if (began)
return false;
began = true;
socketArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
socketArgs.Completed += SocketArgs_Completed;
if (!sock.ReceiveAsync(socketArgs))
SocketArgs_Completed(null, socketArgs);
//sock.ReceiveAsync(receiveBufferSegment, SocketFlags.None).ContinueWith(DataReceived);
return true;
}
@ -80,11 +116,21 @@ namespace Esiur.Net.Sockets
return;
}
//if (receiveNetworkBuffer.Protected)
// Console.WriteLine();
//lock (receiveNetworkBuffer.SyncLock)
receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)task.Result);
//Console.WriteLine("TC IN: " + (uint)task.Result + " " + DC.ToHex(receiveBuffer, 0, (uint)task.Result));
OnReceive?.Invoke(receiveNetworkBuffer);
if (state == SocketState.Established)
{
sock.ReceiveAsync(receiveBufferSegment, SocketFlags.None).ContinueWith(DataReceived);
}
}
catch (Exception ex)
{
@ -98,6 +144,56 @@ namespace Esiur.Net.Sockets
}
}
private void SocketArgs_Completed(object sender, SocketAsyncEventArgs e)
{
try
{
// SocketError err;
if (state == SocketState.Closed || state == SocketState.Terminated)
return;
if (e.BytesTransferred == 0)
{
Close();
return;
}
//if (receiveNetworkBuffer.Protected)
// Console.WriteLine();
//lock (receiveNetworkBuffer.SyncLock)
receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)e.BytesTransferred);
//Console.WriteLine("TC IN: " + (uint)e.BytesTransferred + " " + DC.ToHex(receiveBuffer, 0, (uint)e.BytesTransferred));
OnReceive?.Invoke(receiveNetworkBuffer);
if (state == SocketState.Established)
{
if (!sock.ReceiveAsync(socketArgs))
{
//Console.WriteLine("Sync");
SocketArgs_Completed(sender, e);
}
}
}
catch (Exception ex)
{
if (state != SocketState.Closed && !sock.Connected)
{
state = SocketState.Terminated;
Close();
}
Global.Log("TCPSocket", LogType.Error, ex.ToString());
}
}
public IPEndPoint LocalEndPoint
{
@ -234,6 +330,7 @@ namespace Esiur.Net.Sockets
public void Send(byte[] message, int offset, int size)
{
if (sock.Connected)
lock (sendLock)
{
if (asyncSending)

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -9,6 +33,7 @@ using Esiur.Misc;
using System.IO;
using Esiur.Engine;
using Esiur.Resource;
using Esiur.Data;
namespace Esiur.Net.Sockets
{
@ -28,6 +53,8 @@ namespace Esiur.Net.Sockets
long totalSent, totalReceived;
bool processing = false;
public IPEndPoint LocalEndPoint
{
get { return (IPEndPoint)sock.LocalEndPoint; }
@ -70,9 +97,17 @@ namespace Esiur.Net.Sockets
if (buffer.Protected)
return;
if (processing)
return;
var msg = buffer.Read();
if (msg == null)
return;
var wsPacketLength = pkt_receive.Parse(msg, 0, (uint)msg.Length);
//Console.WriteLine("WSP: " + wsPacketLength);
if (wsPacketLength < 0)
{
@ -114,12 +149,16 @@ namespace Esiur.Net.Sockets
receiveNetworkBuffer.Write(pkt_receive.Message);
offset += (uint)wsPacketLength;
//Console.WriteLine("WS IN: " + pkt_receive.Opcode.ToString() + " " + pkt_receive.Message.Length + " | " + offset + " " + string.Join(" ", pkt_receive.Message));// DC.ToHex(pkt_receive.Message));
}
else
Console.WriteLine("Unknown WS opcode:" + pkt_receive.Opcode);
if (offset == msg.Length)
{
// Console.WriteLine("WS IN: " + receiveNetworkBuffer.Available);
OnReceive?.Invoke(receiveNetworkBuffer);
return;
}
@ -132,11 +171,18 @@ namespace Esiur.Net.Sockets
//receiveNetworkBuffer.HoldFor(msg, offset, (uint)(msg.Length - offset), (uint)msg.Length + (uint)-wsPacketLength);
// save the incomplete packet to the heldBuffer queue
receiveNetworkBuffer.HoldFor(msg, offset, (uint)(msg.Length - offset), (uint)(msg.Length - offset) + (uint)-wsPacketLength);
buffer.HoldFor(msg, offset, (uint)(msg.Length - offset), (uint)(msg.Length - offset) + (uint)-wsPacketLength);
}
//Console.WriteLine("WS IN: " + receiveNetworkBuffer.Available);
OnReceive?.Invoke(receiveNetworkBuffer);
processing = false;
if (buffer.Available > 0 && !buffer.Protected)
Sock_OnReceive(buffer);
}
private void Sock_OnConnect()

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,3 +1,27 @@
/*
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.Net;
using System.Net.Sockets;

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Release</Configuration>
<TargetFramework>netstandard1.5</TargetFramework>
<PublishDir>M:\opt\esiur</PublishDir>
<Platform>Any CPU</Platform>
</PropertyGroup>
</Project>

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,30 @@
using Esiur.Engine;
/*
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 Esiur.Data;
using Esiur.Engine;
using Esiur.Resource.Template;
using System;
using System.Collections.Generic;
using System.Linq;
@ -13,5 +39,15 @@ namespace Esiur.Resource
AsyncReply<IResource> Retrieve(uint iid);
bool Put(IResource resource);
string Link(IResource resource);
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 Remove(IResource resource);
//AsyncReply<PropertyValue[]> GetPropertyRecord(IResource resource, string propertyName, ulong fromAge, ulong toAge);
//AsyncReply<PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate);
//AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, ulong fromAge, ulong toAge);
// AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecordByDate(IResource resource, DateTime fromDate, DateTime toDate);
AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, DateTime fromDate, DateTime toDate);
}
}

View File

@ -10,6 +10,7 @@ using Esiur.Net.IIP;
using Esiur.Misc;
using Esiur.Security.Permissions;
using Esiur.Resource.Template;
using Esiur.Security.Authority;
namespace Esiur.Resource
{
@ -21,23 +22,29 @@ namespace Esiur.Resource
IResource resource;
IStore store;
AutoList<IResource, Instance> parents;// = new AutoList<IResource>();
bool inherit;
//bool inherit;
ResourceTemplate template;
AutoList<IPermissionManager, Instance> managers;// = new AutoList<IPermissionManager, Instance>();
AutoList<IPermissionsManager, Instance> managers;// = new AutoList<IPermissionManager, Instance>();
public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue);
//public delegate void ResourceEventOccurredEvent(IResource resource, string eventName, string[] users, DistributedConnection[] connections, object[] args);
public delegate void ResourceEventOccurredEvent(IResource resource, object issuer, Session[] receivers, string eventName, object[] args);
public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue, object oldValue);
public delegate void ResourceEventOccurredEvent(IResource resource, string eventName, string[] receivers, object[] args);
public delegate void ResourceDestroyedEvent(IResource resource);
public event ResourceModifiedEvent ResourceModified;
public event ResourceEventOccurredEvent ResourceEventOccured;
public event ResourceEventOccurredEvent ResourceEventOccurred;
public event ResourceDestroyedEvent ResourceDestroyed;
KeyList<string, object> attributes = new KeyList<string, object>();
KeyList<string, object> attributes;
List<uint> ages = new List<uint>();
private uint age;
List<ulong> ages = new List<ulong>();
List<DateTime> modificationDates = new List<DateTime>();
private ulong instanceAge;
private DateTime instanceModificationDate;
uint id;
@ -53,12 +60,151 @@ namespace Esiur.Resource
}
}
public override string ToString()
{
return name + " (" + Link + ")";
}
public bool RemoveAttributes(string[] attributes = null)
{
if (attributes == null)
this.attributes.Clear();
else
{
foreach (var attr in attributes)
this.attributes.Remove(attr);
}
return true;
}
public Structure GetAttributes(string[] attributes = null)
{
var st = new Structure();
if (attributes == null)
{
var clone = this.attributes.Keys.ToList();
clone.Add("managers");
attributes = clone.ToArray();// this.attributes.Keys.ToList().Add("managers");
}
foreach(var attr in attributes)
{
if (attr == "name")
st["name"] = this.name;
else if (attr == "managers")
{
var mngrs = new List<Structure>();
foreach (var manager in this.managers)
mngrs.Add(new Structure()
{
["type"] = manager.GetType().FullName + "," + manager.GetType().GetTypeInfo().Assembly.GetName().Name,
["settings"] = manager.Settings
});
st["managers"] = mngrs.ToArray();
}
else if (attr == "parents")
{
st["parents"] = parents.ToArray();
}
else if (attr == "children")
{
st["children"] = children.ToArray();
}
else if (attr == "childrenCount")
{
st["childrenCount"] = children.Count;
}
else if (attr == "type")
{
st["type"] = resource.GetType().FullName;
}
else
st[attr] = this.attributes[attr];
}
return st;
}
public bool SetAttributes(Structure attributes, bool clearAttributes = false)
{
try
{
if (clearAttributes)
this.attributes.Clear();
foreach (var attr in attributes)
if (attr.Key == "name")
this.name = attr.Value as string;
else if (attr.Key == "managers")
{
this.managers.Clear();
var mngrs = attr.Value as object[];
foreach (var mngr in mngrs)
{
var m = mngr as Structure;
var type = Type.GetType(m["type"] as string);
if (Codec.ImplementsInterface(type, typeof(IPermissionsManager)))
{
var settings = m["settings"] as Structure;
var manager = Activator.CreateInstance(type) as IPermissionsManager;
manager.Initialize(settings, this.resource);
this.managers.Add(manager);
}
else
return false;
}
}
else
{
this.attributes[attr.Key] = attr.Value;
}
}
catch
{
return false;
}
return true;
}
/*
public Structure GetAttributes()
{
var st = new Structure();
foreach (var a in attributes.Keys)
st[a] = attributes[a];
st["name"] = name;
var mngrs = new List<Structure>();
foreach (var manager in managers)
{
var mngr = new Structure();
mngr["settings"] = manager.Settings;
mngr["type"] = manager.GetType().FullName;
mngrs.Add(mngr);
}
st["managers"] = mngrs;
return st;
}*/
/// <summary>
/// Get the age of a given property index.
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <returns>Age.</returns>
public uint GetAge(byte index)
public ulong GetAge(byte index)
{
if (index < ages.Count)
return ages[index];
@ -67,12 +213,107 @@ namespace Esiur.Resource
}
/// <summary>
/// Age of the instance, increments by 1 in every modification.
/// Set the age of a property.
/// </summary>
public uint Age
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Age.</param>
public void SetAge(byte index, ulong value)
{
get { return age; }
internal set { age = value; }
if (index < ages.Count)
{
ages[index] = value;
if (value > instanceAge)
instanceAge = value;
}
}
/// <summary>
/// Set the modification date of a property.
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Modification date.</param>
public void SetModificationDate(byte index, DateTime value)
{
if (index < modificationDates.Count)
{
modificationDates[index] = value;
if (value > instanceModificationDate)
instanceModificationDate = value;
}
}
/// <summary>
/// Get modification date of a specific property.
/// </summary>
/// <param name="index">Zero-based property index</param>
/// <returns>Modification date.</returns>
public DateTime GetModificationDate(byte index)
{
if (index < modificationDates.Count)
return modificationDates[index];
else
return DateTime.MinValue;
}
/// <summary>
/// Load property value (used by stores)
/// </summary>
/// <param name="name">Property name</param>
/// <param name="age">Property age</param>
/// <param name="value">Property value</param>
/// <returns></returns>
public bool LoadProperty(string name, ulong age, DateTime modificationDate, object value)
{
var pt = template.GetPropertyTemplate(name);
if (pt == null)
return false;
#if NETSTANDARD1_5
var pi = resource.GetType().GetTypeInfo().GetProperty(name);
#else
var pi = resource.GetType().GetProperty(pt.Name);
#endif
if (pi.PropertyType == typeof(DistributedPropertyContext))
return false;
try
{
if (pi.CanWrite)
pi.SetValue(resource, DC.CastConvert(value, pi.PropertyType));
}
catch(Exception ex)
{
//Console.WriteLine(resource.ToString() + " " + name);
Global.Log(ex);
}
SetAge(pt.Index, age);
SetModificationDate(pt.Index, modificationDate);
return true;
}
/// <summary>
/// Age of the instance, incremented by 1 in every modification.
/// </summary>
public ulong Age
{
get { return instanceAge; }
internal set { instanceAge = value; }
}
/// <summary>
/// Last modification date.
/// </summary>
public DateTime ModificationDate
{
get
{
return instanceModificationDate;
}
}
/// <summary>
@ -88,18 +329,18 @@ namespace Esiur.Resource
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public bool Deserialize(object[] properties)
public bool Deserialize(PropertyValue[] properties)
{
foreach (var pt in template.Properties)
for (byte i = 0; i < properties.Length; i++)
{
#if NETSTANDARD1_5
var pi = resource.GetType().GetTypeInfo().GetProperty(pt.Name);
#else
var pi = resource.GetType().GetProperty(pt.Name);
#endif
if (!(properties[pt.Index] is NotModified))
pi.SetValue(resource, properties[pt.Index]);
var pt = this.template.GetPropertyTemplate(i);
if (pt != null)
{
var pv = properties[i];
LoadProperty(pt.Name, pv.Age, pv.Date, pv.Value);
}
}
return true;
}
@ -107,9 +348,9 @@ namespace Esiur.Resource
/// Export all properties with ResourceProperty attributed as bytes array.
/// </summary>
/// <returns></returns>
public object[] Serialize()
public PropertyValue[] Serialize()
{
List<object> props = new List<object>();
List<PropertyValue> props = new List<PropertyValue>();
foreach (var pt in template.Properties)
{
@ -119,7 +360,7 @@ namespace Esiur.Resource
var pi = resource.GetType().GetProperty(pt.Name);
#endif
var rt = pi.GetValue(resource, null);
props.Add(rt);
props.Add(new PropertyValue(rt, ages[pt.Index], modificationDates[pt.Index]));
}
return props.ToArray();
@ -207,27 +448,47 @@ namespace Esiur.Resource
}
internal void EmitModification(PropertyTemplate pt, object value)
{
instanceAge++;
var now = DateTime.UtcNow;
ages[pt.Index] = instanceAge;
modificationDates[pt.Index] = now;
if (pt.Storage == StorageMode.NonVolatile)
{
store.Modify(resource, pt.Name, value, ages[pt.Index], now);
}
else if (pt.Storage == StorageMode.Recordable)
{
store.Record(resource, pt.Name, value, ages[pt.Index], now);
}
ResourceModified?.Invoke(resource, pt.Name, value);
}
/// <summary>
/// Notify listeners that a property was modified.
/// </summary>
/// <param name="propertyName"></param>
/// <param name="newValue"></param>
/// <param name="oldValue"></param>
public void Modified([CallerMemberName] string propertyName = "", object newValue = null, object oldValue = null)
public void Modified([CallerMemberName] string propertyName = "")//, object newValue = null)//, object oldValue = null)
{
if (newValue == null)
object value;
if (GetPropertyValue(propertyName, out value))
{
object val;
if (GetPropertyValue(propertyName, out val))
ResourceModified?.Invoke(resource, propertyName, val, oldValue);
var pt = template.GetPropertyTemplate(propertyName);
EmitModification(pt, value);
}
else
ResourceModified?.Invoke(resource, propertyName, newValue, oldValue);
}
internal void EmitResourceEvent(string name, string[] receivers, object[] args)
// internal void EmitResourceEvent(string name, string[] users, DistributedConnection[] connections, object[] args)
internal void EmitResourceEvent(object issuer, Session[] receivers, string name, object[] args)
{
ResourceEventOccured?.Invoke(resource, name, receivers, args);
ResourceEventOccurred?.Invoke(resource, issuer, receivers, name, args);
}
/// <summary>
@ -269,10 +530,11 @@ namespace Esiur.Resource
}
/*
public bool Inherit
{
get { return inherit; }
}
}*/
/// <summary>
/// List of parents.
@ -335,6 +597,7 @@ namespace Esiur.Resource
public string Name
{
get { return name; }
set { name = value; }
}
@ -352,7 +615,47 @@ namespace Esiur.Resource
public ResourceTemplate Template
{
get { return template; }
/*
internal set
{
template = Warehouse.GetTemplate(resource.GetType());
// set ages
for (byte i = 0; i < template.Properties.Length; i++)
{
ages.Add(0);
modificationDates.Add(DateTime.MinValue);
}
}
*/
}
/// <summary>
/// Check for permission.
/// </summary>
/// <param name="session">Caller sessions.</param>
/// <param name="action">Action type</param>
/// <param name="member">Function, property or event to check for permission.</param>
/// <param name="inquirer">Permission inquirer.</param>
/// <returns>Ruling.</returns>
public Ruling Applicable(Session session, ActionType action, MemberTemplate member, object inquirer = null)
{
foreach (IPermissionsManager manager in managers)
{
var r = manager.Applicable(this.resource, session, action, member, inquirer);
if (r != Ruling.DontCare)
return r;
}
return Ruling.DontCare;
}
/// <summary>
/// Execution managers.
/// </summary>
public AutoList<IPermissionsManager, Instance> Managers => managers;
/// <summary>
/// Create new instance.
@ -361,28 +664,36 @@ namespace Esiur.Resource
/// <param name="name">Name of the instance.</param>
/// <param name="resource">Resource to manage.</param>
/// <param name="store">Store responsible for the resource.</param>
public Instance(uint id, string name, IResource resource, IStore store)
public Instance(uint id, string name, IResource resource, IStore store, ResourceTemplate customTemplate = null, ulong age = 0)
{
this.store = store;
this.resource = resource;
this.id = id;
this.name = name;
this.instanceAge = age;
this.attributes = new KeyList<string, object>(this);
children = new AutoList<IResource, Instance>(this);
parents = new AutoList<IResource, Instance>(this);
managers = new AutoList<IPermissionManager, Instance>(this);
managers = new AutoList<IPermissionsManager, Instance>(this);
children.OnAdd += Children_OnAdd;
children.OnRemoved += Children_OnRemoved;
parents.OnAdd += Parents_OnAdd;
parents.OnRemoved += Parents_OnRemoved;
resource.OnDestroy += Resource_OnDestroy;
template = Warehouse.GetTemplate(resource.GetType());
if (customTemplate != null)
this.template = customTemplate;
else
this.template = Warehouse.GetTemplate(resource.GetType());
// set ages
for (byte i = 0; i < template.Properties.Length; i++)
{
ages.Add(0);
modificationDates.Add(DateTime.MinValue);
}
// connect events
Type t = resource.GetType();
@ -396,16 +707,62 @@ namespace Esiur.Resource
foreach (var evt in events)
{
if (evt.EventHandlerType != typeof(ResourceEventHanlder))
continue;
//if (evt.EventHandlerType != typeof(ResourceEventHanlder))
// continue;
if (evt.EventHandlerType == typeof(ResourceEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
ResourceEventHanlder proxyDelegate = (receivers, args) => EmitResourceEvent(evt.Name, receivers, args);
ResourceEventHanlder proxyDelegate = (args) => EmitResourceEvent(null, null, evt.Name, args);
evt.AddEventHandler(resource, proxyDelegate);
}
else if (evt.EventHandlerType == typeof(CustomResourceEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
CustomResourceEventHanlder proxyDelegate = (issuer, receivers, args) => EmitResourceEvent(issuer, receivers, evt.Name, args);
evt.AddEventHandler(resource, proxyDelegate);
}
/*
else if (evt.EventHandlerType == typeof(CustomUsersEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
CustomUsersEventHanlder proxyDelegate = (users, args) => EmitResourceEvent(evt.Name, users, null, args);
evt.AddEventHandler(resource, proxyDelegate);
}
else if (evt.EventHandlerType == typeof(CustomConnectionsEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
CustomConnectionsEventHanlder proxyDelegate = (connections, args) => EmitResourceEvent(evt.Name, null, connections, args);
evt.AddEventHandler(resource, proxyDelegate);
}
else if (evt.EventHandlerType == typeof(CustomReceiversEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
CustomReceiversEventHanlder proxyDelegate = (users, connections, args) => EmitResourceEvent(evt.Name, users, connections, args);
evt.AddEventHandler(resource, proxyDelegate);
}
*/
}
}
@ -416,9 +773,22 @@ namespace Esiur.Resource
private void Children_OnAdd(Instance parent, IResource value)
{
if (!value.Instance.parents.Contains(resource))
value.Instance.parents.Add(resource);
}
private void Parents_OnRemoved(Instance parent, IResource value)
{
value.Instance.children.Remove(resource);
}
private void Parents_OnAdd(Instance parent, IResource value)
{
if (!value.Instance.children.Contains(resource))
value.Instance.children.Add(resource);
}
private void Resource_OnDestroy(object sender)
{
ResourceDestroyed?.Invoke((IResource)sender);

View File

@ -0,0 +1,47 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Engine;
namespace Esiur.Resource
{
public class Resource : IResource
{
public Instance Instance { get; set; }
public event DestroyedEvent OnDestroy;
public virtual void Destroy()
{
}
public virtual AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
return new AsyncReply<bool>(true);
}
}
}

View File

@ -1,4 +1,27 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,5 +1,30 @@
using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Engine;
using Esiur.Net.IIP;
using Esiur.Security.Authority;
using System;
using System.Collections.Generic;
using System.Linq;
@ -8,6 +33,13 @@ using System.Threading.Tasks;
namespace Esiur.Resource
{
public delegate void ResourceEventHanlder(string[] receivers, params object[] args);
public delegate void ResourceEventHanlder(params object[] args);
// public delegate void CustomUsersEventHanlder(string[] usernames, params object[] args);
//public delegate void CustomReceiversEventHanlder(DistributedConnection[] connections, params object[] args);
//public delegate void CustomInquirerEventHanlder(object inquirer, params object[] args);
public delegate void CustomResourceEventHanlder(object issuer, Session[] receivers, params object[] args);
// public delegate void CustomReceiversEventHanlder(string[] usernames, DistributedConnection[] connections, params object[] args);
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,29 @@
using System;
/*
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 Esiur.Resource.Template;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -12,7 +37,15 @@ namespace Esiur.Resource
{
string readExpansion;
string writeExpansion;
// bool recordable;
//bool storable;
//public bool Recordable => recordable;
//public bool Storable => storable;
StorageMode storage;
public StorageMode Storage => storage;
public string ReadExpansion
{
@ -30,10 +63,11 @@ namespace Esiur.Resource
}
}
public ResourceProperty(string readExpansion = null, string writeExpansion = null)
public ResourceProperty(StorageMode storage = StorageMode.Volatile, string readExpansion = null, string writeExpansion = null)
{
this.readExpansion = readExpansion;
this.writeExpansion = writeExpansion;
this.storage = storage;
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Engine;
using System;
using System.Collections.Generic;

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource
{
public enum StorageMode : byte
{
Volatile = 0,
NonVolatile,
Recordable
}
}

View File

@ -28,6 +28,11 @@ namespace Esiur.Resource.Template
return BinaryList.ToBytes((byte)0x40, (byte)name.Length, name);
}
public EventTemplate() { Type = MemberType.Event; }
public EventTemplate(ResourceTemplate template, byte index, string name, string expansion)
:base(template, MemberType.Property, index, name)
{
this.Expansion = expansion;
}
}
}

View File

@ -37,6 +37,11 @@ namespace Esiur.Resource.Template
}
public FunctionTemplate() { Type = MemberType.Function; }
public FunctionTemplate(ResourceTemplate template, byte index, string name,bool isVoid, string expansion)
:base(template, MemberType.Property, index, name)
{
this.IsVoid = isVoid;
this.Expansion = expansion;
}
}
}

View File

@ -16,9 +16,26 @@ namespace Esiur.Resource.Template
Event = 2,
}
public byte Index { get; set; }
public string Name { get; set; }
public MemberType Type { get; set; }
public byte Index => index;
public string Name => name;
public MemberType Type => type;
ResourceTemplate template;
string name;
MemberType type;
byte index;
public ResourceTemplate Template => template;
public MemberTemplate(ResourceTemplate 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()
{

View File

@ -16,6 +16,7 @@ namespace Esiur.Resource.Template
ReadWrite
}
//bool ReadOnly;
//IIPTypes::DataType ReturnType;
public PropertyPermission Permission {
@ -23,6 +24,19 @@ namespace Esiur.Resource.Template
set;
}
/*
public bool Recordable
{
get;
set;
}*/
public StorageMode Storage
{
get;
set;
}
public string ReadExpansion
{
get;
@ -35,37 +49,46 @@ namespace Esiur.Resource.Template
set;
}
/*
public bool Storable
{
get;
set;
}
}*/
public override byte[] Compose()
{
var name = base.Compose();
var pv = ((byte)(Permission) << 1) | (Storage == StorageMode.Recordable ? 1 : 0);
if (WriteExpansion != null && ReadExpansion != null)
{
var rexp = DC.ToBytes(ReadExpansion);
var wexp = DC.ToBytes(WriteExpansion);
return BinaryList.ToBytes((byte)(0x38 | (byte)Permission), wexp.Length, wexp, rexp.Length, rexp, (byte)name.Length, name);
return BinaryList.ToBytes((byte)(0x38 | pv), wexp.Length, wexp, rexp.Length, rexp, (byte)name.Length, name);
}
else if (WriteExpansion != null)
{
var wexp = DC.ToBytes(WriteExpansion);
return BinaryList.ToBytes((byte)(0x30 | (byte)Permission), wexp.Length, wexp, (byte)name.Length, name);
return BinaryList.ToBytes((byte)(0x30 | pv), wexp.Length, wexp, (byte)name.Length, name);
}
else if (ReadExpansion != null)
{
var rexp = DC.ToBytes(ReadExpansion);
return BinaryList.ToBytes((byte)(0x28 | (byte)Permission), rexp.Length, rexp, (byte)name.Length, name);
return BinaryList.ToBytes((byte)(0x28 | pv), rexp.Length, rexp, (byte)name.Length, name);
}
else
return BinaryList.ToBytes((byte)(0x20 | (byte)Permission), (byte)name.Length, name);
return BinaryList.ToBytes((byte)(0x20 | pv), (byte)name.Length, name);
}
public PropertyTemplate() { Type = MemberType.Property; }
public PropertyTemplate(ResourceTemplate template, byte index, string name, string read, string write, StorageMode storage)
:base(template, MemberType.Property, index, name)
{
//this.Recordable = recordable;
this.Storage = storage;
this.ReadExpansion = read;
this.WriteExpansion = write;
}
}
}

View File

@ -155,11 +155,7 @@ namespace Esiur.Resource.Template
var ps = (ResourceProperty[])pi.GetCustomAttributes(typeof(ResourceProperty), true);
if (ps.Length > 0)
{
var pt = new PropertyTemplate();
pt.Name = pi.Name;
pt.Index = i++;
pt.ReadExpansion = ps[0].ReadExpansion;
pt.WriteExpansion = ps[0].WriteExpansion;
var pt = new PropertyTemplate(this, i++, pi.Name, ps[0].ReadExpansion, ps[0].WriteExpansion, ps[0].Storage);
properties.Add(pt);
}
}
@ -171,10 +167,7 @@ namespace Esiur.Resource.Template
var es = (ResourceEvent[])ei.GetCustomAttributes(typeof(ResourceEvent), true);
if (es.Length > 0)
{
var et = new EventTemplate();
et.Name = ei.Name;
et.Index = i++;
et.Expansion = es[0].Expansion;
var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion);
events.Add(et);
}
}
@ -185,11 +178,7 @@ namespace Esiur.Resource.Template
var fs = (ResourceFunction[])mi.GetCustomAttributes(typeof(ResourceFunction), true);
if (fs.Length > 0)
{
var ft = new FunctionTemplate();
ft.Name = mi.Name;
ft.Index = i++;
ft.IsVoid = mi.ReturnType == typeof(void);
ft.Expansion = fs[0].Expansion;
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion);
functions.Add(ft);
}
}
@ -258,69 +247,76 @@ namespace Esiur.Resource.Template
if (type == 0) // function
{
var ft = new FunctionTemplate();
ft.Index = functionIndex++;
var expansion = ((data[offset] & 0x10) == 0x10);
ft.IsVoid = ((data[offset++] & 0x08) == 0x08);
ft.Name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
string expansion = null;
var hasExpansion = ((data[offset] & 0x10) == 0x10);
var isVoid = ((data[offset++] & 0x08) == 0x08);
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
if (expansion) // expansion ?
if (hasExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
offset += 4;
ft.Expansion = data.GetString(offset, cs);
expansion = data.GetString(offset, cs);
offset += cs;
}
var ft = new FunctionTemplate(od, functionIndex++, name, isVoid, expansion);
od.functions.Add(ft);
}
else if (type == 1) // property
{
var pt = new PropertyTemplate();
pt.Index = propertyIndex++;
var readExpansion = ((data[offset] & 0x8) == 0x8);
var writeExpansion = ((data[offset] & 0x10) == 0x10);
pt.Permission = (PropertyTemplate.PropertyPermission)((data[offset++] >> 1) & 0x3);
pt.Name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
string readExpansion = null, writeExpansion = null;
var hasReadExpansion = ((data[offset] & 0x8) == 0x8);
var hasWriteExpansion = ((data[offset] & 0x10) == 0x10);
var recordable = ((data[offset] & 1) == 1);
var permission = (PropertyTemplate.PropertyPermission)((data[offset++] >> 1) & 0x3);
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
if (readExpansion) // expansion ?
if (hasReadExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
offset += 4;
pt.ReadExpansion = data.GetString(offset, cs);
readExpansion = data.GetString(offset, cs);
offset += cs;
}
if (writeExpansion) // expansion ?
if (hasWriteExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
offset += 4;
pt.WriteExpansion = data.GetString(offset, cs);
writeExpansion = data.GetString(offset, cs);
offset += cs;
}
var pt = new PropertyTemplate(od, propertyIndex++, name, readExpansion, writeExpansion, recordable ? StorageMode.Recordable : StorageMode.Volatile);
od.properties.Add(pt);
}
else if (type == 2) // Event
{
var et = new EventTemplate();
et.Index = eventIndex++;
var expansion = ((data[offset++] & 0x10) == 0x10);
et.Name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
string expansion = null;
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
offset += (uint)data[offset] + 1;
if (expansion) // expansion ?
if (hasExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
offset += 4;
et.Expansion = data.GetString(offset, cs);
expansion = data.GetString(offset, cs);
offset += cs;
}
var et = new EventTemplate(od, eventIndex++, name, expansion);
od.events.Add(et);
}

View File

@ -1,6 +1,31 @@
using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Engine;
using Esiur.Resource.Template;
using Esiur.Security.Permissions;
using System;
using System.Collections.Generic;
using System.Linq;
@ -14,12 +39,20 @@ namespace Esiur.Resource
{
//static byte prefixCounter;
static List<IStore> stores = new List<IStore>();
static AutoList<IResource, Instance> stores = new AutoList<IResource, Instance>(null);
static Dictionary<uint, IResource> resources = new Dictionary<uint, IResource>();
static uint resourceCounter = 0;
static KeyList<Guid, ResourceTemplate> templates = new KeyList<Guid, ResourceTemplate>();
static bool storeIsOpen = false;
public delegate void StoreConnectedEvent(IStore store, string name);
public delegate void StoreDisconnectedEvent(IStore store);
public static event StoreConnectedEvent StoreConnected;
public static event StoreDisconnectedEvent StoreDisconnected;
/// <summary>
/// Get a store by its name.
@ -30,7 +63,7 @@ namespace Esiur.Resource
{
foreach (var s in stores)
if (s.Instance.Name == name)
return s;
return s as IStore;
return null;
}
@ -44,7 +77,7 @@ namespace Esiur.Resource
if (resources.ContainsKey(id))
return new AsyncReply<IResource>(resources[id]);
else
return null;
return new AsyncReply<IResource>(null);
}
/// <summary>
@ -59,8 +92,6 @@ namespace Esiur.Resource
foreach (var store in stores)
bag.Add(store.Trigger(ResourceTrigger.Initialize));
foreach (var store in stores)
bag.Add(store.Trigger(ResourceTrigger.SystemInitialized));
bag.Seal();
@ -74,7 +105,25 @@ namespace Esiur.Resource
return;
}
var rBag = new AsyncBag<bool>();
foreach (var rk in resources)
rBag.Add(rk.Value.Trigger(ResourceTrigger.SystemInitialized));
rBag.Seal();
rBag.Then(y =>
{
foreach (var b in y)
if (!b)
{
rt.Trigger(false);
return;
}
rt.Trigger(true);
storeIsOpen = true;
});
});
return rt;
@ -122,6 +171,63 @@ namespace Esiur.Resource
return rt;
}
private static IResource[] QureyIn(string[] path, int index, AutoList<IResource, Instance> resources)
{
var rt = new List<IResource>();
if (index == path.Length - 1)
{
if (path[index] == "")
foreach (IResource child in resources)
rt.Add(child);
else
foreach (IResource child in resources)
if (child.Instance.Name == path[index])
rt.Add(child);
}
else
foreach (IResource child in resources)
if (child.Instance.Name == path[index])
rt.AddRange(QureyIn(path, index+1, child.Instance.Children));
return rt.ToArray();
}
public static AsyncReply<IResource[]> Query(string path)
{
if (path == null || path == "")
{
var roots = stores.Where(s => s.Instance.Parents.Count == 0).ToArray();
return new AsyncReply<IResource[]>(roots);
}
else
{
var rt = new AsyncReply<IResource[]>();
Get(path).Then(x =>
{
var p = path.Split('/');
if (x == null)
{
rt.Trigger(QureyIn(p, 0, stores));
}
else
{
var ar = QureyIn(p, 0, stores).Where(r => r != x).ToList();
ar.Insert(0, x);
rt.Trigger(ar.ToArray());
}
});
return rt;
}
}
/// <summary>
/// Get a resource by its path.
/// Resource path is sperated by '/' character, e.g. "system/http".
@ -169,9 +275,12 @@ namespace Esiur.Resource
/// <param name="name">Resource name.</param>
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
public static void Put(IResource resource, string name, IStore store = null, IResource parent = null)
public static void Put(IResource resource, string name, IStore store = null, IResource parent = null, ResourceTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null)
{
resource.Instance = new Instance(resourceCounter++, name, resource, store);
resource.Instance = new Instance(resourceCounter++, name, resource, store, customTemplate, age);
if (manager != null)
resource.Instance.Managers.Add(manager);
if (store == parent)
parent = null;
@ -185,18 +294,26 @@ namespace Esiur.Resource
parent.Instance.Children.Add(resource);
if (resource is IStore)
{
stores.Add(resource as IStore);
StoreConnected?.Invoke(resource as IStore, name);
}
else
store.Put(resource);
resources.Add(resource.Instance.Id, resource);
if (!storeIsOpen)
resource.Trigger(ResourceTrigger.Initialize);
}
public static T New<T>(string name, IStore store = null, IResource parent = null)
public static T New<T>(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null)
{
var res = Activator.CreateInstance(typeof(T)) as IResource;
Put(res, name, store, parent);
Put(res, name, store, parent, null, 0, manager);
return (T)res;
}
@ -206,7 +323,7 @@ namespace Esiur.Resource
/// <param name="template">Resource template.</param>
public static void PutTemplate(ResourceTemplate template)
{
if (templates.ContainsKey(template.ClassId))
if (!templates.ContainsKey(template.ClassId))
templates.Add(template.ClassId, template);
}
@ -254,5 +371,36 @@ namespace Esiur.Resource
return null;
}
public static bool Remove(IResource resource)
{
if (resource.Instance == null)
return false;
if (resources.ContainsKey(resource.Instance.Id))
resources.Remove(resource.Instance.Id);
else
return false;
if (resource is IStore)
{
stores.Remove(resource as IStore);
// remove all objects associated with the store
var toBeRemoved = resources.Values.Where(x => x.Instance.Store == resource);
foreach (var o in toBeRemoved)
Remove(o);
StoreDisconnected?.Invoke(resource as IStore);
}
if (resource.Instance.Store != null)
resource.Instance.Store.Remove(resource);
resource.Destroy();
return true;
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,8 +32,8 @@ namespace Esiur.Security.Authority
{
public class AlienAuthentication : Authentication
{
public AlienAuthentication(Certificate certificate, AuthenticationState state) :
base(certificate, state, AuthenticationType.Alien)
public AlienAuthentication() :
base(AuthenticationType.Alien)
{
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,28 +32,31 @@ namespace Esiur.Security.Authority
{
public class Authentication
{
Certificate certificate;
AuthenticationState state;
AuthenticationType type;
public Certificate Certificate
{
get { return certificate; }
}
public string Username { get; set; }
public Certificate Certificate { get; set; }
public string Domain { get; set; }
public string FullName => Username + "@" + Domain;
public Source Source { get; } = new Source();
public AuthenticationState State
{
get { return state; }
get;
set;
}
public AuthenticationType Type
{
get { return type; }
get => type;
}
public Authentication(Certificate certificate, AuthenticationState state, AuthenticationType type)
public Authentication(AuthenticationType type)
{
this.type = type;
}
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Engine;
using Esiur.Misc;
using Esiur.Security.Cryptography;

View File

@ -1,4 +1,28 @@
using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Engine;
using Esiur.Misc;
using Esiur.Security.Cryptography;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,27 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,10 +31,42 @@ namespace Esiur.Security.Authority
{
public class ClientAuthentication : Authentication
{
public ClientAuthentication(byte[] credentials, UserCertificate certificate, AuthenticationState state)
: base(certificate, state, AuthenticationType.Client)
/*
string username;
byte[] password;
string domain;
byte[] token;
UserCertificate certificate;
public string Username => username;
public byte[] Password => password;
//public string Domain => domain;
public byte[] Token => token;
public byte[] Nounce { get; set; }
*/
public ClientAuthentication()
:base(AuthenticationType.Client)
{
}
/*
public ClientAuthentication(byte[] token)
: base(AuthenticationType.Client)
{
this.token = token;
}
public ClientAuthentication(string username, byte[] password)
: base(AuthenticationType.Client)
{
this.username = username;
this.password = password;
//this.domain = domain;
}
*/
}
}

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,8 +32,8 @@ namespace Esiur.Security.Authority
{
public class CoHostAuthentication : Authentication
{
public CoHostAuthentication(DomainCertificate certificate, AuthenticationState state)
: base(certificate, state, AuthenticationType.CoHost)
public CoHostAuthentication()
: base(AuthenticationType.CoHost)
{
}

View File

@ -1,4 +1,28 @@
using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Misc;
using Esiur.Security.Cryptography;
using Esiur.Security.Integrity;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,10 +32,12 @@ namespace Esiur.Security.Authority
{
public class HostAuthentication : Authentication
{
public HostAuthentication(DomainCertificate certificate, AuthenticationState state)
: base(certificate, state, AuthenticationType.Host)
public HostAuthentication()
:base(AuthenticationType.Host)
{
}
}
}

View File

@ -1,4 +1,27 @@
using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Engine;
using Esiur.Net;
using Esiur.Resource;
@ -12,12 +35,27 @@ namespace Esiur.Security.Authority
{
public class Session
{
Authentication Authentication { get; }
Source Source { get; }
string Id { get; }
DateTime Creation { get; }
DateTime Modification { get; }
public Authentication LocalAuthentication => localAuth;
public Authentication RemoteAuthentication => remoteAuth;
// public Source Source { get; }
public byte[] Id { get; set; }
public DateTime Creation { get; }
public DateTime Modification { get; }
public KeyList<string, object> Variables {get;} = new KeyList<string, object>();
//KeyList<string, object> Variables { get; }
//IStore Store { get; }
//string id;
Authentication localAuth, remoteAuth;
//string domain;
public Session(Authentication localAuthentication, Authentication remoteAuthentication)
{
this.localAuth = localAuthentication;
this.remoteAuth = remoteAuthentication;
}
}
}

View File

@ -1,4 +1,28 @@
using Esiur.Data;
/*
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 Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
@ -10,21 +34,26 @@ namespace Esiur.Security.Authority
public class Source
{
string id;
KeyList<SourceAttributeType, Structure> attributes;
//string id;
KeyList<SourceAttributeType, object> attributes;
string Id { get { return id; } }
public string Id { get; set; }
KeyList<SourceAttributeType, Structure> Attributes
public KeyList<SourceAttributeType, object> Attributes
{
get { return attributes; }
get => attributes;
}
public Source(string id, KeyList<SourceAttributeType, Structure> attributes)
public Source(string id, KeyList<SourceAttributeType, object> attributes)
{
this.id = id;
Id = id;
this.attributes = attributes;
}
public Source()
{
attributes = new KeyList<SourceAttributeType, object>();
}
}
}

View File

@ -1,4 +1,28 @@
using Esiur.Data;
/*
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 Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,7 +35,10 @@ namespace Esiur.Security.Authority
{
Mobility, // Stationary/Mobile
CPU, // Arc, Speed, Cores
IP, // IPv4, IPv6 Address
IPv4, // IPv4, IPv6 Address
IPv6, // IPv4, IPv6 Address
Port, // TCP or UDP port
Proxy, // Proxy
Route, // Trace Root
Location, // Lon, Lat, Alt, Accuracy
OS, // OS name, version, distro, kernel

View File

@ -1,4 +1,28 @@
using Esiur.Data;
/*
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 Esiur.Data;
using Esiur.Security.Cryptography;
using Esiur.Security.Integrity;
using System;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,27 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -1,4 +1,28 @@
using Esiur.Resource;
/*
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 Esiur.Resource;
using Esiur.Security.Authority;
using System;
using System.Collections.Generic;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -22,8 +46,10 @@ namespace Esiur.Security.Membership
//DomainCertificate[] GetDomainCertificates(string domain);
bool UserExists(string username);
AsyncReply<bool> UserExists(string username, string domain);
AsyncReply<byte[]> GetPassword(string username, string domain);
AsyncReply<bool> Login(Session session);
AsyncReply<bool> Logout(Session session);
//ClientAuthentication Authenticate(string username, byte[] credentials, int flag);
//HostAuthentication Authenticate(DomainCertificate domainCertificate);

View File

@ -1,4 +1,28 @@
using Esiur.Engine;
/*
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 Esiur.Engine;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -1,4 +1,28 @@
using System;
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -11,7 +35,16 @@ namespace Esiur.Security.Permissions
Attach,
Delete,
Execute,
Get,
Set,
GetProperty,
SetProperty,
CreateResource,
UpdateAttributes,
InquireAttributes,
AddParent,
RemoveParent,
AddChild,
RemoveChild,
Rename,
ReceiveEvent
}
}

View File

@ -1,18 +0,0 @@
using Esiur.Engine;
using Esiur.Net;
using Esiur.Resource;
using Esiur.Resource.Template;
using Esiur.Security.Authority;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Permissions
{
public interface IPermissionManager
{
bool Applicable(IResource resource, Session session, ActionType action, MemberTemplate member);
}
}

View File

@ -0,0 +1,56 @@
/*
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 Esiur.Data;
using Esiur.Engine;
using Esiur.Net;
using Esiur.Resource;
using Esiur.Resource.Template;
using Esiur.Security.Authority;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Permissions
{
public interface IPermissionsManager
{
/// <summary>
/// Check for permission.
/// </summary>
/// <param name="resource">IResource.</param>
/// <param name="session">Caller sessions.</param>
/// <param name="action">Action type</param>
/// <param name="member">Function, property or event to check for permission.</param>
/// <param name="inquirer">Permission inquirer object.</param>
/// <returns>Allowed or denined.</returns>
Ruling Applicable(IResource resource, Session session, ActionType action, MemberTemplate member, object inquirer = null);
bool Initialize(Structure settings, IResource resource);
Structure Settings { get; }
}
}

View File

@ -0,0 +1,60 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Data;
using Esiur.Engine;
using Esiur.Resource;
using Esiur.Resource.Template;
using Esiur.Security.Authority;
namespace Esiur.Security.Permissions
{
public class ParentalPermissionsManager : IPermissionsManager
{
Structure settings;
public Structure Settings => settings;
public Ruling Applicable(IResource resource, Session session, ActionType action, MemberTemplate member, object inquirer = null)
{
foreach (IResource parent in resource.Instance.Parents)
{
var ruling = parent.Instance.Applicable(session, action, member, inquirer);
if (ruling != Ruling.DontCare)
return ruling;
}
return Ruling.DontCare;
}
public bool Initialize(Structure settings, IResource resource)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Security.Permissions
{
public enum Ruling
{
Denied,
Allowed,
DontCare
}
}

Some files were not shown because too many files have changed in this diff Show More