Refactoring and localization

pull/1/head
Ogoun 6 years ago
parent 618d1de5ff
commit d30d681f0c

@ -6,21 +6,34 @@ namespace ZeroExample
public sealed class MyFirstApp
: BaseWindowsService, IZeroService
{
public MyFirstApp() : base("MyApp") { Log.AddConsoleLogger(); }
public override void PauseAction() { }
public override void ResumeAction() { }
public MyFirstApp() : base("MyApp")
{
Log.AddConsoleLogger();
}
public override void PauseAction()
{
}
public override void ResumeAction()
{
}
public override void StartAction()
{
Log.Info("Started");
}
public override void StopAction() { }
public override void StopAction()
{
}
}
class Program
internal class Program
{
static void Main(string[] args)
private static void Main(string[] args)
{
Bootstrap.Startup<MyFirstApp>(args);
}
}
}
}

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@ -33,4 +32,4 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key="console" value="true"/>
<add key="port" value="8885"/>
<add key="console" value="true" />
<add key="port" value="8885" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

@ -11,6 +11,7 @@ namespace ZeroLevel.Discovery
public abstract class BaseController : ApiController
{
#region Responce create helpers
public static HttpResponseMessage BadRequestAnswer(HttpRequestMessage request, string message)
{
return request.CreateSelfDestroyingResponse(HttpStatusCode.BadRequest,
@ -90,6 +91,7 @@ namespace ZeroLevel.Discovery
}
return null;
}
#endregion
#endregion Responce create helpers
}
}
}

@ -69,4 +69,4 @@ namespace ZeroLevel.Discovery
return response;
}
}
}
}

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using ZeroLevel.Models;
@ -52,4 +51,4 @@ namespace ZeroLevel.Discovery
}
}
}
}
}

@ -5,7 +5,7 @@ namespace ZeroLevel.Discovery
public sealed class DiscoveryService
: BaseWindowsService, IZeroService
{
public DiscoveryService()
public DiscoveryService()
: base("Discovery")
{
}
@ -29,4 +29,4 @@ namespace ZeroLevel.Discovery
{
}
}
}
}

@ -107,4 +107,4 @@ namespace ZeroLevel.Microservices
throw new NotSupportedException($"Protocol {protocol} not supported");
}
}
}
}

@ -1,10 +1,10 @@
namespace ZeroLevel.Discovery
{
class Program
internal class Program
{
static void Main(string[] args)
private static void Main(string[] args)
{
Bootstrap.Startup<DiscoveryService>(args);
}
}
}
}

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@ -33,4 +32,4 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

@ -3,7 +3,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using ZeroLevel.Microservices;
using ZeroLevel.Models;
@ -24,6 +23,7 @@ namespace ZeroLevel.Discovery
}
#region Snapshot
private static readonly object _snapshot_lock = new object();
private void Save()
@ -89,7 +89,8 @@ namespace ZeroLevel.Discovery
Log.Error(ex, "Fault load snapshot");
}
}
#endregion
#endregion Snapshot
private bool Ping(string protocol, string endpoint, string msg)
{
@ -243,4 +244,4 @@ namespace ZeroLevel.Discovery
_lock.Dispose();
}
}
}
}

@ -48,7 +48,7 @@ namespace ZeroLevel.Discovery
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes(new EnableInheritRoutingDirectRouteProvider());
config.Routes.MapHttpRoute(
@ -67,6 +67,7 @@ namespace ZeroLevel.Discovery
}
private static bool _log_request_response;
public static void StartWebPanel(int port,
bool log_request_response)
{
@ -76,4 +77,4 @@ namespace ZeroLevel.Discovery
Log.Info(string.Format("Web panel url: {0}", baseAddress));
}
}
}
}

@ -155,4 +155,4 @@ namespace ZeroLevel.ProxyREST
_baseUrl = baseUri;
}
}
}
}

@ -6,10 +6,13 @@ namespace ZeroLevel.Microservices.Contracts
public interface IDiscoveryClient
{
void Register(MicroserviceInfo info);
IEnumerable<ServiceEndpointInfo> GetServiceEndpoints(string serviceKey);
IEnumerable<ServiceEndpointInfo> GetServiceEndpointsByGroup(string serviceGroup);
IEnumerable<ServiceEndpointInfo> GetServiceEndpointsByType(string serviceType);
ServiceEndpointInfo GetService(string serviceKey, string endpoint);
}
}
}

@ -10,4 +10,4 @@
string Group { get; }
string Type { get; }
}
}
}

@ -18,9 +18,11 @@ namespace ZeroLevel.Microservices
public MicroserviceInfo ServiceInfo { get; set; }
public ExService Server { get; set; }
}
private bool _disposed = false;
private readonly long _registerTaskKey = -1;
private readonly IDiscoveryClient _discoveryClient;
private readonly ConcurrentDictionary<string, MetaService> _services
= new ConcurrentDictionary<string, MetaService>();
@ -116,6 +118,7 @@ namespace ZeroLevel.Microservices
}
#region Private methods
private void ValidateService(IExchangeService service)
{
if (string.IsNullOrWhiteSpace(service.Protocol))
@ -127,6 +130,7 @@ namespace ZeroLevel.Microservices
throw new ArgumentNullException("Service.Key");
}
}
private void ValidateService(MicroserviceInfo service)
{
if (string.IsNullOrWhiteSpace(service.Protocol))
@ -218,9 +222,11 @@ namespace ZeroLevel.Microservices
_discoveryClient.Register(service);
}
}
#endregion
#endregion Private methods
#region Utils
private static Delegate CreateDelegate(MethodInfo methodInfo, object target)
{
Func<Type[], Type> getType;
@ -241,9 +247,11 @@ namespace ZeroLevel.Microservices
}
return Delegate.CreateDelegate(getType(types.ToArray()), target, methodInfo.Name);
}
#endregion
#endregion Utils
#region Inboxes
/// <summary>
/// Регистрация обработчика входящих сообщений
/// </summary>
@ -263,6 +271,7 @@ namespace ZeroLevel.Microservices
Log.SystemError(ex, $"[Exchange] Register inbox handler error. Protocol '{meta.ServiceInfo.Protocol}'. Inbox '{inbox}'. Service '{meta.ServiceInfo.ServiceKey}'");
}
}
/// <summary>
/// Регистрация метода отдающего ответ на входящий запрос
/// </summary>
@ -283,6 +292,7 @@ namespace ZeroLevel.Microservices
Log.SystemError(ex, $"[Exchange] Register inbox replier error. Protocol '{meta.ServiceInfo.Protocol}'. Inbox '{inbox}'. Service '{meta.ServiceInfo.ServiceKey}'");
}
}
/// <summary>
/// Регистрация метода отдающего ответ на входящий запрос, не принимающего входящих данных
/// </summary>
@ -302,9 +312,11 @@ namespace ZeroLevel.Microservices
Log.SystemError(ex, $"[Exchange] Register inbox replier error. Protocol '{meta.ServiceInfo.Protocol}'. Inbox '{inbox}'. Service '{meta.ServiceInfo.ServiceKey}'");
}
}
#endregion
#endregion Inboxes
#region Transport helpers
/// <summary>
/// Call service with round-robin balancing
/// </summary>
@ -503,7 +515,8 @@ namespace ZeroLevel.Microservices
}
}
}
#endregion
#endregion Transport helpers
public void Dispose()
{
@ -516,4 +529,4 @@ namespace ZeroLevel.Microservices
}
}
}
}
}

