mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2026-07-30 17:30:40 +00:00
Types
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Parameter, AllowMultiple = true)]
|
||||
public class AnnotationAttribute : Attribute
|
||||
{
|
||||
|
||||
public readonly string? Key;
|
||||
public readonly string Value;
|
||||
|
||||
public AnnotationAttribute(string annotation)
|
||||
{
|
||||
Key = "";
|
||||
Value = annotation;
|
||||
}
|
||||
public AnnotationAttribute(string key, string value)
|
||||
{
|
||||
Key = key;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
//public AnnotationAttribute(params string[] annotations)
|
||||
//{
|
||||
// this.Annotation = String.Join("\n", annotations);
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
|
||||
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.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Resource;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class AttributeAttribute : System.Attribute
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public AttributeAttribute(string name = null)
|
||||
{
|
||||
this.Name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2021 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;
|
||||
|
||||
namespace Esiur.Resource;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that an event is delivered to attached clients without
|
||||
/// requiring an explicit subscription.
|
||||
/// </summary>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Event |
|
||||
AttributeTargets.Field,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class AutoDeliveredAttribute : Attribute
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a running remote invocation may be cancelled.
|
||||
/// </summary>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class CancellableAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Esiur.Resource;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class | AttributeTargets.Enum)]
|
||||
|
||||
public class ExportAttribute : Attribute
|
||||
{
|
||||
public string Name { get; private set; } = null;
|
||||
public PropertyPermission? Permission { get; private set; }
|
||||
|
||||
public ExportAttribute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ExportAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public ExportAttribute(PropertyPermission permission)
|
||||
{
|
||||
Permission = permission;
|
||||
}
|
||||
|
||||
public ExportAttribute(string name, PropertyPermission permission)
|
||||
{
|
||||
Name = name;
|
||||
Permission = permission;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that previous values of an exported property are retained
|
||||
/// and may be fetched remotely.
|
||||
/// </summary>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Property |
|
||||
AttributeTargets.Field,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class HistoricalAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that repeating the same invocation should have the same
|
||||
/// externally observable effect as invoking it once.
|
||||
/// </summary>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class IdempotentAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource;
|
||||
public class IgnoreAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ImportAttribute : Attribute
|
||||
{
|
||||
public ImportAttribute(params string[] urls)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Esiur.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies non-default notification ordering for a property or event.
|
||||
/// Absence of this attribute means strict ordering.
|
||||
/// </summary>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Property |
|
||||
AttributeTargets.Field |
|
||||
AttributeTargets.Event,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class OrderingAttribute : Attribute
|
||||
{
|
||||
public OrderingControl Control { get; }
|
||||
|
||||
public OrderingAttribute(OrderingControl control)
|
||||
{
|
||||
Control = control;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that an exported function does not change resource state,
|
||||
/// or that an exported property cannot be changed remotely.
|
||||
/// </summary>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method |
|
||||
AttributeTargets.Property |
|
||||
AttributeTargets.Field,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class ReadOnlyAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Esiur.Resource
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Class, Inherited = false)]
|
||||
public class RemoteAttribute : Attribute
|
||||
{
|
||||
public string[] Domains { get; private set; }
|
||||
public string FullName { get; private set; }
|
||||
|
||||
static readonly Regex StrictIPv4 = new(
|
||||
@"^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$",
|
||||
RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||
|
||||
static readonly Regex IPv4Like = new(
|
||||
@"^\d+(?:\.\d+){3}$",
|
||||
RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||
|
||||
static readonly Regex HostName = new(
|
||||
@"^(?=.{1,253}\.?$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)*[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.?$",
|
||||
RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||
|
||||
|
||||
public bool IsValidFullName()
|
||||
{
|
||||
return IsValidQualifiedClassName(FullName, true, false); ;
|
||||
}
|
||||
|
||||
private static readonly HashSet<string> ReservedKeywords = new HashSet<string>(
|
||||
new[]
|
||||
{
|
||||
"abstract", "as", "base", "bool", "break", "byte", "case", "catch",
|
||||
"char", "checked", "class", "const", "continue", "decimal", "default",
|
||||
"delegate", "do", "double", "else", "enum", "event", "explicit",
|
||||
"extern", "false", "finally", "fixed", "float", "for", "foreach",
|
||||
"goto", "if", "implicit", "in", "int", "interface", "internal",
|
||||
"is", "lock", "long", "namespace", "new", "null", "object",
|
||||
"operator", "out", "override", "params", "private", "protected",
|
||||
"public", "readonly", "ref", "return", "sbyte", "sealed", "short",
|
||||
"sizeof", "stackalloc", "static", "string", "struct", "switch",
|
||||
"this", "throw", "true", "try", "typeof", "uint", "ulong",
|
||||
"unchecked", "unsafe", "ushort", "using", "virtual", "void",
|
||||
"volatile", "while"
|
||||
},
|
||||
StringComparer.Ordinal);
|
||||
|
||||
public RemoteAttribute(string fullName, params string[] domains)
|
||||
{
|
||||
Domains = domains;
|
||||
FullName = fullName;
|
||||
}
|
||||
|
||||
// @TODO: support wildcard records
|
||||
public bool AreValidDomains()
|
||||
{
|
||||
foreach(var domain in Domains)
|
||||
{
|
||||
if (!IsValidDomain(domain))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsValidDomain(string domain)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(domain))
|
||||
return false;
|
||||
|
||||
string s = domain.Trim();
|
||||
|
||||
// Accept URI-style IPv6 literals, e.g. [::1]
|
||||
if (s.Length > 2 && s[0] == '[' && s[s.Length - 1] == ']')
|
||||
s = s.Substring(1, s.Length - 2);
|
||||
|
||||
// Strict IPv4 only: 0.0.0.0 to 255.255.255.255
|
||||
if (StrictIPv4.IsMatch(s))
|
||||
return true;
|
||||
|
||||
// Reject IPv4-looking strings that failed strict IPv4,
|
||||
// e.g. 999.999.999.999
|
||||
if (IPv4Like.IsMatch(s))
|
||||
return false;
|
||||
|
||||
IPAddress ip;
|
||||
|
||||
// IPv6
|
||||
if (IPAddress.TryParse(s, out ip) &&
|
||||
ip.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
return true;
|
||||
|
||||
// Hostname or domain
|
||||
return HostName.IsMatch(s);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static bool IsValidQualifiedClassName(string value, bool requireNamespace, bool allowVerbatimIdentifiers)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
return false;
|
||||
|
||||
string s = value.Trim();
|
||||
|
||||
if (s.Length == 0)
|
||||
return false;
|
||||
|
||||
// Reject whitespace inside the name
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
if (char.IsWhiteSpace(s[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Optional source-style prefix: global::Namespace.Type
|
||||
if (s.StartsWith("global::", StringComparison.Ordinal))
|
||||
s = s.Substring("global::".Length);
|
||||
|
||||
string[] parts = s.Split('.');
|
||||
|
||||
if (requireNamespace && parts.Length < 2)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
if (!IsValidIdentifier(parts[i], allowVerbatimIdentifiers))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsValidIdentifier(string identifier, bool allowVerbatimIdentifier)
|
||||
{
|
||||
if (string.IsNullOrEmpty(identifier))
|
||||
return false;
|
||||
|
||||
string id = identifier;
|
||||
|
||||
if (id[0] == '@')
|
||||
{
|
||||
if (!allowVerbatimIdentifier)
|
||||
return false;
|
||||
|
||||
id = id.Substring(1);
|
||||
|
||||
if (id.Length == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsIdentifierStartCharacter(id[0]))
|
||||
return false;
|
||||
|
||||
for (int i = 1; i < id.Length; i++)
|
||||
{
|
||||
if (!IsIdentifierPartCharacter(id[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reject reserved keywords unless written as @keyword
|
||||
if (identifier[0] != '@' && ReservedKeywords.Contains(id))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsIdentifierStartCharacter(char ch)
|
||||
{
|
||||
if (ch == '_')
|
||||
return true;
|
||||
|
||||
UnicodeCategory category = CharUnicodeInfo.GetUnicodeCategory(ch);
|
||||
|
||||
return category == UnicodeCategory.UppercaseLetter ||
|
||||
category == UnicodeCategory.LowercaseLetter ||
|
||||
category == UnicodeCategory.TitlecaseLetter ||
|
||||
category == UnicodeCategory.ModifierLetter ||
|
||||
category == UnicodeCategory.OtherLetter ||
|
||||
category == UnicodeCategory.LetterNumber;
|
||||
}
|
||||
|
||||
private static bool IsIdentifierPartCharacter(char ch)
|
||||
{
|
||||
if (IsIdentifierStartCharacter(ch))
|
||||
return true;
|
||||
|
||||
UnicodeCategory category = CharUnicodeInfo.GetUnicodeCategory(ch);
|
||||
|
||||
return category == UnicodeCategory.DecimalDigitNumber ||
|
||||
category == UnicodeCategory.ConnectorPunctuation ||
|
||||
category == UnicodeCategory.NonSpacingMark ||
|
||||
category == UnicodeCategory.SpacingCombiningMark ||
|
||||
category == UnicodeCategory.Format;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
||||
public class ResourceAttribute : Attribute
|
||||
{
|
||||
public ResourceAttribute()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class StorageAttribute : Attribute
|
||||
{
|
||||
public StorageMode Mode { get; set; }
|
||||
public StorageAttribute(StorageMode mode)
|
||||
{
|
||||
Mode = mode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Esiur.Data.Types;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource
|
||||
{
|
||||
/// <summary>
|
||||
/// Marks an exported function as streaming and specifies its delivery mode.
|
||||
/// </summary>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class StreamAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the stream delivery mode.
|
||||
/// </summary>
|
||||
public StreamMode Mode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a push stream may be paused and resumed remotely.
|
||||
/// This should only be true when Mode is Push.
|
||||
/// </summary>
|
||||
public bool Pausable { get; set; }
|
||||
|
||||
public StreamAttribute(StreamMode mode = StreamMode.Push)
|
||||
{
|
||||
Mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource.Attributes
|
||||
{
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Class |
|
||||
AttributeTargets.Struct |
|
||||
AttributeTargets.Interface |
|
||||
AttributeTargets.Enum |
|
||||
AttributeTargets.Delegate |
|
||||
AttributeTargets.Method |
|
||||
AttributeTargets.Property |
|
||||
AttributeTargets.Field |
|
||||
AttributeTargets.Event |
|
||||
AttributeTargets.Parameter |
|
||||
AttributeTargets.ReturnValue,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class UsageAttribute : Attribute
|
||||
{
|
||||
public string Value { get; }
|
||||
|
||||
public UsageAttribute(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
throw new ArgumentException(
|
||||
"Usage text cannot be null or empty.",
|
||||
nameof(value));
|
||||
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Resource.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that an exported property has volatile synchronization
|
||||
/// semantics. This is unrelated to the C# volatile memory modifier.
|
||||
/// </summary>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Property |
|
||||
AttributeTargets.Field,
|
||||
AllowMultiple = false,
|
||||
Inherited = true)]
|
||||
public sealed class VolatileAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user