Localization

pull/1/head
unknown 6 years ago
parent e4b376d05b
commit 618d1de5ff

@ -1 +1 @@
4f0bbfe8ac44b56784f7eeaa3cdef96609d6b97e
02ab5562f7a9f633d41e073aff759527ff59696c

@ -1 +1 @@
48781ba1f58e845d50aedda0cbff5881dfe0563f
1a68033c72e3e719a45c8165f48f4effb88b5e68

@ -91,7 +91,7 @@ namespace ZeroLevel.Models
#region Fabric methods
public static InvokeResult<T> Succeeding(T value, string comment = "") { return new InvokeResult<T>(value, true, comment); }
public static InvokeResult<T> Fault(string comment) { return new InvokeResult<T>(false, comment); }
public static InvokeResult<T> Fault<T>(string comment) { return new InvokeResult<T>(false, comment); }
#endregion
public override void Serialize(IBinaryWriter writer)

@ -83,7 +83,7 @@ namespace ZeroLevel
IConfiguration result;
if (false == _cachee.TryGetValue(name, out result))
{
throw new KeyNotFoundException(string.Format("Not found configuration '{0}'", name));
throw new KeyNotFoundException("Not found configuration '{name}'");
}
return result;
}
@ -93,7 +93,7 @@ namespace ZeroLevel
IConfigurationSet result;
if (false == _setCachee.TryGetValue(name, out result))
{
throw new KeyNotFoundException(string.Format("Not found configuration set '{0}'", name));
throw new KeyNotFoundException("Not found configuration set '{name}'");
}
return result;
}