@ -4,10 +4,8 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ZeroLevel.Microservices.Contracts;
using ZeroLevel.Microservices.Model;
using ZeroLevel.Network.Microservices;
using ZeroLevel.Services.Network;
using ZeroLevel.Services.Serialization;
namespace ZeroLevel.Microservices
{
@ -21,12 +19,14 @@ namespace ZeroLevel.Microservices
private readonly ExServiceHost _host;
#region Ctor
public Exchange(IDiscoveryClient discoveryClient)
{
this._discoveryClient = discoveryClient ?? throw new ArgumentNullException(nameof(discoveryClient));
this._host = new ExServiceHost(this._discoveryClient);
}
#endregion
#endregion Ctor
/// <summary>
/// Регистрация сервиса
@ -42,6 +42,7 @@ namespace ZeroLevel.Microservices
}
#region Balanced send
/// <summary>
/// Отправка сообщения сервису
/// </summary>
@ -63,9 +64,11 @@ namespace ZeroLevel.Microservices
}
public bool Send<T>(string serviceKey, T data) => Send(serviceKey, ZBaseNetwork.DEFAULT_MESSAGE_INBOX, data);
#endregion
#endregion Balanced send
#region Balanced request
public Tresp Request<Treq, Tresp>(string serviceKey, string inbox, Treq data)
{
Tresp response = default(Tresp);
@ -157,9 +160,11 @@ namespace ZeroLevel.Microservices
public Tresp Request<Tresp>(string serviceKey) =>
Request<Tresp>(serviceKey, ZBaseNetwork.DEFAULT_REQUEST_INBOX);
#endregion
#endregion Balanced request
#region Direct request
public Tresp RequestDirect<Treq, Tresp>(string endpoint, string serviceKey, string inbox, Treq data)
{
Tresp response = default(Tresp);
@ -251,9 +256,11 @@ namespace ZeroLevel.Microservices
public Tresp RequestDirect<Tresp>(string endpoint, string serviceKey) =>
RequestDirect<Tresp>(endpoint, serviceKey, ZBaseNetwork.DEFAULT_REQUEST_INBOX);
#endregion
#endregion Direct request
#region Broadcast
/// <summary>
/// Отправка сообщения всем сервисам с указанным ключом в указанный обработчик
/// </summary>
@ -287,6 +294,7 @@ namespace ZeroLevel.Microservices
}
return false;
}
/// <summary>
/// Отправка сообщения всем сервисам с указанным ключом, в обработчик по умолчанию
/// </summary>
@ -295,6 +303,7 @@ namespace ZeroLevel.Microservices
/// <param name="data">Сообщение</param>
/// <returns>true - при успешной отправке</returns>
public bool SendBroadcast<T>(string serviceKey, T data) => SendBroadcast(serviceKey, ZBaseNetwork.DEFAULT_MESSAGE_INBOX, data);
/// <summary>
/// Отправка сообщения всем сервисам конкретного типа в указанный обработчик
/// </summary>
@ -328,6 +337,7 @@ namespace ZeroLevel.Microservices
}
return false;
}
/// <summary>
/// Отправка сообщения всем сервисам конкретного типа, в обработчик по умолчанию
/// </summary>
@ -337,6 +347,7 @@ namespace ZeroLevel.Microservices
/// <returns>true - при успешной отправке</returns>
public bool SendBroadcastByType<T>(string serviceType, T data) =>
SendBroadcastByType(serviceType, ZBaseNetwork.DEFAULT_MESSAGE_INBOX, data);
/// <summary>
/// Отправка сообщения всем сервисам конкретной группы в указанный обработчик
/// </summary>
@ -370,6 +381,7 @@ namespace ZeroLevel.Microservices
}
return false;
}
/// <summary>
/// Отправка сообщения всем сервисам конкретной группы, в обработчик по умолчанию
/// </summary>
@ -379,6 +391,7 @@ namespace ZeroLevel.Microservices
/// <returns>true - при успешной отправке</returns>
public bool SendBroadcastByGroup<T>(string serviceGroup, T data) =>
SendBroadcastByGroup(serviceGroup, ZBaseNetwork.DEFAULT_MESSAGE_INBOX, data);
/// <summary>
/// Широковещательный опрос сервисов по ключу
/// </summary>
@ -402,6 +415,7 @@ namespace ZeroLevel.Microservices
}
return Enumerable.Empty<Tresp>();
}
/// <summary>
/// Широковещательный опрос сервисов по ключу, без сообщеня запроса
/// </summary>
@ -423,6 +437,7 @@ namespace ZeroLevel.Microservices
}
return Enumerable.Empty<Tresp>();
}
/// <summary>
/// Широковещательный опрос сервисов по ключу, в обработчик по умолчанию
/// </summary>
@ -434,6 +449,7 @@ namespace ZeroLevel.Microservices
/// <returns>true - в случае успешной рассылки</returns>
public IEnumerable<Tresp> RequestBroadcast<Treq, Tresp>(string serviceKey, Treq data) =>
RequestBroadcast<Treq, Tresp>(serviceKey, ZBaseNetwork.DEFAULT_REQUEST_INBOX, data);
/// <summary>
/// Широковещательный опрос сервисов по ключу, без сообщеня запроса, в обработчик по умолчанию
/// </summary>
@ -443,6 +459,7 @@ namespace ZeroLevel.Microservices
/// <returns>true - в случае успешной рассылки</returns>
public IEnumerable<Tresp> RequestBroadcast<Tresp>(string serviceKey) =>
RequestBroadcast<Tresp>(serviceKey, ZBaseNetwork.DEFAULT_REQUEST_INBOX);
/// <summary>
/// Широковещательный опрос сервисов по типу сервису
/// </summary>
@ -466,6 +483,7 @@ namespace ZeroLevel.Microservices
}
return Enumerable.Empty<Tresp>();
}
/// <summary>
/// Широковещательный опрос сервисов по типу сервису, без сообщеня запроса
/// </summary>
@ -487,6 +505,7 @@ namespace ZeroLevel.Microservices
}
return Enumerable.Empty<Tresp>();
}
/// <summary>
/// Широковещательный опрос сервисов по типу сервису, в обработчик по умолчанию
/// </summary>
@ -498,6 +517,7 @@ namespace ZeroLevel.Microservices
/// <returns>true - в случае успешной рассылки</returns>
public IEnumerable<Tresp> RequestBroadcastByType<Treq, Tresp>(string serviceType, Treq data) =>
RequestBroadcastByType<Treq, Tresp>(serviceType, ZBaseNetwork.DEFAULT_REQUEST_INBOX, data);
/// <summary>
/// Широковещательный опрос сервисов по типу, без сообщеня запроса, в обработчик по умолчанию
/// </summary>
@ -507,6 +527,7 @@ namespace ZeroLevel.Microservices
/// <returns>true - в случае успешной рассылки</returns>
public IEnumerable<Tresp> RequestBroadcastByType<Tresp>(string serviceType) =>
RequestBroadcastByType<Tresp>(serviceType, ZBaseNetwork.DEFAULT_REQUEST_INBOX);
/// <summary>
/// Широковещательный опрос сервисов по группе сервисов
/// </summary>
@ -530,6 +551,7 @@ namespace ZeroLevel.Microservices
}
return Enumerable.Empty<Tresp>();
}
/// <summary>
/// Широковещательный опрос сервисов по группе сервисов, без сообщения запроса
/// </summary>
@ -551,6 +573,7 @@ namespace ZeroLevel.Microservices
}
return Enumerable.Empty<Tresp>();
}
/// <summary>
/// Широковещательный опрос сервисов по группе сервисов в обработчик по умолчанию
/// </summary>
@ -562,6 +585,7 @@ namespace ZeroLevel.Microservices
/// <returns>true - в случае успешной рассылки</returns>
public IEnumerable<Tresp> RequestBroadcastByGroup<Treq, Tresp>(string serviceGroup, Treq data) =>
RequestBroadcastByGroup<Treq, Tresp>(serviceGroup, ZBaseNetwork.DEFAULT_REQUEST_INBOX, data);
/// <summary>
/// Широковещательный опрос сервисов по группе сервисов, без сообщения запроса, в обработчик по умолчанию
/// </summary>
@ -573,6 +597,7 @@ namespace ZeroLevel.Microservices
RequestBroadcastByGroup<Tresp>(serviceGroup, ZBaseNetwork.DEFAULT_REQUEST_INBOX);
#region Private
private IEnumerable<Tresp> _RequestBroadcast<Treq, Tresp>(List<IExClient> clients, string inbox, Treq data)
{
var response = new List<Tresp>();
@ -628,13 +653,14 @@ namespace ZeroLevel.Microservices
}
return response;
}
#endregion
#endregion
#endregion Private
#endregion Broadcast
public void Dispose()
{
this._host.Dispose();
}
}
}
}

@ -107,4 +107,4 @@ namespace ZeroLevel.Microservices
throw new NotSupportedException($"Protocol {protocol} not supported");
}
}
}
}

@ -19,6 +19,7 @@ namespace ZeroLevel.Microservices.Model
public byte[] Payload { get; set; }
#region IBinarySerializable
public void Deserialize(IBinaryReader reader)
{
this.Id = reader.ReadGuid();
@ -40,19 +41,23 @@ namespace ZeroLevel.Microservices.Model
writer.WriteInt32((int)this.CheckpointType);
writer.WriteBytes(this.Payload);
}
#endregion
#endregion IBinarySerializable
#region Ctors
public Checkpoint()
{
this.Id = Guid.NewGuid();
this.Timestamp = DateTime.Now.Ticks;
}
public Checkpoint(Guid id)
{
this.Timestamp = DateTime.Now.Ticks;
this.Id = id;
}
public Checkpoint(Checkpoint other)
{
this.Id = other.Id;
@ -63,9 +68,11 @@ namespace ZeroLevel.Microservices.Model
this.Payload = other.Payload;
this.ReasonPhrase = other.ReasonPhrase;
}
#endregion
#endregion Ctors
#region Equals & Hash
public override int GetHashCode()
{
return base.GetHashCode();
@ -75,16 +82,20 @@ namespace ZeroLevel.Microservices.Model
{
return this.Equals(obj as Checkpoint);
}
#endregion
#endregion Equals & Hash
#region ICloneable
public object Clone()
{
return new Checkpoint(this);
}
#endregion
#endregion ICloneable
#region IEquatable
public bool Equals(Checkpoint other)
{
if (this.Id != other.Id) return false;
@ -96,6 +107,7 @@ namespace ZeroLevel.Microservices.Model
if (false == ArrayExtensions.Equals(this.Payload, other.Payload)) return false;
return true;
}
#endregion
#endregion IEquatable
}
}
}

@ -18,4 +18,4 @@ namespace ZeroLevel.Microservices.Model
this.ReasonPhrase = other.ReasonPhrase;
}
}
}
}

@ -7,4 +7,4 @@
Finish = 2,
Transfer = 3
}
}
}

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@ -33,4 +32,4 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

@ -15,6 +15,7 @@ namespace ZeroLevel.Microservices
BaseProxy, IDiscoveryClient
{
#region WebAPI
private IEnumerable<ServiceEndpointsInfo> GetRecords()
{
return GET<IEnumerable<ServiceEndpointsInfo>>("api/v0/routes");
@ -24,13 +25,16 @@ namespace ZeroLevel.Microservices
{
return POST<InvokeResult>("api/v0/routes", info);
}
#endregion
#endregion WebAPI
// Таблица по ключам
private readonly ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>> _tableByKey =
new ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>>();
private readonly ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>> _tableByGroups =
new ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>>();
private readonly ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>> _tableByTypes =
new ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>>();
@ -176,4 +180,4 @@ namespace ZeroLevel.Microservices
return Enumerable.Empty<ServiceEndpointInfo>();
}
}
}
}

@ -8,6 +8,7 @@ namespace ZeroLevel.Models
public abstract class BaseModel
{
#region Equal
public bool Equals(BaseModel other)
{
if (this == null)
@ -30,10 +31,13 @@ namespace ZeroLevel.Models
}
public static bool operator ==(BaseModel first, BaseModel second) => Equals(first, second);
public static bool operator !=(BaseModel first, BaseModel second) => !Equals(first, second);
#endregion
#endregion Equal
public abstract override int GetHashCode();
public abstract object Clone();
}
}
}

