diff --git a/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj b/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj index 68248ce..ba9a5a1 100644 --- a/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj +++ b/Esyur.Stores.EntityCore/Esyur.Stores.EntityCore.csproj @@ -3,6 +3,11 @@ netstandard2.0 Esyur.Stores.EntityCore + Ahmed Kh. Zamil + Esyur Foundation + Esyur for Entity Framework Core + Esyur Entity Framework Extension + true diff --git a/Esyur.Stores.EntityCore/EsyurExtensions.cs b/Esyur.Stores.EntityCore/EsyurExtensions.cs index 9c59ac6..7aede75 100644 --- a/Esyur.Stores.EntityCore/EsyurExtensions.cs +++ b/Esyur.Stores.EntityCore/EsyurExtensions.cs @@ -35,18 +35,28 @@ namespace Esyur.Stores.EntityCore { public static class EsyurExtensions { - public static T CreateResource(this DbContext dbContext) where T:IResource + public static T CreateResource(this DbContext dbContext, object properties = null) where T:class,IResource { - return dbContext.GetInfrastructure().CreateResource(); + return dbContext.GetInfrastructure().CreateResource(properties); } - public static T CreateResource(this IServiceProvider serviceProvider) where T:IResource + public static T CreateResource(this DbSet dbSet, object properties = null) where T:class,IResource + { + var resource = dbSet.GetInfrastructure().CreateResource(properties); + dbSet.Add(resource); + return resource; + } + + public static T CreateResource(this IServiceProvider serviceProvider, object properties = null) where T:class,IResource { var options = serviceProvider.GetService().FindExtension(); - var manager = options.Store.Instance.Managers.Count > 0 ? options.Store.Instance.Managers.First() : null; - return Warehouse.New("", options.Store, null, manager); + var resource = Warehouse.New("", options.Store, null, null, null, properties); + + resource.Instance.Managers.AddRange(options.Store.Instance.Managers.ToArray()); + + return resource; } public static DbContextOptionsBuilder UseEsyur(this DbContextOptionsBuilder optionsBuilder, diff --git a/Esyur.Stores.MongoDB/Esyur.Stores.MongoDB.csproj b/Esyur.Stores.MongoDB/Esyur.Stores.MongoDB.csproj index a8974b8..3a14028 100644 --- a/Esyur.Stores.MongoDB/Esyur.Stores.MongoDB.csproj +++ b/Esyur.Stores.MongoDB/Esyur.Stores.MongoDB.csproj @@ -11,7 +11,7 @@ http://www.esyur.com https://github.com/esyur/esyur-dotnet/ True - 1.3.3 + 1.4.0 diff --git a/Esyur.Stores.MongoDB/MongoDBStore.cs b/Esyur.Stores.MongoDB/MongoDBStore.cs index f00af1d..fe67528 100644 --- a/Esyur.Stores.MongoDB/MongoDBStore.cs +++ b/Esyur.Stores.MongoDB/MongoDBStore.cs @@ -51,15 +51,15 @@ namespace Esyur.Stores.MongoDB Dictionary resources = new Dictionary(); - [ResourceEvent] + [Public] public event ResourceEventHanlder ResourceAdded; - [ResourceEvent] + [Public] public event ResourceEventHanlder ResourceRemoved; int count = 0; - [ResourceProperty] + [Public] public virtual int Count { get @@ -109,7 +109,7 @@ namespace Esyur.Stores.MongoDB return true; } - [ResourceFunction] + [Public] public bool Remove(IResource resource) { var objectId = resource.Instance.Variables["objectId"].ToString(); @@ -510,11 +510,11 @@ namespace Esyur.Stores.MongoDB throw new NotImplementedException(); } - [ResourceAttribute] + [Attribute] public string Connection { get; set; } - [ResourceAttribute] + [Attribute] public string Collection { get; set; } - [ResourceAttribute] + [Attribute] public string Database { get; set; } public AsyncReply Trigger(ResourceTrigger trigger) { @@ -725,7 +725,7 @@ namespace Esyur.Stores.MongoDB AsyncReply> GetRecordByAge(IResource resource, ulong fromAge, ulong toAge) { - var properties = resource.Instance.Template.Properties.Where(x => x.Storage == StorageMode.Recordable).ToList(); + var properties = resource.Instance.Template.Properties.Where(x => x.Recordable).ToList(); var reply = new AsyncReply>(); @@ -751,7 +751,7 @@ namespace Esyur.Stores.MongoDB public AsyncReply> GetRecord(IResource resource, DateTime fromDate, DateTime toDate) { - var properties = resource.Instance.Template.Properties.Where(x => x.Storage == StorageMode.Recordable).ToList(); + var properties = resource.Instance.Template.Properties.Where(x => x.Recordable).ToList(); var reply = new AsyncReply>(); diff --git a/Esyur.Stores.MongoDB/MongoDBStoreGeneric.cs b/Esyur.Stores.MongoDB/MongoDBStoreGeneric.cs index e6d078f..1cc86a0 100644 --- a/Esyur.Stores.MongoDB/MongoDBStoreGeneric.cs +++ b/Esyur.Stores.MongoDB/MongoDBStoreGeneric.cs @@ -35,13 +35,15 @@ namespace Esyur.Stores.MongoDB { public class MongoDBStore : MongoDBStore where T:IResource { - [ResourceFunction] - public T Create(string name, Structure values) + [Public] + public T New(string name = null, object properties = null) { - return Warehouse.New(name, this, null, null, null, null, values); + var resource = Warehouse.New(name, this, null, null, null, properties); + resource.Instance.Managers.AddRange(this.Instance.Managers.ToArray()); + return resource; } - [ResourceFunction] + [Public] public async AsyncReply Slice(int index, int limit) { var list = await this.Instance.Children(); diff --git a/Esyur/Data/AutoList.cs b/Esyur/Data/AutoList.cs index 455ec61..6fcf4fa 100644 --- a/Esyur/Data/AutoList.cs +++ b/Esyur/Data/AutoList.cs @@ -32,7 +32,7 @@ using System.Reflection; namespace Esyur.Data { - public class AutoList : IEnumerable + public class AutoList : IEnumerable, ICollection, ICollection { private readonly object syncRoot = new object(); @@ -239,6 +239,10 @@ namespace Esyur.Data get { return list.Count; } } + public bool IsSynchronized => (list as ICollection).IsSynchronized; + + public bool IsReadOnly => throw new NotImplementedException(); + /// /// Check if an item exists in the list @@ -282,5 +286,20 @@ namespace Esyur.Data { return ((IEnumerable)list).GetEnumerator(); } + + public void CopyTo(Array array, int index) + { + (list as ICollection).CopyTo(array, index); + } + + public void CopyTo(T[] array, int arrayIndex) + { + list.CopyTo(array, arrayIndex); + } + + bool ICollection.Remove(T item) + { + return list.Remove(item); + } } } diff --git a/Esyur/Data/DataConverter.cs b/Esyur/Data/DataConverter.cs index c4ecff7..25c9c0a 100644 --- a/Esyur/Data/DataConverter.cs +++ b/Esyur/Data/DataConverter.cs @@ -43,13 +43,9 @@ namespace Esyur.Data { public static object CastConvert(object value, Type destinationType) { - if (value == null) return null; - //if (destinationType.IsArray && destinationType.GetElementType().IsArray) - // Console.Beep(); - var sourceType = value.GetType(); if (destinationType == sourceType) @@ -69,22 +65,6 @@ namespace Esyur.Data for (var i = 0; i < rt.Length; i++) { rt.SetValue(CastConvert(v.GetValue(i), destinationType), i); - - // try - // { - //#if NETSTANDARD - // if (destinationType.GetTypeInfo().IsInstanceOfType(v.GetValue(i))) - //#else - // if (destinationType.IsInstanceOfType(v.GetValue(i))) - //#endif - // rt.SetValue(v.GetValue(i), i); - // else - // rt.SetValue(Convert.ChangeType(v.GetValue(i), destinationType), i); - // } - // catch - // { - // rt.SetValue(null, i); - // } } return rt; @@ -94,8 +74,6 @@ namespace Esyur.Data { try { - - var underType = Nullable.GetUnderlyingType(destinationType); if (underType != null) { @@ -105,7 +83,6 @@ namespace Esyur.Data destinationType = underType; } - if (destinationType.IsInstanceOfType(value)) { return value; @@ -134,8 +111,6 @@ namespace Esyur.Data } - - public static byte[] ToBytes(sbyte value) { return new byte[1] { (byte)value }; @@ -602,8 +577,6 @@ namespace Esyur.Data return rt; } - - public static bool TryParse(object Input, out T Results) { try @@ -918,20 +891,6 @@ namespace Esyur.Data return rt; } - /* - public static PhysicalAddress GetPhysicalAddress(this byte[] data, uint offset) - { - return new PhysicalAddress(Clip(data, offset, 6)); - } - - public static PhysicalAddress[] GetPhysicalAddressArray(this byte[] data, uint offset, uint length) - { - var rt = new PhysicalAddress[length / 6]; - for (var i = 0; i < length; i += 6) - rt[i] = GetPhysicalAddress(data, (uint)(offset + i)); - return rt; - } - */ public static IPAddress GetIPv4Address(this byte[] data, uint offset) { return new IPAddress((long)GetUInt32(data, offset)); @@ -958,83 +917,7 @@ namespace Esyur.Data return rt; } - /* - public static T FromBytes(byte[] data, uint offset, uint length = 0) - { - if (typeof(T) == typeof(bool)) - { - return (T)(object)(data[offset] == 1); - } - else if (typeof(T) == typeof(byte)) - { - return (T)(object)data[offset]; - } - else if (typeof(T) == typeof(char)) - { - return (T)(object)BitConverter.ToChar(ReverseArray(data, offset, 2), 0); - } - else if (typeof(T) == typeof(short)) - { - return (T)(object)BitConverter.ToInt16(ReverseArray(data, offset, 2), 0); - } - else if (typeof(T) == typeof(ushort)) - { - return (T)(object)BitConverter.ToUInt16(ReverseArray(data, offset, 2), 0); - } - else if (typeof(T) == typeof(int)) - { - return (T)(object)BitConverter.ToInt32(ReverseArray(data, offset, 4), 0); - } - else if (typeof(T) == typeof(uint)) - { - return (T)(object)BitConverter.ToUInt32(ReverseArray(data, offset, 4), 0); - } - else if (typeof(T) == typeof(long)) - { - return (T)(object)BitConverter.ToInt64(ReverseArray(data, offset, 8), 0); - } - else if (typeof(T) == typeof(ulong)) - { - return (T)(object)BitConverter.ToUInt64(ReverseArray(data, offset, 8), 0); - } - else if (typeof(T) == typeof(float)) - { - return (T)(object)BitConverter.ToSingle(ReverseArray(data, offset, 4), 0); - } - else if (typeof(T) == typeof(double)) - { - return (T)(object)BitConverter.ToDouble(ReverseArray(data, offset, 8), 0); - } - else if (typeof(T) == typeof(string)) - { - return (T)(object)Encoding.UTF8.GetString(data, (int)offset, (int)length); - } - else if (typeof(T) == typeof(Guid)) - { - return (T)(object)new Guid(DC.Clip(data, offset, 16)); - } - else if (typeof(T) == typeof(IPAddress)) - { - if (length == 0) - return (T)(object)(new IPAddress((long)GetUInt32(data, offset))); - else - return (T)(object)(new IPAddress(Clip(data, offset, length))); - } - else if (typeof(T) == typeof(PhysicalAddress)) - { - return (T)(object)new PhysicalAddress(Clip(data, offset, 6)); - } - else if (typeof(T) == typeof(DateTime)) - { - long ticks = BitConverter.ToInt64(ReverseArray(data, offset, 8), 0); - return (T)(object)new DateTime(ticks, DateTimeKind.Utc); - } - else - { - return default(T); - } - } - */ + public static byte[] Clip(this byte[] data, uint offset, uint length) { diff --git a/Esyur/Data/ResourceList.cs b/Esyur/Data/ResourceList.cs new file mode 100644 index 0000000..eb9e3bd --- /dev/null +++ b/Esyur/Data/ResourceList.cs @@ -0,0 +1,274 @@ +/* + +Copyright (c) 2020 Ahmed Kh. Zamil + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections; +using Esyur.Core; +using System.Reflection; + +namespace Esyur.Data +{ + public class ResourceList : IEnumerable, ICollection, ICollection + { + + private readonly object syncRoot = new object(); + private List list = new List(); + + public delegate void Modified(ST sender, int index, T oldValue, T newValue); + public delegate void Added(ST sender, T value); + public delegate void Removed(ST sender, int index, T value); + public delegate void Cleared(ST sender); + + + public event Modified OnModified; + public event Removed OnRemoved; + public event Cleared OnCleared; + public event Added OnAdd; + + ST state; + + public void Sort() + { + list.Sort(); + } + + public void Sort(IComparer comparer) + { + list.Sort(comparer); + } + + public void Sort(Comparison comparison) + { + list.Sort(comparison); + } + + public IEnumerable Where(Func predicate) + { + return list.Where(predicate); + } + + /// + /// Convert AutoList to array + /// + /// Array + public T[] ToArray() + { + // list.OrderBy() + return list.ToArray(); + } + + /// + /// Create a new instance of AutoList + /// + /// State object to be included when an event is raised. + public ResourceList(ST state) + { + this.state = state; + } + + /// + /// Create a new instance of AutoList + /// + /// Populate the list with items + /// + public ResourceList(ST state, T[] values) + { + this.state = state; + AddRange(values); + } + + /// + /// Synchronization lock of the list + /// + public object SyncRoot + { + get + { + return syncRoot; + } + } + + /// + /// First item in the list + /// + public T First() + { + return list.First(); + } + + /// + /// Get an item at a specified index + /// + public T this[int index] + { + get + { + return list[index]; + } + set + { + var oldValue = list[index]; + + lock (syncRoot) + list[index] = value; + + OnModified?.Invoke(state, index, oldValue, value); + } + } + + /// + /// Add item to the list + /// + public void Add(T value) + { + lock (syncRoot) + list.Add(value); + + OnAdd?.Invoke(state, value); + } + + /// + /// Add an array of items to the list + /// + public void AddRange(T[] values) + { + foreach (var v in values) + Add(v); + } + + private void ItemDestroyed(object sender) + { + Remove((T)sender); + } + + /// + /// Clear the list + /// + public void Clear() + { + + lock (syncRoot) + list.Clear(); + + OnCleared?.Invoke(state); + } + + /// + /// Remove an item from the list + /// Item to remove + /// + public void Remove(T value) + { + var index = 0; + + lock (syncRoot) + { + index = list.IndexOf(value); + + if (index == -1) + return; + + list.RemoveAt(index); + + + } + + OnRemoved?.Invoke(state, index, value); + } + + /// + /// Number of items in the list + /// + public int Count + { + get { return list.Count; } + } + + public bool IsSynchronized => (list as ICollection).IsSynchronized; + + public bool IsReadOnly => throw new NotImplementedException(); + + + /// + /// Check if an item exists in the list + /// + /// Item to check if exists + public bool Contains(T value) + { + return list.Contains(value); + } + + /// + /// Check if any item of the given array is in the list + /// + /// Array of items + public bool ContainsAny(T[] values) + { + foreach (var v in values) + if (list.Contains(v)) + return true; + return false; + } + + /// + /// Check if any item of the given list is in the list + /// + /// List of items + public bool ContainsAny(AutoList values) + { + foreach (var v in values) + if (list.Contains((T)v)) + return true; + return false; + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)list).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)list).GetEnumerator(); + } + + public void CopyTo(Array array, int index) + { + (list as ICollection).CopyTo(array, index); + } + + public void CopyTo(T[] array, int arrayIndex) + { + list.CopyTo(array, arrayIndex); + } + + bool ICollection.Remove(T item) + { + return list.Remove(item); + } + } +} diff --git a/Esyur/Esyur.csproj b/Esyur/Esyur.csproj index ccfb857..82b6558 100644 --- a/Esyur/Esyur.csproj +++ b/Esyur/Esyur.csproj @@ -7,7 +7,7 @@ https://github.com/Esyur/Esyur-dotnet/blob/master/LICENSE http://www.esyur.com true - 1.4.9 + 1.5.0 https://github.com/esyur/esyur-dotnet Ahmed Kh. Zamil 1.3.1.0 @@ -29,7 +29,9 @@ - + + + @@ -40,7 +42,9 @@ - + + + diff --git a/Esyur/Net/HTTP/HTTPConnection.cs b/Esyur/Net/HTTP/HTTPConnection.cs index e613771..991f6d5 100644 --- a/Esyur/Net/HTTP/HTTPConnection.cs +++ b/Esyur/Net/HTTP/HTTPConnection.cs @@ -141,6 +141,12 @@ namespace Esyur.Net.HTTP } } + public void Send(WebsocketPacket packet) + { + if (packet.Data != null) + base.Send(packet.Data); + } + public override void Send(string data) { Response.Message = Encoding.UTF8.GetBytes(data); diff --git a/Esyur/Net/HTTP/HTTPServer.cs b/Esyur/Net/HTTP/HTTPServer.cs index 3514e8b..0faa12a 100644 --- a/Esyur/Net/HTTP/HTTPServer.cs +++ b/Esyur/Net/HTTP/HTTPServer.cs @@ -44,7 +44,7 @@ namespace Esyur.Net.HTTP public class HTTPServer : NetworkServer, IResource { Dictionary sessions= new Dictionary(); - HTTPFilter[] filters = null; + HTTPFilter[] filters = new HTTPFilter[0]; public Instance Instance { @@ -52,63 +52,55 @@ namespace Esyur.Net.HTTP set; } - [Storable] - public virtual string ip - { - get; - set; - } - [Storable] - public virtual ushort port + [Attribute] + public virtual string IP { get; set; } - [Storable] - public virtual uint timeout + [Attribute] + public virtual ushort Port { get; set; } - [Storable] - public virtual uint clock + [Attribute] + public virtual uint Timeout { get; set; } - [Storable] - public virtual uint maxPost + [Attribute] + public virtual uint Clock { get; set; } - [Storable] - public virtual bool ssl + [Attribute] + public virtual uint MaxPost { get; set; } - [Storable] - public virtual string certificate + [Attribute] + public virtual bool SSL { get; set; } - //public override void ClientConnected(TClient Sender) - //{ - //} - /* - public DStringDictionary Configurations + [Attribute] + public virtual string Certificate { - get { return config; } + get; + set; } - */ + public enum ResponseCodes : int { @@ -118,7 +110,7 @@ namespace Esyur.Net.HTTP HTTP_MOVED = 301, HTTP_NOTMODIFIED = 304, HTTP_REDIRECT = 307 - } + } public HTTPSession CreateSession(string id, int timeout) @@ -132,27 +124,6 @@ namespace Esyur.Net.HTTP return s; } - - - /* - protected override void SessionModified(NetworkSession session, string key, object oldValue, object newValue) - { - foreach (var instance in Instance.Children) - { - var f = (HTTPFilter)instance; - f.SessionModified(session as HTTPSession, key, oldValue, newValue); - } - } - */ - - //public override object InitializeLifetimeService() - //{ - // return null; - //} - - - - public static string MakeCookie(string Item, string Value, DateTime Expires, string Domain, string Path, bool HttpOnly) { @@ -183,7 +154,7 @@ namespace Esyur.Net.HTTP protected override void ClientDisconnected(HTTPConnection sender) { //Console.WriteLine("OUT: " + this.Connections.Count); - + foreach (var filter in filters) filter.ClientDisconnected(sender); } @@ -222,11 +193,11 @@ namespace Esyur.Net.HTTP } else if (BL > 0) { - if (BL > maxPost) + if (BL > MaxPost) { sender.Send( "POST method content is larger than " - + maxPost + + MaxPost + " bytes."); sender.Close(); @@ -326,7 +297,7 @@ namespace Esyur.Net.HTTP */ - public AsyncReply Trigger(ResourceTrigger trigger) + public async AsyncReply Trigger(ResourceTrigger trigger) { if (trigger == ResourceTrigger.Initialize) @@ -341,19 +312,19 @@ namespace Esyur.Net.HTTP ISocket listener; IPAddress ipAdd; - if (ip == null) + if (IP == null) ipAdd = IPAddress.Any; else - ipAdd = IPAddress.Parse(ip); + ipAdd = IPAddress.Parse(IP); // if (ssl) // listener = new SSLSocket(new IPEndPoint(ipAdd, port), new X509Certificate2(certificate)); // else - listener = new TCPSocket(new IPEndPoint(ipAdd, port)); + listener = new TCPSocket(new IPEndPoint(ipAdd, Port)); Start(listener, - timeout, - clock); + Timeout, + Clock); } else if (trigger == ResourceTrigger.Terminate) { @@ -361,15 +332,15 @@ namespace Esyur.Net.HTTP } else if (trigger == ResourceTrigger.SystemReload) { - Trigger(ResourceTrigger.Terminate); - Trigger(ResourceTrigger.Initialize); + await Trigger(ResourceTrigger.Terminate); + await Trigger(ResourceTrigger.Initialize); } else if (trigger == ResourceTrigger.SystemInitialized) { - Instance.Children().Then(x => filters = x); + filters = await Instance.Children(); } - return new AsyncReply(true); + return true; } @@ -380,7 +351,7 @@ namespace Esyur.Net.HTTP sender.SetParent(this); //Console.WriteLine("IN: " + this.Connections.Count); - if (filters == null) + if (filters.Length == 0) { sender.Close(); return; diff --git a/Esyur/Net/HTTP/IIPoWS.cs b/Esyur/Net/HTTP/IIPoWS.cs index 25f563c..2e8bc81 100644 --- a/Esyur/Net/HTTP/IIPoWS.cs +++ b/Esyur/Net/HTTP/IIPoWS.cs @@ -36,8 +36,8 @@ namespace Esyur.Net.HTTP { public class IIPoWS: HTTPFilter { - [ResourceProperty] - public DistributedServer DistributedServer + [Attribute] + public DistributedServer Server { get; set; @@ -48,7 +48,7 @@ namespace Esyur.Net.HTTP if (sender.IsWebsocketRequest()) { - if (DistributedServer == null) + if (Server == null) return false; var tcpSocket = sender.Unassign(); @@ -62,7 +62,7 @@ namespace Esyur.Net.HTTP var iipConnection = new DistributedConnection(); - DistributedServer.AddConnection(iipConnection); + Server.AddConnection(iipConnection); iipConnection.Assign(wsSocket); wsSocket.Begin(); diff --git a/Esyur/Net/IIP/DistributedConnection.cs b/Esyur/Net/IIP/DistributedConnection.cs index 4f00c46..5d8dc67 100644 --- a/Esyur/Net/IIP/DistributedConnection.cs +++ b/Esyur/Net/IIP/DistributedConnection.cs @@ -801,13 +801,13 @@ namespace Esyur.Net.IIP } - [ResourceAttribute] + [Attribute] public string Username { get; set; } - [ResourceAttribute] + [Attribute] public string Password { get; set; } - [ResourceAttribute] + [Attribute] public string Domain { get; set; } /// /// Resource interface diff --git a/Esyur/Net/IIP/DistributedServer.cs b/Esyur/Net/IIP/DistributedServer.cs index 5ffaf1f..1afc275 100644 --- a/Esyur/Net/IIP/DistributedServer.cs +++ b/Esyur/Net/IIP/DistributedServer.cs @@ -39,48 +39,44 @@ namespace Esyur.Net.IIP { public class DistributedServer : NetworkServer, IResource { - - //[Storable] - //[ResourceProperty] - public string ip + [Attribute] + public string IP { get; set; } - //[Storable] - //[ResourceProperty] + [Attribute] public IMembership Membership { get; set; } + [Attribute] public EntryPoint EntryPoint { get; set; } - //[Storable] - //[ResourceProperty] - public ushort port + [Attribute] + public ushort Port { get; set; } - //[Storable] - //[ResourceProperty] - public uint timeout + [Attribute] + public uint Timeout { get; set; } - //[Storable] - //[ResourceProperty] - public uint clock + + [Attribute] + public uint Clock { get; set; @@ -99,12 +95,12 @@ namespace Esyur.Net.IIP { TCPSocket listener; - if (ip != null) - listener = new TCPSocket(new IPEndPoint(IPAddress.Parse(ip), port)); + if (IP != null) + listener = new TCPSocket(new IPEndPoint(IPAddress.Parse(IP), Port)); else - listener = new TCPSocket(new IPEndPoint(IPAddress.Any, port)); + listener = new TCPSocket(new IPEndPoint(IPAddress.Any, Port)); - Start(listener, timeout, clock); + Start(listener, Timeout, Clock); } else if (trigger == ResourceTrigger.Terminate) { diff --git a/Esyur/Net/IIP/EntryPoint.cs b/Esyur/Net/IIP/EntryPoint.cs index dd11c83..ea908d5 100644 --- a/Esyur/Net/IIP/EntryPoint.cs +++ b/Esyur/Net/IIP/EntryPoint.cs @@ -35,6 +35,6 @@ namespace Esyur.Net.IIP { public abstract AsyncReply Query(string path, DistributedConnection sender); - public abstract override bool Create(); + protected abstract override bool Create(); } } diff --git a/Esyur/Net/NetworkServer.cs b/Esyur/Net/NetworkServer.cs index 80fe22d..1349856 100644 --- a/Esyur/Net/NetworkServer.cs +++ b/Esyur/Net/NetworkServer.cs @@ -31,18 +31,19 @@ using Esyur.Core; using Esyur.Net.Sockets; using Esyur.Resource; using System.Threading.Tasks; +using System.Diagnostics; namespace Esyur.Net { - public abstract class NetworkServer: IDestructible where TConnection : NetworkConnection, new() + public abstract class NetworkServer : IDestructible where TConnection : NetworkConnection, new() { //private bool isRunning; uint clock; private ISocket listener; private AutoList> connections; - //private Thread thread; + private Thread thread; protected abstract void DataReceived(TConnection sender, NetworkBuffer data); protected abstract void ClientConnected(TConnection sender); @@ -102,18 +103,18 @@ namespace Esyur.Net } */ - /* - protected virtual void SessionModified(NetworkSession session, string key, object oldValue, object newValue) - { + /* + protected virtual void SessionModified(NetworkSession session, string key, object oldValue, object newValue) + { - } + } - protected virtual void SessionEnded(NetworkSession session) - { - Sessions.Remove(session.Id); - session.Destroy(); - } - */ + protected virtual void SessionEnded(NetworkSession session) + { + Sessions.Remove(session.Id); + session.Destroy(); + } + */ private void MinuteThread(object state) { @@ -179,14 +180,21 @@ namespace Esyur.Net listener = socket; // Start accepting - var r = listener.Accept(); - r.Then(NewConnection); + //var r = listener.Accept(); + //r.Then(NewConnection); //r.timeout?.Dispose(); //var rt = listener.Accept().Then() - //thread = new Thread(new System.Threading.ThreadStart(ListenForConnections)); + thread = new Thread(new ThreadStart(() => + { + while (true) + { + var s = listener.Accept(); + NewConnection(s); + } + })); - //thread.Start(); + thread.Start(); } @@ -221,7 +229,7 @@ namespace Esyur.Net // wait until the listener stops //while (isRunning) //{ - // Thread.Sleep(100); + // Thread.Sleep(100); //} //Console.WriteLine("Listener stopped"); @@ -230,8 +238,8 @@ namespace Esyur.Net //lock (connections.SyncRoot) //{ - foreach (TConnection con in cons) - con.Close(); + foreach (TConnection con in cons) + con.Close(); //} //Console.WriteLine("Sockets Closed"); @@ -268,48 +276,35 @@ namespace Esyur.Net private void NewConnection(ISocket sock) { - try { - /* - if (listener.State == SocketState.Closed || listener.State == SocketState.Terminated) - { - Console.WriteLine("Listen socket break "); - Console.WriteLine(listener.LocalEndPoint.Port); - break; - } - */ - - if (sock == null) - { - //Console.Write("sock == null"); - return; - } - - //sock.ReceiveBufferSize = 102400; - //sock.SendBufferSize = 102400; + + if (sock == null) + { + Console.Write("sock == null"); + return; + } - TConnection c = new TConnection(); - AddConnection(c); + TConnection c = new TConnection(); + AddConnection(c); - c.Assign(sock); + c.Assign(sock); - try - { - ClientConnected(c); - } - catch - { - // something wrong with the child. - } + try + { + ClientConnected(c); + } + catch + { + // something wrong with the child. + } + // Accept more - listener.Accept().Then(NewConnection); - //l.timeout?.Dispose(); - - sock.Begin(); + //listener.Accept().Then(NewConnection); + sock.Begin(); } @@ -332,7 +327,7 @@ namespace Esyur.Net //isRunning; } } - + public void OnDataReceived(NetworkConnection sender, NetworkBuffer data) { DataReceived((TConnection)sender, data); @@ -372,7 +367,7 @@ namespace Esyur.Net GC.Collect(); } - + public void Destroy() { Stop(); diff --git a/Esyur/Net/Sockets/ISocket.cs b/Esyur/Net/Sockets/ISocket.cs index cde8e98..434dbae 100644 --- a/Esyur/Net/Sockets/ISocket.cs +++ b/Esyur/Net/Sockets/ISocket.cs @@ -58,7 +58,9 @@ namespace Esyur.Net.Sockets AsyncReply Connect(string hostname, ushort port); bool Begin(); //ISocket Accept(); - AsyncReply Accept(); + AsyncReply AcceptAsync(); + ISocket Accept(); + IPEndPoint RemoteEndPoint { get; } IPEndPoint LocalEndPoint { get; } diff --git a/Esyur/Net/Sockets/SSLSocket.cs b/Esyur/Net/Sockets/SSLSocket.cs index b25f7b5..d7187bb 100644 --- a/Esyur/Net/Sockets/SSLSocket.cs +++ b/Esyur/Net/Sockets/SSLSocket.cs @@ -311,24 +311,26 @@ namespace Esyur.Net.Sockets OnDestroy?.Invoke(this); } - public AsyncReply Accept() + public async AsyncReply AcceptAsync() { - var reply = new AsyncReply(); + //var reply = new AsyncReply(); try { - sock.AcceptAsync().ContinueWith((x) => - { - try - { - reply.Trigger(new SSLSocket(x.Result, cert, true)); - } - catch - { - reply.Trigger(null); - } + return new SSLSocket(await sock.AcceptAsync(), cert, true); - }, null); + //sock.AcceptAsync().ContinueWith((x) => + //{ + // try + // { + // reply.Trigger(new SSLSocket(x.Result, cert, true)); + // } + // catch + // { + // reply.Trigger(null); + // } + + //}, null); } catch @@ -337,7 +339,7 @@ namespace Esyur.Net.Sockets return null; } - return reply; + //return reply; } public void Hold() @@ -354,5 +356,18 @@ namespace Esyur.Net.Sockets { throw new NotImplementedException(); } + + public ISocket Accept() + { + try + { + return new SSLSocket(sock.Accept(), cert, true); + } + catch + { + state = SocketState.Terminated; + return null; + } + } } } \ No newline at end of file diff --git a/Esyur/Net/Sockets/TCPSocket.cs b/Esyur/Net/Sockets/TCPSocket.cs index 078973d..c1ed314 100644 --- a/Esyur/Net/Sockets/TCPSocket.cs +++ b/Esyur/Net/Sockets/TCPSocket.cs @@ -178,7 +178,9 @@ namespace Esyur.Net.Sockets //lock (receiveNetworkBuffer.SyncLock) // Console.WriteLine(e. + " " + e.BytesTransferred); - receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)e.BytesTransferred); + var recCount = e.BytesTransferred > e.Count ? e.Count : e.BytesTransferred; + + receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)recCount); //Console.WriteLine("TC IN: " + (uint)e.BytesTransferred + " " + DC.ToHex(receiveBuffer, 0, (uint)e.BytesTransferred)); @@ -365,7 +367,15 @@ namespace Esyur.Net.Sockets else { asyncSending = true; - sock.BeginSend(msg, 0, msg.Length, SocketFlags.None, PacketSent, null); + try + { + sock.BeginSend(msg, 0, msg.Length, SocketFlags.None, PacketSent, null); + } + catch { + asyncSending = false; + state = SocketState.Terminated; + Close(); + } //sock.SendAsync(new ArraySegment(msg), SocketFlags.None).ContinueWith(DataSent); } } @@ -403,7 +413,7 @@ namespace Esyur.Net.Sockets } catch (Exception ex2) { - Console.WriteLine("Level 2 {0}", ex2); + state = SocketState.Terminated; } Global.Log("TCPSocket", LogType.Error, ex.ToString()); @@ -427,33 +437,35 @@ namespace Esyur.Net.Sockets OnDestroy?.Invoke(this); } - public AsyncReply Accept() + public ISocket Accept() { - var reply = new AsyncReply(); - try { - sock.AcceptAsync().ContinueWith((x) => - { - try - { - reply.Trigger(new TCPSocket(x.Result)); - } - catch - { - reply.Trigger(null); - } - }); + var s = sock.Accept(); + return new TCPSocket(s); } catch { state = SocketState.Terminated; return null; } - - return reply; } + public async AsyncReply AcceptAsync() + { + try + { + var s = await sock.AcceptAsync(); + return new TCPSocket(s); + } + catch + { + state = SocketState.Terminated; + return null; + } + } + + public void Hold() { held = true; @@ -494,12 +506,23 @@ namespace Esyur.Net.Sockets else { asyncSending = true; - sock.BeginSend(msg, 0, msg.Length, SocketFlags.None, PacketSent, rt);// null); + try + { + sock.BeginSend(msg, 0, msg.Length, SocketFlags.None, PacketSent, rt);// null); + } + catch + { + asyncSending = false; + state = SocketState.Terminated; + Close(); + } //sock.SendAsync(new ArraySegment(msg), SocketFlags.None).ContinueWith(DataSent); } return rt; } } + + } } \ No newline at end of file diff --git a/Esyur/Net/Sockets/WSSocket.cs b/Esyur/Net/Sockets/WSSocket.cs index a6345df..715c552 100644 --- a/Esyur/Net/Sockets/WSSocket.cs +++ b/Esyur/Net/Sockets/WSSocket.cs @@ -63,13 +63,13 @@ namespace Esyur.Net.Sockets get { return (IPEndPoint)sock.LocalEndPoint; } } - - - public IPEndPoint RemoteEndPoint - { - get { return sock.RemoteEndPoint; } - } - + + + public IPEndPoint RemoteEndPoint + { + get { return sock.RemoteEndPoint; } + } + public SocketState State { @@ -79,7 +79,7 @@ namespace Esyur.Net.Sockets } } - + public WSSocket(ISocket socket) { pkt_send.FIN = true; @@ -103,7 +103,7 @@ namespace Esyur.Net.Sockets if (processing) return; - + var msg = buffer.Read(); if (msg == null) @@ -161,7 +161,7 @@ namespace Esyur.Net.Sockets if (offset == msg.Length) { - // Console.WriteLine("WS IN: " + receiveNetworkBuffer.Available); + // Console.WriteLine("WS IN: " + receiveNetworkBuffer.Available); OnReceive?.Invoke(receiveNetworkBuffer); return; } @@ -200,14 +200,14 @@ namespace Esyur.Net.Sockets public void Send(WebsocketPacket packet) { - lock(sendLock) + lock (sendLock) if (packet.Compose()) sock.Send(packet.Data); } public void Send(byte[] message) { - lock(sendLock) + lock (sendLock) { if (held) { @@ -219,13 +219,16 @@ namespace Esyur.Net.Sockets //Console.WriteLine("TX " + message.Length +"/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size)); pkt_send.Message = message; + + if (pkt_send.Compose()) sock.Send(pkt_send.Data); + } } } - + public void Send(byte[] message, int offset, int size) { lock (sendLock) @@ -258,7 +261,7 @@ namespace Esyur.Net.Sockets throw new NotImplementedException(); } - + public bool Begin() { return sock.Begin(); @@ -275,20 +278,20 @@ namespace Esyur.Net.Sockets OnDestroy?.Invoke(this); } - public AsyncReply Accept() + public AsyncReply AcceptAsync() { throw new NotImplementedException(); } public void Hold() { - //Console.WriteLine("WS Hold "); + //Console.WriteLine("WS Hold "); held = true; } public void Unhold() { - lock(sendLock) + lock (sendLock) { held = false; @@ -305,7 +308,7 @@ namespace Esyur.Net.Sockets if (pkt_send.Compose()) sock.Send(pkt_send.Data); - + } } @@ -314,5 +317,10 @@ namespace Esyur.Net.Sockets { throw new NotImplementedException(); } + + public ISocket Accept() + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/Esyur/Net/TCP/TCPServer.cs b/Esyur/Net/TCP/TCPServer.cs index 78fe863..1e4c242 100644 --- a/Esyur/Net/TCP/TCPServer.cs +++ b/Esyur/Net/TCP/TCPServer.cs @@ -39,26 +39,26 @@ namespace Esyur.Net.TCP public class TCPServer : NetworkServer, IResource { - [Storable] - string ip + [Attribute] + public string IP + { + get; + set; + } + [Attribute] + public ushort Port { get; set; } [Storable] - ushort port + public uint Timeout { get; set; } - [Storable] - uint timeout - { - get; - set; - } - [Storable] - uint clock + [Attribute] + public uint Clock { get; set; @@ -75,12 +75,12 @@ namespace Esyur.Net.TCP TCPSocket listener; - if (ip != null) - listener =new TCPSocket(new IPEndPoint(IPAddress.Parse(ip), port)); + if (IP != null) + listener = new TCPSocket(new IPEndPoint(IPAddress.Parse(IP), Port)); else - listener = new TCPSocket(new IPEndPoint(IPAddress.Any, port)); + listener = new TCPSocket(new IPEndPoint(IPAddress.Any, Port)); - Start(listener, timeout, clock); + Start(listener, Timeout, Clock); } @@ -108,9 +108,9 @@ namespace Esyur.Net.TCP var msg = data.Read(); foreach (var filter in filters) - { - if (filter.Execute(msg, data, sender)) - return; + { + if (filter.Execute(msg, data, sender)) + return; } } diff --git a/Esyur/Net/UDP/UDPServer.cs b/Esyur/Net/UDP/UDPServer.cs index 0af7c83..3adda0d 100644 --- a/Esyur/Net/UDP/UDPServer.cs +++ b/Esyur/Net/UDP/UDPServer.cs @@ -30,8 +30,8 @@ using System.Text; using System.Collections; using Esyur.Data; using Esyur.Misc; -using Esyur.Engine; using Esyur.Resource; +using Esyur.Core; namespace Esyur.Net.UDP { @@ -43,8 +43,9 @@ namespace Esyur.Net.UDP }*/ public class UDPServer : IResource { - Thread Receiver; - UdpClient Udp; + Thread receiver; + UdpClient udp; + UDPFilter[] filters = new UDPFilter[0]; public event DestroyedEvent OnDestroy; @@ -54,48 +55,30 @@ namespace Esyur.Net.UDP set; } - [Storable] - string ip + [Attribute] + string IP { get; set; } - [Storable] - ushort port + [Attribute] + ushort Port { get; set; } - public bool Trigger(ResourceTrigger trigger) - { - if (trigger == ResourceTrigger.Initialize) - { - var address = ip == null ? IPAddress.Any : IPAddress.Parse(ip); - - Udp = new UdpClient(new IPEndPoint(address, (int)port)); - Receiver = new Thread(Receiving); - Receiver.Start(); - } - else if (trigger == ResourceTrigger.Terminate) - { - if (Receiver != null) - Receiver.Abort(); - } - return true; - } - - private void Receiving() + private void Receiving() { IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0); - + while (true) { - byte[] b = Udp.Receive(ref ep); + byte[] b = udp.Receive(ref ep); - foreach(var child in Instance.Children) + foreach (var child in filters) { var f = child as UDPFilter; @@ -119,7 +102,7 @@ namespace Esyur.Net.UDP { try { - Udp.Send(Data, Count, EP); + udp.Send(Data, Count, EP); return true; } catch @@ -131,7 +114,7 @@ namespace Esyur.Net.UDP { try { - Udp.Send(Data, Data.Length, EP); + udp.Send(Data, Data.Length, EP); return true; } catch @@ -143,7 +126,7 @@ namespace Esyur.Net.UDP { try { - Udp.Send(Data, Count, Host, Port); + udp.Send(Data, Count, Host, Port); return true; } catch @@ -155,7 +138,7 @@ namespace Esyur.Net.UDP { try { - Udp.Send(Data, Data.Length, Host, Port); + udp.Send(Data, Data.Length, Host, Port); return true; } catch @@ -167,7 +150,7 @@ namespace Esyur.Net.UDP { try { - Udp.Send(Encoding.Default.GetBytes(Data), Data.Length, EP); + udp.Send(Encoding.Default.GetBytes(Data), Data.Length, EP); return true; } catch @@ -179,7 +162,7 @@ namespace Esyur.Net.UDP { try { - Udp.Send(Encoding.Default.GetBytes(Data), Data.Length, Host, Port); + udp.Send(Encoding.Default.GetBytes(Data), Data.Length, Host, Port); return true; } catch @@ -190,8 +173,32 @@ namespace Esyur.Net.UDP public void Destroy() { - Udp.Close(); + udp.Close(); OnDestroy?.Invoke(this); } + + async AsyncReply IResource.Trigger(ResourceTrigger trigger) + { + if (trigger == ResourceTrigger.Initialize) + { + var address = IP == null ? IPAddress.Any : IPAddress.Parse(IP); + + udp = new UdpClient(new IPEndPoint(address, Port)); + + receiver = new Thread(Receiving); + receiver.Start(); + } + else if (trigger == ResourceTrigger.Terminate) + { + if (receiver != null) + receiver.Abort(); + } + else if (trigger == ResourceTrigger.SystemInitialized) + { + filters = await Instance.Children(); + } + + return true; + } } } \ No newline at end of file diff --git a/Esyur/Proxy/ResourceProxy.cs b/Esyur/Proxy/ResourceProxy.cs index 0275d6c..736acff 100644 --- a/Esyur/Proxy/ResourceProxy.cs +++ b/Esyur/Proxy/ResourceProxy.cs @@ -51,9 +51,9 @@ namespace Esyur.Proxy if (typeInfo.IsSealed || typeInfo.IsAbstract) throw new Exception("Sealed/Abastract classes can't be proxied."); - var props = from p in typeInfo.GetProperties() - where p.CanWrite && p.GetSetMethod().IsVirtual && - p.GetCustomAttributes(typeof(ResourceProperty), false).Count() > 0 + var props = from p in typeInfo.GetProperties(BindingFlags.Instance | BindingFlags.Public) + where p.CanWrite && p.SetMethod.IsVirtual && + p.GetCustomAttribute(false) != null select p; #else diff --git a/Esyur/Resource/AnnotationAttribute.cs b/Esyur/Resource/AnnotationAttribute.cs new file mode 100644 index 0000000..5e4763b --- /dev/null +++ b/Esyur/Resource/AnnotationAttribute.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esyur.Resource +{ + + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Event)] + public class AnnotationAttribute : Attribute + { + + public string Annotation { get; set; } + public AnnotationAttribute(string annotation) + { + this.Annotation = annotation; + } + } +} diff --git a/Esyur/Resource/ResourceAttribute.cs b/Esyur/Resource/AttributeAttribute.cs similarity index 93% rename from Esyur/Resource/ResourceAttribute.cs rename to Esyur/Resource/AttributeAttribute.cs index 06cf302..19cdb2f 100644 --- a/Esyur/Resource/ResourceAttribute.cs +++ b/Esyur/Resource/AttributeAttribute.cs @@ -31,10 +31,10 @@ namespace Esyur.Resource { [AttributeUsage(AttributeTargets.Property)] - public class ResourceAttribute : System.Attribute + public class AttributeAttribute : System.Attribute { - public ResourceAttribute() + public AttributeAttribute() { } diff --git a/Esyur/Resource/Instance.cs b/Esyur/Resource/Instance.cs index 5d67a08..d2b6b19 100644 --- a/Esyur/Resource/Instance.cs +++ b/Esyur/Resource/Instance.cs @@ -176,7 +176,8 @@ namespace Esyur.Resource if (at != null) if (at.Info.CanWrite) - at.Info.SetValue(res, kv.Value); + at.Info.SetValue(res, DC.CastConvert(kv.Value, at.Info.PropertyType)); + } } @@ -442,7 +443,7 @@ namespace Esyur.Resource IResource res; if (resource.TryGetTarget(out res)) { - var rt = pt.Serilize ? pt.Info.GetValue(res, null) : null; + var rt = pt.Info.GetValue(res, null);// pt.Serilize ? pt.Info.GetValue(res, null) : null; props.Add(new PropertyValue(rt, ages[pt.Index], modificationDates[pt.Index])); } @@ -546,13 +547,14 @@ namespace Esyur.Resource ages[pt.Index] = instanceAge; modificationDates[pt.Index] = now; - if (pt.Storage == StorageMode.NonVolatile) - { - store.Modify(res, pt.Name, value, ages[pt.Index], now); - } - else if (pt.Storage == StorageMode.Recordable) + if (pt.Recordable) { store.Record(res, pt.Name, value, ages[pt.Index], now); + + } + else //if (pt.Storage == StorageMode.Recordable) + { + store.Modify(res, pt.Name, value, ages[pt.Index], now); } ResourceModified?.Invoke(res, pt.Name, value); @@ -839,7 +841,7 @@ namespace Esyur.Resource this.store = store; this.resource = new WeakReference(resource); this.id = id; - this.name = name; + this.name = name ?? ""; this.instanceAge = age; //this.attributes = new KeyList(this); @@ -875,30 +877,32 @@ namespace Esyur.Resource var events = t.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); #endif - foreach (var evt in events) + + foreach (var evt in template.Events) { //if (evt.EventHandlerType != typeof(ResourceEventHanlder)) // continue; - - if (evt.EventHandlerType == typeof(ResourceEventHanlder)) + + if (evt.Info.EventHandlerType == typeof(ResourceEventHanlder)) { - var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true); - if (ca.Length == 0) - continue; + + // var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true); + // if (ca.Length == 0) + // continue; ResourceEventHanlder proxyDelegate = (args) => EmitResourceEvent(null, null, evt.Name, args); - evt.AddEventHandler(resource, proxyDelegate); + evt.Info.AddEventHandler(resource, proxyDelegate); } - else if (evt.EventHandlerType == typeof(CustomResourceEventHanlder)) + else if (evt.Info.EventHandlerType == typeof(CustomResourceEventHanlder)) { - var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true); - if (ca.Length == 0) - continue; + //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); + evt.Info.AddEventHandler(resource, proxyDelegate); } diff --git a/Esyur/Resource/PrivateAttribute.cs b/Esyur/Resource/PrivateAttribute.cs new file mode 100644 index 0000000..bc320be --- /dev/null +++ b/Esyur/Resource/PrivateAttribute.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esyur.Resource +{ + public class PrivateAttribute:Attribute + { + + } +} diff --git a/Esyur/Resource/PublicAttribute.cs b/Esyur/Resource/PublicAttribute.cs new file mode 100644 index 0000000..8c87e5f --- /dev/null +++ b/Esyur/Resource/PublicAttribute.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esyur.Resource +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class)] + + public class PublicAttribute : Attribute + { + + // public StorageMode Storage { get; set; } + + //public bool Serialize { get; set; } + + public PublicAttribute()//StorageMode storage = StorageMode.NonVolatile, bool serialize = true) + { + // Storage = storage; + //Serialize = serialize; + } + } +} diff --git a/Esyur/Resource/Resource.cs b/Esyur/Resource/Resource.cs index 467f89f..c66753e 100644 --- a/Esyur/Resource/Resource.cs +++ b/Esyur/Resource/Resource.cs @@ -47,7 +47,7 @@ namespace Esyur.Resource return new AsyncReply(true); } - public virtual bool Create() + protected virtual bool Create() { return true; } diff --git a/Esyur/Resource/StorageAttribute.cs b/Esyur/Resource/StorageAttribute.cs new file mode 100644 index 0000000..2614d9d --- /dev/null +++ b/Esyur/Resource/StorageAttribute.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esyur.Resource +{ + [AttributeUsage(AttributeTargets.Property)] + public class StorageAttribute:Attribute + { + public StorageMode Mode { get; set; } + public StorageAttribute(StorageMode mode) + { + Mode = mode; + } + } +} diff --git a/Esyur/Resource/StoreGeneric.cs b/Esyur/Resource/StoreGeneric.cs new file mode 100644 index 0000000..4d4b74d --- /dev/null +++ b/Esyur/Resource/StoreGeneric.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Esyur.Core; +using Esyur.Data; +using Esyur.Resource.Template; + +namespace Esyur.Resource +{ + public abstract class Store : IStore where T:IResource + { + public Instance Instance { get; set; } + + public event DestroyedEvent OnDestroy; + + public abstract AsyncReply AddChild(IResource parent, IResource child); + + public abstract AsyncReply AddParent(IResource child, IResource parent); + + public abstract AsyncBag Children(IResource resource, string name) where T1 : IResource; + + public virtual void Destroy() + { + OnDestroy?.Invoke(this); + } + + public abstract AsyncReply Get(string path); + + public abstract AsyncReply> GetRecord(IResource resource, DateTime fromDate, DateTime toDate); + + + public abstract string Link(IResource resource); + + public abstract bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime); + + public abstract AsyncBag Parents(IResource resource, string name) where T1 : IResource; + + public abstract AsyncReply Put(IResource resource); + + public abstract bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime); + + public abstract bool Remove(IResource resource); + + public abstract AsyncReply RemoveChild(IResource parent, IResource child); + + public abstract AsyncReply RemoveParent(IResource child, IResource parent); + + public abstract AsyncReply Trigger(ResourceTrigger trigger); + + public T New(string name = null, object attributes = null, object properties = null) + { + var resource = Warehouse.New(name, this, null, null, attributes, properties); + resource.Instance.Managers.AddRange(this.Instance.Managers.ToArray()); + return resource; + } + } +} diff --git a/Esyur/Resource/Template/EventTemplate.cs b/Esyur/Resource/Template/EventTemplate.cs index e7abdba..6abc4ca 100644 --- a/Esyur/Resource/Template/EventTemplate.cs +++ b/Esyur/Resource/Template/EventTemplate.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -15,6 +16,8 @@ namespace Esyur.Resource.Template set; } + public EventInfo Info { get; set; } + public override byte[] Compose() { var name = base.Compose(); @@ -39,7 +42,7 @@ namespace Esyur.Resource.Template } - public EventTemplate(ResourceTemplate template, byte index, string name, string expansion) + public EventTemplate(ResourceTemplate template, byte index, string name, string expansion = null) :base(template, MemberType.Property, index, name) { this.Expansion = expansion; diff --git a/Esyur/Resource/Template/FunctionTemplate.cs b/Esyur/Resource/Template/FunctionTemplate.cs index 41c250f..c2b5534 100644 --- a/Esyur/Resource/Template/FunctionTemplate.cs +++ b/Esyur/Resource/Template/FunctionTemplate.cs @@ -45,7 +45,7 @@ namespace Esyur.Resource.Template } - public FunctionTemplate(ResourceTemplate template, byte index, string name,bool isVoid, string expansion) + public FunctionTemplate(ResourceTemplate template, byte index, string name,bool isVoid, string expansion = null) :base(template, MemberType.Property, index, name) { this.IsVoid = isVoid; diff --git a/Esyur/Resource/Template/PropertyTemplate.cs b/Esyur/Resource/Template/PropertyTemplate.cs index bf873a6..687d22f 100644 --- a/Esyur/Resource/Template/PropertyTemplate.cs +++ b/Esyur/Resource/Template/PropertyTemplate.cs @@ -24,10 +24,12 @@ namespace Esyur.Resource.Template set; } + /* public bool Serilize { get;set; } + */ //bool ReadOnly; //IIPTypes::DataType ReturnType; public PropertyPermission Permission { @@ -35,18 +37,19 @@ namespace Esyur.Resource.Template set; } - /* + public bool Recordable { get; set; - }*/ + } - public StorageMode Storage + /* + public PropertyType Mode { get; set; - } + }*/ public string ReadExpansion { @@ -71,7 +74,7 @@ namespace Esyur.Resource.Template public override byte[] Compose() { var name = base.Compose(); - var pv = ((byte)(Permission) << 1) | (Storage == StorageMode.Recordable ? 1 : 0); + var pv = ((byte)(Permission) << 1) | (Recordable ? 1 : 0); if (WriteExpansion != null && ReadExpansion != null) { @@ -117,11 +120,11 @@ namespace Esyur.Resource.Template .ToArray(); } - public PropertyTemplate(ResourceTemplate template, byte index, string name, string read, string write, StorageMode storage) + public PropertyTemplate(ResourceTemplate template, byte index, string name, string read = null, string write = null, bool recordable = false) :base(template, MemberType.Property, index, name) { - //this.Recordable = recordable; - this.Storage = storage; + this.Recordable = recordable; + //this.Storage = storage; this.ReadExpansion = read; this.WriteExpansion = write; } diff --git a/Esyur/Resource/Template/ResourceTemplate.cs b/Esyur/Resource/Template/ResourceTemplate.cs index d28302d..c9c2698 100644 --- a/Esyur/Resource/Template/ResourceTemplate.cs +++ b/Esyur/Resource/Template/ResourceTemplate.cs @@ -8,6 +8,7 @@ using Esyur.Data; using Esyur.Core; using System.Security.Cryptography; using Esyur.Proxy; +using Esyur.Net.IIP; namespace Esyur.Resource.Template { @@ -159,52 +160,87 @@ namespace Esyur.Resource.Template MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); #endif - //byte currentIndex = 0; + + bool classIsPublic = type.GetCustomAttribute() != null; byte i = 0; - foreach (var pi in propsInfo) + if (classIsPublic) { - var rp = pi.GetCustomAttribute(true); - - if (rp != null) - { - var pt = new PropertyTemplate(this, i++, pi.Name, rp.ReadExpansion, rp.WriteExpansion, rp.Storage); - pt.Info = pi; - pt.Serilize = rp.Serialize; - properties.Add(pt); - } - var ra = pi.GetCustomAttribute(true); - - if (ra != null) - { - var at = new AttributeTemplate(this, i++, pi.Name); - at.Info = pi; - attributes.Add(at); - } } - - i = 0; - - foreach (var ei in eventsInfo) + else { - var es = ei.GetCustomAttributes(true).ToArray(); - if (es.Length > 0) + + foreach (var pi in propsInfo) { - var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion); - events.Add(et); + var publicAttr = pi.GetCustomAttribute(true); + + if (publicAttr != null) + { + var annotationAttr = pi.GetCustomAttribute(true); + var storageAttr = pi.GetCustomAttribute(true); + + var pt = new PropertyTemplate(this, i++, pi.Name);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage); + if (storageAttr != null) + pt.Recordable = storageAttr.Mode == StorageMode.Recordable; + + if (annotationAttr != null) + pt.ReadExpansion = annotationAttr.Annotation; + else + pt.ReadExpansion = pi.PropertyType.Name; + + pt.Info = pi; + //pt.Serilize = publicAttr.Serialize; + properties.Add(pt); + } + else + { + var attributeAttr = pi.GetCustomAttribute(true); + if (attributeAttr != null) + { + var at = new AttributeTemplate(this, 0, pi.Name); + at.Info = pi; + attributes.Add(at); + } + } } - } - i = 0; - foreach (MethodInfo mi in methodsInfo) - { - var fs = mi.GetCustomAttributes(true).ToArray(); - if (fs.Length > 0) + i = 0; + + foreach (var ei in eventsInfo) { - var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion); - functions.Add(ft); + var publicAttr = ei.GetCustomAttribute(true); + if (publicAttr != null) + { + var annotationAttr = ei.GetCustomAttribute(true); + + var et = new EventTemplate(this, i++, ei.Name); + et.Info = ei; + + if (annotationAttr != null) + et.Expansion = annotationAttr.Annotation; + + events.Add(et); + } + } + + i = 0; + foreach (MethodInfo mi in methodsInfo) + { + var publicAttr = mi.GetCustomAttribute(true); + if (publicAttr != null) + { + var annotationAttr = mi.GetCustomAttribute(true); + + var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void)); + + if (annotationAttr != null) + ft.Expansion = annotationAttr.Annotation; + else + ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x=>x.ParameterType != typeof(DistributedConnection)).Select(x=> "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name; + functions.Add(ft); + } } } @@ -323,7 +359,7 @@ namespace Esyur.Resource.Template offset += cs; } - var pt = new PropertyTemplate(od, propertyIndex++, name, readExpansion, writeExpansion, recordable ? StorageMode.Recordable : StorageMode.Volatile); + var pt = new PropertyTemplate(od, propertyIndex++, name, readExpansion, writeExpansion, recordable); od.properties.Add(pt); } diff --git a/Esyur/Resource/Warehouse.cs b/Esyur/Resource/Warehouse.cs index 52fa54c..3ab8d20 100644 --- a/Esyur/Resource/Warehouse.cs +++ b/Esyur/Resource/Warehouse.cs @@ -35,6 +35,7 @@ using System.Threading.Tasks; using Esyur.Net.IIP; using System.Text.RegularExpressions; using Esyur.Misc; +using System.Collections.Concurrent; namespace Esyur.Resource { @@ -43,8 +44,11 @@ namespace Esyur.Resource { //static byte prefixCounter; - static AutoList stores = new AutoList(null); - static Dictionary> resources = new Dictionary>(); + //static AutoList stores = new AutoList(null); + static ConcurrentDictionary> resources = new ConcurrentDictionary>(); + static ConcurrentDictionary>> stores = new ConcurrentDictionary>>(); + + static uint resourceCounter = 0; static KeyList templates = new KeyList(); @@ -61,7 +65,7 @@ namespace Esyur.Resource private static Regex urlRegex = new Regex(@"^(?:([\S]*)://([^/]*)/?)"); - private static object resourcesLock = new object(); + //private static object resourcesLock = new object(); static KeyList> getSupportedProtocols() { @@ -78,8 +82,8 @@ namespace Esyur.Resource public static IStore GetStore(string name) { foreach (var s in stores) - if (s.Instance.Name == name) - return s as IStore; + if (s.Key.Instance.Name == name) + return s.Key; return null; } @@ -113,22 +117,28 @@ namespace Esyur.Resource { warehouseIsOpen = true; - var resSnap = resources.Select(x => { - IResource r; + var resSnap = resources.Select(x => + { + IResource r; if (x.Value.TryGetTarget(out r)) return r; else return null; - }).Where(r=>r!=null).ToArray(); + }).Where(r => r != null).ToArray(); foreach (var r in resSnap) { //IResource r; //if (rk.Value.TryGetTarget(out r)) //{ - var rt = await r.Trigger(ResourceTrigger.Initialize); - if (!rt) - return false; + var rt = await r.Trigger(ResourceTrigger.Initialize); + //if (!rt) + // return false; + + if (!rt) + { + Console.WriteLine($"Resource failed at Initialize {r.Instance.Name} [{r.Instance.Template.ClassName}]"); + } //} } @@ -137,9 +147,12 @@ namespace Esyur.Resource //IResource r; //if (rk.Value.TryGetTarget(out r)) //{ - var rt = await r.Trigger(ResourceTrigger.SystemInitialized); - if (!rt) - return false; + var rt = await r.Trigger(ResourceTrigger.SystemInitialized); + if (!rt) + { + Console.WriteLine($"Resource failed at SystemInitialized {r.Instance.Name} [{r.Instance.Template.ClassName}]"); + } + //return false; //} } @@ -217,7 +230,7 @@ namespace Esyur.Resource } foreach (var store in stores) - bag.Add(store.Trigger(ResourceTrigger.Terminate)); + bag.Add(store.Key.Trigger(ResourceTrigger.Terminate)); foreach (var resource in resources.Values) @@ -232,7 +245,7 @@ namespace Esyur.Resource foreach (var store in stores) - bag.Add(store.Trigger(ResourceTrigger.SystemTerminated)); + bag.Add(store.Key.Trigger(ResourceTrigger.SystemTerminated)); bag.Seal(); @@ -318,7 +331,7 @@ namespace Esyur.Resource var p = path.Trim().Split('/'); IResource resource; - foreach (var store in stores) + foreach (var store in stores.Keys) if (p[0] == store.Instance.Name) { @@ -433,19 +446,26 @@ namespace Esyur.Resource if (resource.Instance != null) throw new Exception("Resource has a store."); + var resourceReference = new WeakReference(resource); + if (store == null) { // assign parent as a store if (parent is IStore) + { store = (IStore)parent; + stores[store].Add(resourceReference); + } // assign parent's store as a store else if (parent != null) + { store = parent.Instance.Store; + stores[store].Add(resourceReference); + } // assign self as a store (root store) else if (resource is IStore) { store = (IStore)resource; - stores.Add(resource as IStore); } else throw new Exception("Can't find a store for the resource."); @@ -475,10 +495,13 @@ namespace Esyur.Resource if (resource is IStore) + { + stores.TryAdd(resource as IStore, new List>()); StoreConnected?.Invoke(resource as IStore, name); + } //else - + store.Put(resource); @@ -493,15 +516,17 @@ namespace Esyur.Resource var t = resource.GetType(); Global.Counters["T-" + t.Namespace + "." + t.Name]++; - lock (resourcesLock) - resources.Add(resource.Instance.Id, new WeakReference(resource)); + //var wr = new WeakReference(resource); + + //lock (resourcesLock) + resources.TryAdd(resource.Instance.Id, resourceReference); if (warehouseIsOpen) resource.Trigger(ResourceTrigger.Initialize); } - public static IResource New(Type type, string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null, Structure arguments = null, Structure properties = null) + public static IResource New(Type type, string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, object attributes = null, object properties = null) { type = ResourceProxy.GetProxy(type); @@ -539,9 +564,12 @@ namespace Esyur.Resource */ var res = Activator.CreateInstance(type) as IResource; + if (properties != null) { - foreach (var p in properties) + var ps = Structure.FromObject(properties); + + foreach (var p in ps) { var pi = type.GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly); if (pi != null) @@ -556,10 +584,10 @@ namespace Esyur.Resource } - public static T New(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null, Structure arguments = null, Structure properties = null) + public static T New(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, object attributes = null, object properties = null) where T : IResource { - return (T)New(typeof(T), name, store, parent, manager, attributes, arguments, properties); + return (T)New(typeof(T), name, store, parent, manager, attributes, properties); } /// @@ -619,31 +647,45 @@ namespace Esyur.Resource public static bool Remove(IResource resource) { - + if (resource.Instance == null) return false; + //lock (resourcesLock) + //{ + + WeakReference resourceReference; + if (resources.ContainsKey(resource.Instance.Id)) - lock(resourcesLock) - resources.Remove(resource.Instance.Id); + resources.TryRemove(resource.Instance.Id, out resourceReference); else return false; + //} + + if (resource != resource.Instance.Store) + stores[resource.Instance.Store].Remove(resourceReference); if (resource is IStore) { - stores.Remove(resource as IStore); + var store = resource as IStore; - WeakReference[] toBeRemoved; + List> toBeRemoved;// = stores[store]; + + stores.TryRemove(store, out toBeRemoved); + + //lock (resourcesLock) + //{ + // // remove all objects associated with the store + // toBeRemoved = resources.Values.Where(x => + // { + // IResource r; + // if (x.TryGetTarget(out r)) + // return r.Instance.Store == resource; + // else + // return false; + // }).ToArray(); + //} - lock (resourcesLock) - { - // remove all objects associated with the store - toBeRemoved = resources.Values.Where(x => - { - IResource r; - return x.TryGetTarget(out r) && r.Instance.Store == resource; - }).ToArray(); - } foreach (var o in toBeRemoved) { diff --git a/Esyur/Security/Integrity/CRC16IBM.cs b/Esyur/Security/Integrity/CRC16IBM.cs new file mode 100644 index 0000000..d09cb0e --- /dev/null +++ b/Esyur/Security/Integrity/CRC16IBM.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esyur.Security.Integrity +{ + + public class CRC16IBM + { + static UInt16[] table = { +0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, +0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, +0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, +0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, +0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, +0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, +0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, +0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, +0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, +0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, +0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, +0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, +0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, +0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, +0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, +0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, +0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, +0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, +0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, +0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, +0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, +0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, +0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, +0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, +0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, +0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, +0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, +0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, +0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, +0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, +0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, +0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040}; + + public static ushort Compute(byte[] data) + { + return Compute(data, 0, (uint)data.Length); + } + + + public static ushort Compute(byte[] data, uint offset, uint length) + { + ushort crc = 0;// 0xffff; + ushort x; + for (var i = offset; i < length; i++) + { + x = (ushort)(crc ^ data[i]); + crc = (UInt16)((crc >> 8) ^ table[x & 0x00FF]); + } + + return crc; + } + + public static ushort Compute2(byte[] data, uint offset, uint length) + { + ushort crc = 0; + for (var i = offset; i < length; i++) + { + crc ^= data[i]; + + for (var j = 0; j < 8; j++) + { + var carry = crc & 0x1; + crc >>= 1; + if (carry == 1) + crc ^= 0xa001; + } + } + return crc; + } + } +} + diff --git a/Esyur/Security/Integrity/CRC16ITU.cs b/Esyur/Security/Integrity/CRC16ITU.cs new file mode 100644 index 0000000..b081d71 --- /dev/null +++ b/Esyur/Security/Integrity/CRC16ITU.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esyur.Security.Integrity +{ + + public class CRC16ITU + { + static UInt16[] table = +{ + 0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF, + 0X8C48, 0X9DC1, 0XAF5A, 0XBED3, 0XCA6C, 0XDBE5, 0XE97E, 0XF8F7, + 0X1081, 0X0108, 0X3393, 0X221A, 0X56A5, 0X472C, 0X75B7, 0X643E, + 0X9CC9, 0X8D40, 0XBFDB, 0XAE52, 0XDAED, 0XCB64, 0XF9FF, 0XE876, + 0X2102, 0X308B, 0X0210, 0X1399, 0X6726, 0X76AF, 0X4434, 0X55BD, + 0XAD4A, 0XBCC3, 0X8E58, 0X9FD1, 0XEB6E, 0XFAE7, 0XC87C, 0XD9F5, + 0X3183, 0X200A, 0X1291, 0X0318, 0X77A7, 0X662E, 0X54B5, 0X453C, + 0XBDCB, 0XAC42, 0X9ED9, 0X8F50, 0XFBEF, 0XEA66, 0XD8FD, 0XC974, + 0X4204, 0X538D, 0X6116, 0X709F, 0X0420, 0X15A9, 0X2732, 0X36BB, + 0XCE4C, 0XDFC5, 0XED5E, 0XFCD7, 0X8868, 0X99E1, 0XAB7A, 0XBAF3, + 0X5285, 0X430C, 0X7197, 0X601E, 0X14A1, 0X0528, 0X37B3, 0X263A, + 0XDECD, 0XCF44, 0XFDDF, 0XEC56, 0X98E9, 0X8960, 0XBBFB, 0XAA72, + 0X6306, 0X728F, 0X4014, 0X519D, 0X2522, 0X34AB, 0X0630, 0X17B9, + 0XEF4E, 0XFEC7, 0XCC5C, 0XDDD5, 0XA96A, 0XB8E3, 0X8A78, 0X9BF1, + 0X7387, 0X620E, 0X5095, 0X411C, 0X35A3, 0X242A, 0X16B1, 0X0738, + 0XFFCF, 0XEE46, 0XDCDD, 0XCD54, 0XB9EB, 0XA862, 0X9AF9, 0X8B70, + 0X8408, 0X9581, 0XA71A, 0XB693, 0XC22C, 0XD3A5, 0XE13E, 0XF0B7, + 0X0840, 0X19C9, 0X2B52, 0X3ADB, 0X4E64, 0X5FED, 0X6D76, 0X7CFF, + 0X9489, 0X8500, 0XB79B, 0XA612, 0XD2AD, 0XC324, 0XF1BF, 0XE036, + 0X18C1, 0X0948, 0X3BD3, 0X2A5A, 0X5EE5, 0X4F6C, 0X7DF7, 0X6C7E, + 0XA50A, 0XB483, 0X8618, 0X9791, 0XE32E, 0XF2A7, 0XC03C, 0XD1B5, + 0X2942, 0X38CB, 0X0A50, 0X1BD9, 0X6F66, 0X7EEF, 0X4C74, 0X5DFD, + 0XB58B, 0XA402, 0X9699, 0X8710, 0XF3AF, 0XE226, 0XD0BD, 0XC134, + 0X39C3, 0X284A, 0X1AD1, 0X0B58, 0X7FE7, 0X6E6E, 0X5CF5, 0X4D7C, + 0XC60C, 0XD785, 0XE51E, 0XF497, 0X8028, 0X91A1, 0XA33A, 0XB2B3, + 0X4A44, 0X5BCD, 0X6956, 0X78DF, 0X0C60, 0X1DE9, 0X2F72, 0X3EFB, + 0XD68D, 0XC704, 0XF59F, 0XE416, 0X90A9, 0X8120, 0XB3BB, 0XA232, + 0X5AC5, 0X4B4C, 0X79D7, 0X685E, 0X1CE1, 0X0D68, 0X3FF3, 0X2E7A, + 0XE70E, 0XF687, 0XC41C, 0XD595, 0XA12A, 0XB0A3, 0X8238, 0X93B1, + 0X6B46, 0X7ACF, 0X4854, 0X59DD, 0X2D62, 0X3CEB, 0X0E70, 0X1FF9, + 0XF78F, 0XE606, 0XD49D, 0XC514, 0XB1AB, 0XA022, 0X92B9, 0X8330, + 0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3, 0X2C6A, 0X1EF1, 0X0F78, +}; + + + public static ushort Compute(byte[] data) + { + return Compute(data, 0, (uint)data.Length); + } + + + public static ushort Compute(byte[] data, uint offset, uint length) + { + ushort fcs = 0xffff; // initialization + while (length > 0) + { + fcs = (ushort)((fcs >> 8) ^ table[(fcs ^ data[offset++]) & 0xff]); + length--; + } + return (ushort)~fcs; // negated + } + + } + +} diff --git a/Esyur/Security/Integrity/NMEA0183.cs b/Esyur/Security/Integrity/NMEA0183.cs new file mode 100644 index 0000000..cba0cc3 --- /dev/null +++ b/Esyur/Security/Integrity/NMEA0183.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Esyur.Security.Integrity +{ + + public class NMEA0183 + { + public static byte Compute(string data) + { + return Compute(data, 0, (uint)data.Length); + } + + public static byte Compute(string data, uint offset, uint length) + { + byte rt = 0; + var ends = offset + length; + for (int i = (int)offset; i < ends; i++) + rt ^= (byte)data[i]; + + return rt; + } + } + +}