@ -14,7 +14,7 @@ namespace ZeroLevel.Services.Config.Implementation
{
if (configFilePath == null)
{
var appConfig = Path.Combine(Configuration.BaseDirectory, string.Format("{0}.config", System.AppDomain.CurrentDomain.FriendlyName));
var appConfig = Path.Combine(Configuration.BaseDirectory, $"{System.AppDomain.CurrentDomain.FriendlyName}.config");
if (File.Exists(appConfig))
{
_configFilePath = appConfig;

@ -63,7 +63,7 @@ namespace ZeroLevel.Services.Config.Implementation
{
if (!string.IsNullOrEmpty(sectionName))
{
result.Append(string.Format("{0}.{1}", sectionName, key), value);
result.Append($"{sectionName}.{key}", value);
}
else
{

@ -32,7 +32,7 @@ namespace DOM.DSL.Contexts
{
reader.Move();
var name = reader.ReadIdentity();
if (name.Equals(string.Format("end{0}", _name)))
if (name.Equals($"end{_name}"))
{
reader.Move(name.Length);
return;
@ -64,7 +64,7 @@ namespace DOM.DSL.Contexts
{
reader.Move();
var name = reader.ReadIdentity();
if (name.Equals(string.Format("end{0}", _name)))
if (name.Equals($"end{_name}"))
{
reader.Move(name.Length);
return;
@ -106,7 +106,7 @@ namespace DOM.DSL.Contexts
if (offset == -1) return;
reader.Move(offset + 1);
var name = reader.ReadIdentity();
if (name.Equals(string.Format("end{0}", _name)))
if (name.Equals($"end{_name}"))
{
reader.Move(name.Length);
return;

@ -50,7 +50,7 @@ namespace DOM.Services
case ContentElementType.Form:
return new FormContent(reader);
}
throw new InvalidCastException(string.Format("Uncknown element type: {0}", type));
throw new InvalidCastException($"Uncknown element type: {type}");
}
public static List<IContentElement> ReadCollection(IBinaryReader reader)

@ -5,12 +5,12 @@ using System.Threading;
namespace ZeroLevel.Services
{
/// <summary>
/// Предоставляет различные варианты генерации идентификаторов
/// Provides various options for generating identifiers
/// </summary>
public static class IdGenerator
{
/// <summary>
/// Возвращает функцию для получения последовательных значений int64
/// Returns a function to get consecutive int64 values.
/// </summary>
public static Func<long> IncreasingSequenceIdGenerator()
{
@ -18,7 +18,7 @@ namespace ZeroLevel.Services
return new Func<long>(() => Interlocked.Increment(ref id));
}
/// <summary>
/// Создает Base64 хэш от указанного даты/времени
/// Creates a base64 hash from the specified datetime
/// </summary>
public static string HashFromDateTime(DateTime date)
{
@ -29,35 +29,35 @@ namespace ZeroLevel.Services
.TrimEnd('=');
}
/// <summary>
/// Создает Base64 хэш от текущего даты/времени
/// Creates a base64 hash from the current datetime
/// </summary>
public static string HashFromCurrentDateTime()
{
return HashFromDateTime(DateTime.Now);
}
/// <summary>
/// Возвращает хэш в виде строки от 32-хбитного значения хэша указанного даты/времени
/// Returns a hash as a string from the 32-bit hash value of the specified datetime
/// </summary>
public static string ShortHashFromDateTime(DateTime date)
{
return date.ToString(CultureInfo.InvariantCulture).GetHashCode().ToString("x");
}
/// <summary>
/// Возвращает хэш в виде строки от 32-хбитного значения хэша текущего даты/времени
/// Returns a hash as a string from the 32-bit hash value of the current datetime
/// </summary>
public static string ShortHashFromCurrentDateTime()
{
return DateTime.Now.ToString(CultureInfo.InvariantCulture).GetHashCode().ToString("x");
}
/// <summary>
/// Создает временную отметку из текущей даты/времени
/// Creates a timestamp from current datetime
/// </summary>
public static string CreateTimestamp()
{
return DateTime.Now.ToString("yyyyMMddHHmmssFFF");
}
/// <summary>
/// Создает временную отметку из указанной даты/времени
/// Creates a timestamp from a specified datetime
/// </summary>
public static string CreateTimestamp(DateTime date)
{

@ -1,9 +0,0 @@
using System;
namespace ZeroLevel.Services.Network.Exceptions
{
public class NoConnectionException
: Exception
{
}
}

@ -4,15 +4,15 @@ namespace ZeroLevel.Network.Microservices
{
public abstract class ExchangeAttribute : Attribute { }
/// <summary>
/// Отмечает метод который является обработчиком сообщений по умолчанию
/// Marks the method that is the default message handler
/// </summary>
public sealed class ExchangeMainHandlerAttribute : ExchangeAttribute { }
/// <summary>
/// Отмечает метод который является обработчиком запросов по умолчанию
/// Marks the method that is the default message handler
/// </summary>
public sealed class ExchangeMainReplierAttribute : ExchangeAttribute { }
/// <summary>
/// Отмечает метод-обработчик сообщений для inbox'а с указанным именем
/// Marks a message handler method for an inbox with the specified name.
/// </summary>
public sealed class ExchangeHandlerAttribute : ExchangeAttribute
{
@ -24,7 +24,7 @@ namespace ZeroLevel.Network.Microservices
}
}
/// <summary>
/// Отмечает метод-обработчик запросов для inbox'а с указанным именем
/// Marks a message handler method for an inbox with the specified name.
/// </summary>
public sealed class ExchangeReplierAttribute : ExchangeAttribute
{
@ -36,11 +36,11 @@ namespace ZeroLevel.Network.Microservices
}
}
/// <summary>
/// Отмечает метод-обработчик сообщений для inbox'а с указанным именем
/// Marks a message handler method for an inbox with the specified name.
/// </summary>
public sealed class ExchangeMainReplierWithoutArgAttribute : ExchangeAttribute { }
/// <summary>
/// Отмечает метод-обработчик запросов для inbox'а с указанным именем
/// Marks a message handler method for an inbox with the specified name.
/// </summary>
public sealed class ExchangeReplierWithoutArgAttribute : ExchangeAttribute
{

@ -12,35 +12,33 @@ namespace ZeroLevel.Network.Microservices
public const string DEFAULT_TYPE_NAME = "__service_default_type__";
/// <summary>
/// Ключ сервиса, должен быть уникален в рамках бизнес функционала
/// т.е. с одинаковым ключом могут работать только копии сервиса, для горизонтальной балансировки
/// Service key, must be unique within the business functionality.
/// two services with same key will be horizontally balanced
/// </summary>
[DataMember]
public string ServiceKey { get; set; }
/// <summary>
/// Группа, для фильтрации, в качетсве группы можно определять сервисы работающие в одном домене,
/// например сервисы обрабатывющие новости в одной группе, сервисы по котировкам в другой
/// The group can determine the services working in the same domain
/// </summary>
[DataMember]
public string ServiceGroup { get; set; } = DEFAULT_GROUP_NAME;
/// <summary>
/// Тип сервиса, для фильтрации, определяет принадлежность к подгруппе, например сервисы для доставки информации,
/// или сервисы-адаптеры и т.д.
/// The type of service, for filtering, determines membership in a subgroup.
/// </summary>
[DataMember]
public string ServiceType { get; set; } = DEFAULT_TYPE_NAME;
/// <summary>
/// Протокол по которому разрешен доступ к API сервиса
/// Protocol on which access to the service API is allowed
/// </summary>
[DataMember]
public string Protocol { get; set; }
/// <summary>
/// Точка подключения, адрес
/// Connection point, address
/// </summary>
[DataMember]
public string Endpoint { get; set; }
/// <summary>
/// Версия сервиса
/// Service version
/// </summary>
[DataMember]
public string Version { get; set; }

@ -3,7 +3,7 @@
namespace ZeroLevel.Network.Microservices
{
/// <summary>
/// Точка подключения
/// Endpoint
/// </summary>
public class ServiceEndpointInfo :
IEquatable<ServiceEndpointInfo>

@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace ZeroLevel.Network.Microservices
{
/// <summary>
/// Информация о точках подключения для сервиса
/// Information about service connection points
/// </summary>
public class ServiceEndpointsInfo :
IEquatable<ServiceEndpointsInfo>

@ -14,10 +14,8 @@ namespace ZeroLevel.Services.Network.Services
private sealed class MRInvoker
{
/// <summary>
/// Создает скомпилированное выражение для быстрого вызова метода, возвращает идентификатор выражения и делегат для вызова
/// Creates a compiled expression for a quick method call, returns the identifier of the expression and a delegate for the call.
/// </summary>
/// <param name="method">Оборачиваемый метод</param>
/// <returns>Кортеж с идентификатором выражения и делегатом</returns>
private static Invoker CreateCompiledExpression(MethodInfo method)
{
var targetArg = Expression.Parameter(typeof(object)); // Цель на которой происходит вызов
@ -36,11 +34,6 @@ namespace ZeroLevel.Services.Network.Services
body = Expression.Convert(body, typeof(object));
return Expression.Lambda<Invoker>(body, targetArg, argsArg).Compile();
}
/// <summary>
/// Оборачивает вызов делегата
/// </summary>
/// <param name="handler">Оборачиваемый делегат</param>
/// <returns>Кортеж с идентификатором выражения и делегатом</returns>
private static Invoker CreateCompiledExpression(Delegate handler)
{
return CreateCompiledExpression(handler.GetMethodInfo());
@ -127,7 +120,7 @@ namespace ZeroLevel.Services.Network.Services
}
else
{
throw new Exception(string.Format("[SocketExchangeServer] Inbox {0} already exists", inbox));
throw new Exception($"[SocketExchangeServer] Inbox {inbox} already exists");
}
}
@ -139,7 +132,7 @@ namespace ZeroLevel.Services.Network.Services
}
else
{
throw new Exception(string.Format("[SocketExchangeServer] Inbox {0} already exists", inbox));
throw new Exception($"[SocketExchangeServer] Inbox {inbox} already exists");
}
}
#endregion

@ -47,11 +47,11 @@ namespace ZeroLevel.Services.Network
public IPEndPoint Endpoint => _server.Endpoint;
/// <summary>
/// Регистрация обработчика входящих сообщений
/// Registering an Inbox Handler
/// </summary>
/// <typeparam name="T">Тип сообщения</typeparam>
/// <param name="inbox">Имя точки приема</param>
/// <param name="handler">Обработчик</param>
/// <typeparam name="T">Message type</typeparam>
/// <param name="inbox">Inbox name</param>
/// <param name="handler">Handler</param>
public void RegisterInbox<T>(string inbox, Action<T, long, IZBackward> handler)
{
_router.RegisterInbox(inbox, handler);
@ -61,13 +61,13 @@ namespace ZeroLevel.Services.Network
_router.RegisterInbox(DEFAULT_MESSAGE_INBOX, handler);
}
/// <summary>
/// Регистрация метода отдающего ответ на входящий запрос
/// Registration method responding to an incoming request
/// </summary>
/// <typeparam name="Treq">Тип входного сообщения</typeparam>
/// <typeparam name="Tresp">Тип ответа</typeparam>
/// <param name="protocol">Транспортный протокол</param>
/// <param name="inbox">Имя точки приема</param>
/// <param name="replier">Обработчик</param>
/// <typeparam name="Treq">Type of input message</typeparam>
/// <typeparam name="Tresp">Type of response</typeparam>
/// <param name="protocol">Protocol</param>
/// <param name="inbox">Inbox name</param>
/// <param name="replier">Handler</param>
public void RegisterInbox<Treq, Tresp>(string inbox, Func<Treq, long, IZBackward, Tresp> handler)
{
_router.RegisterInbox<Treq, Tresp>(inbox, handler);
@ -77,12 +77,12 @@ namespace ZeroLevel.Services.Network
_router.RegisterInbox<Treq, Tresp>(DEFAULT_REQUEST_INBOX, handler);
}
/// <summary>
/// Регистрация метода отдающего ответ на входящий запрос, не принимающего входящих данных
/// Registration of the method of responding to the incoming request, not receiving incoming data
/// </summary>
/// <typeparam name="Tresp">Тип ответа</typeparam>
/// <param name="protocol">Транспортный протокол</param>
/// <param name="inbox">Имя точки приема</param>
/// <param name="replier">Обработчик</param>
/// <typeparam name="Tresp">Type of response</typeparam>
/// <param name="protocol">Protocol</param>
/// <param name="inbox">Inbox name</param>
/// <param name="replier">Handler</param>
public void RegisterInbox<Tresp>(string inbox, Func<long, IZBackward, Tresp> handler)
{
_router.RegisterInbox<Tresp>(inbox, handler);

@ -48,7 +48,7 @@ namespace ZeroLevel.Services.Network
offset = 0;
if (Size == 0)
{
// Как минимум 1 байт с контрольной суммой должен быть
// At least 1 byte with checksum must be
Corrupted = true;
}
}
@ -135,7 +135,7 @@ namespace ZeroLevel.Services.Network
{
for (; start < length; start++)
{
// Поиск начала заголовка пакета
// Search for the beginning of the package header
if ((part[start] & ZBaseNetwork.PACKET_HEADER_START_BYTE) == ZBaseNetwork.PACKET_HEADER_START_BYTE)
{
_accum.Reset();

@ -11,32 +11,32 @@ namespace ZeroLevel.Services.Network
protected const string DEFAULT_PING_INBOX = "__ping__";
protected const string DEFAULT_REQUEST_ERROR_INBOX = "__request_error__";
/// <summary>
/// Размер буфера для приема данных
/// Buffer size for receiving data
/// </summary>
protected const int DEFAULT_RECEIVE_BUFFER_SIZE = 4096;
/// <summary>
/// Если в течение указанного периода не было сетевой активности, выслать пинг-реквест
/// If during the specified period there was no network activity, send a ping-request
/// </summary>
protected const long HEARTBEAT_PING_PERIOD_TICKS = 1500 * TimeSpan.TicksPerMillisecond;
/// <summary>
/// Период проверки наличия соединения
/// Connection check period
/// </summary>
protected const int HEARTBEAT_UPDATE_PERIOD_MS = 7500;
/// <summary>
/// Период выполнения запроса, после которого считать его неудачным
/// The period of the request, after which it is considered unsuccessful
/// </summary>
protected const long MAX_REQUEST_TIME_TICKS = 30000 * TimeSpan.TicksPerMillisecond;
public const int MAX_REQUEST_TIME_MS = 30000;
/// <summary>
/// Максимальный размер пакета данных для передачи (сериализованный размер фрейма)
/// Maximum size of data packet to transmit (serialized frame size)
/// </summary>
public const int MAX_FRAME_PAYLOAD_SIZE = 1024 * 1024 * 32;
/// <summary>
/// Начальный байт заголовка пакета данных
/// Starting byte of the data packet header
/// </summary>
public const byte PACKET_HEADER_START_BYTE = 181;
/// <summary>
/// Размер очереди сообщения для отправки
/// The size of the message queue to send
/// </summary>
public const int MAX_SEND_QUEUE_SIZE = 1024;

@ -5,7 +5,6 @@ using System.Net;
using System.Net.Sockets;
using System.Threading;
using ZeroLevel.Services.Network.Contract;
using ZeroLevel.Services.Network.Exceptions;
using ZeroLevel.Services.Network.Models;
using ZeroLevel.Services.Pools;
using ZeroLevel.Services.Serialization;

@ -91,8 +91,7 @@ namespace ZeroLevel.Services.ObjectMapping
var setter = this._fields[name].Setter;
if (setter == null)
{
throw new Exception(string.Format("{0} '{1}' has not setter",
this._fields[name].IsField ? "Field" : "Property", name));
throw new Exception($"{(this._fields[name].IsField ? "Field" : "Property")} '{name}' has not setter");
}
if (value == null)
{
@ -116,12 +115,11 @@ namespace ZeroLevel.Services.ObjectMapping
var getter = this._fields[name]?.Getter;
if (getter == null)
{
throw new Exception(string.Format("{0} '{1}' has not getter",
this._fields[name].IsField ? "Field" : "Property", name));
throw new Exception($"{(this._fields[name].IsField ? "Field" : "Property")} '{name}' has not getter");
}
return getter(instance);
}
throw new KeyNotFoundException(string.Format("Not found field {0}", name));
throw new KeyNotFoundException($"Not found field {name}");
}
public T Get<T>(object instance, string name)
@ -131,12 +129,11 @@ namespace ZeroLevel.Services.ObjectMapping
var getter = this._fields[name]?.Getter;
if (getter == null)
{
throw new Exception(string.Format("{0} '{1}' has not getter",
this._fields[name].IsField ? "Field" : "Property", name));
throw new Exception($"{(this._fields[name].IsField ? "Field" : "Property")} '{name}' has not getter");
}
return (T)getter(instance);
}
throw new KeyNotFoundException(string.Format("Not found field {0}", name));
throw new KeyNotFoundException($"Not found field {name}");
}
public object GetOrDefault(object instance, string name, object defaultValue)
@ -150,7 +147,7 @@ namespace ZeroLevel.Services.ObjectMapping
}
return getter(instance);
}
throw new KeyNotFoundException(string.Format("Not found field {0}", name));
throw new KeyNotFoundException($"Not found field {name}");
}
public T GetOrDefault<T>(object instance, string name, T defaultValue)
@ -164,7 +161,7 @@ namespace ZeroLevel.Services.ObjectMapping
}
return (T)getter(instance);
}
throw new KeyNotFoundException(string.Format("Not found field {0}", name));
throw new KeyNotFoundException($"Not found field {name}");
}
#endregion

@ -3,10 +3,10 @@
public interface IQueryBuilder<T, Q>
{
/// <summary>
/// Превращение абстрактного запроса в реальный, под конкретное хранилище
/// Turning an abstract query into a real one, for a specific repository
/// </summary>
/// <param name="query">Абстрактный запрос</param>
/// <returns>Запрос к хранилищу конкретного типа</returns>
/// <param name="query">Abstract query</param>
/// <returns>Request to store a specific type</returns>
IRealQuery<T, Q> Build(IQuery query);
}
}

@ -8,12 +8,8 @@ namespace ZeroLevel.Services.Reflection
#region TypeHelpers
/// <summary>
/// Преобразование строки в тип, если для типа есть соответствующий конвертер, при отсутствии конвертера возвращается
/// состояние по умолчанию для указанного типа
/// Сonverting a string to a type, if there is a corresponding converter for the type, in the absence of a converter, the default state for the specified type is returned
/// </summary>
/// <param name="input">Строка</param>
/// <param name="to">Тип к которому требуется привести значение в строке</param>
/// <returns>Результат преобразования</returns>
public static object TryConvert(string input, Type to)
{
try
@ -28,17 +24,14 @@ namespace ZeroLevel.Services.Reflection
}
/// <summary>
/// Создание значения по умолчанию для указанного типа
/// Creating default values for specified type
/// </summary>
/// <param name="type">Тип</param>
/// <returns>Значение по умолчанию</returns>
private static object CreateDefaultState(Type type)
{
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}

@ -34,7 +34,7 @@ namespace ZeroLevel.Services.Reflection
return (Func<object, object>)lambda.Compile();
}
/// <summary>
/// Создает быстрый сеттер для свойства
/// Creates a quick setter for a property
/// </summary>
public Action<object, object> BuildSetter(PropertyInfo property)
{
@ -53,7 +53,7 @@ namespace ZeroLevel.Services.Reflection
return expr.Compile();
}
/// <summary>
/// Создает быстрый сеттер для поля
/// Creates a quick setter for a field.
/// </summary>
public Action<object, object> BuildSetter(FieldInfo field)
{

@ -9,113 +9,78 @@ using System.Runtime.Serialization;
namespace ZeroLevel.Services.Reflection
{
/// <summary>
/// Набор методов для работы с типами объектов
/// A set of methods for working with object types
/// </summary>
public static class TypeHelpers
{
/// <summary>
/// True если массив
/// </summary>
public static bool IsArray(Type type)
{
return type.Return(t => t.IsArray, false);
}
/// <summary>
/// True если структура
/// </summary>
public static bool IsStruct(Type type)
{
return type.Return(t => t.IsValueType && !IsSimpleType(t), false);
}
/// <summary>
/// True если класс
/// </summary>
public static bool IsClass(Type type)
{
return type.Return(t => t.IsClass, false);
}
/// <summary>
/// True если URI
/// </summary>
public static bool IsUri(Type type)
{
return type.Return(t => (typeof(Uri).IsAssignableFrom(t)), false);
}
/// <summary>
/// True если хэшсет
/// </summary>
public static bool IsHashSet(Type type)
{
return type.Return(t => t.IsGenericType
&& t.GetGenericTypeDefinition() == typeof(HashSet<>), false);
}
/// <summary>
/// True если строка
/// </summary>
public static bool IsString(Type type)
{
return type.Return(t => t == typeof(string));
}
/// <summary>
/// True если базовый тип - date, decimal, string, или GUID
/// </summary>
public static bool IsSimpleType(Type type)
{
return type.Return(t =>
{
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
{
t = Nullable.GetUnderlyingType(t);
}
return t.IsPrimitive
|| t == typeof(DateTime)
|| t == typeof(decimal)
|| t == typeof(string)
|| t == typeof(Guid)
|| t == typeof(TimeSpan);
}, false);
}
/// <summary>
/// True если тип данных
/// </summary>
public static bool IsRuntimeType(Type type)
{
return type.Return(t => (typeof(Type).IsAssignableFrom(t)), false);
}
/// <summary>
/// True если IPEndPoint
/// </summary>
public static bool IsIpEndPoint(Type type)
{
return type.Return(t => t == typeof(IPEndPoint), false);
}
/// <summary>
/// True если DataSet
/// </summary>
public static bool IsDataset(Type type)
{
return type.Return(t => t == typeof(DataSet), false);
}
/// <summary>
/// True если DataTable
/// </summary>
public static bool IsDataTable(Type type)
{
return type.Return(t => t == typeof(DataTable), false);
}
/// <summary>
/// True если DataRow
/// </summary>
public static bool IsDataRow(Type type)
{
return type.Return(t => t == typeof(DataRow), false);
}
public static bool IsList(Type type)
{
return type.Return(t => t.GetInterfaces().Contains(typeof(IList)), false);
}
/// <summary>
/// True if the base type is datetime, decimal, string, or GUID
/// </summary>
public static bool IsSimpleType(Type type)
{
return type.Return(t =>
{
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
{
t = Nullable.GetUnderlyingType(t);
}
return t.IsPrimitive
|| t == typeof(DateTime)
|| t == typeof(decimal)
|| t == typeof(string)
|| t == typeof(Guid)
|| t == typeof(TimeSpan);
}, false);
}
public static bool IsDictionary(Type type)
{

@ -5,33 +5,33 @@ namespace ZeroLevel.Services.Semantic
public interface ILexProvider
{
/// <summary>
/// Выделение токенов из текста как есть
/// Extract tokens from text as is
/// </summary>
/// <returns>Список токенов</returns>
/// <returns>Spisok tokenov</returns>
IEnumerable<LexToken> ExtractLexTokens(string text);
/// <summary>
/// Выделение уникальных токенов из текста
/// Selecting unique tokens from text
/// </summary>
/// <returns>Список токенов</returns>
/// <returns>Tokens</returns>
IEnumerable<LexToken> ExtractUniqueLexTokens(string text);
/// <summary>
/// Выделение уникальных токенов из текста с отбрасыванием стоп-слов
/// Allocation of unique tokens from text with drop of stop words
/// </summary>
/// <returns>Список токенов</returns>
/// <returns>Tokens</returns>
IEnumerable<LexToken> ExtractUniqueLexTokensWithoutStopWords(string text);
/// <summary>
/// Поиск токенов в тексте соответствующих указанным словам (полнотекстовый поиск)
/// Search for tokens in the text corresponding to the specified words (full-text search)
/// </summary>
/// <param name="text">Текст по которому выполняется поиск</param>
/// <param name="words">Слова для поиска</param>
/// <returns>Словарь, где ключ - слово, значение - список соответствующих ему найденных токенов</returns>
/// <param name="text">Search text</param>
/// <param name="words">Search words</param>
/// <returns>Dictionary, where key is a word, value is a list of matching tokens found for it</returns>
IDictionary<string, IEnumerable<LexToken>> SearchLexTokensByWords(string text, string[] words);
/// <summary>
/// Поиск токенов в тексте соответствующих указанным фразам (полнотекстовый поиск)
/// Search for tokens in the text corresponding to the specified phrases (full-text search)
/// </summary>
/// <param name="text">Текст по которому выполняется поиск</param>
/// <param name="phrases">Фразы для поиска</param>
/// <returns>Словарь, где ключ - фраза, значение - список соответствующих ему найденных массивов токенов</returns>
/// <param name="text">Search text</param>
/// <param name="phrases">Search phrases</param>
/// <returns>The dictionary, where the key is a phrase, a value is a list of token arrays corresponding to it</returns>
IDictionary<string, IEnumerable<LexToken[]>> SearchLexTokensByPhrases(string text, string[] phrases);
}
}

@ -1,7 +1,7 @@
namespace ZeroLevel.Services.Semantic
{
/// <summary>
/// Выполняет преобразование слова к абстрактной основе слова(корень, стем, лемма и т.п.)
/// Performs word conversion to abstract word basis (root, stem, lemma, etc.)
/// </summary>
public interface ILexer
{

@ -32,7 +32,7 @@ namespace ZeroLevel.Services.Semantic
{
if ((object)this == (object)other)
return true;
if (this == null) // и так бывает
if (this == null)
throw new NullReferenceException();
if (other == null)
return false;

@ -1,22 +1,22 @@
Реализация основы для семантической работы с текстом.
The implementation of the basis for semantic work with the text.
LexProvider - реализует выделение токенов из текста, где под токеном понимается какое-либо приведение слова.
Например, токеном может являться непосредственно само слово, стем, лемма.
LexProvider - implements the selection of tokens from the text, where a token is any coercion of a word.
For example, a token can be directly the word itself, a system, a lemma.
В качестве реализации созданы две фабрики:
Two factories were created as an implementation:
SnowbolLexProviderFactory - возвращает провайдеры на основе стемминга 'Snowball'
JustWordLexProviderFactory - возвращает провайдер который принимает за токен непосредственно слово, без изменений (lower case)
SnowbolLexProviderFactory - returns providers based on stemming 'Snowball'
JustWordLexProviderFactory - returns a provider that takes the word itself for the token, no change (lower case)
Для реализации собственного провайдера потребуется создать класс на основе интерфейса ILexer и реализовать метод Lex,
в котором будет проведена необходимая нормализация слова в нужном семантическом контексте.
To implement your own provider, you need to create a class based on the ILexer interface and implement the Lex method,
in which the necessary normalization of the word in the necessary semantic context will be carried out.
Например:
For example:
public class LemmaLexer: ILexer
{
public string Lex (string word) {return Lemmatizer.Lemma (word); }
}
После чего можно создать на его основе провайдер:
Then you can create a provider based on it:
var provider = new LexProvider (new LemmaLexer ());

@ -11,10 +11,10 @@ namespace ZeroLevel.Implementation.Semantic.Helpers
RegexOptions.Compiled | RegexOptions.IgnoreCase);
/// <summary>
/// Выделение слов из текста
/// Highlighting words from text
/// </summary>
/// <param name="text">Текст</param>
/// <returns>Список слов</returns>
/// <param name="text">Text</param>
/// <returns>Words</returns>
public static IEnumerable<string> ExtractWords(string text)
{
var result = new List<string>();
@ -27,30 +27,30 @@ namespace ZeroLevel.Implementation.Semantic.Helpers
}
/// <summary>
/// Выделение уникальных слов из текста
/// Highlighting unique words from text
/// </summary>
/// <param name="text">Текст</param>
/// <returns>Список уникальных слов</returns>
/// <param name="text">Text</param>
/// <returns>List of unique words</returns>
public static IEnumerable<string> ExtractUniqueWords(string text)
{
return new HashSet<string>(ExtractWords(text));
}
/// <summary>
/// Выделение уникальных слов из текста без стоп слов
/// Highlighting unique words from text without stop words
/// </summary>
/// <param name="text">Текст</param>
/// <returns>Список уникальных слов без стоп слов</returns>
/// <param name="text">Text</param>
/// <returns>List of unique words without stop words</returns>
public static IEnumerable<string> ExtractUniqueWordsWithoutStopWords(string text)
{
return new HashSet<string>(ExtractUniqueWords(text).Where(w => StopWords.IsStopWord(w) == false));
}
/// <summary>
/// Выделение токенов из текста
/// Extract tokens from text
/// </summary>
/// <param name="text">Текст</param>
/// <returns>Список токенов</returns>
/// <param name="text">Text</param>
/// <returns>Tokens</returns>
public static IEnumerable<WordToken> ExtractWordTokens(string text)
{
var result = new List<WordToken>();
@ -63,20 +63,20 @@ namespace ZeroLevel.Implementation.Semantic.Helpers
}
/// <summary>
/// Выделение уникальных токенов из текста (первое вхождение)
/// Selection of unique tokens from the text (first entry)
/// </summary>
/// <param name="text">Текст</param>
/// <returns>Список уникальных токенов</returns>
/// <param name="text">Text</param>
/// <returns>List of unique tokens</returns>
public static IEnumerable<WordToken> ExtractUniqueWordTokens(string text)
{
return ExtractWordTokens(text).DistinctBy(t => t.Word);
}
/// <summary>
/// Выделение уникальных токенов из текста с отбрасыванием стоп-слов
/// Allocation of unique tokens from text with drop of stop words
/// </summary>
/// <param name="text">Текст</param>
/// <returns>Список уникальных токенов без стоп слов</returns>
/// <param name="text">Text</param>
/// <returns>List of unique tokens without stop words</returns>
public static IEnumerable<WordToken> ExtractUniqueWordTokensWithoutStopWords(string text)
{
return ExtractWordTokens(text).DistinctBy(t => t.Word).Where(t => StopWords.IsStopWord(t.Word) == false);

@ -1,6 +1,4 @@
using ZeroLevel.Services.Semantic;
namespace ZeroLevel.Services.Semantic
namespace ZeroLevel.Services.Semantic
{
public class WordLexer : ILexer
{

@ -7,16 +7,13 @@ using System.Text;
namespace ZeroLevel.Services.Serialization
{
/// <summary>
/// Обертка над MemoryStream для чтения, с проверкой выхода за пределы потока
/// A wrapper over a MemoryStream for reading, with a check for overflow
/// </summary>
public sealed class MemoryStreamReader
: IBinaryReader
{
private readonly MemoryStream _stream;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="data">Данные для чтения</param>
public MemoryStreamReader(byte[] data)
{
if (data == null)
@ -25,7 +22,7 @@ namespace ZeroLevel.Services.Serialization
}
/// <summary>
/// Чтение флага
/// Flag reading
/// </summary>
public bool ReadBoolean()
{
@ -34,7 +31,7 @@ namespace ZeroLevel.Services.Serialization
return BitConverter.ToBoolean(new byte[1] { ReadByte() }, 0);
}
/// <summary>
/// Чтение байта
/// Reading byte
/// </summary>
public byte ReadByte()
{
@ -43,7 +40,7 @@ namespace ZeroLevel.Services.Serialization
return (byte)_stream.ReadByte();
}
/// <summary>
/// Чтение байт-массива
/// Reading bytes
/// </summary>
/// <returns></returns>
public byte[] ReadBytes()
@ -53,7 +50,7 @@ namespace ZeroLevel.Services.Serialization
return ReadBuffer(length);
}
/// <summary>
/// Чтение целого 32-хбитного числа (4 байта)
/// Read 32-bit integer (4 bytes)
/// </summary>
public Int32 ReadInt32()
{
@ -67,7 +64,7 @@ namespace ZeroLevel.Services.Serialization
return BitConverter.ToInt32(buffer, 0);
}
/// <summary>
/// Чтение целого 64-хбитного числа (8 байт)
/// Read integer 64-bit number (8 bytes)
/// </summary>
public Int64 ReadLong()
{
@ -87,7 +84,7 @@ namespace ZeroLevel.Services.Serialization
}
/// <summary>
/// Чтение строки (4 байта на длину + Length байт)
/// Read string (4 bytes per length + Length bytes)
/// </summary>
public string ReadString()
{
@ -97,7 +94,7 @@ namespace ZeroLevel.Services.Serialization
return Encoding.UTF8.GetString(buffer);
}
/// <summary>
/// Чтение GUID (16 байт)
/// Read GUID (16 bytes)
/// </summary>
public Guid ReadGuid()
{
@ -105,7 +102,7 @@ namespace ZeroLevel.Services.Serialization
return new Guid(buffer);
}
/// <summary>
/// Чтение байт-пакета (читается размер из указанного количества байт и затем сам пакет прочитанного размера)
/// Reading byte-package (read the size of the specified number of bytes, and then the packet itself read size)
/// </summary>
public byte[] ReadBuffer(int count)
{
@ -115,11 +112,11 @@ namespace ZeroLevel.Services.Serialization
var buffer = new byte[count];
var readedCount = _stream.Read(buffer, 0, count);
if (count != readedCount)
throw new InvalidOperationException(string.Format("The stream returned less data ({0} bytes) than expected ({1} bytes)", count, readedCount));
throw new InvalidOperationException($"The stream returned less data ({count} bytes) than expected ({readedCount} bytes)");
return buffer;
}
/// <summary>
/// Чтение даты времени
/// Reading the datetime
/// </summary>
/// <returns></returns>
public DateTime? ReadDateTime()
@ -145,7 +142,7 @@ namespace ZeroLevel.Services.Serialization
}
/// <summary>
/// Проверка не выходит ли чтение данных за пределы потока
/// Check if data reading is outside the stream
/// </summary>
bool CheckOutOfRange(Stream stream, int offset)
{
@ -333,9 +330,6 @@ namespace ZeroLevel.Services.Serialization
}
#endregion
/// <summary>
/// Очистка
/// </summary>
public void Dispose()
{
_stream.Dispose();

@ -9,7 +9,7 @@ using ZeroLevel.Services.Extensions;
namespace ZeroLevel.Services.Serialization
{
/// <summary>
/// Обертка над MemoryStream для записи
/// Wrapper over memorystream for writing
/// </summary>
public sealed class MemoryStreamWriter :
IBinaryWriter
@ -29,21 +29,21 @@ namespace ZeroLevel.Services.Serialization
_stream = new MemoryStream();
}
/// <summary>
/// Запись булевого значения (1 байт)
/// Record a boolean value (1 byte)
/// </summary>
public void WriteBoolean(bool val)
{
_stream.WriteByte(BitConverter.GetBytes(val)[0]);
}
/// <summary>
/// Запись байта (1 байт)
/// Write byte (1 byte)
/// </summary>
public void WriteByte(byte val)
{
_stream.WriteByte(val);
}
/// <summary>
/// Запись байт массива
/// Write array bytes
/// </summary>
/// <param name="val"></param>
public void WriteBytes(byte[] val)
@ -60,14 +60,14 @@ namespace ZeroLevel.Services.Serialization
}
/// <summary>
/// Запись целого 32-хбитного числа (4 байта)
/// Record a 32-bit integer (4 bytes)
/// </summary>
public void WriteInt32(Int32 number)
{
_stream.Write(BitConverter.GetBytes(number), 0, 4);
}
/// <summary>
/// Запись целого 64-хбитного числа (8 байт)
/// Record an integer 64-bit number (8 bytes)
/// </summary>
public void WriteLong(Int64 number)
{
@ -90,7 +90,7 @@ namespace ZeroLevel.Services.Serialization
}
/// <summary>
/// Запись строки (4 байта на длину + Length байт)
/// Write string (4 bytes long + Length bytes)
/// </summary>
public void WriteString(string line)
{
@ -106,14 +106,14 @@ namespace ZeroLevel.Services.Serialization
}
}
/// <summary>
/// Запись GUID (16 байт)
/// GUID record (16 bytes)
/// </summary>
public void WriteGuid(Guid guid)
{
_stream.Write(guid.ToByteArray(), 0, 16);
}
/// <summary>
/// Запись даты времени
/// Record the datetime
/// </summary>
/// <param name="datetime"></param>
public void WriteDateTime(DateTime? datetime)

@ -1,7 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using ZeroLevel.Services.Logging;
namespace ZeroLevel.Services.Shedulling
{
@ -31,7 +30,7 @@ namespace ZeroLevel.Services.Shedulling
private readonly ConcurrentDictionary<long, ExpiredAsyncObject> _repitableAsyncActions = new ConcurrentDictionary<long, ExpiredAsyncObject>();
/// <summary>
/// Исполняет действие раз в период, при этом период перерасчитывается по переданной функции при каждом пересоздании задачи
/// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task.
/// </summary>
/// <param name="nextEventPeriodCalcFunction">Функция для расчета следующего периода</param>
/// <param name="callback">Действие</param>

@ -1,11 +1,10 @@
using System;
using System.Collections.Concurrent;
using ZeroLevel.Services.Logging;
namespace ZeroLevel.Services.Shedulling
{
/// <summary>
/// Простой планировщик для периодических и разовых задач выполняемых по расписанию
/// Simple scheduler for periodic and one-time scheduled tasks
/// </summary>
internal class ShedullerImpl
: ISheduller
@ -32,11 +31,10 @@ namespace ZeroLevel.Services.Shedulling
#region Repitable behaviour
private readonly ConcurrentDictionary<long, ExpiredObject> _repitableActions = new ConcurrentDictionary<long, ExpiredObject>();
/// <summary>
/// Исполняет действие раз в период, при этом период перерасчитывается по переданной функции при каждом пересоздании задачи
/// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task.
/// </summary>
/// <param name="nextEventPeriodCalcFunction">Функция для расчета следующего периода</param>
/// <param name="callback">Действие</param>
/// <returns>Идентификатор задания</returns>
/// <param name="nextEventPeriodCalcFunction">Function to calculate the next period</param>
/// <returns>Task ID</returns>
public long RemindEveryNonlinearPeriod(Func<TimeSpan> nextEventPeriodCalcFunction,
Action<long> callback,
bool breakWherError = false)
@ -44,12 +42,11 @@ namespace ZeroLevel.Services.Shedulling
return RemindEveryNonlinearPeriod(nextEventPeriodCalcFunction, nextEventPeriodCalcFunction, callback, breakWherError);
}
/// <summary>
/// Исполняет действие раз в период, при этом период перерасчитывается по переданной функции при каждом пересоздании задачи
/// Performs an action once a period, while the period is recalculated according to the transferred function at each re-creation of the task.
/// </summary>
/// <param name="firstEventPeriodCalcFunction">Функция для расчета периода до первого исполнения</param>
/// <param name="nextEventPeriodCalcFunction">Функция для расчета периода до последующих исполнений</param>
/// <param name="callback">Действие</param>
/// <returns>Идентификатор задания</returns>
/// <param name="firstEventPeriodCalcFunction">The function to calculate the period to the first execution</param>
/// <param name="nextEventPeriodCalcFunction">The function for calculating the period until subsequent performances</param>
/// <returns>Task ID</returns>
public long RemindEveryNonlinearPeriod(Func<TimeSpan> firstEventPeriodCalcFunction,
Func<TimeSpan> nextEventPeriodCalcFunction,
Action<long> callback,
@ -82,7 +79,7 @@ namespace ZeroLevel.Services.Shedulling
/// </summary>
/// <param name="nextEventDateCalcFunction">Функция для расчета следующей даты</param>
/// <param name="callback">Действие</param>
/// <returns>Идентификатор задания</returns>
/// <returns>Task ID</returns>
public long RemindEveryNonlinearDate(Func<DateTime, DateTime> nextEventDateCalcFunction,
Action<long> callback,
bool breakWherError = false)
@ -130,7 +127,7 @@ namespace ZeroLevel.Services.Shedulling
/// <param name="firstEventDateCalcFunction">Функция для расчет даты первого запуска</param>
/// <param name="nextEventDateCalcFunction">Функция для расчета следующей даты</param>
/// <param name="callback">Действие</param>
/// <returns>Идентификатор задания</returns>
/// <returns>Task ID</returns>
public long RemindEveryNonlinearDate(Func<DateTime, DateTime> firstEventDateCalcFunction,
Func<DateTime, DateTime> nextEventDateCalcFunction,
Action<long> callback,
@ -171,7 +168,7 @@ namespace ZeroLevel.Services.Shedulling
/// </summary>
/// <param name="timespan">Период</param>
/// <param name="callback">Действие</param>
/// <returns>Идентификатор задания</returns>
/// <returns>Task ID</returns>
public long RemindEvery(TimeSpan timespan,
Action<long> callback,
bool breakWherError = false)
@ -184,7 +181,7 @@ namespace ZeroLevel.Services.Shedulling
/// <param name="first">Период до первого выполнения</param>
/// <param name="next">Период</param>
/// <param name="callback">Действие</param>
/// <returns>Идентификатор задания</returns>
/// <returns>Task ID</returns>
public long RemindEvery(TimeSpan first,
TimeSpan next,
Action<long> callback,

@ -24,12 +24,12 @@ namespace ZeroLevel.Contracts.Specification.Building
}
}
/// <summary>
/// Для выбора одного значения из списка
/// To select a single value from the list
/// </summary>
private static readonly Dictionary<Type, Dictionary<string, ParamEnum>> _enums =
new Dictionary<Type, Dictionary<string, ParamEnum>>();
/// <summary>
/// Для выбора нескольких значений из списка
/// To select multiple values from the list
/// </summary>
private static readonly Dictionary<Type, Dictionary<string, ITree>> _trees =
new Dictionary<Type, Dictionary<string, ITree>>();
@ -37,7 +37,7 @@ namespace ZeroLevel.Contracts.Specification.Building
private static readonly object _locker = new object();
/// <summary>
/// Регистрация перечисления
/// Registration of enumerable
/// </summary>
public static void Register<TFilter>(string paramName, Dictionary<string, object> map)
{
@ -57,7 +57,7 @@ namespace ZeroLevel.Contracts.Specification.Building
}
}
/// <summary>
/// Регистрация дерева
/// Tree Registration
/// </summary>
public static void RegisterTree<TFilter>(string paramName, ITree tree)
{

@ -3,24 +3,24 @@
namespace ZeroLevel.Contracts.Specification.Building
{
/// <summary>
/// Параметр конструктора спецификации
/// Specification constructor parameter
/// </summary>
public class SpecificationParameter
{
/// <summary>
/// Отображаемое имя
/// Display Name
/// </summary>
public string DisplayName;
/// <summary>
/// Имя параметра
/// Parameter name
/// </summary>
public string ParameterName;
/// <summary>
/// Тип параметра
/// Parameter type
/// </summary>
public Type ParameterType;
/// <summary>
/// Значение параметра
/// Parameter value
/// </summary>
public object Value;
}

@ -37,7 +37,7 @@ namespace ZeroLevel.Specification
{
if (false == _filterTypes.ContainsKey(filterName))
{
throw new KeyNotFoundException(string.Format("Not found specification '{0}'", filterName));
throw new KeyNotFoundException($"Not found specification '{filterName}'");
}
return (ISpecification<T>)Activator.CreateInstance(_filterTypes[filterName], args);
@ -47,7 +47,7 @@ namespace ZeroLevel.Specification
{
if (false == _filterTypes.ContainsKey(filterName))
{
throw new KeyNotFoundException(string.Format("Not found specification '{0}'", filterName));
throw new KeyNotFoundException($"Not found specification '{filterName}'");
}
return _filterTypes[filterName];
}

@ -7,23 +7,23 @@ using ZeroLevel.Services.Trees;
namespace ZeroLevel.Specification
{
/// <summary>
/// Создает спецификацию используя конкретный конструктор
/// Creates a specification using a specific constructor.
/// </summary>
public class SpecificationBuilder :
ISpecificationBuilder,
IEquatable<SpecificationBuilder>
{
/// <summary>
/// Тип спецификации
/// Type of specification
/// </summary>
private readonly Type _instanceType;
/// <summary>
/// Список параметров конструктора
/// List of Constructor Parameters
/// </summary>
private readonly List<SpecificationParameter> _values =
new List<SpecificationParameter>();
/// <summary>
/// Обозначение конструктора
/// Constructor name
/// </summary>
public string Name { get; }
public Type FilterType { get { return _instanceType; } }
@ -38,7 +38,7 @@ namespace ZeroLevel.Specification
_values = parameters;
}
/// <summary>
/// Обход параметров
/// Parameter traversal
/// </summary>
public void ParametersTraversal(Action<SpecificationParameter> parameterHandler)
{
@ -48,7 +48,7 @@ namespace ZeroLevel.Specification
}
}
/// <summary>
/// Построение спецификации
/// Build specification
/// </summary>
public ISpecification<T> Build<T>()
{

@ -39,7 +39,7 @@ namespace ZeroLevel.Specification
public ISpecificationBuilder GetVariant(string variantName)
{
if (false == _specificationActivateVariants.ContainsKey(variantName))
throw new InvalidOperationException(string.Format("Not found variant name {0}", variantName));
throw new InvalidOperationException($"Not found variant name {variantName}");
return new SpecificationBuilder(variantName, _specificationActivateVariants[variantName], _specificationType);
}
@ -48,7 +48,7 @@ namespace ZeroLevel.Specification
int index = 0;
foreach (var ctor in _specificationType.GetConstructors())
{
var vName = string.Format("{0} #{1:D2}", _specificationType.Name, index);
var vName = $"{_specificationType.Name} #{index:D2}";
var ca = ctor.GetCustomAttribute<DescriptionAttribute>();
if (null != ca)
{

@ -79,7 +79,7 @@ namespace ZeroLevel.Services.PlainTextTables
#region API
/// <summary>
/// Установка заголовков столбцов
/// Setting column headers
/// </summary>
public void SetColumnsHeaders(string[] headers)
{
@ -99,7 +99,7 @@ namespace ZeroLevel.Services.PlainTextTables
}
/// <summary>
/// Добавление строки значений
/// Adding a value row
/// </summary>
public void AppendRow(string[] cells)
{

@ -21,7 +21,7 @@ namespace ZeroLevel.Services.PlainTextTables
{
columns_width[i] += ow;
}
// Обновление ширины столбцов при необходимости
// Update column widths as needed
if (options.MaxCellWidth > 0)
{
for (int i = 0; i < columns_width.Length; i++)
@ -47,7 +47,7 @@ namespace ZeroLevel.Services.PlainTextTables
var table_width = GetTableWidth(options, columns_width);
var table = new StringBuilder();
// Отрисовка таблицы
// Table drawing
var rows = data.Rows.ToArray();
for (int i = 0; i < rows.Length; i++)
{
@ -70,20 +70,20 @@ namespace ZeroLevel.Services.PlainTextTables
}
catch (Exception ex)
{
Log.SystemError(ex, "Сбой при преобразовании таблицы");
Log.SystemError(ex, "Failed to convert table");
return string.Empty;
}
}
/// <summary>
/// Рендеринг отображения строки
/// Render row view
/// </summary>
private static List<string[]> RenderRow(TextTableData.TextTableRow row,
TextTableRenderOptions options,
int[] columns_width)
{
var result = new List<string[]>();
// Добавление пустых строк если есть padding сверху
// Adding blank lines if there is padding on top
if (options.PaddingTop > 0)
{
for (int i = 0; i < options.PaddingTop; i++)
@ -96,13 +96,13 @@ namespace ZeroLevel.Services.PlainTextTables
result.Add(empty);
}
}
// Разделение значений ячеек на части в зависимости от ширины столбца
// Separation of cell values into parts depending on the width of the column
var cells = new List<string[]>();
for (int i = 0; i < columns_width.Length; i++)
{
cells.Add(Split(row.Cells[i].Text, columns_width[i], options.PaddingLeft, options.PaddingRight).ToArray());
}
// Определение максимального количества строк по ячейкам (высота строки таблицы)
// Determining the maximum number of rows per cell (row height of the table)
var max = cells.Max(c => c.Length);
for (int i = 0; i < max; i++)
{
@ -118,7 +118,7 @@ namespace ZeroLevel.Services.PlainTextTables
}
result.Add(line);
}
// Добавление пустых строк если есть padding снизу
// Adding blank lines if there is padding below
if (options.PaddingBottom > 0)
{
for (int i = 0; i < options.PaddingBottom; i++)
@ -134,7 +134,7 @@ namespace ZeroLevel.Services.PlainTextTables
return result;
}
/// <summary>
/// Разделение текстовой строки на подстроки указанной длины
/// Splitting a text string into substrings of the specified length
/// </summary>
private static IEnumerable<string> Split(string str, int chunkSize, int leftPad, int rightPad)
{
@ -169,26 +169,26 @@ namespace ZeroLevel.Services.PlainTextTables
return result;
}
/// <summary>
/// Подсчет реальной ширины таблицы, для указанного стиля
/// Calculate the actual width of the table for the specified style
/// </summary>
private static int GetTableWidth(TextTableRenderOptions options, int[] columns_width)
{
int width =
columns_width.Sum() + // ширина областей текста
columns_width.Length - 1; // границы между ячейками
columns_width.Sum() + // width of text areas
columns_width.Length - 1; // cell boundaries
switch (options.Style)
{
case TextTableStyle.Columns:
case TextTableStyle.Simple:
case TextTableStyle.Borders:
case TextTableStyle.DoubleBorders:
width += 2; // внешние границы
width += 2; // outer borders
break;
}
return width;
}
/// <summary>
/// Отрисовка разделителя столбцов
/// Rendering column separator
/// </summary>
private static void DrawColumnSeparator(StringBuilder sb, TextTableRenderOptions options, int column_index)
{
@ -219,10 +219,10 @@ namespace ZeroLevel.Services.PlainTextTables
}
}
/// <summary>
/// Отрисовка разделителя строк
/// Row separator rendering
/// </summary>
/// <param name="sb"></param>
/// <param name="row_index">Индекс строки, имеется в виду индекс следующей строки, т.е. 0 - до отрисовки первой строки</param>
/// <param name="row_index">Line index, meaning the index of the next line, those 0 - before the first line is drawn</param>
private static void DrawRowSeparator(StringBuilder sb, TextTableRenderOptions options, int width, int row_index,
bool isFirst, bool isLast, int[] columns_width)
{

@ -3,31 +3,31 @@
public enum TextTableStyle
{
/// <summary>
/// Без рамок
/// No borders
/// </summary>
NoBorders,
/// <summary>
/// Рамки из символов !+-
/// Borders of characters! + -
/// </summary>
Simple,
/// <summary>
/// Рамки из символов +|, только для первой и последней строки и колонок
/// Borders of characters +|, only for the first and last row and columns
/// </summary>
Columns,
/// <summary>
/// Полные рамки
/// Full borders
/// </summary>
Borders,
/// <summary>
/// Линия для отделения названий колонок
/// Line to separate column names
/// </summary>
HeaderLine,
/// <summary>
/// Линии для отделения названий колонок и первого стоблца (названий строк)
/// Lines for separating column names and first column (row names)
/// </summary>
HeaderAndFirstColumn,
/// <summary>
/// Полные двойные рамки
/// Full double borders
/// </summary>
DoubleBorders,
DoubleHeaderLine,

@ -27,14 +27,14 @@ namespace ZeroLevel.Services.Trees
return result;
}
/// <summary>
/// Выделяет все ветви дерева, возвращая массив ветвей состоящий из специфицированных значений узлов
/// Selects all branches of the tree, returning an array of branches consisting of the specified node values.
/// </summary>
/// <typeparam name="T">Тип узлов дерева</typeparam>
/// <typeparam name="TCode">Тип значений для возвращаемых элементов ветвей</typeparam>
/// <param name="root">Корень</param>
/// <param name="childrenExtractor">Выделяет дочерние узлы для текущего узла</param>
/// <param name="codeExtractor">Выделяет значение узла</param>
/// <returns>Список ветвей дерева</returns>
/// <typeparam name="T">Type of tree nodes</typeparam>
/// <typeparam name="TCode">Value type for returned branch elements</typeparam>
/// <param name="root">Root</param>
/// <param name="childrenExtractor">Selects child nodes for the current node.</param>
/// <param name="codeExtractor">Select the value of the node</param>
/// <returns>List of tree branches</returns>
public static List<TCode[]> SpecifyExtractBranches<T, TCode>(T root,
Func<T, IEnumerable<T>> childrenExtractor,
Func<T, TCode> codeExtractor)
@ -53,12 +53,8 @@ namespace ZeroLevel.Services.Trees
return result;
}
/// <summary>
/// Выполняет обход ветвей дерева
/// Performs tree branch traversal.
/// </summary>
/// <typeparam name="T">Тип узлов дерева</typeparam>
/// <param name="root">Корень</param>
/// <param name="childrenExtractor">Выделяет дочерние узлы для текущего узла</param>
/// <param name="handler">Обработчик ветви</param>
public static void TraversTreeBrunches<T>(T root,
Func<T, IEnumerable<T>> childrenExtractor,
Action<IEnumerable<T>> handler)

@ -237,7 +237,6 @@
<Compile Include="Services\Network\Contract\IZBackward.cs" />
<Compile Include="Services\Network\Contract\IZObservableServer.cs" />
<Compile Include="Services\Network\Contract\IZTransport.cs" />
<Compile Include="Services\Network\Exceptions\NoConnectionException.cs" />
<Compile Include="Services\Network\Models\ExchangeAttributes.cs" />
<Compile Include="Services\Network\Models\MicroserviceInfo.cs" />
<Compile Include="Services\Network\Models\RequestInfo.cs" />

@ -1 +1 @@
3af5ac7a6b742028005a8a0757e8f6fbb4fd20fa
1f24b3553bbdd4eeac0eb648e295a8fad68b0131

Loading…
Cancel
Save

Powered by TurnKey Linux.