@ -17,32 +17,39 @@ namespace ZeroLevel.Models
/// Id
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// File name
/// </summary>
public string FileName { get; set; }
/// <summary>
/// Content type (pdf, doc, etc.)
/// </summary>
public string ContentType { get; set; }
/// <summary>
/// Content
/// </summary>
public byte[] Document { get; set; }
/// <summary>
/// Creation date
/// </summary>
public DateTime Created { get; set; }
/// <summary>
/// Optional headers
/// </summary>
public List<Header> Headers { get; set; }
/// <summary>
/// Categories
/// </summary>
public List<Category> Categories { get; set; }
#region Ctors
public BinaryDocument()
{
Created = DateTime.Now;
@ -58,9 +65,11 @@ namespace ZeroLevel.Models
Deserialize(reader);
}
}
#endregion
#endregion Ctors
#region IBinarySerializable
public void Serialize(IBinaryWriter writer)
{
writer.WriteGuid(this.Id);
@ -82,9 +91,11 @@ namespace ZeroLevel.Models
this.Headers = reader.ReadCollection<Header>();
this.Categories = reader.ReadCollection<Category>();
}
#endregion
#endregion IBinarySerializable
#region Equals & Hash
public override bool Equals(object obj)
{
return this.Equals(obj as BinaryDocument);
@ -111,11 +122,12 @@ namespace ZeroLevel.Models
{
return Id.GetHashCode();
}
#endregion
#endregion Equals & Hash
public object Clone()
{
return new BinaryDocument(this);
}
}
}
}

@ -2,15 +2,15 @@
namespace ZeroLevel.Models
{
public interface IEntity
public interface IEntity
: ICloneable
{
Guid Id { get; }
}
public interface IEntity<TKey>
public interface IEntity<TKey>
: ICloneable
{
TKey Id { get; }
}
}
}

@ -12,10 +12,13 @@ namespace ZeroLevel.Models
IBinarySerializable
{
#region Static
private static readonly InvokeResult _successResultWitoutComment = new InvokeResult(true, String.Empty);
#endregion
#endregion Static
#region Ctor
public InvokeResult()
{
}
@ -25,35 +28,43 @@ namespace ZeroLevel.Models
Success = success;
Comment = comment;
}
#endregion
#endregion Ctor
#region Properties
/// <summary>
/// true when action successfully invoked
/// </summary>
[DataMember]
public bool Success;
/// <summary>
/// Comment
/// </summary>
[DataMember]
public string Comment;
#endregion
#endregion Properties
#region Fabric methods
/// <summary>
/// Error when action invoking
/// </summary>
public static InvokeResult Fault(string comment) { return new InvokeResult(false, comment); }
/// <summary>
/// Successfully
/// </summary>
/// </summary>
public static InvokeResult Succeeding(string comment = "") { return new InvokeResult(true, comment); }
/// <summary>
/// Successfully
/// </summary>
public static InvokeResult Succeeding() { return _successResultWitoutComment; }
#endregion
#endregion Fabric methods
public virtual void Serialize(IBinaryWriter writer)
{
@ -75,6 +86,7 @@ namespace ZeroLevel.Models
public T Value { get { return _value; } }
#region Ctor
public InvokeResult(bool success, string comment)
{
Success = success;
@ -87,12 +99,22 @@ namespace ZeroLevel.Models
Success = success;
Comment = comment;
}
#endregion
#endregion Ctor
#region Fabric methods
public static InvokeResult<T> Succeeding(T value, string comment = "") { return new InvokeResult<T>(value, true, comment); }
public static InvokeResult<T> Fault<T>(string comment) { return new InvokeResult<T>(false, comment); }
#endregion
public static InvokeResult<T> Succeeding(T value, string comment = "")
{
return new InvokeResult<T>(value, true, comment);
}
public static InvokeResult<T> Fault<T>(string comment)
{
return new InvokeResult<T>(false, comment);
}
#endregion Fabric methods
public override void Serialize(IBinaryWriter writer)
{
@ -108,4 +130,4 @@ namespace ZeroLevel.Models
this._value = reader.ReadCompatible<T>();
}
}
}
}

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@ -33,4 +32,4 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

@ -22,7 +22,6 @@ namespace ZeroLevel.Services.Applications
public ZeroServiceState State => _state;
private ZeroServiceState _state;
private ManualResetEvent InteraciveModeWorkingFlag = new ManualResetEvent(false);
public void InteractiveStart(string[] args)
@ -35,13 +34,19 @@ namespace ZeroLevel.Services.Applications
}
#region IZeroService
public abstract void StartAction();
public abstract void StopAction();
public abstract void PauseAction();
public abstract void ResumeAction();
#endregion
#endregion IZeroService
#region Windows service
protected override void OnStart(string[] args)
{
if (_state == ZeroServiceState.Initialized)
@ -116,6 +121,7 @@ namespace ZeroLevel.Services.Applications
}
}
}
#endregion
#endregion Windows service
}
}
}

@ -111,4 +111,4 @@ namespace ZeroLevel.Services.Applications
return installer;
}
}
}
}

@ -57,6 +57,7 @@ namespace ZeroLevel
Log.Fatal(ex, "[Bootstrap] Fault service install");
}
}
/// <summary>
/// Uninstall from windows services
/// </summary>
@ -163,4 +164,4 @@ namespace ZeroLevel
try { Injector.Default.Dispose(); Injector.Dispose(); } catch { }
}
}
}
}

@ -5,10 +5,13 @@
ZeroServiceState State { get; }
void StartAction();
void StopAction();
void PauseAction();
void ResumeAction();
void InteractiveStart(string[] args);
}
}
}

@ -10,4 +10,4 @@ namespace ZeroLevel.Services.Applications
Paused = 2,
Stopped = 3
}
}
}

@ -179,6 +179,7 @@ namespace ZeroLevel.Services.Async
public IAsyncWaitQueue<object> WaitQueue { get { return _cv._queue; } }
}
// ReSharper restore UnusedMember.Local
}
}
}

@ -35,4 +35,4 @@ namespace ZeroLevel.Services.Async
return default(T);
}
}
}
}

@ -186,6 +186,7 @@ namespace ZeroLevel.Services.Async
public IAsyncWaitQueue<IDisposable> WaitQueue { get { return _mutex._queue; } }
}
// ReSharper restore UnusedMember.Local
}
}
}

@ -154,6 +154,7 @@ namespace ZeroLevel.Services.Async
public Task CurrentTask { get { return _mre._tcs.Task; } }
}
// ReSharper restore UnusedMember.Local
}
}
}

@ -132,4 +132,4 @@ namespace ZeroLevel.Services.Async
_conditionVariable.NotifyAll();
}
}
}
}

@ -734,4 +734,4 @@ namespace ZeroLevel.Services.Async
return DequeueFromAny(queues, CancellationToken.None);
}
}
}
}

@ -82,6 +82,7 @@ namespace ZeroLevel.Services.Async
[DebuggerNonUserCode]
internal int GetReaderCountForDebugger { get { return (_locksHeld > 0 ? _locksHeld : 0); } }
[DebuggerNonUserCode]
internal bool GetUpgradeInProgressForDebugger { get { return !_upgradeReaderQueue.IsEmpty; } }
@ -764,6 +765,7 @@ namespace ZeroLevel.Services.Async
public IAsyncWaitQueue<IDisposable> UpgradeReaderWaitQueue { get { return _rwl._upgradeReaderQueue; } }
}
// ReSharper restore UnusedMember.Local
}
}
}

@ -172,6 +172,7 @@ namespace ZeroLevel.Services.Async
public IAsyncWaitQueue<object> WaitQueue { get { return _semaphore._queue; } }
}
// ReSharper restore UnusedMember.Local
}
}
}

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -205,4 +203,4 @@ namespace ZeroLevel.Services.Async
}
}
}
}
}

@ -100,4 +100,4 @@ namespace ZeroLevel.Services.Async
return FromTask(source, TaskContinuationOptions.None);
}
}
}
}

@ -7,7 +7,7 @@ namespace ZeroLevel.Services.Async
/// <summary>
/// Holds the task for a cancellation token, as well as the token registration. The registration is disposed when this instance is disposed.
/// </summary>
public sealed class CancellationTokenTaskSource<T>
public sealed class CancellationTokenTaskSource<T>
: IDisposable
{
/// <summary>
@ -44,4 +44,4 @@ namespace ZeroLevel.Services.Async
_registration?.Dispose();
}
}
}
}

@ -248,7 +248,8 @@ namespace ZeroLevel.Services.Async
return this.GetEnumerator();
}
#endregion
#endregion GenericListImplementations
#region ObjectListImplementations
int System.Collections.IList.Add(object value)
@ -329,7 +330,8 @@ namespace ZeroLevel.Services.Async
get { return this; }
}
#endregion
#endregion ObjectListImplementations
#region GenericListHelpers
/// <summary>
@ -386,7 +388,7 @@ namespace ZeroLevel.Services.Async
}
}
#endregion
#endregion GenericListHelpers
/// <summary>
/// Gets a value indicating whether this instance is empty.
@ -833,4 +835,4 @@ namespace ZeroLevel.Services.Async
}
}
}
}
}

@ -9,7 +9,7 @@ namespace ZeroLevel.Services.Async
public static class ExceptionHelpers
{
/// <summary>
/// Attempts to prepare the exception for re-throwing by preserving the stack trace.
/// Attempts to prepare the exception for re-throwing by preserving the stack trace.
/// The returned exception should be immediately thrown.
/// </summary>
/// <param name="exception">The exception. May not be <c>null</c>.</param>
@ -20,4 +20,4 @@ namespace ZeroLevel.Services.Async
return exception;
}
}
}
}

@ -15,6 +15,7 @@ namespace ZeroLevel.Services.Async
/// </summary>
// ReSharper disable StaticFieldInGenericType
private static int _lastId;
// ReSharper restore StaticFieldInGenericType
/// <summary>
@ -45,4 +46,4 @@ namespace ZeroLevel.Services.Async
return id;
}
}
}
}

@ -58,4 +58,4 @@ namespace ZeroLevel.Services.Async
/// </summary>
public CancellationToken Token { get { return _token; } }
}
}
}

@ -134,4 +134,4 @@ namespace ZeroLevel.Services.Async
return _tcs.TrySetResult(null);
}
}
}
}

@ -75,6 +75,7 @@ namespace ZeroLevel.Services.Async
}
return @this.TrySetResult(resultFunc());
}
/// <summary>
/// Attempts to complete a <see cref="TaskCompletionSource{TResult}"/>, propagating the completion of <paramref name="eventArgs"/>.
/// </summary>
@ -91,6 +92,7 @@ namespace ZeroLevel.Services.Async
return @this.TrySetException(eventArgs.Error);
return @this.TrySetResult(getResult());
}
/// <summary>
/// Attempts to complete a <see cref="TaskCompletionSource"/>, propagating the completion of <paramref name="task"/>.
/// </summary>
@ -105,6 +107,7 @@ namespace ZeroLevel.Services.Async
return @this.TrySetCanceled();
return @this.TrySetResult();
}
/// <summary>
/// Attempts to complete a <see cref="TaskCompletionSource"/>, propagating the completion of <paramref name="eventArgs"/>.
/// </summary>
@ -119,6 +122,7 @@ namespace ZeroLevel.Services.Async
return @this.TrySetException(eventArgs.Error);
return @this.TrySetResult();
}
/// <summary>
/// Attempts to complete a <see cref="TaskCompletionSource{TResult}"/> with the specified value, forcing all continuations onto a threadpool thread even if they specified <c>ExecuteSynchronously</c>.
/// </summary>
@ -166,6 +170,7 @@ namespace ZeroLevel.Services.Async
{
}
}
/// <summary>
/// Creates a new TCS for use with async code, and which forces its continuations to execute asynchronously.
/// </summary>
@ -174,6 +179,7 @@ namespace ZeroLevel.Services.Async
{
return new TaskCompletionSource<TResult>(TaskCreationOptions.RunContinuationsAsynchronously);
}
/// <summary>
/// Attempts to complete a <see cref="TaskCompletionSource"/> as canceled, forcing all continuations onto a threadpool thread even if they specified <c>ExecuteSynchronously</c>.
/// </summary>
@ -275,4 +281,4 @@ namespace ZeroLevel.Services.Async
}
}
}
}
}

@ -140,4 +140,4 @@ namespace ZeroLevel.Services.Async
}
}
}
}
}

@ -54,6 +54,7 @@ namespace ZeroLevel.Services.Async
using (var cancelTaskSource = new CancellationTokenTaskSource<TResult>(cancellationToken))
return await await Task.WhenAny(task, cancelTaskSource.Task).ConfigureAwait(false);
}
/// <summary>
/// Waits for the task to complete, unwrapping any exceptions.
/// </summary>
@ -152,4 +153,4 @@ namespace ZeroLevel.Services.Async
}
}
}
}
}

@ -51,4 +51,4 @@ namespace ZeroLevel.Services.Async
return Task.WhenAll(tasks);
}
}
}
}

@ -68,6 +68,7 @@ namespace ZeroLevel.Services.Collections
return (T)_getter.Invoke(_instance, key);
}
}
private readonly ConcurrentDictionary<Type, ConcreteTypeRepository> _shardedRepositories =
new ConcurrentDictionary<Type, ConcreteTypeRepository>();
@ -138,4 +139,4 @@ namespace ZeroLevel.Services.Collections
this[typeof(T)].InsertOrUpdate<T>(key, value);
}
}
}
}

@ -22,6 +22,7 @@ namespace ZeroLevel.Services.Collections
_nextIndex = 0;
_count = 0;
}
/// <summary>
/// If count is limited when intem adding, oldest item replace with new item
/// </summary>
@ -138,4 +139,4 @@ namespace ZeroLevel.Services.Collections
return dump;
}
}
}
}

@ -3,11 +3,17 @@
public interface IEverythingStorage
{
bool TryAdd<T>(string key, T value);
bool ContainsKey<T>(string key);
bool TryRemove<T>(string key);
void Add<T>(string key, T value);
void AddOrUpdate<T>(string key, T value);
void Remove<T>(string key);
T Get<T>(string key);
}
}
}

@ -5,10 +5,15 @@ namespace ZeroLevel.Services.Collections
public interface IFixSizeQueue<T>
{
void Push(T item);
long Count { get; }
bool TryTake(out T t);
T Take();
IEnumerable<T> Dump();
bool Contains(T item, IComparer<T> comparer = null);
}
}
}

@ -15,7 +15,9 @@ namespace ZeroLevel.Services.Collections
{
private readonly List<T> _collection =
new List<T>();
private int _index = -1;
private readonly ReaderWriterLockSlim _lock =
new ReaderWriterLockSlim();
@ -134,4 +136,4 @@ namespace ZeroLevel.Services.Collections
_lock.Dispose();
}
}
}
}

@ -14,19 +14,24 @@ namespace ZeroLevel.Services.Config
IConfiguration
{
#region Private members
/// <summary>
/// When true, any changes disallow
/// </summary>
private bool _freezed = false;
/// <summary>
/// When true, freeze permanent, can't be canceled
/// </summary>
private bool _permanentFreezed = false;
private readonly object _freezeLock = new object();
/// <summary>
/// Key-values dictionary
/// </summary>
private readonly ConcurrentDictionary<string, IList<string>> _keyValues = new ConcurrentDictionary<string, IList<string>>();
/// <summary>
/// Empty list
/// </summary>
@ -40,9 +45,11 @@ namespace ZeroLevel.Services.Config
}
return key.Trim().ToLower(CultureInfo.InvariantCulture);
}
#endregion
#endregion Private members
#region Properties
/// <summary>
/// Get values by key
/// </summary>
@ -61,6 +68,7 @@ namespace ZeroLevel.Services.Config
return EmptyValuesList;
}
}
/// <summary>
/// Keys list
/// </summary>
@ -76,11 +84,13 @@ namespace ZeroLevel.Services.Config
return _freezed;
}
}
#endregion
#endregion Properties
#region Public methods
#region Get
/// <summary>
/// Получение списка значение соотвествующих указанному ключу
/// </summary>
@ -90,6 +100,7 @@ namespace ZeroLevel.Services.Config
{
return this[key];
}
/// <summary>
/// Получение первого значения для указанного ключа
/// </summary>
@ -140,6 +151,7 @@ namespace ZeroLevel.Services.Config
}
throw new KeyNotFoundException("Parameter not found: " + key);
}
/// <summary>
/// Получение первого значения для указанного ключа, или значения по умолчанию
/// </summary>
@ -156,6 +168,7 @@ namespace ZeroLevel.Services.Config
}
return defaultValue;
}
/// <summary>
/// Получение первого значения для указанного ключа, или значения по умолчанию, с попыткой преобразования в указанный тип
/// </summary>
@ -172,6 +185,7 @@ namespace ZeroLevel.Services.Config
}
return default(T);
}
/// <summary>
/// Получение первого значения для указанного ключа, или значения по умолчанию, с попыткой преобразования в указанный тип
/// </summary>
@ -189,6 +203,7 @@ namespace ZeroLevel.Services.Config
}
return defaultValue;
}
/// <summary>
/// Проверка наличия ключа и непустого списка связанных с ним значений
/// </summary>
@ -199,6 +214,7 @@ namespace ZeroLevel.Services.Config
key = GetKey(key);
return _keyValues.ContainsKey(key) && _keyValues[key].Count > 0;
}
/// <summary>
/// Проверка наличия одного из ключей
/// </summary>
@ -208,6 +224,7 @@ namespace ZeroLevel.Services.Config
if (Contains(key)) return true;
return false;
}
/// <summary>
/// Проверка наличия ключа и связанного с ним значения
/// </summary>
@ -223,6 +240,7 @@ namespace ZeroLevel.Services.Config
}
return false;
}
/// <summary>
/// Количество значений связанных с указанным ключом
/// </summary>
@ -237,7 +255,8 @@ namespace ZeroLevel.Services.Config
}
return 0;
}
#endregion
#endregion Get
/// <summary>
/// Add key-value
@ -257,6 +276,7 @@ namespace ZeroLevel.Services.Config
}
return this;
}
/// <summary>
/// Set unique value for key
/// </summary>
@ -277,6 +297,7 @@ namespace ZeroLevel.Services.Config
}
return this;
}
/// <summary>
/// Clean values binded with key
/// </summary>
@ -293,6 +314,7 @@ namespace ZeroLevel.Services.Config
}
return this;
}
/// <summary>
/// Configuration drop
/// </summary>
@ -304,6 +326,7 @@ namespace ZeroLevel.Services.Config
}
return this;
}
/// <summary>
/// Remove key and binded values
/// </summary>
@ -349,9 +372,11 @@ namespace ZeroLevel.Services.Config
return false;
}
}
#endregion
#endregion Public methods
#region IEquatable
public bool Equals(IConfiguration other)
{
if (other == null)
@ -371,9 +396,11 @@ namespace ZeroLevel.Services.Config
}
return true;
}
#endregion
#endregion IEquatable
#region Binary Serializable
public void Serialize(IBinaryWriter writer)
{
writer.WriteBoolean(this._freezed);
@ -408,6 +435,7 @@ namespace ZeroLevel.Services.Config
_keyValues.TryAdd(key, list_values);
}
}
#endregion
#endregion Binary Serializable
}
}
}

@ -13,6 +13,7 @@ namespace ZeroLevel.Services.Config
IConfigurationSet
{
#region Private members
/// <summary>
/// Sections
/// </summary>
@ -26,9 +27,11 @@ namespace ZeroLevel.Services.Config
}
return key.Trim().ToLower(CultureInfo.InvariantCulture);
}
#endregion
#endregion Private members
#region Properties
public IConfiguration Default
{
get { return _sections[Configuration.DEFAULT_SECTION_NAME]; }
@ -60,9 +63,10 @@ namespace ZeroLevel.Services.Config
}
}
#endregion
#endregion Properties
#region Methods
public BaseConfigurationSet()
{
CreateSection(Configuration.DEFAULT_SECTION_NAME);
@ -119,18 +123,22 @@ namespace ZeroLevel.Services.Config
}
return false;
}
#endregion
#endregion Methods
#region IEquatable
public bool Equals(IConfigurationSet other)
{
if (other == null) return false;
return this.SectionNames.NoOrderingEquals(other.SectionNames) &&
this.Sections.NoOrderingEquals(other.Sections);
}
#endregion
#endregion IEquatable
#region Freezing
private readonly object _freezeLock = new object();
public bool FreezeConfiguration(bool permanent = false)
@ -193,9 +201,11 @@ namespace ZeroLevel.Services.Config
return false;
}
}
#endregion
#endregion Freezing
#region Binary Serializable
public void Serialize(IBinaryWriter writer)
{
writer.WriteBoolean(this._sectionsFreezed);
@ -220,6 +230,7 @@ namespace ZeroLevel.Services.Config
_sections.TryAdd(key, reader.Read<BaseConfiguration>());
}
}
#endregion
#endregion Binary Serializable
}
}
}

@ -23,6 +23,7 @@ namespace ZeroLevel
public const string DEFAULT_SECTION_NAME = "_defaultsection";
#region Ctor
static Configuration()
{
_empty = new BaseConfiguration();
@ -30,9 +31,11 @@ namespace ZeroLevel
_empty.Freeze(true);
_emptySet.FreezeConfiguration(true);
}
#endregion
#endregion Ctor
#region Cachee
private static readonly IConfiguration _empty;
private static readonly IConfigurationSet _emptySet;
private static readonly ConcurrentDictionary<string, IConfiguration> _cachee = new ConcurrentDictionary<string, IConfiguration>();
@ -97,9 +100,11 @@ namespace ZeroLevel
}
return result;
}
#endregion
#endregion Cachee
#region Factory
public static IConfiguration Create()
{
return new BaseConfiguration();
@ -114,41 +119,49 @@ namespace ZeroLevel
{
return new BaseConfigurationSet(defaultConfiguration);
}
#endregion
#endregion Factory
#region Read configuration
/// <summary>
/// Создание конфигурации из секции AppSettings файла app.config или web.config
/// </summary>
/// <returns>Конфигурация</returns>
public static IConfiguration ReadFromApplicationConfig() { return new ApplicationConfigReader().ReadConfiguration(); }
/// <summary>
/// Создание конфигурации из секции AppSettings файла app.config или web.config, дополняется секцией 'ConnectionStrings'
/// </summary>
/// <returns>Конфигурация</returns>
public static IConfigurationSet ReadSetFromApplicationConfig() { return new ApplicationConfigReader().ReadConfigurationSet(); }
/// <summary>
/// Создание конфигурации из секции AppSettings файла app.config или web.config
/// </summary>
/// <returns>Конфигурация</returns>
public static IConfiguration ReadFromApplicationConfig(string configFilePath) { return new ApplicationConfigReader(configFilePath).ReadConfiguration(); }
/// <summary>
/// Создание конфигурации из секции AppSettings файла app.config или web.config, дополняется секцией 'ConnectionStrings'
/// </summary>
/// <returns>Конфигурация</returns>
public static IConfigurationSet ReadSetFromApplicationConfig(string configFilePath) { return new ApplicationConfigReader(configFilePath).ReadConfigurationSet(); }
/// <summary>
/// Создание конфигурации из ini файла
/// </summary>
/// <param name="path">Путь к ini-файлу</param>
/// <returns>Конфигурация</returns>
public static IConfiguration ReadFromIniFile(string path) { return new IniFileReader(path).ReadConfiguration(); }
/// <summary>
/// Создание конфигурации из ini файла, с учетом секций
/// </summary>
/// <param name="path">Путь к ini-файлу</param>
/// <returns>Конфигурация</returns>
public static IConfigurationSet ReadSetFromIniFile(string path) { return new IniFileReader(path).ReadConfigurationSet(); }
/// <summary>
/// Создание конфигурации из параметров командной строки
/// </summary>
@ -156,22 +169,29 @@ namespace ZeroLevel
/// <returns>Конфигурация</returns>
public static IConfiguration ReadFromCommandLine(string[] args) { return new CommandLineReader(args).ReadConfiguration(); }
public static IConfigurationSet ReadBinary(IBinaryReader reader) { return reader.Read<BaseConfigurationSet>(); }
#endregion
public static IConfigurationSet ReadBinary(IBinaryReader reader)
{
return reader.Read<BaseConfigurationSet>();
}
#endregion Read configuration
#region Write configuration
/// <summary>
/// Запись простой конфигурации в ini-файл
/// </summary>
/// <param name="configuration">Конфигурация</param>
/// <param name="path">Путь к ini-файлу</param>
public static void WriteToIniFile(IConfiguration configuration, string path) { new IniFileWriter(path).WriteConfiguration(configuration); }
/// <summary>
/// Запись полной конфигурации в ini-файл
/// </summary>
/// <param name="configuration">Конфигурация</param>
/// <param name="path">Путь к ini-файлу</param>
public static void WriteSetToIniFile(IConfigurationSet configuration, string path) { new IniFileWriter(path).WriteConfigurationSet(configuration); }
#endregion
#endregion Write configuration
}
}
}

@ -12,103 +12,128 @@ namespace ZeroLevel
IBinarySerializable
{
#region Properties
/// <summary>
/// Get values by key
/// </summary>
IEnumerable<string> this[string key] { get; }
/// <summary>
/// Keys
/// </summary>
IEnumerable<string> Keys { get; }
/// <summary>
/// Configuration is locked for change when true
/// </summary>
bool Freezed { get; }
#endregion
#endregion Properties
#region Methods
/// <summary>
/// Get values by key
/// </summary>
/// <param name="key">Key</param>
/// <returns>Values list</returns>
IEnumerable<string> Items(string key);
/// <summary>
/// Get first value by key
/// </summary>
string First(string key);
/// <summary>
/// Get first value by key with cast to <typeparamref name="T"/>
/// </summary>
T First<T>(string key);
/// <summary>
/// Get first or default value by key
/// </summary>
string FirstOrDefault(string name, string defaultValue);
/// <summary>
/// Get first or default value by key with cast to <typeparamref name="T"/>
/// </summary>
T FirstOrDefault<T>(string name);
/// <summary>
/// Get first or default value by key with cast to <typeparamref name="T"/>
/// </summary>
T FirstOrDefault<T>(string name, T defaultValue);
/// <summary>
/// Check key exists
/// </summary>
bool Contains(string key);
/// <summary>
/// Check one of key exists
/// </summary>
bool Contains(params string[] keys);
/// <summary>
/// true if exists one or more values by key
/// </summary>
bool ContainsValue(string key, string value);
/// <summary>
/// Count values by key
/// </summary>
int Count(string key);
/// <summary>
/// Do action if key exists, action takes first value
/// </summary>
void DoWithFirst(string key, Action<string> action);
/// <summary>
/// Do action if key exists, action takes first value with cast to <typeparamref name="T"/>
/// </summary>
void DoWithFirst<T>(string key, Action<T> action);
#endregion
#endregion Methods
#region Create, Clean, Delete
/// <summary>
/// Clean
/// </summary>
IConfiguration Clear();
/// <summary>
/// Clean values by key
/// </summary>
IConfiguration Clear(string key);
/// <summary>
/// Remove key and binded values
/// </summary>
IConfiguration Remove(string key);
/// <summary>
/// Append key and value
/// </summary>
IConfiguration Append(string key, string value);
/// <summary>
/// Set key with one value, if any values by key exists, they will be dropped
/// </summary>
IConfiguration SetUnique(string key, string value);
/// <summary>
/// Sets a prohibition on changing
/// </summary>
/// <returns>false - prohibition was set already</returns>
bool Freeze(bool permanent = false);
/// <summary>
/// Remove a prohibition on changing
/// </summary>
bool Unfreeze();
#endregion
#endregion Create, Clean, Delete
}
}
}

@ -3,6 +3,7 @@
public interface IConfigurationReader
{
IConfiguration ReadConfiguration();
IConfigurationSet ReadConfigurationSet();
}
}
}

@ -12,66 +12,81 @@ namespace ZeroLevel
IBinarySerializable
{
#region Properties
/// <summary>
/// Default section, always exists
/// </summary>
IConfiguration Default { get; }
/// <summary>
/// Get configuration section by name
/// </summary>
IConfiguration this[string sectionName] { get; }
/// <summary>
/// Get configuration section names
/// </summary>
IEnumerable<string> SectionNames { get; }
/// <summary>
/// Get all sections
/// </summary>
IEnumerable<IConfiguration> Sections { get; }
/// <summary>
/// true if changing disallow
/// </summary>
bool SectionsFreezed { get; }
#endregion
#endregion Properties
#region Methods
/// <summary>
/// Create section
/// </summary>
/// <param name="sectionName">Section name</param>
IConfiguration CreateSection(string sectionName);
/// <summary>
/// Get configuration section by name
/// </summary>
/// <param name="sectionName">Название секции</param>
/// <returns>Секция с данными</returns>
IConfiguration GetSection(string sectionName);
/// <summary>
/// Check for a section by name
/// </summary>
/// <param name="sectionName">Section name</param>
bool ContainsSection(string sectionName);
/// <summary>Remove section by name
/// </summary>
/// <param name="sectionName">Section name</param>
bool RemoveSection(string sectionName);
/// <summary>
/// Sets a prohibition on changing configurations
/// </summary>
bool FreezeConfiguration(bool permanent = false);
/// <summary>
/// Sets a prohibition on changing sections
/// </summary>
bool FreezeSections(bool permanent = false);
/// <summary>
/// Remove a prohibition on changing configurations
/// </summary>
/// <returns>false - если запрет снят</returns>
bool UnfreezeConfiguration();
/// <summary>
/// Sets a prohibition on changing sections
/// </summary>
bool UnfreezeSections();
#endregion
#endregion Methods
}
}
}

@ -3,6 +3,7 @@
public interface IConfigurationWriter
{
void WriteConfiguration(IConfiguration configuration);
void WriteConfigurationSet(IConfigurationSet configuration);
}
}
}

@ -102,4 +102,4 @@ namespace ZeroLevel.Services.Config.Implementation
return ReadSection("appSettings");
}
}
}
}

@ -1,12 +1,19 @@
namespace ZeroLevel.Services.Config.Implementation
{
internal sealed class ApplicationConfigReader
internal sealed class ApplicationConfigReader
: IConfigurationReader
{
private readonly AppWebConfigReader _reader;
internal ApplicationConfigReader() { _reader = new AppWebConfigReader(); }
internal ApplicationConfigReader(string configFilePath) { _reader = new AppWebConfigReader(configFilePath); }
internal ApplicationConfigReader()
{
_reader = new AppWebConfigReader();
}
internal ApplicationConfigReader(string configFilePath)
{
_reader = new AppWebConfigReader(configFilePath);
}
public IConfiguration ReadConfiguration()
{
@ -36,4 +43,4 @@
return result;
}
}
}
}

@ -3,7 +3,7 @@ using System.Globalization;
namespace ZeroLevel.Services.Config.Implementation
{
internal sealed class CommandLineReader
internal sealed class CommandLineReader
: IConfigurationReader
{
private readonly string[] _args;
@ -51,4 +51,4 @@ namespace ZeroLevel.Services.Config.Implementation
return Configuration.CreateSet(ReadConfiguration());
}
}
}
}

@ -7,7 +7,7 @@ namespace ZeroLevel.Services.Config.Implementation
/// <summary>
/// Чтение конфигурации из ini файла
/// </summary>
internal sealed class IniFileReader
internal sealed class IniFileReader
: IConfigurationReader
{
private readonly string _iniPath;
@ -122,4 +122,4 @@ namespace ZeroLevel.Services.Config.Implementation
return result;
}
}
}
}

@ -5,7 +5,7 @@ namespace ZeroLevel.Services.Config.Implementation
/// <summary>
/// Write config to ini-file
/// </summary>
public class IniFileWriter
public class IniFileWriter
: IConfigurationWriter
{
/// <summary>
@ -17,6 +17,7 @@ namespace ZeroLevel.Services.Config.Implementation
{
_iniPath = iniPath;
}
/// <summary>
/// Write config to file
/// </summary>
@ -41,6 +42,7 @@ namespace ZeroLevel.Services.Config.Implementation
writer.Flush();
}
}
/// <summary>
/// Write configuration set to file
/// </summary>
@ -71,4 +73,4 @@ namespace ZeroLevel.Services.Config.Implementation
}
}
}
}
}

@ -6,41 +6,62 @@ namespace ZeroLevel.DocumentObjectModel
{
// Primitives
void ReadText(Text text);
void ReadQuote(Quote quote);
void ReadLink(Link link, int order);
void ReadImage(Image image, int order);
void ReadAudio(Audio audio, int order);
void ReadVideo(Video video, int order);
// Containers
void EnterSection(Section section);
void LeaveSection(Section section);
void EnterParagraph(Paragraph paragraph);
void LeaveParagraph(Paragraph paragraph);
void EnterList(List list);
void EnterListItem(List list, IContentElement item, int order);
void LeaveListItem(List list, IContentElement item, int order);
void LeaveList(List list);
void EnterTable(Table table);
void EnterColumns(Table table);
void ReadColumn(Table table, Column column, int order);
void LeaveColumns(Table table);
void EnterRow(Table table, Row row, int order);
void EnterRowCell(Table table, Row row, IContentElement cell, int order);
void LeaveRowCell(Table table, Row row, IContentElement cell, int order);
void LeaveRow(Table table, Row row, int order);
void LeaveTable(Table table);
void EnterGallery(Gallery gallery);
void LeaveGallery(Gallery gallery);
void EnterAudioplayer(Audioplayer player);
void LeaveAudioplayer(Audioplayer player);
void EnterVideoplayer(Videoplayer player);
void LeaveVideoplayer(Videoplayer player);
// Feature
@ -48,4 +69,4 @@ namespace ZeroLevel.DocumentObjectModel
T Complete();
}
}
}

@ -6,56 +6,93 @@ namespace ZeroLevel.DocumentObjectModel
public interface IMetadataReader<T>
{
void ReadId(Guid Id);
void ReadSummary(string summary);
void ReadHeader(string header);
void EnterIdentifier(Identifier identifier);
void ReadVersion(int version);
void ReadTimestamp(long timestamp);
void ReadDateLabel(string datelabel);
void LeaveIdentifier(Identifier identifier);
void EnterTagsBlock(TagMetadata tagBlock);
void EnterKeywords(IEnumerable<string> keywords);
void ReadKeyword(string keyword, int order);
void LeaveKeywords(IEnumerable<string> keywords);
void EnterPlaces(IEnumerable<Tag> places);
void ReadPlace(Tag place, int order);
void LeavePlaces(IEnumerable<Tag> places);
void EnterCompanies(IEnumerable<Tag> companies);
void ReadCompany(Tag company, int order);
void LeaveCompanies(IEnumerable<Tag> companies);
void EnterPersons(IEnumerable<Tag> persons);
void ReadPerson(Tag person, int order);
void LeavePersons(IEnumerable<Tag> persons);
void LeaveTagsBlock(TagMetadata tagBlock);
void EnterDescriptioveBlock(DescriptiveMetadata metadata);
void ReadAuthors(string byline);
void ReadCopiright(string copyright);
void ReadCreated(DateTime created);
void ReadLanguage(string language);
void ReadPriority(Priority priority);
void ReadSource(Agency source);
void ReadPublisher(Agency publisher);
void ReadOriginal(Tag original);
void EnterHeaders(IEnumerable<Header> headers);
void ReadHeader(Header header, int order);
void LeaveHeaders(IEnumerable<Header> headers);
void LeaveDescriptioveBlock(DescriptiveMetadata metadata);
void EnterAsides(IEnumerable<AttachContent> asides);
void ReadAside(AttachContent aside, int order);
void LeaveAsides(IEnumerable<AttachContent> asides);
void EnterAssotiations(IEnumerable<Assotiation> assotiations);
void ReadAssotiation(Assotiation assotiation, int order);
void LeaveAssotiations(IEnumerable<Assotiation> assotiations);
void EnterCategories(IEnumerable<Category> categories);
void ReadCategory(Category category, int order);
void LeaveCategories(IEnumerable<Category> categories);
T Complete();
}
}
}

@ -126,4 +126,4 @@ namespace DOM.DSL.Contexts
return new TBlockToken(_name, _blockToken, _tokens);
}
}
}
}

@ -22,6 +22,7 @@ namespace DOM.DSL.Contexts
};
public TContext ParentContext { get; protected set; }
public abstract void Read(TStringReader reader);
}
}
}

@ -19,7 +19,7 @@ namespace DOM.DSL.Contexts
public override void Read(TStringReader reader)
{
if (reader.EOF == false && reader.Current == TChar.PropertyOrFuncStart)
{
{
if (reader.Move())
{
reader.SkipBreaks();
@ -75,4 +75,4 @@ namespace DOM.DSL.Contexts
return new TElementToken { ElementName = _name, NextToken = _next?.Clone() };
}
}
}
}

@ -1,10 +1,10 @@
using System;
using System.Linq;
using DOM.DSL.Model;
using DOM.DSL.Services;
using DOM.DSL.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DOM.DSL.Tokens;
using DOM.DSL.Services;
using DOM.DSL.Model;
namespace DOM.DSL.Contexts
{
@ -47,6 +47,7 @@ namespace DOM.DSL.Contexts
switch (reader.Current)
{
#region Ecsaping
case TChar.Escape:
{
switch (reader.Next)
@ -55,18 +56,22 @@ namespace DOM.DSL.Contexts
text.Append(' ');
reader.Move(2);
break;
case 'r':
text.Append(TChar.CaretReturn);
reader.Move(2);
break;
case 'n':
text.Append(TChar.Newline);
reader.Move(2);
break;
case 't':
text.Append(TChar.Tab);
reader.Move(2);
break;
case '@':
case '(':
case ')':
@ -76,6 +81,7 @@ namespace DOM.DSL.Contexts
text.Append(reader.Next);
reader.Move(2);
break;
default:
text.Append(reader.Current);
reader.Move();
@ -83,7 +89,8 @@ namespace DOM.DSL.Contexts
}
}
break;
#endregion
#endregion Ecsaping
case TChar.FuncArgsEnd:
{
@ -162,6 +169,7 @@ namespace DOM.DSL.Contexts
}
}
break;
default:
{
text.Append(reader.Current);
@ -184,4 +192,4 @@ namespace DOM.DSL.Contexts
};
}
}
}
}

@ -69,6 +69,7 @@ namespace DOM.DSL.Contexts
switch (reader.Current)
{
#region Ecsaping
case TChar.Escape:
{
switch (reader.Next)
@ -77,18 +78,22 @@ namespace DOM.DSL.Contexts
text.Append(' ');
reader.Move(2);
break;
case 'r':
text.Append(TChar.CaretReturn);
reader.Move(2);
break;
case 'n':
text.Append(TChar.Newline);
reader.Move(2);
break;
case 't':
text.Append(TChar.Tab);
reader.Move(2);
break;
case '@':
case '(':
case ')':
@ -98,6 +103,7 @@ namespace DOM.DSL.Contexts
text.Append(reader.Next);
reader.Move(2);
break;
default:
text.Append(reader.Current);
reader.Move();
@ -105,7 +111,8 @@ namespace DOM.DSL.Contexts
}
}
break;
#endregion
#endregion Ecsaping
case TChar.PropertyIndexEnd:
{
@ -160,6 +167,7 @@ namespace DOM.DSL.Contexts
}
}
break;
default:
{
text.Append(reader.Current);
@ -182,4 +190,4 @@ namespace DOM.DSL.Contexts
};
}
}
}
}

@ -40,6 +40,7 @@ namespace DOM.DSL.Contexts
switch (reader.Current)
{
#region Ecsaping
case TChar.Escape:
{
switch (reader.Next)
@ -48,18 +49,22 @@ namespace DOM.DSL.Contexts
text.Append(' ');
reader.Move(2);
break;
case 'r':
text.Append(TChar.CaretReturn);
reader.Move(2);
break;
case 'n':
text.Append(TChar.Newline);
reader.Move(2);
break;
case 't':
text.Append(TChar.Tab);
reader.Move(2);
break;
case '@':
case '(':
case ')':
@ -69,6 +74,7 @@ namespace DOM.DSL.Contexts
text.Append(reader.Next);
reader.Move(2);
break;
default:
text.Append(reader.Current);
reader.Move();
@ -76,7 +82,8 @@ namespace DOM.DSL.Contexts
}
}
break;
#endregion
#endregion Ecsaping
case TChar.TokenStart:
{
@ -122,11 +129,13 @@ namespace DOM.DSL.Contexts
}
}
break;
case TChar.CaretReturn:
case TChar.Newline:
case TChar.Tab:
reader.Move();
break;
default:
{
text.Append(reader.Current);
@ -143,4 +152,4 @@ namespace DOM.DSL.Contexts
return _tokens;
}
}
}
}

@ -9,12 +9,19 @@ namespace DOM.DSL.Contracts
/// Indicates that a table cell body entry is expected.
/// </summary>
bool WaitCellBody { get; }
void WriteToCell(string part);
void EnterTable(Column[] colunmns);
void EnterRow(int count_columns);
void EnterCell(int order);
void LeaveCell();
void LeaveRow();
void FlushTable(StringBuilder builder);
}
}
}

@ -6,4 +6,4 @@ namespace DOM.DSL.Contracts
{
TToken Clone();
}
}
}

@ -25,23 +25,94 @@
public int GalleryId { get; private set; } = -1;
public int ImageId { get; private set; } = -1;
public void IncSectionId() { SectionId++; }
public void IncParagraphId() { ParagraphId++; }
public void IncListId() { ListId++; }
public void IncListItemId() { ListItemId++; }
public void IncTableId() { TableId++; }
public void IncColumnId() { ColumnId++; }
public void IncRowId() { RowId++; }
public void IncCellId() { CellId++; }
public void IncFormId() { FormId++; }
public void IncLinkId() { LinkId++; }
public void IncQuoteId() { QuoteId++; }
public void IncTextId() { TextId++; }
public void IncAudioplayerId() { AudioplayerId++; }
public void IncAudioId() { AudioId++; }
public void IncVideoplayerId() { VideoplayerId++; }
public void IncVideoId() { VideoId++; }
public void IncGalleryId() { GalleryId++; }
public void IncImageId() { ImageId++; }
public void IncSectionId()
{
SectionId++;
}
public void IncParagraphId()
{
ParagraphId++;
}
public void IncListId()
{
ListId++;
}
public void IncListItemId()
{
ListItemId++;
}
public void IncTableId()
{
TableId++;
}
public void IncColumnId()
{
ColumnId++;
}
public void IncRowId()
{
RowId++;
}
public void IncCellId()
{
CellId++;
}
public void IncFormId()
{
FormId++;
}
public void IncLinkId()
{
LinkId++;
}
public void IncQuoteId()
{
QuoteId++;
}
public void IncTextId()
{
TextId++;
}
public void IncAudioplayerId()
{
AudioplayerId++;
}
public void IncAudioId()
{
AudioId++;
}
public void IncVideoplayerId()
{
VideoplayerId++;
}
public void IncVideoId()
{
VideoId++;
}
public void IncGalleryId()
{
GalleryId++;
}
public void IncImageId()
{
ImageId++;
}
}
}
}

@ -14,4 +14,4 @@
public const char Newline = '\n';
public const char Tab = '\t';
}
}
}

@ -31,6 +31,7 @@ namespace DOM.DSL.Model
TraversElement(item, type, handler);
}
break;
case ContentElementType.Paragraph:
var paragraph = (element as Paragraph);
foreach (var item in paragraph.Parts)
@ -38,6 +39,7 @@ namespace DOM.DSL.Model
TraversElement(item, type, handler);
}
break;
case ContentElementType.List:
var list = (element as List);
foreach (var item in list.Items)
@ -45,6 +47,7 @@ namespace DOM.DSL.Model
TraversElement(item, type, handler);
}
break;
case ContentElementType.Gallery:
var gallery = (element as Gallery);
foreach (var item in gallery.Images)
@ -52,6 +55,7 @@ namespace DOM.DSL.Model
TraversElement(item, type, handler);
}
break;
case ContentElementType.Audioplayer:
var audioplayer = (element as Audioplayer);
foreach (var item in audioplayer.Tracks)
@ -59,6 +63,7 @@ namespace DOM.DSL.Model
TraversElement(item, type, handler);
}
break;
case ContentElementType.Videoplayer:
var videoplayer = (element as Videoplayer);
foreach (var item in videoplayer.Playlist)
@ -66,6 +71,7 @@ namespace DOM.DSL.Model
TraversElement(item, type, handler);
}
break;
case ContentElementType.Table:
var table = (element as Table);
foreach (var column in table.Columns)
@ -90,34 +96,49 @@ namespace DOM.DSL.Model
{
case "section":
return ContentElementType.Section;
case "paragraph":
return ContentElementType.Paragraph;
case "link":
return ContentElementType.Link;
case "list":
return ContentElementType.List;
case "table":
return ContentElementType.Table;
case "audio":
return ContentElementType.Audio;
case "audioplayer":
return ContentElementType.Audioplayer;
case "form":
return ContentElementType.Form;
case "gallery":
return ContentElementType.Gallery;
case "image":
return ContentElementType.Image;
case "video":
return ContentElementType.Video;
case "videoplayer":
return ContentElementType.Videoplayer;
case "quote":
return ContentElementType.Quote;
case "text":
return ContentElementType.Text;
case "column":
return ContentElementType.Column;
case "row":
return ContentElementType.Row;
}
@ -131,7 +152,7 @@ namespace DOM.DSL.Model
var list = new List<IContentElement>();
foreach (var section in _document.Content.Sections)
{
TraversElement(section, type, e=>list.Add(e));
TraversElement(section, type, e => list.Add(e));
}
return list;
}
@ -141,4 +162,4 @@ namespace DOM.DSL.Model
return "Content";
}
}
}
}

@ -24,4 +24,4 @@ namespace DOM.DSL.Model
CustomVariables.Add(name.ToLowerInvariant().Trim(), value);
}
}
}
}

@ -7,6 +7,7 @@ namespace DOM.DSL.Model
internal sealed class TFlowRules
{
#region Rules
public TBlockToken ListPrefix;
public TBlockToken ListPostfix;
public TBlockToken ListItemPrefix;
@ -55,12 +56,15 @@ namespace DOM.DSL.Model
public TBlockToken VideoplayerPostfix;
public TBlockToken GalleryPrefix;
public TBlockToken GalleryPostfix;
#endregion
#endregion Rules
#region Special table builder
public bool UseSpecialTableBuilder = false;
public ISpecialTableBuilder SpecialTableBuilder;
#endregion
#endregion Special table builder
public void Bootstrap()
{
@ -124,297 +128,361 @@ namespace DOM.DSL.Model
case "prefix":
ListPrefix = rule_token;
break;
case "postfix":
ListPostfix = rule_token;
break;
case "ignore":
ListPostfix = ListPrefix = null;
break;
}
break;
case "listitem":
switch (functionName)
{
case "prefix":
ListItemPrefix = rule_token;
break;
case "postfix":
ListItemPostfix = rule_token;
break;
case "ignore":
ListItemPrefix = ListItemPostfix = null;
break;
}
break;
case "text":
switch (functionName)
{
case "prefix":
TextPrefix = rule_token;
break;
case "template":
TextTemplate = rule_token;
break;
case "postfix":
TextPostfix = rule_token;
break;
case "ignore":
TextPrefix = TextTemplate = TextPostfix = null;
break;
}
break;
case "link":
switch (functionName)
{
case "prefix":
LinkPrefix = rule_token;
break;
case "template":
LinkTemplate = rule_token;
break;
case "postfix":
LinkPostfix = rule_token;
break;
case "ignore":
LinkPrefix = LinkTemplate = LinkPostfix = null;
break;
}
break;
case "image":
switch (functionName)
{
case "prefix":
ImagePrefix = rule_token;
break;
case "template":
ImageTemplate = rule_token;
break;
case "postfix":
ImagePostfix = rule_token;
break;
case "ignore":
ImagePrefix = ImageTemplate = ImagePostfix = null;
break;
}
break;
case "quote":
switch (functionName)
{
case "prefix":
QuotePrefix = rule_token;
break;
case "template":
QuoteTemplate = rule_token;
break;
case "postfix":
QuotePostfix = rule_token;
break;
case "ignore":
QuotePrefix = QuoteTemplate = QuotePostfix = null;
break;
}
break;
case "form":
switch (functionName)
{
case "prefix":
FormPrefix = rule_token;
break;
case "template":
FormTemplate = rule_token;
break;
case "postfix":
FormPostfix = rule_token;
break;
case "ignore":
FormPrefix = FormTemplate = FormPostfix = null;
break;
}
break;
case "video":
switch (functionName)
{
case "prefix":
VideoPrefix = rule_token;
break;
case "template":
VideoTemplate = rule_token;
break;
case "postfix":
VideoPostfix = rule_token;
break;
case "ignore":
VideoPrefix = VideoTemplate = VideoPostfix = null;
break;
}
break;
case "audio":
switch (functionName)
{
case "prefix":
AudioPrefix = rule_token;
break;
case "template":
AudioTemplate = rule_token;
break;
case "postfix":
AudioPostfix = rule_token;
break;
case "ignore":
AudioPrefix = AudioTemplate = AudioPostfix = null;
break;
}
break;
case "section":
switch (functionName)
{
case "prefix":
SectionPrefix = rule_token;
break;
case "postfix":
SectionPostfix = rule_token;
break;
case "ignore":
SectionPrefix = SectionPostfix = null;
break;
}
break;
case "paragraph":
switch (functionName)
{
case "prefix":
ParagraphPrefix = rule_token;
break;
case "postfix":
ParagraphPostfix = rule_token;
break;
case "ignore":
ParagraphPrefix = ParagraphPostfix = null;
break;
}
break;
case "table":
switch (functionName)
{
case "prefix":
TablePrefix = rule_token;
break;
case "postfix":
TablePostfix = rule_token;
break;
case "ignore":
TablePrefix = TablePostfix = null;
break;
case "special": // Using a hardcoded table conversion
//TablePrefix = TablePostfix = null;
ColumnsPrefix = ColumnsPostfix = null;
ColumnPrefix = ColumnTemplate = ColumnPostfix = null;
RowPrefix = RowPostfix = null;
CellPrefix = CellPostfix = null;
// Args: (style, paddings l-t-r-b, maxcellwidth, maxtablewidth)
// Args: (style, paddings l-t-r-b, maxcellwidth, maxtablewidth)
UseSpecialTableBuilder = true;
SpecialTableBuilder = SpecialTableBuilderFactory.CreateSpecialTableBuilder(special);
if (SpecialTableBuilder == null) UseSpecialTableBuilder = false;
break;
}
break;
case "columns":
switch (functionName)
{
case "prefix":
ColumnsPrefix = rule_token;
break;
case "postfix":
ColumnsPostfix = rule_token;
break;
case "ignore":
ColumnsPrefix = ColumnsPostfix = null;
break;
}
break;
case "column":
switch (functionName)
{
case "prefix":
ColumnPrefix = rule_token;
break;
case "template":
ColumnTemplate = rule_token;
break;
case "postfix":
ColumnPostfix = rule_token;
break;
case "ignore":
ColumnPrefix = ColumnTemplate = ColumnPostfix = null;
break;
}
break;
case "tablerow":
switch (functionName)
{
case "prefix":
RowPrefix = rule_token;
break;
case "postfix":
RowPostfix = rule_token;
break;
case "ignore":
RowPrefix = RowPostfix = null;
break;
}
break;
case "tablecell":
switch (functionName)
{
case "prefix":
CellPrefix = rule_token;
break;
case "postfix":
CellPostfix = rule_token;
break;
case "ignore":
CellPrefix = CellPostfix = null;
break;
}
break;
case "videoplayer":
switch (functionName)
{
case "prefix":
VideoplayerPrefix = rule_token;
break;
case "postfix":
VideoplayerPostfix = rule_token;
break;
case "ignore":
VideoplayerPrefix = VideoplayerPostfix = null;
break;
}
break;
case "audioplayer":
switch (functionName)
{
case "prefix":
AudioplayerPrefix = rule_token;
break;
case "postfix":
AudioplayerPostfix = rule_token;
break;
case "ignore":
AudioplayerPrefix = AudioplayerPostfix = null;
break;
}
break;
case "gallery":
switch (functionName)
{
case "prefix":
GalleryPrefix = rule_token;
break;
case "postfix":
GalleryPostfix = rule_token;
break;
case "ignore":
GalleryPrefix = GalleryPostfix = null;
break;
@ -423,4 +491,4 @@ namespace DOM.DSL.Model
}
}
}
}
}

@ -38,7 +38,7 @@ namespace DOM.DSL.Model
.Select(i => word.Substring(i * max, max)).
ToArray();
int k = 0;
if(current_max > 0) text.Append("\r\n");
if (current_max > 0) text.Append("\r\n");
for (; k < lines.Length - 1; k++)
{
text.Append(lines[k]);
@ -70,7 +70,7 @@ namespace DOM.DSL.Model
{
if (reader.Next == '\r' &&
reader.FindOffsetTo('\n') == 2)
{
{
text.Append("\r\n");
reader.Move(2);
}
@ -86,4 +86,4 @@ namespace DOM.DSL.Model
return text.ToString();
}
}
}
}

@ -31,6 +31,7 @@ namespace DOM.DSL.Services
public int RowCellIndex = -1;
private StringBuilder _cellBody = new StringBuilder();
public void FlushCell()
{
if (RowCellIndex >= 0)
@ -51,6 +52,7 @@ namespace DOM.DSL.Services
return TextTableRender.Render(Data, options);
}
}
private readonly TextTableRenderOptions _options;
private Stack<TextTableMeta> _textTables = new Stack<TextTableMeta>();
@ -107,4 +109,4 @@ namespace DOM.DSL.Services
_textTables.Peek().WriteCell(part);
}
}
}
}

@ -61,4 +61,4 @@ namespace DOM.DSL.Services
return result;
}
}
}
}

File diff suppressed because it is too large Load Diff

@ -5,7 +5,7 @@ namespace DOM.DSL.Services
{
public class TContainerFactory
{
private readonly ObjectPool<TContainer> _pool;
private readonly ObjectPool<TContainer> _pool;
private static int _get_count = 0;
private static int _release_count = 0;
@ -22,6 +22,7 @@ namespace DOM.DSL.Services
c.Reset(value);
return c;
}
internal TContainer Get(object value, int index)
{
Interlocked.Increment(ref _get_count);
@ -30,6 +31,7 @@ namespace DOM.DSL.Services
c.Index = index;
return c;
}
internal void Release(TContainer container)
{
if (container != null)
@ -40,6 +42,7 @@ namespace DOM.DSL.Services
}
public static int GetsCount() => _get_count;
public static int ReleasesCount() => _release_count;
}
}
}

@ -54,6 +54,7 @@ namespace DOM.DSL.Services
}
#region Primitives
public void ReadAudio(Audio audio, int order)
{
_render.Counter.IncAudioId();
@ -189,9 +190,11 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.VideoPostfix, video, order));
}
}
#endregion
#endregion Primitives
#region Containers
public void EnterParagraph(Paragraph paragraph)
{
_render.Counter.IncParagraphId();
@ -200,6 +203,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.ParagraphPrefix, paragraph, _render.Counter.ParagraphId));
}
}
public void LeaveParagraph(Paragraph paragraph)
{
if (_transformRules.ParagraphPostfix != null)
@ -207,6 +211,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.ParagraphPostfix, paragraph, _render.Counter.ParagraphId));
}
}
public void EnterSection(Section section)
{
_render.Counter.IncSectionId();
@ -215,6 +220,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.SectionPrefix, section, _render.Counter.SectionId));
}
}
public void LeaveSection(Section section)
{
if (_transformRules.SectionPostfix != null)
@ -222,9 +228,11 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.SectionPostfix, section, _render.Counter.SectionId));
}
}
#endregion
#endregion Containers
#region Table
public void EnterTable(Table table)
{
_render.Counter.IncTableId();
@ -238,6 +246,7 @@ namespace DOM.DSL.Services
_specialTableBuilder.EnterTable(table.Columns.ToArray());
}
}
public void EnterColumns(Table table)
{
if (_useSpecialTableBuilder == false && _transformRules.ColumnsPrefix != null)
@ -245,6 +254,7 @@ namespace DOM.DSL.Services
_builder.Append(Resolve(_transformRules.ColumnsPrefix, table.Columns, 0));
}
}
public void EnterRow(Table table, Row row, int order)
{
_render.Counter.IncRowId();
@ -257,6 +267,7 @@ namespace DOM.DSL.Services
_builder.Append(Resolve(_transformRules.RowPrefix, row, order));
}
}
public void EnterRowCell(Table table, Row row, IContentElement cell, int order)
{
_render.Counter.IncCellId();
@ -276,6 +287,7 @@ namespace DOM.DSL.Services
}
}
}
public void LeaveColumns(Table table)
{
if (_useSpecialTableBuilder == false && _transformRules.ColumnsPostfix != null)
@ -283,6 +295,7 @@ namespace DOM.DSL.Services
_builder.Append(Resolve(_transformRules.ColumnsPostfix, table.Columns, 0));
}
}
public void LeaveRow(Table table, Row row, int order)
{
if (_useSpecialTableBuilder)
@ -294,6 +307,7 @@ namespace DOM.DSL.Services
_builder.Append(Resolve(_transformRules.RowPostfix, row, order));
}
}
public void LeaveRowCell(Table table, Row row, IContentElement cell, int order)
{
if (_useSpecialTableBuilder)
@ -312,6 +326,7 @@ namespace DOM.DSL.Services
}
}
}
public void LeaveTable(Table table)
{
if (_useSpecialTableBuilder)
@ -323,9 +338,11 @@ namespace DOM.DSL.Services
_builder.Append(Resolve(_transformRules.TablePostfix, table, _render.Counter.TableId));
}
}
#endregion
#endregion Table
#region List
public void EnterList(List list)
{
_render.Counter.IncListId();
@ -334,6 +351,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.ListPrefix, list, 0));
}
}
public void EnterListItem(List list, IContentElement item, int order)
{
_render.Counter.IncListItemId();
@ -342,6 +360,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.ListItemPrefix, item, order));
}
}
public void LeaveList(List list)
{
if (_transformRules.ListPostfix != null)
@ -349,6 +368,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.ListPostfix, list, 0));
}
}
public void LeaveListItem(List list, IContentElement item, int order)
{
if (_transformRules.ListItemPostfix != null)
@ -356,9 +376,11 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.ListItemPostfix, item, order));
}
}
#endregion
#endregion List
#region Media
public void EnterAudioplayer(Audioplayer player)
{
_render.Counter.IncAudioplayerId();
@ -367,6 +389,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.AudioplayerPrefix, player, 0));
}
}
public void EnterGallery(Gallery gallery)
{
_render.Counter.IncGalleryId();
@ -375,6 +398,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.GalleryPrefix, gallery, 0));
}
}
public void EnterVideoplayer(Videoplayer player)
{
_render.Counter.IncVideoplayerId();
@ -383,6 +407,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.VideoplayerPrefix, player, 0));
}
}
public void LeaveAudioplayer(Audioplayer player)
{
if (_transformRules.AudioplayerPostfix != null)
@ -390,6 +415,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.AudioplayerPostfix, player, 0));
}
}
public void LeaveGallery(Gallery gallery)
{
if (_transformRules.GalleryPostfix != null)
@ -397,6 +423,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.GalleryPostfix, gallery, 0));
}
}
public void LeaveVideoplayer(Videoplayer player)
{
if (_transformRules.VideoplayerPostfix != null)
@ -404,6 +431,7 @@ namespace DOM.DSL.Services
WriteText(Resolve(_transformRules.VideoplayerPostfix, player, 0));
}
}
#endregion
#endregion Media
}
}
}

@ -238,6 +238,7 @@ namespace DOM.DSL.Services
}
}
break;
case "flow":
{
return new List<TContainer>
@ -356,6 +357,7 @@ namespace DOM.DSL.Services
Log.Debug(args[0].ToString(), args.Skip(1).ToArray());
}
break;
case "validate":
if (args?.Length == 1)
{
@ -364,15 +366,18 @@ namespace DOM.DSL.Services
case "xml":
Options.ValidateAsXml = true;
break;
case "html":
Options.ValidateAsHtml = true;
break;
case "json":
Options.ValidateAsJson = true;
break;
}
}
break;
case "fixwidth":
{
if (args?.Length == 1)
@ -400,4 +405,4 @@ namespace DOM.DSL.Services
}
}
}
}
}

@ -78,4 +78,4 @@ namespace DOM.DSL
return text.ToString();
}
}
}
}

@ -36,4 +36,4 @@ namespace DOM.DSL.Tokens
return Clone();
}
}
}
}

@ -10,6 +10,7 @@
/// Имя элемента
/// </summary>
public string ElementName;
/// <summary>
/// Optionally, next token
/// </summary>
@ -33,4 +34,4 @@
};
}
}
}
}

@ -30,4 +30,4 @@ namespace DOM.DSL.Tokens
};
}
}
}
}

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

Loading…
Cancel
Save

Powered by TurnKey Linux.