Compare commits

..

No commits in common. "master" and "net7-final" have entirely different histories.

101 changed files with 804 additions and 4693 deletions

View File

@ -1,4 +0,0 @@
[*.cs]
# SYSLIB1045: Преобразовать в "GeneratedRegexAttribute".
dotnet_diagnostic.SYSLIB1045.severity = silent

View File

@ -1,5 +1,10 @@
# Что такое ANB Software Components Pack?
ANB Software Components Pack - набор полезных классов C#, которые расширяют возможности языка. Они могут использоваться в приложенях для ОС Widows и серверов на базе этой ОС.
# anbsoftware_componentspack
some classes that extend the capabilities of the C # language
# Welcome to ANB Software Components Pack!
You are on the component set «ANB» page. Thanks for your interest in the project
# License
# Лицензия
MIIT

View File

@ -0,0 +1,63 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Класс ошибки
/// </summary>
public sealed class ActionError: IActionError
{
/// <summary>
/// Критичность ошибки:
/// при некритичных ошибках продолжение выполнения операции возможно,
/// а при критичных -- нет
/// </summary>
public bool IsCritical { get; init; }
/// <summary>
/// Объект ошибки
/// </summary>
public object Object { get; set; }
/// <summary>
/// Сообщение об ошибке
/// </summary>
public string Message { get; set; }
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public ActionError ()
{
IsCritical = true;
Object = "Not Implemented";
Message = "Not Implemented";
}
/// <summary>
/// Конструктор с 2 параметрами
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="isCritical">Критичность ошибки</param>
public ActionError (string message, bool isCritical = true)
{
IsCritical = isCritical;
Object = "";
Message = message;
}
/// <summary>
/// Конструктор с 3 параметрами
/// </summary>
/// <param name="eObject">Объект ошибки</param>
/// <param name="message">Сообщение</param>
/// <param name="isCritical">Критичность ошибки</param>
public ActionError (object eObject, string message, bool isCritical = true)
{
IsCritical = isCritical;
Object = eObject;
Message = message;
}
#endregion
}

View File

@ -0,0 +1,49 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Класс предупреждения
/// </summary>
public sealed class ActionInfo: IActionInfo
{
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public ActionInfo ()
{
IsStatusInfo = false;
Object = string.Empty;
Message = string.Empty;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="eObject">Объект</param>
/// <param name="message">Сообщение</param>
/// <param name="isStatus">Является статусной информацией?</param>
public ActionInfo (string eObject, string message, bool isStatus = false)
{
IsStatusInfo = isStatus;
Object = eObject;
Message = message;
}
#endregion
#region Реализация интерфейса
/// <summary>
/// Объект
/// </summary>
public object Object { get; set; }
/// <summary>
/// Сообщение
/// </summary>
public string Message { get; set; }
/// <summary>
/// Статусная информация (например, начало работы)
/// </summary>
public bool IsStatusInfo { get; init; }
#endregion
}

View File

@ -1,65 +1,71 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable MemberCanBeProtected.Global
using anbs_cp.Enums;
using anbs_cp.Interfaces;
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/*
История версий
Обновлено 2024.03.28
* Все поля Errors, Warnings и Infos объеденины в одно Messages
* В ActionStateMessage добавлен параметр, определяющий тип: MessageType
Обновлено 2024.03.26
* Все интерфейсы объеденины в один класс ActionStateMessage
* Интерфейс IActionState удалён
Обновлено 2023.12.10
* Заменены классы Action* на соответствующие интерфейсы
* Класс ActionState теперь наследует интерфейс IActionState, позволяющий добавлять состояния (ошибки, предупреждения и информацию)
из разных классов ActionState, т.е. например, данные из ActionState<bool> (кроме значения!) можно перенести в ActionState<int>.
Обновлено 2023.11.1
* Добавлен возвращаемый результат
Обновлено 2023.01.121.1:
* Заменены интерфейсы IAction* на соответствующие классы
*/
/// <summary>
/// Состояние действия
///
/// Обновлено 2023.11.1
/// * Добавлен возвращаемый результат
///
/// Обновлено 2023.01.121.1:
/// * Заменены интерфейсы IAction* на соответствующие классы
/// </summary>
/// <typeparam name="T">Тип класса</typeparam>
public class ActionState<T>: ISerializable
public class ActionState<T>
{
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public ActionState ()
{
Info = new();
Warnings = new();
Errors = new();
Value = default;
}
/// <summary>
/// Конструктор с указанием начального значения <see cref="Value"/>
/// </summary>
/// <param name="defaultValue">Начальное значение <see cref="Value"/></param>
public ActionState (T defaultValue)
{
Info = new();
Warnings = new();
Errors = new();
Value = defaultValue;
}
/// <summary>
/// Список информации
/// </summary>
// ReSharper disable once CollectionNeverQueried.Local
internal List<ActionStateMessage> Messages { get; } = [];
public List<ActionInfo> Info { get; }
/// <summary>
/// Список предупреждений
/// </summary>
public List<ActionWarning> Warnings { get; }
/// <summary>
/// Список ошибок
/// </summary>
public List<ActionError> Errors { get; }
/// <summary>
/// Значение
/// </summary>
public T? Value { get; set; }
/// <summary>
/// Метод для выбора всех значений для условия
/// </summary>
// ReSharper disable once StaticMemberInGenericType
public static readonly Func<ActionStateMessage, bool> SelectAll = static _ => true;
#region Методы
#region Очистка
/// <summary>
/// Очищает список ошибок
/// </summary>
public void ClearErrors ()
{
Clear(static message => message.MessageType == EActionStateMessageType.Error);
Errors.Clear();
Errors.TrimExcess();
}
/// <summary>
@ -67,7 +73,8 @@ public class ActionState<T>: ISerializable
/// </summary>
public void ClearWarnings ()
{
Clear(static message => message.MessageType == EActionStateMessageType.Warning);
Warnings.Clear();
Warnings.TrimExcess();
}
/// <summary>
@ -75,56 +82,62 @@ public class ActionState<T>: ISerializable
/// </summary>
public void ClearInfo ()
{
Clear(static message => message.MessageType == EActionStateMessageType.Information);
Info.Clear();
Info.TrimExcess();
}
/// <summary>
/// Очищает список по условию <paramref name="predicate"/>
/// Очищает все списки
/// </summary>
/// <param name="predicate">Условие выборки</param>
public void Clear (Func<ActionStateMessage, bool> predicate)
public void Clear ()
{
// Получаю список элементов
IEnumerable<ActionStateMessage> list = Messages.Where(predicate);
// Для каждого элемента
foreach (ActionStateMessage actionStateMessage in list)
// - запускаю его удаление
Messages.Remove(actionStateMessage);
ClearInfo();
ClearWarnings();
ClearErrors();
}
#endregion
#region Добавление
/// <summary>
/// Добавление сообщения
/// </summary>
/// <param name="message">Сообщение</param>
// ReSharper disable once MemberCanBeMadeStatic.Global
// ReSharper disable once FunctionRecursiveOnAllPaths
public void Add (ActionStateMessage message) => Messages.Add(message);
/// <summary>
/// Добавляет список
/// </summary>
/// <param name="messages">Список сообщений</param>
public void AddRange (IEnumerable<ActionStateMessage> messages) => Messages.AddRange(messages);
#endregion
#region Добавление ошибки
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="error">Ошибка</param>
// ReSharper disable once MemberCanBeMadeStatic.Global
// ReSharper disable once FunctionRecursiveOnAllPaths
public void AddError (ActionError error) => Errors.Add(error);
/// <summary>
/// Добавляет ошибки в список
/// </summary>
/// <param name="errors">Список ошибок</param>
public void AddErrors(IEnumerable<ActionError> errors) => Errors.AddRange(errors);
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="critical">Является ли ошибка критической</param>
public void AddError (bool critical = true) => Add(new(EActionStateMessageType.Error, critical));
public void AddError (bool critical = true)
{
//Создаю ошибку
ActionError error = new("", critical);
//Добавляю ошибку
AddError(error);
}
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="message">Сообщение об ошибке</param>
/// <param name="critical">Является ли ошибка критической</param>
public void AddError (string message, bool critical = true) =>
Add(new(EActionStateMessageType.Error, critical, message: message));
public void AddError (string message, bool critical = true)
{
//Создаю ошибку
ActionError error = new(message, critical);
//Добавляю ошибку
AddError(error);
}
/// <summary>
/// Добавление ошибки
@ -132,71 +145,118 @@ public class ActionState<T>: ISerializable
/// <param name="errorObject">Объект ошибки</param>
/// <param name="message">Сообщение об ошибке</param>
/// /// <param name="critical">Является ли ошибка критической</param>
public void AddError (string errorObject, string message, bool critical = true) =>
Add(new(EActionStateMessageType.Error, critical, errorObject, message));
public void AddError (string errorObject, string message, bool critical = true)
{
//Создаю ошибку
ActionError error = new(errorObject, message, critical);
//Добавляю ошибку
AddError(error);
}
#endregion
#region Добавление предупреждения
/// <summary>
/// Добавление предупреждения
/// </summary>
/// <param name="warning">Предупреждение</param>
public void AddWarning (ActionWarning warning) => Warnings.Add(warning);
/// <summary>
/// Добавление предупреждений
/// </summary>
/// <param name="warnings">Список предупреждений</param>
public void AddWarnings(IEnumerable<ActionWarning> warnings) => Warnings.AddRange(warnings);
/// <summary>
/// Добавление предупреждение
/// </summary>
/// <param name="message">Текст предупреждения</param>
/// <param name="warningObject">Объект предупреждения</param>
public void AddWarning (string message, string warningObject = "") =>
Add(new(EActionStateMessageType.Warning, message: message, obj: warningObject));
public void AddWarning (string message, string warningObject = "")
{
//Создаю предупреждение
ActionWarning warning = new(warningObject, message);
//Добавляю предупреждение
AddWarning(warning);
}
#endregion
#region Добавление информации
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="info">Информация</param>
public void AddInfo (ActionInfo info) => Info.Add(info);
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="infos">Список информации</param>
public void AddInfos (IEnumerable<ActionInfo> infos) => Info.AddRange(infos);
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="message">Текст информации</param>
/// <param name="infoObject">Объект информации</param>
public void AddInfo (string message, string infoObject = "") => Add(new(message: message, obj: infoObject));
public void AddInfo (string message, string infoObject = "")
{
//Создаю информацию
ActionInfo info = new(infoObject, message);
//Добавляю информацию
AddInfo(info);
}
#endregion
#region Печать
/// <summary>
/// Печать сообщений
/// Печать списка ошибок
/// </summary>
/// <param name="area">Область печати</param>
/// <param name="formatList">Оформление всей области</param>
/// <param name="formatItem">Оформление элемента</param>
/// <returns>Текстовое представление выбранных списокв</returns>
/// <exception cref="ArgumentOutOfRangeException">Ошибка при неизвестной области</exception>
public string PrintMessage (EActionStatePrintArea area, string formatList, string formatItem)
/// <param name="formatList">Формат списка</param>
/// <param name="formatItem">Формат элемента списка</param>
/// <returns>Список ошибок в текстовой форме</returns>
public string PrintErrorList (string formatList, string formatItem)
{
// Создаю список
List<ActionStateMessage> list = [];
string elements =
#pragma warning disable CS8625
Errors.Aggregate<IActionError, string>(null, (current, error) => current + error.PrintMessage(formatItem));
#pragma warning restore CS8625
// Выбираю списки по областям
switch (area)
{
case EActionStatePrintArea.All:
list.AddRange(Messages);
break;
case EActionStatePrintArea.ErrorsAndWarnings:
list.AddRange(Messages.Where(static message =>
message.MessageType is EActionStateMessageType.Error or EActionStateMessageType.Warning));
break;
case EActionStatePrintArea.ErrorsOnly:
list.AddRange(Messages.Where(static message => message.MessageType == EActionStateMessageType.Error));
break;
case EActionStatePrintArea.WarningsOnly:
list.AddRange(Messages.Where(static message => message.MessageType == EActionStateMessageType.Warning));
break;
case EActionStatePrintArea.InfosOnly:
list.AddRange(Messages.Where(static message =>
message.MessageType == EActionStateMessageType.Information));
break;
default:
throw new ArgumentOutOfRangeException(nameof(area), area, null);
return string.Format(formatList, elements);
}
// Создаю элементы
/// <summary>
/// Печать списка предупреждений
/// </summary>
/// <param name="formatList">Формат списка</param>
/// <param name="formatItem">Формат элемента списка</param>
/// <returns>Список предупреждений в текстовой форме</returns>
public string PrintWarningList (string formatList, string formatItem)
{
string elements =
list.Aggregate(string.Empty, (current, item) => current + item.PrintMessage(formatItem));
#pragma warning disable CS8625
Warnings.Aggregate<IActionWarning, string>(null,
#pragma warning restore CS8625
(current, warning) => current + warning.PrintMessage(formatItem));
return string.Format(formatList, elements);
}
/// <summary>
/// Печать списка информации
/// </summary>
/// <param name="formatList">Формат списка</param>
/// <param name="formatItem">Формат элемента списка</param>
/// <returns>Список информации в текстовой форме</returns>
public string PrintInfoList (string formatList, string formatItem)
{
string elements =
#pragma warning disable CS8625
Info.Aggregate<IActionInfo, string>(null, (current, info) => current + info.PrintMessage(formatItem));
#pragma warning restore CS8625
return string.Format(formatList, elements);
}
@ -208,24 +268,24 @@ public class ActionState<T>: ISerializable
/// </summary>
/// <param name="ignoreNonCritical">Игнорировать не критические</param>
/// <returns>Наличие ошибок</returns>
public bool HasErrors (bool ignoreNonCritical = false) => Messages.Any(message =>
message.MessageType == EActionStateMessageType.Error && (!ignoreNonCritical || !message.IsCritical));
public bool HasErrors (bool ignoreNonCritical = false) =>
ignoreNonCritical ? Errors.Any(static error => error.IsCritical) : Errors.Any();
/// <summary>
/// Проверяет, есть ли предупреждения
/// </summary>
/// <param name="ignoreInformWarning">Игнорировать информационные предупреждения</param>
/// <returns>Наличие предупреждений</returns>
public bool HasWarnings (bool ignoreInformWarning = false) => Messages.Any(message =>
message.MessageType == EActionStateMessageType.Warning && (!ignoreInformWarning || !message.IsCritical));
public bool HasWarnings (bool ignoreInformWarning = false) => ignoreInformWarning
? Warnings.Any(static warning => !warning.IsInformWarning)
: Warnings.Any();
/// <summary>
/// Проверяет, есть ли сообщения
/// </summary>
/// <param name="ignoreStatus">Игнорировать статусные сообщения</param>
/// <returns>Наличие сообщений</returns>
public bool HasInfo (bool ignoreStatus) => Messages.Any(message =>
message.MessageType == EActionStateMessageType.Information && (!ignoreStatus || !message.IsCritical));
public bool HasInfo (bool ignoreStatus) => ignoreStatus ? Info.Any(static info => !info.IsStatusInfo) : Info.Any();
/// <summary>
/// Успешно ли завершилось
@ -235,36 +295,29 @@ public class ActionState<T>: ISerializable
#endregion
#region Количество сообщений
/// <summary>
/// Количество сообщений, удовлеьворяющих условию <paramref name="predicate"/>
/// </summary>
/// <param name="predicate">Условие выборки</param>
/// <returns>Число сообщений</returns>
public int Count (Func<ActionStateMessage, bool> predicate) => Messages.Count(predicate);
/// <summary>
/// Количество ошибок
/// </summary>
/// <param name="ignoreNonCritical">Игнорировать не критические</param>
/// <returns>Количество ошибок</returns>
public int ErrorsCount (bool ignoreNonCritical = false) => Count(message =>
message.MessageType == EActionStateMessageType.Error && (!ignoreNonCritical || !message.IsCritical));
public int ErrorsCount (bool ignoreNonCritical = false) =>
ignoreNonCritical ? Errors.Count(static error => error.IsCritical) : Errors.Count;
/// <summary>
/// Количество предупреждений
/// </summary>
/// <param name="ignoreInformWarning">Игнорировать информационные предупреждения</param>
/// <returns>Количество предупреждений</returns>
public int WarningsCount (bool ignoreInformWarning = false) => Count(message =>
message.MessageType == EActionStateMessageType.Warning && (!ignoreInformWarning || !message.IsCritical));
public int WarningsCount (bool ignoreInformWarning = false) => ignoreInformWarning
? Warnings.Count(static warning => !warning.IsInformWarning)
: Warnings.Count;
/// <summary>
/// Количество информационных сообщений
/// </summary>
/// <param name="ignoreStatus">Игнорировать статусные сообщения</param>
/// <returns>Количество информационных сообщений</returns>
public int InfoCount (bool ignoreStatus) => Count(message =>
message.MessageType == EActionStateMessageType.Information && (!ignoreStatus || !message.IsCritical));
public int InfoCount (bool ignoreStatus) => ignoreStatus ? Info.Count(static info => !info.IsStatusInfo) : Info.Count;
#endregion
#region Добавление другого состояния
@ -272,69 +325,13 @@ public class ActionState<T>: ISerializable
/// <summary>
/// Добавляет другое состояние (например, результат другого действия, который возвращает <see cref="ActionState"/>).
/// </summary>
/// <typeparam name="TO">Тип параметра</typeparam>
/// <param name="state">Запись состояния</param>
public void AddState<TO> (ActionState<TO> state) => AddRange(state.Messages);
public void AddState(ActionState state)
{
AddErrors(state.Errors);
AddWarnings(state.Warnings);
AddInfos(state.Info);
}
#endregion
#endregion
#region Реализация интерфейса ISerializable
/// <inheritdoc />
public string Serialize ()
{
// Создаю модель
ActionStateSerializable serializableModel = new();
// Для каждого сообщения
foreach (ActionStateMessage message in Messages)
// - добавляю в модель
serializableModel.Messages.Add(message.Serialize());
// Создаю модель значения
ActionStateSerializableValue value = new();
// Получаю данные
value.GetValue(Value);
// Добавляю в модель
serializableModel.Value = value.Serialize();
// Возвращаю сериализованную модель
return new NewtonsoftJsonSerializer().Serialize(serializableModel);
}
/// <inheritdoc />
public void Deserialize (string json)
{
// Удаляю лишние символы
json = json.Trim("\"".ToCharArray());
// Десериализую строку
ActionStateSerializable itemSerializable =
new NewtonsoftJsonSerializer().Deserialize<ActionStateSerializable>(json) ?? new();
// Создаю модель значения
ActionStateSerializableValue value = new();
// Очищаю списки
Clear(SelectAll);
// Для каждого сообщения
foreach (string messageString in itemSerializable.Messages)
{
// - создаю сообщение
ActionStateMessage message = new();
// - десериализую в него данные из модели
message.Deserialize(messageString);
// - добавляю в список
Add(message);
}
// Десериализую данные значения из модели
value.Deserialize(itemSerializable.Value);
// Получаю значение
Value = value.SetValue<T>();
}
#endregion
}

View File

@ -1,115 +0,0 @@
// ReSharper disable MemberCanBeInternal
// ReSharper disable MemberCanBePrivate.Global
using anbs_cp.Enums;
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Класс сообщения состояния
/// </summary>
public sealed class ActionStateMessage (
EActionStateMessageType type = EActionStateMessageType.Information,
bool isCritical = false,
string obj = "",
string message = ""): ISerializable
{
#region Свойства
/// <summary>
/// Тип сообщения
/// </summary>
public EActionStateMessageType MessageType { get; set; } = type;
/// <summary>
/// Критичность сообщения
/// </summary>
public bool IsCritical { get; set; } = isCritical;
/// <summary>
/// Объект сообщения
/// </summary>
public string Object { get; set; } = obj;
/// <summary>
/// Текст сообщения
/// </summary>
public string Message { get; set; } = message;
#endregion
#region Методы
/// <summary>
/// Вывод сообщения
/// </summary>
/// <param name="format">Строка-форматирование (например, «[{0}] - {1}»)</param>
/// <returns>Отформатированную строка</returns>
public string PrintMessage (string format) => string.Format(format, Object, Message);
/// <summary>
/// Устанавливает объект
/// </summary>
/// <param name="obj">Объект</param>
/// <typeparam name="T">Тип объекта</typeparam>
public void SetObject<T> (T obj)
{
// Если объект реализует интерфейс ISerializable
if (obj is ISerializable serializable)
{
// - то сериализуем его методами интерфейса
Object = serializable.Serialize();
// - и прерываем
return;
}
// Сериализуем объект с помощью NewtonsoftJson
Object = new NewtonsoftJsonSerializer().Serialize(obj);
}
/// <summary>
/// Получает объект
/// </summary>
/// <typeparam name="T">Класс объекта</typeparam>
/// <returns>Объект или null</returns>
public T? GetObject<T> () => new NewtonsoftJsonSerializer().Deserialize<T>(Object);
/// <summary>
/// Получает объект
/// </summary>
/// <typeparam name="T">Класс объекта, реализующий интерфейс ISerializable</typeparam>
/// <returns>Объект</returns>
public T GetSerializedObject<T> () where T : ISerializable, new()
{
// Создаём результирующую модель
T model = new();
// Десериализуем её методами интерфейса ISerializable
model.Deserialize(Object);
// Возвращаем модель
return model;
}
#endregion
#region Реализация интерфейса ISerializable
/// <inheritdoc />
public string Serialize () => new NewtonsoftJsonSerializer().Serialize(this);
/// <inheritdoc />
public void Deserialize (string json)
{
// Десериализую строку
ActionStateMessage item = new NewtonsoftJsonSerializer().Deserialize<ActionStateMessage>(json) ?? new();
// Передаю параметры
MessageType = item.MessageType;
IsCritical = item.IsCritical;
Object = item.Object;
Message = item.Message;
}
#endregion
}

View File

@ -1,18 +0,0 @@
// ReSharper disable CollectionNeverUpdated.Global
namespace anbs_cp.Classes;
/// <summary>
/// Сериализованная модель класса, хранящего в себе состояния действия
/// </summary>
public class ActionStateSerializable
{
/// <summary>
/// Список всех сообщений
/// </summary>
public List<string> Messages { get; } = [];
/// <summary>
/// Значение
/// </summary>
public string Value { get; set; } = string.Empty;
}

View File

@ -1,96 +0,0 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable MemberCanBeInternal
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Сериализованная модель значения класса, хранящего в себе состояния действия
/// </summary>
public sealed class ActionStateSerializableValue: ISerializable
{
/// <summary>
/// Значение - null?
/// </summary>
public bool IsNull { get; set; }
/// <summary>
/// Сериализуемое значение
/// </summary>
public string Serialized { get; set; } = string.Empty;
/// <summary>
/// Получает значение из <paramref name="value"/>
/// </summary>
/// <param name="value">Значение</param>
/// <typeparam name="T">Тип значения</typeparam>
internal void GetValue<T> (T? value)
{
// Значение - null?
IsNull = value is null;
// Если не null
// - сериализую
Serialized = value is not null ? new SysTextSerializer().Serialize(value) : string.Empty;
}
/// <summary>
/// Устанавливает значение
/// </summary>
/// <typeparam name="T">Класс</typeparam>
/// <returns>Значение</returns>
internal T? SetValue<T> () => IsNull ? default : new SysTextSerializer().Deserialize<T>(Serialized);
/// <summary>
/// Получает значение из <paramref name="value"/>
/// </summary>
/// <param name="value">Значение</param>
/// <typeparam name="T">Тип значения</typeparam>
internal void GetSerializedValue<T> (T? value) where T : ISerializable, new()
{
// Значение - null?
IsNull = value is null;
// Если не null
// - сериализую
Serialized = value is not null ? value.Serialize() : string.Empty;
}
/// <summary>
/// Устанавливает значение
/// </summary>
/// <typeparam name="T">Класс</typeparam>
/// <returns>Значение</returns>
internal T? SetSerializedValue<T> () where T : ISerializable, new()
{
// Если null
if (IsNull)
// - то возвращаем null
return default;
// Создаю модель
T model = new ();
// Десериализую модель
model.Deserialize(Serialized);
// Возвращаю модель
return model;
}
#region Реализация интерфейса ISerializable
/// <inheritdoc />
public string Serialize () => new SysTextSerializer().Serialize(this);
/// <inheritdoc />
public void Deserialize (string json)
{
// Десериализую строку
ActionStateSerializableValue item = new SysTextSerializer().Deserialize<ActionStateSerializableValue>(json) ?? new();
// Передаю параметры
IsNull = item.IsNull;
Serialized = item.Serialized;
}
#endregion
}

View File

@ -1,86 +0,0 @@
using anbs_cp.Exceptions;
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Состояние действия
///
/// Обновлено 2024.03.26
/// * Добавлен класс ActionState для классов, поддерживаемых интерфейс I
/// </summary>
public sealed class ActionStateSerialized<T>: ActionState<T> where T : ISerializable, new()
{
/// <summary>
/// Добавляет другое состояние (например, результат другого действия, который возвращает <see cref="ActionState"/>).
/// </summary>
/// <param name="state">Запись состояния</param>
public void AddState (ActionStateSerialized<T> state)
{
base.AddState(state);
}
#region Переопределение реализации интерфейса ISerializable
/// <summary>
/// Сериализовать элемент в формат json
/// </summary>
/// <returns>Строка в формате json</returns>
/// <exception cref="SerializeException">Ошибка при сериализации</exception>
public new string Serialize ()
{
// Создаю модель
ActionStateSerializable serializableModel = new();
// Для каждого сообщения
foreach (ActionStateMessage message in Messages)
// - добавляю в модель
serializableModel.Messages.Add(message.Serialize());
// Создаю модель значения
ActionStateSerializableValue value = new();
// Получаю данные
value.GetSerializedValue(Value);
// Добавляю в модель
serializableModel.Value = value.Serialize();
// Возвращаю сериализованную модель
return new SysTextSerializer().Serialize(serializableModel);
}
/// <summary>
/// Восстановить элемент из формата json
/// </summary>
/// <param name="json">Строка в формате json</param>
/// <exception cref="SerializeException">Ошибка при десериализации</exception>
public new void Deserialize (string json)
{
// Десериализую строку
ActionStateSerializable itemSerializable = new SysTextSerializer().Deserialize<ActionStateSerializable>(json) ?? new();
// Создаю модель значения
ActionStateSerializableValue value = new();
// Очищаю списки
Clear(SelectAll);
// Для каждого сообщения
foreach (string messageString in itemSerializable.Messages)
{
// - создаю сообщение
ActionStateMessage message = new();
// - десериализую в него данные из модели
message.Deserialize(messageString);
// - добавляю в список
Add(message);
}
// Десериализую данные значения из модели
value.Deserialize(itemSerializable.Value);
// Получаю значение
Value = value.SetSerializedValue<T>();
}
#endregion
}

View File

@ -6,14 +6,4 @@
/// Обновлено 2023.11.1
/// * Добавлен класс ActionState без возвращаемого значения
/// </summary>
public sealed class ActionState: ActionState<string>
{
/// <summary>
/// Добавляет другое состояние (например, результат другого действия, который возвращает <see cref="ActionState"/>).
/// </summary>
/// <param name="state">Запись состояния</param>
public void AddState (ActionState state)
{
base.AddState(state);
}
}
public sealed class ActionState: ActionState<string> { }

View File

@ -0,0 +1,49 @@
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <summary>
/// Класс предупреждения
/// </summary>
public sealed class ActionWarning: IActionWarning
{
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public ActionWarning ()
{
IsInformWarning = false;
Object = string.Empty;
Message = string.Empty;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="eObject">Объект</param>
/// <param name="message">Сообщение</param>
/// <param name="isInform">Является ли информирующим предупреждением</param>
public ActionWarning (string eObject, string message, bool isInform = false)
{
IsInformWarning = isInform;
Object = eObject;
Message = message;
}
#endregion
#region Реализация интерфейса
/// <summary>
/// Объект
/// </summary>
public object Object { get; set; }
/// <summary>
/// Сообщение
/// </summary>
public string Message { get; set; }
/// <summary>
/// Информирующее предупреждение возникает для предупреждения ВОЗМОЖНОЙ ошибки в дальнейшей эксплуатации и не влияет на текущую операцию.
/// </summary>
public bool IsInformWarning { get; init; }
#endregion
}

View File

@ -3,50 +3,37 @@
/// <summary>
/// Обработчик параметров консоли
/// </summary>
/// <param name="consoleParams">Параметры консоли</param>
/// <param name="caseSensitive">Регистрозависимые ли параметры</param>
public sealed class ConsoleParamsParser(IEnumerable<string> consoleParams, bool caseSensitive = true)
public sealed class ConsoleParamsParser
{
/// <summary>
/// Массив параметров
/// </summary>
private readonly KeyValueList<string, string?> _paramsList = ParseConsoleParams(consoleParams, caseSensitive);
private readonly List<(string, string?)> _paramsList;
/// <summary>
/// Парсер параметров
/// Конструктор
/// </summary>
/// <param name="paramsList">Входящий список параметров</param>
/// <param name="caseSensitive">Регистрозависимые ли параметры</param>
/// <returns>Список параметров</returns>
private static KeyValueList<string, string?> ParseConsoleParams(IEnumerable<string> paramsList,
bool caseSensitive = true)
/// <param name="consoleParams">Параметры консоли</param>
public ConsoleParamsParser (string[] consoleParams)
{
// Создаю список параметров
KeyValueList<string, string?> result = [];
//Создаю список параметров
_paramsList = new();
// Заполняю его
foreach (string consoleParam in paramsList)
//Заполняю его
foreach (string consoleParam in consoleParams)
{
// Индекс знака "="
//Индекс знака "="
int eqPlace = consoleParam.IndexOf('=');
// Получаю параметр
//Получаю параметр
string param = eqPlace > -1 ? consoleParam[..eqPlace] : consoleParam;
// Проверяю, требуются ли регистрозависимые параметры
if (!caseSensitive)
// - если нет, то переводим в нижний регистр
param = param.ToLower();
//Получаю значение параметра
string? value = eqPlace == -1 ? null : consoleParam[(eqPlace + 1)..].Trim(new[] { '"' });
// Получаю значение параметра
string? value = eqPlace == -1 ? null : consoleParam[(eqPlace + 1)..].Trim(['"']);
// Сохраняю в списке
result.Add(param.ToLower(), value);
//Сохраняю в списке
_paramsList.Add((param.ToLower(), value));
}
// Возвращаю значение
return result;
}
/// <summary>
@ -54,76 +41,21 @@ public sealed class ConsoleParamsParser(IEnumerable<string> consoleParams, bool
/// </summary>
/// <param name="param">Параметр</param>
/// <returns>Есть ли параметр в списке</returns>
// ReSharper disable once MemberCanBePrivate.Global
public bool HasParam(string param)
{
// Проверяю регистрозависимость
if (!caseSensitive)
// - если нет, то переводим в нижний регистр
param = param.ToLower();
// Проверяю наличие параметра
return _paramsList.Any(keyValue => keyValue.Key == param.ToLower());
}
public bool HasParam (string param) =>
_paramsList.Any(keyValue => keyValue.Item1 == param.ToLower());
/// <summary>
/// Проверяет наличие параметров
/// Получает значение параметра
/// </summary>
/// <param name="params">Массив параметров</param>
/// <returns>Задан ли хотя бы один параметр</returns>
public bool HasParams(IEnumerable<string> @params) =>
@params.Aggregate(false, (current, param) => current || HasParam(param));
/// <summary>
/// Получает значение параметра,
/// </summary>
/// <param name="param">Имя параметра</param>
/// <param name="default">Значение по умолчанию</param>
/// <returns>Значение параметра или значение по умолчанию</returns>
public string GetValue(string param, string @default = "") =>
!HasParam(param)
? @default
: _paramsList.FirstOrDefault(keyValue => keyValue.Key == param.ToLower()).Value ?? @default;
/// <summary>
/// Получает значения параметров из списка.
/// </summary>
/// <param name="params">Список параметров</param>
/// <returns>Список значений параметров</returns>
public IEnumerable<string> GetValue(IEnumerable<string> @params)
{
// Задаю результат
List<string> result = [];
// Получаю список параметров
List<string> paramsList = @params.ToList();
// Проверяю наличие параметров
if (!HasParams(paramsList))
// - если нет, возвращаю значение по умолчанию
return [];
// Для каждого параметра, если задано значение - добавляю его в результат
result.AddRange(paramsList.Where(HasParam).Select(param => GetValue(param))
.Where(value => !string.IsNullOrWhiteSpace(value)));
// Возвращаю результат
return result;
}
/// <summary>
/// Получает значение первого заданного параметра и возвращает значение по умолчанию, если ни один из параметров не задан.
/// </summary>
/// <param name="params">Список параметров</param>
/// <param name="default">Значение по умолчанию</param>
/// <returns>Значение первого заданного параметра из списка или значение по умолчанию</returns>
public string GetValue(IEnumerable<string> @params, string @default) =>
GetValue(@params).FirstOrDefault() ?? @default;
/// <param name="param"></param>
/// <returns></returns>
public string? GetValue (string param) =>
!HasParam(param) ? null : _paramsList.FirstOrDefault(keyValue => keyValue.Item1 == param.ToLower()).Item2;
/// <summary>
/// Получает список всех параметров
/// </summary>
/// <returns>Список всех параметров</returns>
public List<string> GetParamsList() =>
_paramsList.Select(static keyValue => keyValue.Key.ToLower()).ToList();
public List<string> GetParamsList () =>
_paramsList.Select(static keyValue => keyValue.Item1.ToLower()).ToList();
}

View File

@ -3,11 +3,19 @@
/// <summary>
/// Конвертер количества элементов
/// </summary>
public sealed class CountConverter (IEnumerable<string> valueNames, byte decimalPlace = 0): ValueConverter(
valueNames, 1000, decimalPlace)
public sealed class CountConverter : ValueConverter
{
/// <summary>
/// Имена размеров файлов по умолчанию
/// </summary>
public static readonly string[] DefaultNames = { "", "тыс.", "млн." };
public static readonly string[] DefaultNames = {"", "тыс.", "млн."};
/// <summary>
/// Конструктор класса
/// </summary>
/// <param name="valueNames">Массив имён размерностей</param>
/// <param name="decimalPlace">Знаков после запятой (0, 1, 2)</param>
public CountConverter (string[] valueNames, byte decimalPlace = 0) : base(valueNames, 1000, decimalPlace)
{
}
}

View File

@ -30,12 +30,8 @@ public sealed class StringEncryptor: IEncryptor
/// </summary>
/// <param name="value">Строка, которая должна быть зашифрована</param>
/// <param name="salt">Ключ</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Этот метод возвращает зашифрованную строку <paramref name="value"/></returns>
/// <exception cref="FormatException">Ошибка неверного формата</exception>
public string Encrypt (string value, string salt, string valueIfFail = "")
{
try
public string Encrypt (string value, string salt)
{
// Создаю криптограф
using Aes aes = Aes.Create();
@ -57,23 +53,14 @@ public sealed class StringEncryptor: IEncryptor
// Возвращаю зашифрованный текст
return Convert.ToBase64String(ms.ToArray());
}
catch (FormatException)
{
return valueIfFail;
}
}
/// <summary>
/// Метод для дешифрования строки <paramref name="encryptedValue"/>
/// </summary>
/// <param name="encryptedValue">Строка, которая должна быть дешифрована</param>
/// <param name="salt">Ключ</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Этот метод возвращает дешифрованную строку <paramref name="encryptedValue"/></returns>
/// <exception cref="FormatException">Ошибка неверного формата</exception>
public string Decrypt (string encryptedValue, string salt, string valueIfFail = "")
{
try
public string Decrypt (string encryptedValue, string salt)
{
// Открываю поток в памяти
using MemoryStream ms = new(Convert.FromBase64String(encryptedValue));
@ -105,32 +92,20 @@ public sealed class StringEncryptor: IEncryptor
// Вывожу расшифрованный текст
return Encoding.UTF8.GetString(output.ToArray());
}
catch (FormatException)
{
return valueIfFail;
}
}
/// <summary>
/// Декодирует зашифрованную строку в HTML-пригодный формат
/// </summary>
/// <param name="text">Зашифрованная строка</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Этот метод возвращает дешифрованную строку <paramref name="text"/></returns>
/// <exception cref="FormatException">Ошибка неверного формата</exception>
public string Base64UrlEncode(string text, string valueIfFail = "") =>
text.TrimEnd('=').Replace('+', '-').Replace('/', '_');
public string Base64UrlEncode (string text) => text.TrimEnd('=').Replace('+', '-').Replace('/', '_');
/// <summary>
/// Раскодирует из декодированной строки в HTML-пригодный формат
/// </summary>
/// <param name="text">Декодированная строка</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Этот метод возвращает шифрованную строку <paramref name="text"/></returns>
/// <exception cref="FormatException">Ошибка неверного формата</exception>
public string Base64UrlDecode (string text, string valueIfFail = "")
{
try
public string Base64UrlDecode (string text)
{
// Первоначальная замена
string result = text.Replace('_', '/').Replace('-', '+');
@ -149,9 +124,4 @@ public sealed class StringEncryptor: IEncryptor
// Возвращаю результат
return result;
}
catch (FormatException)
{
return valueIfFail;
}
}
}

View File

@ -0,0 +1,27 @@
namespace anbs_cp.Classes;
/// <summary>
/// Класс -- расширение для класса File
/// </summary>
public static class FileExtension
{
/// <summary>
/// Получает MIME-тип файла
/// </summary>
/// <param name="filename">Имя файла</param>
/// <returns>MIME-тип файла</returns>
public static string MIMEType (string filename) =>
MimeTypes.GetMimeType(filename);
/// <summary>
/// Размер файла в байтах
/// </summary>
/// <param name="fileName">Полное имя и путь к файлу</param>
/// <returns>Размер файла в байтах</returns>
public static long FileSize(string fileName)
{
FileInfo fileInfo = new (fileName);
return fileInfo.Length;
}
}

View File

@ -24,7 +24,10 @@ public sealed class FileHash
/// <summary>
/// Простой конструктор
/// </summary>
public FileHash () => Hash = [];
public FileHash ()
{
Hash = new byte[] { };
}
/// <summary>
/// Хэш файла
@ -46,13 +49,4 @@ public sealed class FileHash
UTF8Encoding utf8 = new();
Hash = utf8.GetBytes(value);
}
/// <summary>
/// Сравнивает текущий хэш с хэшем <paramref name="otherHash"/> и выдаёт <see cref="bool.TrueString"/>, если совпадают,
/// и <see cref="bool.FalseString"/>, если не совпадают.
/// </summary>
/// <param name="otherHash">Другой хэш</param>
/// <returns><see cref="bool.TrueString"/>, если совпадают, и <see cref="bool.FalseString"/>, если не совпадают</returns>
public bool IsEqual (FileHash otherHash) =>
string.Equals(ToString(), otherHash.ToString(), StringComparison.OrdinalIgnoreCase);
}

View File

@ -3,13 +3,19 @@
/// <summary>
/// Конвертер размеров файлов
/// </summary>
/// <param name="valueNames">Массив имён размерностей</param>
/// <param name="decimalPlace">Знаков после запятой (0, 1, 2)</param>
public sealed class FileSizeConverter (IEnumerable<string> valueNames, byte decimalPlace = 2): ValueConverter(
valueNames, 1024, decimalPlace)
public sealed class FileSizeConverter : ValueConverter
{
/// <summary>
/// Имена размеров файлов по умолчанию
/// </summary>
public static readonly string[] DefaultNames = { "байт", "Кб", "Мб", "Гб", "Тб" };
public static readonly string[] DefaultNames = {"байт", "Кб", "Мб", "Гб", "Тб"};
/// <summary>
/// Конструктор класса
/// </summary>
/// <param name="valueNames">Массив имён размерностей</param>
/// <param name="decimalPlace">Знаков после запятой (0, 1, 2)</param>
public FileSizeConverter (string[] valueNames, byte decimalPlace = 2) : base(valueNames, 1024, decimalPlace)
{
}
}

View File

@ -1,6 +1,5 @@
using System.Collections;
using anbs_cp.Interfaces;
using anbs_cp.Structs;
namespace anbs_cp.Classes;
@ -10,13 +9,19 @@ namespace anbs_cp.Classes;
/// </summary>
/// <typeparam name="TK">Тип ключа</typeparam>
/// <typeparam name="TV">Тип значения</typeparam>
// ReSharper disable once ClassCanBeSealed.Global
public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>
{
/// <summary>
/// Хранение значений
/// </summary>
private readonly List<KeyValue<TK, TV>> _list = [];
private readonly List<KeyValue<TK, TV>> _list;
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public KeyValueList () => _list = new();
#endregion
#region Свойства
/// <summary>
@ -26,6 +31,7 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
#endregion
#region Методы
/// <summary>
/// Получает список ключей
/// </summary>
@ -36,47 +42,23 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
/// Добавляет в список параметр
/// </summary>
/// <param name="keyValue">Параметр</param>
public void Add (KeyValue<TK, TV> keyValue)
{
// Проверяет, существует ли ключ в списке
if (Contains(keyValue.Key))
ChangeValue(keyValue);
// Добавляем в список
_list.Add(keyValue);
}
public void Add (KeyValue<TK, TV> keyValue) => _list.Add(keyValue);
/// <summary>
/// Добавляет в список параметр
/// </summary>
/// <param name="key">Ключ параметра</param>
/// <param name="value">Значение</param>
public void Add (TK key, TV value) => Add(new(key, value));
/// <summary>
/// Добавляет в список некоторый набор элементов
/// </summary>
/// <param name="list">Некоторый набор элементов</param>
public void AddRange (IEnumerable<KeyValue<TK, TV>> list)
{
// Получаю список
List<KeyValue<TK, TV>> keyValues = list.ToList();
// Для каждого элемента списка
foreach (KeyValue<TK, TV> keyValue in keyValues)
// - добавляю его в список
Add(keyValue);
}
public void Add (TK key, TV value) => _list.Add(new(key, value));
/// <summary>
/// Изменяет значение
/// </summary>
/// <param name="keyValue">Новое значение</param>
// ReSharper disable once MemberCanBePrivate.Global
public void ChangeValue (KeyValue<TK, TV> keyValue)
{
// Если такой ключ не существует
if (!Contains(keyValue.Key))
if (!Contains(keyValue.Key!))
{
// - тогда добавляю новое значение
Add(keyValue);
@ -86,7 +68,7 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
}
// Существующее значение
KeyValue<TK, TV> existValue = GetItem(keyValue.Key) ?? new();
KeyValue<TK, TV> existValue = GetItem(keyValue.Key!) ?? new();
// Удаляем существующее
_list.Remove(existValue);
@ -107,11 +89,9 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
/// </summary>
/// <param name="key">Ключ</param>
/// <returns>Элемент <see cref="KeyValue{TK,TV}"/></returns>
// ReSharper disable once MemberCanBePrivate.Global
public KeyValue<TK, TV>? GetItem (TK key)
{
// Ищем элемент в списке
// ReSharper disable once NullableWarningSuppressionIsUsed
foreach (KeyValue<TK, TV> keyValueItem in _list.Where(keyValueItem => keyValueItem.Key!.Equals(key)))
// - возвращаем его при нахождении
return keyValueItem;
@ -143,7 +123,6 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
/// Удаляет элемент из списка
/// </summary>
/// <param name="keyValue">Элемент</param>
// ReSharper disable once MemberCanBePrivate.Global
public void Remove (KeyValue<TK, TV> keyValue) => _list.Remove(keyValue);
/// <summary>
@ -157,7 +136,6 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
/// </summary>
/// <param name="keyValue">Элемент</param>
/// <returns>Результат проверки</returns>
// ReSharper disable once MemberCanBePrivate.Global
public bool Contains (KeyValue<TK, TV> keyValue) => _list.Contains(keyValue);
/// <summary>
@ -165,19 +143,8 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
/// </summary>
/// <param name="key">Ключ элемента</param>
/// <returns>Результат проверки</returns>
// ReSharper disable once NullableWarningSuppressionIsUsed
// ReSharper disable once MemberCanBePrivate.Global
public bool Contains (TK key) => Keys.Any(keyParam => keyParam!.Equals(key));
/// <summary>
/// Очистка списка
/// </summary>
public void Clear ()
{
// Очищаю список
_list.Clear();
}
#endregion
#region Реализация интерфейса IEnumerable<KeyValue<TK, TV>>
@ -193,42 +160,4 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
/// <returns><see cref="IEnumerator"/></returns>
IEnumerator IEnumerable.GetEnumerator () => GetEnumerator();
#endregion
#region Реализация интерфейса ISerializable
/// <inheritdoc />
public string Serialize ()
{
// Создаю результат
List<string> result = [];
// Добавляю сериализованные значения
result.AddRange(_list.Select(static item => item.Serialize()));
// Вывожу результат
return new NewtonsoftJsonSerializer().Serialize(result);
}
/// <inheritdoc />
public void Deserialize (string json)
{
// Создаю результат
List<string> result = new NewtonsoftJsonSerializer().Deserialize<List<string>>(json) ?? [];
// Очищаю список
_list.Clear();
// Пробегаю все значения
foreach (string itemString in result)
{
// - создаю новое значение
KeyValue<TK, TV> item = new();
// - десериализую в него элемента
item.Deserialize(itemString);
// - добавляю получившееся в список
_list.Add(item);
}
}
#endregion
}

View File

@ -1,222 +0,0 @@
using System.Collections;
using anbs_cp.Interfaces;
using anbs_cp.Structs;
namespace anbs_cp.Classes;
/// <summary>
/// Упорядоченный список из пары ключ-значение
/// </summary>
/// <typeparam name="TV">Тип значения</typeparam>
// ReSharper disable once ClassCanBeSealed.Global
public class KeyValueOrderedList<TV>: IEnumerable<KeyValueOrdered<TV>>, ISerializable
{
/// <summary>
/// Хранение значений
/// </summary>
private readonly SortedSet<KeyValueOrdered<TV>> _list = [];
#region Свойства
/// <summary>
/// Список ключей из списка
/// </summary>
public IEnumerable<string> Keys => GetKeys();
#endregion
#region Методы
/// <summary>
/// Получает список ключей
/// </summary>
/// <returns>Список ключей</returns>
private IEnumerable<string> GetKeys () => from keyValue in _list where keyValue.Key is not null select keyValue.Key;
/// <summary>
/// Добавляет в список параметр
/// </summary>
/// <param name="keyValue">Параметр</param>
public void Add (KeyValueOrdered<TV> keyValue)
{
// Проверяет, существует ли ключ в списке
if (Contains(keyValue.Key))
ChangeValue(keyValue);
// Добавляем в список
_list.Add(keyValue);
}
/// <summary>
/// Добавляет в список параметр
/// </summary>
/// <param name="key">Ключ параметра</param>
/// <param name="value">Значение</param>
public void Add (string key, TV value) => Add(new(key, value));
/// <summary>
/// Добавляет в список некоторый набор элементов
/// </summary>
/// <param name="list">Некоторый набор элементов</param>
public void AddRange (IEnumerable<KeyValueOrdered<TV>> list)
{
// Получаю список
List<KeyValueOrdered<TV>> keyValues = list.ToList();
// Для каждого элемента списка
foreach (KeyValueOrdered<TV> keyValue in keyValues)
// - добавляю его в список
Add(keyValue);
}
/// <summary>
/// Изменяет значение
/// </summary>
/// <param name="keyValue">Новое значение</param>
// ReSharper disable once MemberCanBePrivate.Global
public void ChangeValue (KeyValueOrdered<TV> keyValue)
{
// Если такой ключ не существует
if (!Contains(keyValue.Key))
{
// - тогда добавляю новое значение
Add(keyValue);
// - прерываю
return;
}
// Удаляем существующее
_list.RemoveWhere(item => item.Key == keyValue.Key);
// Добавляем новое
_list.Add(keyValue);
}
/// <summary>
/// Изменяет значение
/// </summary>
/// <param name="key">Ключ</param>
/// <param name="newValue">Новое значение</param>
public void ChangeValue (string key, TV newValue) => ChangeValue(new(key, newValue));
/// <summary>
/// Получает элемент по ключу
/// </summary>
/// <param name="key">Ключ</param>
/// <returns>Элемент <see cref="KeyValue{TK,TV}"/></returns>
// ReSharper disable once MemberCanBePrivate.Global
public KeyValueOrdered<TV>? GetItem (string key)
{
// Ищем элемент в списке
foreach (KeyValueOrdered<TV> keyValueItem in _list.Where(item => item.Key == key))
// - возвращаем его при нахождении
return keyValueItem;
// Элемент не найден -- вывожу null
return null;
}
/// <summary>
/// Получает значение
/// </summary>
/// <param name="key">Ключ</param>
/// <returns>Значение</returns>
public TV? GetValue (string key)
{
// Если такой ключ не существует
if (!Contains(key))
// Тогда возвращаю значение по умолчанию
return default;
// Получаю элемент
KeyValueOrdered<TV> keyValue = GetItem(key) ?? new();
// Вывожу значение
return keyValue.Value;
}
/// <summary>
/// Удаляет элемент из списка
/// </summary>
/// <param name="keyValue">Элемент</param>
// ReSharper disable once MemberCanBePrivate.Global
public void Remove (KeyValueOrdered<TV> keyValue) => _list.Remove(keyValue);
/// <summary>
/// Удаляет элемент из списка
/// </summary>
/// <param name="key">Ключ элемента</param>
public void Remove (string key) => Remove(GetItem(key) ?? new());
/// <summary>
/// Проверяет, содержится ли элемент в списке
/// </summary>
/// <param name="keyValue">Элемент</param>
/// <returns>Результат проверки</returns>
// ReSharper disable once MemberCanBePrivate.Global
public bool Contains (KeyValueOrdered<TV> keyValue) => _list.Contains(keyValue);
/// <summary>
/// Проверяет, содержится ли элемент в списке
/// </summary>
/// <param name="key">Ключ элемента</param>
/// <returns>Результат проверки</returns>
// ReSharper disable once NullableWarningSuppressionIsUsed
// ReSharper disable once MemberCanBePrivate.Global
public bool Contains (string key) => Keys.Any(keyName => keyName == key);
/// <summary>
/// Очистка списка
/// </summary>
public void Clear ()
{
// Очищаю список
_list.Clear();
}
#endregion
#region Реализация интерфейса IEnumerable<KeyValue<TK, TV>>
/// <inheritdoc />
public IEnumerator<KeyValueOrdered<TV>> GetEnumerator () => _list.GetEnumerator();
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator () => GetEnumerator();
#endregion
#region Реализация интерфейса ISerializable
/// <inheritdoc />
public string Serialize ()
{
// Создаю результат
List<string> result = [];
// Добавляю сериализованные значения
result.AddRange(_list.Select(static item => item.Serialize()));
// Вывожу результат
return new NewtonsoftJsonSerializer().Serialize(result);
}
/// <inheritdoc />
public void Deserialize (string json)
{
// Создаю результат
List<string> result = new NewtonsoftJsonSerializer().Deserialize<List<string>>(json) ?? [];
// Очищаю список
_list.Clear();
// Пробегаю все значения
foreach (string itemString in result)
{
// - создаю новое значение
KeyValueOrdered<TV> item = new();
// - десериализую в него элемента
item.Deserialize(itemString);
// - добавляю получившееся в список
_list.Add(item);
}
}
#endregion
}

View File

@ -10,20 +10,20 @@ public static class LikeDelphi
{
/// <summary>
/// Аналог функции IncludeTrailingBackslash
/// версия 2.1 (20240403) - исправлена ошибка;
/// версия 2.0 (20231213) - ОС-независимая реализация.
/// </summary>
/// <param name="path">Путь, к которому нужно добавить slash</param>
/// <returns>Путь со slash в конце</returns>
public static string IncludeTrailingBackslash (string path)
{
// Если path не заканчивается slash-ем
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
// - то добавляем slash
path += Path.DirectorySeparatorChar;
//По умолчанию сохраняем путь
string result = path;
// Выводим результат
return path;
//Если последний символ не "\", то добавим "\" в конце
if (path[^1] != '\\')
result = $@"{path}\";
//Вернём результат
return result;
}
/// <summary>
@ -32,7 +32,7 @@ public static class LikeDelphi
/// <param name="str">Строка, которую нужно разбить</param>
/// <param name="delimiter">Символ-делитель строки</param>
/// <returns>Массив строк</returns>
public static List<string> ParseString (string str, char delimiter) => [.. str.Split(delimiter)];
public static List<string> ParseString (string str, char delimiter) => str.Split(delimiter).ToList();
/// <summary>
/// Переименовываю файл
@ -59,7 +59,7 @@ public static class LikeDelphi
break;
//Только для папок (для файлов равносилен RaiseException)
case EOnExistAction.RaiseExceptionIfNotEmpty:
throw new RenameException(newName, "Папка уже существует!");
throw new RenameException(newName, "Файл уже существует!");
//Только для папок (для файлов равносилен Abort)
case EOnExistAction.AbortIfNotEmpty:
return;

View File

@ -1,16 +0,0 @@
using anbs_cp.Interfaces;
using Newtonsoft.Json;
namespace anbs_cp.Classes;
/// <inheritdoc />
public class NewtonsoftJsonSerializer: ISerializer
{
/// <inheritdoc />
public string Serialize<T> (T data) => JsonConvert.SerializeObject(data);
/// <inheritdoc />
public T? Deserialize<T>(string json) => JsonConvert.DeserializeObject<T>(json,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
}

View File

@ -1,15 +0,0 @@
using System.Text.Json;
using anbs_cp.Interfaces;
namespace anbs_cp.Classes;
/// <inheritdoc />
public class SysTextSerializer: ISerializer
{
/// <inheritdoc />
public string Serialize<T> (T data) => JsonSerializer.Serialize(data);
/// <inheritdoc />
public T? Deserialize<T> (string json) => JsonSerializer.Deserialize<T>(json);
}

View File

@ -71,13 +71,13 @@ public static class TimestampValidator
/// Проверка временного интервала (в час)
/// </summary>
/// <param name="timestamp">Временной интервал</param>
/// <param name="checkedStamp">Проверяемый временной интервал</param>
/// <param name="deltaHour">Временная дельта в часах</param>
/// <param name="checkedstamp">Проверяемый временной интервал</param>
/// <param name="deltahr">Временная дельта в часах</param>
/// <returns>
/// Попал ли <see cref="checkedStamp" /> в промежуток <paramref name="timestamp" /> + <paramref name="deltaHour" />
/// Попал ли <see cref="checkedstamp" /> в промежуток <paramref name="timestamp" /> + <paramref name="deltahr" />
/// </returns>
public static bool ValidateFromHour(long timestamp, long checkedStamp, ulong deltaHour) =>
Validate(timestamp, checkedStamp, checked(deltaHour * 3600000UL));
public static bool ValidateFromHour(long timestamp, long checkedstamp, ulong deltahr) =>
Validate(timestamp, checkedstamp, checked(deltahr * 3600000UL));
/// <summary>
/// Проверка попадания текущего времени в заданный интервал (в час)

View File

@ -1,5 +1,7 @@
using System.Globalization;
using Newtonsoft.Json;
namespace anbs_cp.Classes;
/// <summary>
@ -71,7 +73,7 @@ public static class TypeConverter
/// <typeparam name="T">Тип</typeparam>
/// <param name="value">Значение типа</param>
/// <returns>Значение в <see cref="string"/></returns>
public static string TypeToStr<T> (T value) => new SysTextSerializer().Serialize(value);
public static string TypeToStr<T> (T value) => JsonConvert.SerializeObject(value);
#endregion
@ -157,7 +159,7 @@ public static class TypeConverter
/// <param name="defaultValue">Значение по умолчанию</param>
/// <returns>Значение в <see cref="T"/></returns>
public static T StrToType<T>(string value, T defaultValue) =>
new SysTextSerializer().Deserialize<T>(value) ?? defaultValue;
JsonConvert.DeserializeObject<T>(value) ?? defaultValue;
#endregion
}

View File

@ -5,27 +5,36 @@ namespace anbs_cp.Classes;
/// <summary>
/// Абстрактный класс конвертера величин для отображения (улучшенный аналог ValueFormatter)
/// </summary>
/// <param name="valueNames">Массив имён размерностей</param>
/// <param name="divider">Делитель</param>
/// <param name="decimalPlaces">Число знаков после запятой</param>
public abstract class ValueConverter (IEnumerable<string> valueNames, long divider, byte decimalPlaces): IValueConverter
public abstract class ValueConverter: IValueConverter
{
#region Реализация интерфейса
/// <summary>
/// Конструктор
/// </summary>
/// <param name="valueNames">Массив имён размерностей</param>
/// <param name="divider">Делитель</param>
/// <param name="decimalPlaces">Число знаков после запятой</param>
protected ValueConverter (string[] valueNames, long divider, byte decimalPlaces)
{
ValueNames = valueNames;
Divider = divider;
DecimalPlaces = (byte)(decimalPlaces < 3 ? decimalPlaces : 2);
}
#region Реализация интерфейса
/// <summary>
/// Массив имён размерностей
/// </summary>
public string[] ValueNames { get; init; } = valueNames.ToArray();
public string[] ValueNames { get; init; }
/// <summary>
/// Делитель
/// </summary>
public long Divider { get; init; } = divider;
public long Divider { get; init; }
/// <summary>
/// Знаков после запятой (0, 1, 2)
/// </summary>
public byte DecimalPlaces { get; init; } = (byte)(decimalPlaces < 3 ? decimalPlaces : 2);
public byte DecimalPlaces { get; init; }
#endregion
@ -41,8 +50,7 @@ public abstract class ValueConverter (IEnumerable<string> valueNames, long divid
(decimal, int) result = DivideIt(value, 0);
//Преобразую значение в строку
string resultValue = DecimalPlaces switch
{
string resultValue = DecimalPlaces switch {
0 => $"{result.Item1:F0}",
1 => $"{result.Item1:F1}",
_ => $"{result.Item1:F2}"

View File

@ -1,21 +0,0 @@
namespace anbs_cp.Enums;
/// <summary>
/// Тип сообщения о состоянии
/// </summary>
public enum EActionStateMessageType
{ /// <summary>
/// Информация
/// </summary>
Information = 0,
/// <summary>
/// Предупреждение
/// </summary>
Warning = 1,
/// <summary>
/// Ошибка
/// </summary>
Error = 2
}

View File

@ -1,32 +0,0 @@
namespace anbs_cp.Enums;
/// <summary>
/// Область печати состояния действия
/// </summary>
public enum EActionStatePrintArea
{
/// <summary>
/// Все (сообщения, предупреждения, ошибки)
/// </summary>
All = 0,
/// <summary>
/// Только предупреждения и ошибки
/// </summary>
ErrorsAndWarnings = 1,
/// <summary>
/// Только ошибки
/// </summary>
ErrorsOnly = 2,
/// <summary>
/// Только предупреждения
/// </summary>
WarningsOnly = 3,
/// <summary>
/// Только информационные сообщения
/// </summary>
InfosOnly = 4
}

View File

@ -1,17 +0,0 @@
namespace anbs_cp.Enums;
/// <summary>
/// Действие, которое привело к ошибке сериализации
/// </summary>
public enum ESerializeExceptionAction
{
/// <summary>
/// Сериализация
/// </summary>
Serialize = 0,
/// <summary>
/// Десериализация
/// </summary>
Deserialize = 1
}

View File

@ -1,27 +0,0 @@
namespace anbs_cp.Enums;
/// <summary>
/// Трансформация текста
/// </summary>
public enum ETextTransform
{
/// <summary>
/// Как оригинал
/// </summary>
None = 0,
/// <summary>
/// Все буквы строчные (аналог ToLower)
/// </summary>
LowerCase = 1,
/// <summary>
/// Все буквы прописные (аналог ToUpper)
/// </summary>
UpperCase = 2,
/// <summary>
/// Первая буква заглавная, а остальные строчные
/// </summary>
FirstUpper = 3
}

View File

@ -1,28 +0,0 @@
using anbs_cp.Enums;
namespace anbs_cp.Exceptions;
/// <summary>
/// Ошибка (де)сериализации
/// </summary>
/// <param name="action">Действие сериализатора, приведшее к ошибке</param>
/// <param name="objectJson">Объект сериализации при сериализации или строка json при десериализации</param>
/// <param name="message">Сообщение пользователю</param>
public sealed class SerializeException (ESerializeExceptionAction action, string? objectJson, string? message = null)
: Exception(message)
{
/// <summary>
/// Действие сериализатора, приведшее к ошибке
/// </summary>
public ESerializeExceptionAction Action => action;
/// <summary>
/// Объект сериализации (при action == ESerializeExceptionAction.Serialize)
/// </summary>
public string? Object => action == ESerializeExceptionAction.Serialize ? objectJson : null;
/// <summary>
/// Строка json при десериализации
/// </summary>
public string? Json => action == ESerializeExceptionAction.Deserialize ? objectJson : null;
}

View File

@ -1,32 +0,0 @@
namespace anbs_cp.Extensions;
/// <summary>
/// Расширение типа "правда/ложь"
/// </summary>
public static class BooleanExtensions
{
/// <summary>
/// Вывод в строку <paramref name="ifTrue"/>, если выражение <paramref name="b"/> правдиво и
/// <paramref name="ifFalse"/> в противном случае.
/// </summary>
/// <param name="b">Выражение типа правда/ложь</param>
/// <param name="ifTrue">Строка для правдивого выражения</param>
/// <param name="ifFalse">Строка для лживого выражения</param>
/// <returns>Вывод строки</returns>
public static string ExportToString (this bool b, string ifTrue, string ifFalse) => b ? ifTrue : ifFalse;
/// <summary>
/// Вычисляет количество булевых переменных <paramref name="expressions"/> в значении true.
/// </summary>
/// <param name="expressions">Переменные</param>
/// <returns>Количество переменных в значении true</returns>
public static int TrueCount (params bool[] expressions) => expressions.Count(static b => b);
/// <summary>
/// Вычисляет, есть ли хотя бы одно из булевых переменных <paramref name="expressions"/> в значении true.
/// </summary>
/// <param name="expressions">Переменные</param>
/// <returns>Есть ли хотя бы одно в значении true</returns>
public static bool AnyTrue (params bool[] expressions) => TrueCount(expressions) > 0;
}

View File

@ -1,15 +0,0 @@
namespace anbs_cp.Extensions;
/// <summary>
/// Расширение класса DateTime
/// </summary>
public static class DateTimeExtension
{
/// <summary>
/// "Обнуляет" миллисекунды
/// </summary>
/// <param name="dt">Дата/время</param>
/// <returns>Дата/время с нулевыми миллисекундами</returns>
public static DateTime TrimMilliseconds (this DateTime dt) =>
new(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, 0, dt.Kind);
}

View File

@ -1,15 +0,0 @@
using System.Text;
namespace anbs_cp.Extensions;
/// <summary>
/// Класс-расширение для Encoding
/// </summary>
public static class EncodingExtensions
{
/// <summary>
/// Кодировка UTF8 без Bom
/// </summary>
// ReSharper disable once InconsistentNaming
public static Encoding UTF8WithoutBom (this Encoding encoding) => new UTF8Encoding(false);
}

View File

@ -1,172 +0,0 @@
// ReSharper disable MemberCanBePrivate.Global
using anbs_cp.Classes;
using System.Text;
namespace anbs_cp.Extensions;
/// <summary>
/// Класс -- расширение для класса File
/// </summary>
public static class FileExtension
{
/// <summary>
/// Получает MIME-тип файла
/// </summary>
/// <param name="filename">Имя файла</param>
/// <returns>MIME-тип файла</returns>
public static string MimeType (string filename) =>
MimeTypes.GetMimeType(filename);
/// <summary>
/// Размер файла в байтах
/// </summary>
/// <param name="fileName">Полное имя и путь к файлу</param>
/// <returns>Размер файла в байтах</returns>
public static long FileSize (string fileName) =>
new FileInfo(fileName).Length;
/// <summary>
/// Получает хэш файла
/// </summary>
/// <param name="fileName">Имя файла</param>
/// <returns>Хэш файла в формате <see cref="FileHash"/></returns>
public static FileHash GetHash (string fileName) =>
new(fileName);
/// <summary>
/// Получение содержимого файла
/// </summary>
/// <param name="fileName">Имя файла</param>
/// <returns>Содержимое файла</returns>
public static byte[] GetFileContent (string fileName) => File.ReadAllBytes(fileName);
#region Write
/// <summary>
/// Записывает данные <paramref name="data"/> в текстовый файл <paramref name="fileName"/>
/// </summary>
/// <typeparam name="T">Тип данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="fileName">Имя файла</param>
/// <param name="encoding">Кодировка</param>
public static void Write<T> (T data, string fileName, Encoding encoding)
{
// Открываю файл для создания или перезаписи
using StreamWriter writer = new(new FileStream(fileName, FileMode.OpenOrCreate), encoding);
// Записываю
writer.WriteLine(new NewtonsoftJsonSerializer().Serialize(data));
}
/// <summary>
/// Записывает данные <paramref name="data"/> в текстовый файл <paramref name="fileName"/>
/// </summary>
/// <typeparam name="T">Тип данных</typeparam>
/// <param name="data">Данные</param>
/// <param name="fileName">Имя файла</param>
/// <param name="useUtf8WithBom">Нужно ли использовать кодировку UTF8 With BOM или UTF8 Without BOM</param>
public static void Write<T> (T data, string fileName, bool useUtf8WithBom = false) => Write(data, fileName,
useUtf8WithBom ? Encoding.UTF8 : Encoding.UTF8.UTF8WithoutBom());
/// <summary>
/// Записывает все данные из списка <paramref name="data"/> в текстовый файл <paramref name="fileName"/>
/// </summary>
/// <param name="data">Данные</param>
/// <param name="fileName">Имя файла</param>
/// <param name="encoding">Кодировка файла</param>
/// <typeparam name="T">Тип данных</typeparam>
public static void WriteAll<T> (IEnumerable<T> data, string fileName, Encoding encoding)
{
// Открываю файл для создания или перезаписи
using StreamWriter writer = new(new FileStream(fileName, FileMode.OpenOrCreate), encoding);
// Для каждого элемента списка
foreach (T element in data)
// - записываю его строкой в файл
writer.WriteLine(new NewtonsoftJsonSerializer().Serialize(element));
}
/// <summary>
/// Записывает все данные из списка <paramref name="data"/> в текстовый файл <paramref name="fileName"/>
/// </summary>
/// <param name="data">Данные</param>
/// <param name="fileName">Имя файла</param>
/// <param name="useUtf8WithBom">Нужно ли использовать кодировку UTF8 With BOM или UTF8 Without BOM</param>
/// <typeparam name="T">Тип данных</typeparam>
public static void WriteAll<T> (IEnumerable<T> data, string fileName, bool useUtf8WithBom = false) =>
WriteAll(data, fileName, useUtf8WithBom ? Encoding.UTF8 : Encoding.UTF8.UTF8WithoutBom());
#endregion
#region Read
/// <summary>
/// Читает первую строку из текстового файла <paramref name="fileName"/>
/// </summary>
/// <param name="fileName">Имя файла</param>
/// <param name="encoding">Кодировка файла</param>
/// <typeparam name="T">Тип выходных данных</typeparam>
/// <returns>Данные или null</returns>
public static T? Read<T> (string fileName, Encoding encoding)
{
// Открываю файл для чтения
using StreamReader reader = new(new FileStream(fileName, FileMode.Open), encoding);
// Считываю первую запись
string serialized = reader.ReadLine() ?? "{}";
// Возвращаю конвертированный тип
return new NewtonsoftJsonSerializer().Deserialize<T>(serialized);
}
/// <summary>
/// Читает первую строку из текстового файла <paramref name="fileName"/>
/// </summary>
/// <param name="fileName">Имя файла</param>
/// <param name="useUtf8WithBom">Нужно ли использовать кодировку UTF8 With BOM или UTF8 Without BOM</param>
/// <typeparam name="T">Тип выходных данных</typeparam>
/// <returns>Данные или null</returns>
public static T? Read<T> (string fileName, bool useUtf8WithBom = false) => Read<T>(fileName,
useUtf8WithBom ? Encoding.UTF8 : Encoding.UTF8.UTF8WithoutBom());
/// <summary>
/// Читает все строки из текстового файла <paramref name="fileName"/>
/// </summary>
/// <param name="fileName">Имя файла</param>
/// <param name="encoding">Кодировка файла</param>
/// <typeparam name="T">Тип выходных данных</typeparam>
/// <returns>Список данных</returns>
public static IEnumerable<T> ReadAll<T> (string fileName, Encoding encoding)
{
// Создаю результат
List<T> result = [];
// Открываю файл для чтения
using StreamReader reader = new(new FileStream(fileName, FileMode.Open), encoding);
// Пока есть строки в файле
while (reader.ReadLine() is { } serialized)
{
// - десериализую их
T? data = new NewtonsoftJsonSerializer().Deserialize<T>(serialized);
// - и если они не нулевые
if (data is not null)
// -- то добавляю их в результат
result.Add(data);
}
// Возвращаю полученный список
return result.AsEnumerable();
}
/// <summary>
/// Читает все строки из текстового файла <paramref name="fileName"/>
/// </summary>
/// <param name="fileName">Имя файла</param>
/// <param name="useUtf8WithBom">Нужно ли использовать кодировку UTF8 With BOM или UTF8 Without BOM</param>
/// <typeparam name="T">Тип выходных данных</typeparam>
/// <returns>Список данных</returns>
public static IEnumerable<T> ReadAll<T> (string fileName, bool useUtf8WithBom = false) =>
ReadAll<T>(fileName, useUtf8WithBom ? Encoding.UTF8 : Encoding.UTF8.UTF8WithoutBom());
#endregion
}

View File

@ -1,69 +0,0 @@
using System.Diagnostics.CodeAnalysis;
namespace anbs_cp.Extensions;
/// <summary>
/// Расширение Guid
/// </summary>
public static class GuidExtensions
{
/// <summary>
/// Проверяет Guid на пустоту
/// </summary>
/// <param name="g">Guid или null</param>
/// <returns>Guid пуст (null) или равен Guid.Empty</returns>
public static bool IsNullOrEmpty ([NotNullWhen(false)] this Guid? g) => g == null || g == Guid.Empty;
/// <summary>
/// Проверяет Guid на пустоту
/// </summary>
/// <param name="g">Guid</param>
/// <returns>Guid пуст (null) или равен Guid.Empty</returns>
public static bool IsNullOrEmpty (this Guid g) => g == Guid.Empty;
/// <summary>
/// Генерирует <see cref="Guid"/>, удовлетворяющий условию <paramref name="predicate"/>
/// </summary>
/// <param name="predicate">Условие генерации <see cref="Guid"/></param>
/// <returns>Новый <see cref="Guid"/></returns>
public static Guid GenerateGuid (Func<Guid, bool> predicate)
{
// Задаю GUID
Guid guid;
// Выполняй
do
{
// - генерируй GUID
guid = Guid.NewGuid();
}
// - пока не выполнено условие
while (!predicate(guid));
// Возвращаю сгенерированный GUID
return guid;
}
/// <summary>
/// Генерирует <see cref="Guid"/>, удовлетворяющий условию <paramref name="asyncPredicate"/>
/// </summary>
/// <param name="asyncPredicate">Условие генерации <see cref="Guid"/></param>
/// <returns>Новый <see cref="Guid"/></returns>
public static async Task<Guid> GenerateGuidAsync (Func<Guid, Task<bool>> asyncPredicate)
{
// Задаю GUID
Guid guid;
// Выполняй
do
{
// - генерируй GUID
guid = Guid.NewGuid();
}
// - пока не выполнено условие
while (!await asyncPredicate(guid));
// Возвращаю сгенерированный GUID
return guid;
}
}

View File

@ -1,83 +0,0 @@
using System.Text;
namespace anbs_cp.Extensions;
/// <summary>
/// Класс-расширение для List
/// </summary>
public static class ListExtensions
{
/// <summary>
/// Загрузка строк из текстового файла
/// </summary>
/// <param name="list">Список, в который нужно загрузит</param>
/// <param name="fileName">Имя файла, который нужно загрузить</param>
/// <param name="useUtf8WithBom">Использовать кодировку UTF8 With Bom</param>
public static void LoadFromFile (this List<string> list, string fileName, bool useUtf8WithBom = false)
{
// Очищаю список
list.Clear();
// Кодировка
Encoding fileEncoding =
useUtf8WithBom ? Encoding.UTF8 : Encoding.UTF8.UTF8WithoutBom();
// Открываю файл для чтения
using StreamReader reader = new(new FileStream(fileName, FileMode.Open), fileEncoding);
// Пока есть строки в файле
while (reader.ReadLine() is { } line)
// - добавляю в список
list.Add(line);
}
/// <summary>
/// Загрузка строк из типизированного файла
/// </summary>
/// <typeparam name="T">Тип данных</typeparam>
/// <param name="list">Список, в который нужно загрузит</param>
/// <param name="fileName">Имя файла, который нужно загрузить</param>
/// <param name="encoding">Кодировка файла</param>
public static void LoadFromFile<T> (this List<T> list, string fileName, Encoding encoding)
{
// Очищаю список
list.Clear();
// Добавляю в список загруженные строки
list.AddRange(FileExtension.ReadAll<T>(fileName, encoding));
}
/// <summary>
/// Сохранение списка строк в файл
/// </summary>
/// <param name="list">Список</param>
/// <param name="fileName">Имя файла</param>
/// <param name="useUtf8WithBom">Использовать кодировку UTF8 With Bom</param>
public static void SaveToFile (this List<string> list, string fileName, bool useUtf8WithBom = false)
{
// Очищаю список
list.Clear();
// Кодировка
Encoding fileEncoding =
useUtf8WithBom ? Encoding.UTF8 : Encoding.UTF8.UTF8WithoutBom();
// Открываю файл для создания или перезаписи
using StreamWriter writer = new(new FileStream(fileName, FileMode.OpenOrCreate), fileEncoding);
// Для каждой строки
foreach (string line in list)
// - записываю её
writer.WriteLine(line);
}
/// <summary>
/// Сохранение списка строк в файл
/// </summary>
/// <typeparam name="T">Тип данных</typeparam>
/// <param name="list">Список</param>
/// <param name="fileName">Имя файла</param>
/// <param name="encoding">Кодировка файла</param>
public static void SaveToFile<T> (this List<T> list, string fileName, Encoding encoding) =>
FileExtension.WriteAll(list.AsEnumerable(), fileName, encoding);
}

View File

@ -1,16 +0,0 @@
using System.Reflection;
namespace anbs_cp.Extensions;
/// <summary>
/// Расширение MethodInfo
/// </summary>
public static class MethodInfoExtension
{
/// <summary>
/// Проверяет, является ли метод асинхронным
/// </summary>
/// <param name="method">Метод</param>
/// <returns>Асинхронный или нет</returns>
public static bool IsAsync (this MethodInfo method) => typeof(Task) == method.ReturnType;
}

View File

@ -1,93 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using anbs_cp.Classes;
using anbs_cp.Enums;
namespace anbs_cp.Extensions;
/// <summary>
/// Расширение строк
/// </summary>
public static class StringExtensions
{
/// <summary>
/// Проверяет строку на пустоту
/// </summary>
/// <param name="s">Строка</param>
/// <returns>Строка пуста (null) или содержит только пробелы</returns>
public static bool IsNullOrWhiteSpace ([NotNullWhen(false)] this string? s) => s == null || s.Trim().Length == 0;
/// <summary>
/// Преобразует текстовое имя параметра перечисления <see cref="T"/> в элемент перечисления.
/// Если такой элемент не найден или при ошибке перевода вернётся элемент по умолчанию <paramref name="defaultValue"/>.
/// </summary>
/// <param name="s">Строка</param>
/// <param name="defaultValue">Значение по умолчанию</param>
/// <typeparam name="T">Тип перечисления</typeparam>
/// <returns>Элемент перечисления <see cref="T"/></returns>
public static T ParseToEnum<T> (this string s, T defaultValue)
{
try
{
return (T)Enum.Parse(typeof(T), s, true);
}
catch (ArgumentException)
{
return defaultValue;
}
}
/// <summary>
/// Приводит строку <paramref name="s"/> к виду "Первая буква заглавная, а все остальные -- строчные"
/// </summary>
/// <param name="s">Строка для перевода</param>
/// <returns>Приведённая строка</returns>
public static string ToFirstUpperCase (this string s)
{
// Если строка пуста
if (s.IsNullOrWhiteSpace())
// - то возвращаю её
return s;
// Задаю результат и устанавливаю первую букву заглавной
string result = $"{s[0]}".ToUpper();
// Если длина s больше, чем 1 символ
if (s.Length > 1)
// - то добавляю в результат оставшиеся символы, приведя их к LowerCase
result += s[1..].ToLower();
// Вывожу результат
return result;
}
/// <summary>
/// Трансформация текста <paramref name="s"/> по правилам <paramref name="type"/>
/// </summary>
/// <param name="s">Текст</param>
/// <param name="type">Правила преобразования</param>
/// <returns>Преобразованный текст</returns>
public static string Transform (this string s, ETextTransform type) =>
type switch
{
ETextTransform.None => s,
ETextTransform.LowerCase => s.ToLower(),
ETextTransform.UpperCase => s.ToUpper(),
ETextTransform.FirstUpper => s.ToFirstUpperCase(),
var _ => s
};
/// <summary>
/// Форматирует строку <paramref name="s"/>, заменяя все совпадения
/// по ключам из <paramref name="replaceList"/> соответствующими значениями из <paramref name="replaceList"/>.
/// Т.е. например, исходная строка «Мой дядя #Name был самых честных правил», массив замен содержал строку
/// «#Name» => «Юра», в итоге будет «Мой дядя Юра был самых честных правил».
/// </summary>
/// <param name="s">Строка для замены</param>
/// <param name="replaceList">Список замен</param>
/// <param name="comparisonType">Региональные параметры, регистр и правила сортировки</param>
/// <returns>Заменённая строка</returns>
public static string Format (this string s, KeyValueOrderedList<string> replaceList,
StringComparison comparisonType = StringComparison.CurrentCulture) => replaceList.Aggregate(s,
(current, replaceItem) => current.Replace(replaceItem.Key, replaceItem.Value, comparisonType));
}

View File

@ -0,0 +1,14 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс ошибки
/// </summary>
public interface IActionError : IActionStateMessage
{
/// <summary>
/// Критичность ошибки:
/// при некритичных ошибках продолжение выполнения операции возможно,
/// а при критичных -- нет
/// </summary>
public bool IsCritical { get; init; }
}

View File

@ -0,0 +1,12 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс для информации по статусу
/// </summary>
public interface IActionInfo : IActionStateMessage
{
/// <summary>
/// Статусная информация (например, начало работы)
/// </summary>
public bool IsStatusInfo { get; init; }
}

View File

@ -0,0 +1,24 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс сообщения состояния
/// </summary>
public interface IActionStateMessage
{
/// <summary>
/// Объект сообщения
/// </summary>
public object Object { get; set; }
/// <summary>
/// Текст сообщения
/// </summary>
public string Message { get; set; }
/// <summary>
/// Функция вывода сообщения
/// </summary>
/// <param name="format">Строка-форматирование (например, «[{0}] - {1}»)</param>
/// <returns>Отформатированную строка</returns>
public string PrintMessage (string format) => string.Format (format, Object, Message);
}

View File

@ -0,0 +1,12 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс предупреждения
/// </summary>
public interface IActionWarning : IActionStateMessage
{
/// <summary>
/// Информирующее предупреждение возникает для предупреждения ВОЗМОЖНОЙ ошибки в дальнейшей эксплуатации и не влияет на текущую операцию.
/// </summary>
public bool IsInformWarning { get; init; }
}

View File

@ -10,32 +10,28 @@ public interface IEncryptor
/// </summary>
/// <param name="value">Строка, которая должна быть зашифрована</param>
/// <param name="salt">Ключ шифрования</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Этот метод возвращает зашифрованную строку <paramref name="value"/></returns>
string Encrypt (string value, string salt, string valueIfFail);
string Encrypt (string value, string salt);
/// <summary>
/// Метод для дешифрования строки <paramref name="encryptedValue"/>
/// </summary>
/// <param name="encryptedValue">Строка, которая должна быть дешифрована</param>
/// <param name="salt">Ключ шифрования</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Этот метод возвращает дешифрованную строку <paramref name="encryptedValue"/></returns>
string Decrypt (string encryptedValue, string salt, string valueIfFail);
string Decrypt (string encryptedValue, string salt);
/// <summary>
/// Декодирует зашифрованную строку в HTML-пригодный формат
/// </summary>
/// <param name="text">Зашифрованная строка</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Этот метод возвращает дешифрованную строку <paramref name="text"/></returns>
string Base64UrlEncode (string text, string valueIfFail);
string Base64UrlEncode (string text);
/// <summary>
/// Раскодирует из декодированной строки в HTML-пригодный формат
/// </summary>
/// <param name="text">Декодированная строка</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Этот метод возвращает шифрованную строку <paramref name="text"/></returns>
string Base64UrlDecode (string text, string valueIfFail);
string Base64UrlDecode (string text);
}

View File

@ -1,23 +0,0 @@
using anbs_cp.Exceptions;
namespace anbs_cp.Interfaces;
/// <summary>
/// Интерфейс для сериализации объектов
/// </summary>
public interface ISerializable
{
/// <summary>
/// Сериализовать элемент в формат json
/// </summary>
/// <returns>Строка в формате json</returns>
/// <exception cref="SerializeException">Ошибка при сериализации</exception>
string Serialize();
/// <summary>
/// Восстановить элемент из формата json
/// </summary>
/// <param name="json">Строка в формате json</param>
/// <exception cref="SerializeException">Ошибка при десериализации</exception>
void Deserialize(string json);
}

View File

@ -1,23 +0,0 @@
namespace anbs_cp.Interfaces;
/// <summary>
/// Сериализация моделей, классов и других объектов
/// </summary>
public interface ISerializer
{
/// <summary>
/// Сериализация данных <paramref name="data"/> в строку.
/// </summary>
/// <typeparam name="T">Тип данных</typeparam>
/// <param name="data">Данные</param>
/// <returns>Сериализованные данные</returns>
string Serialize<T> (T data);
/// <summary>
/// Десериализация данных из json-строки <paramref name="json"/>
/// </summary>
/// <typeparam name="T">Ожидаемый тип данных</typeparam>
/// <param name="json">Сериализованные данные</param>
/// <returns>Данные</returns>
T? Deserialize<T> (string json);
}

View File

@ -65,7 +65,6 @@ public interface IValueFormatter
for (int i = 0; i <= DecimalPlaces; i++) delim *= 10;
// ReSharper disable once PossibleLossOfFraction
decimal value = Math.Round((decimal)(dividend * delim / divider)) / delim;
return $"{value}";

View File

@ -1,88 +1,51 @@
using anbs_cp.Classes;
using anbs_cp.Enums;
using anbs_cp.Exceptions;
using anbs_cp.Interfaces;
namespace anbs_cp.Structs;
namespace anbs_cp.Structs;
/// <summary>
/// Пара ключ-значение
/// </summary>
/// <typeparam name="TK">Тип ключа</typeparam>
/// <typeparam name="TV">Тип значения</typeparam>
/// <param name="Key">Ключ</param>
/// <param name="Value">Значение</param>
public record struct KeyValue<TK, TV> (TK Key, TV? Value): ISerializable
public struct KeyValue<TK, TV>
{
#region Свойства
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public KeyValue ()
{
Key = default;
Value = default;
}
/// <summary>
/// Конструктор со значениями
/// </summary>
/// <param name="key">Ключ</param>
/// <param name="value">Значение</param>
public KeyValue (TK key, TV value)
{
Key = key;
Value = value;
}
#endregion
#region Свойства
/// <summary>
/// Ключ
/// </summary>
public TK Key { get; private set; } = Key;
public TK? Key { get; set; }
/// <summary>
/// Значение
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
public TV? Value { get; set; } = Value;
public TV? Value { get; set; }
#endregion
#region Методы
/// <summary>
/// Получает ключ-значение по умолчанию
/// </summary>
/// <returns>Ключ-значение по умолчанию</returns>
public static KeyValue<TK, TV> GetDefault () => new();
#endregion
#region Реализация интерфейса ISerializable
/// <inheritdoc />
public readonly string Serialize ()
{
// Получаю serialized-значение ключа
string keySerialized = new NewtonsoftJsonSerializer().Serialize(Key);
// Исключаю из этого значения = (заменяя на %EQ%)
keySerialized = keySerialized.Replace("=", "%EQ%");
// Получаю serialized-значение значения
string valueSerialized = new NewtonsoftJsonSerializer().Serialize(Value);
// Исключаю из этого значения = (заменяя на %EQ%)
valueSerialized = valueSerialized.Replace("=", "%EQ%");
// Вывожу результат
return $"{keySerialized}={valueSerialized}";
}
/// <inheritdoc />
public void Deserialize (string json)
{
// Разделяю сериализованную строку вида КЛЮЧ=ЗНАЧЕНИЕ на ключ и значение
string[] splited = json.Split('=');
// Проверяю количество частей (должно быть 2)
if (splited.Length != 2)
throw new SerializeException(ESerializeExceptionAction.Deserialize, json,
"Неверное количество частей! Наверное, лишнее =?");
// Получаю сериализованное представление ключа
string keySerialized = splited[0].Replace("%EQ%", "=");
// Получаю сериализованное представление значения
string valueSerialized = splited[1].Replace("%EQ%", "=");
// Десериализую ключ
Key = (new NewtonsoftJsonSerializer().Deserialize<TK>(keySerialized) ?? default(TK))!;
// Десериализую значение
Value = new NewtonsoftJsonSerializer().Deserialize<TV>(valueSerialized);
}
public static KeyValue<TK, TV> GetDefault() => new();
#endregion
}

View File

@ -1,106 +0,0 @@
using anbs_cp.Classes;
using anbs_cp.Enums;
using anbs_cp.Exceptions;
using anbs_cp.Interfaces;
namespace anbs_cp.Structs;
/// <summary>
/// Упорядоченная пара ключ-значение
/// </summary>
/// <typeparam name="TValue">Тип значения</typeparam>
/// <param name="key">Ключ</param>
/// <param name="value">Значение</param>
public struct KeyValueOrdered<TValue> (string key, TValue? value): ISerializable, IComparable<KeyValueOrdered<TValue>>
{
#region Свойства
/// <summary>
/// Ключ
/// </summary>
public string Key { get; private set; } = key;
/// <summary>
/// Значение
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
public TValue? Value { get; set; } = value;
#endregion
#region Методы
/// <summary>
/// Получает ключ-значение по умолчанию
/// </summary>
/// <returns>Ключ-значение по умолчанию</returns>
public static KeyValueOrdered<TValue> GetDefault () => new();
#endregion
#region Конвертация в KeyValue<TKey, TValue>
/// <summary>
/// Переводит тип <see cref="KeyValueOrdered{TValue}"/> в тип <see cref="KeyValue{TK,TV}"/>
/// </summary>
/// <param name="keyValue">Тип <see cref="KeyValueOrdered{TValue}"/></param>
/// <returns>Тип <see cref="KeyValue{TK,TV}"/></returns>
public static KeyValue<string, TValue> ToKeyValue (KeyValueOrdered<TValue> keyValue) =>
new(keyValue.Key, keyValue.Value);
/// <summary>
/// Переводит тип <see cref="KeyValue{TK,TV}"/> в тип <see cref="KeyValueOrdered{TValue}"/>
/// </summary>
/// <param name="keyValue">Тип <see cref="KeyValue{TK,TV}"/></param>
/// <returns>Тип <see cref="KeyValueOrdered{TValue}"/></returns>
public static KeyValueOrdered<TValue> ToOrderedKeyValue (KeyValue<string, TValue> keyValue) =>
new(keyValue.Key, keyValue.Value);
#endregion
#region Реализация интерфейса ISerializable
/// <inheritdoc />
public readonly string Serialize ()
{
// Получаю serialized-значение ключа
string keySerialized = Key;
// Исключаю из этого значения = (заменяя на %EQ%)
keySerialized = keySerialized.Replace("=", "%EQ%");
// Получаю serialized-значение значения
string valueSerialized = new NewtonsoftJsonSerializer().Serialize(Value);
// Исключаю из этого значения = (заменяя на %EQ%)
valueSerialized = valueSerialized.Replace("=", "%EQ%");
// Вывожу результат
return $"{keySerialized}={valueSerialized}";
}
/// <inheritdoc />
public void Deserialize (string json)
{
// Разделяю сериализованную строку вида КЛЮЧ=ЗНАЧЕНИЕ на ключ и значение
string[] splited = json.Split('=');
// Проверяю количество частей (должно быть 2)
if (splited.Length != 2)
throw new SerializeException(ESerializeExceptionAction.Deserialize, json,
"Неверное количество частей! Наверное, лишнее =?");
// Получаю сериализованное представление ключа
string keySerialized = splited[0].Replace("%EQ%", "=");
// Получаю сериализованное представление значения
string valueSerialized = splited[1].Replace("%EQ%", "=");
// Десериализую ключ
Key = keySerialized;
// Десериализую значение
Value = new NewtonsoftJsonSerializer().Deserialize<TValue>(valueSerialized);
}
#endregion
#region Реализация интерфейса IComparable<KeyValueOrdered<TValue>>
/// <inheritdoc />
public int CompareTo (KeyValueOrdered<TValue> other) =>
// ReSharper disable once SuspiciousTypeConversion.Global
string.Compare(Key, other.Key, StringComparison.CurrentCultureIgnoreCase);
#endregion
}

View File

@ -1,25 +1,42 @@
using anbs_cp.Classes;
using anbs_cp.Interfaces;
namespace anbs_cp.Structs;
namespace anbs_cp.Structs;
/// <summary>
/// Двумерный размер
/// </summary>
/// <param name="width">Длина</param>
/// <param name="height">Высота</param>
public struct TwoDimSize (int width = 0, int height = 0): ISerializable
public struct TwoDimSize
{
#region Приватные поля
/// <summary>
/// Длина (приватное)
/// </summary>
private int _pWidth = width;
private int _pWidth;
/// <summary>
/// Ширина (приватное)
/// Высота (приватное)
/// </summary>
private int _pHeight = height;
private int _pHeight;
#endregion
#region Конструкторы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
public TwoDimSize ()
{
Width = 0;
Height = 0;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="width">Длина</param>
/// <param name="height">Высота</param>
public TwoDimSize (int width, int height)
{
Width = width;
Height = height;
}
#endregion
#region Свойства
@ -33,7 +50,7 @@ public struct TwoDimSize (int width = 0, int height = 0): ISerializable
}
/// <summary>
/// Ширина
/// Высота
/// </summary>
public int Height
{
@ -41,70 +58,4 @@ public struct TwoDimSize (int width = 0, int height = 0): ISerializable
set => _pHeight = value < 0 ? 0 : value;
}
#endregion
#region Методы
/// <summary>
/// Конвертация в строку
/// </summary>
/// <param name="delimiter">Делитель размера</param>
/// <returns>Строка</returns>
public readonly string ToString (char delimiter = ':') => $"{_pWidth}{delimiter}{_pHeight}";
/// <summary>
/// Получение размера из строки
/// </summary>
/// <param name="s">Строка</param>
/// <param name="delimiter">Разделитель размеров</param>
/// <returns>Модель размеров</returns>
/// <exception cref="ArgumentOutOfRangeException">Если в строке <paramref name="s"/> не содержится символа
/// <paramref name="delimiter"/> или таких разделителей слишком много</exception>
public static TwoDimSize Parse (string s, char delimiter = ':')
{
// Разделяю значения
string[] splitSizes = s.Split(delimiter);
// Проверяю, что массив имеет ровно два элемента
if (splitSizes.Length != 2)
throw new ArgumentOutOfRangeException(delimiter.ToString(),
$"Похоже, что в строке {s} не содержится символа {delimiter} или таких разделителей слишком много!");
// Пытаюсь получить длину
if (!int.TryParse(splitSizes[0], out int width))
width = 0;
// Пытаюсь получить ширину
if (!int.TryParse(splitSizes[1], out int height))
height = 0;
// Вывожу значение
return new(width, height);
}
#endregion
#region Реализация интерфейса ISerializable
/// <summary>
/// Сериализовать элемент в формат json
/// </summary>
/// <returns>Строка в формате json</returns>
public readonly string Serialize () => new SysTextSerializer().Serialize(ToString());
/// <summary>
/// Восстановить элемент из формата json
/// </summary>
/// <param name="json">Строка в формате json</param>
public void Deserialize (string json)
{
// Десериализую строку
string deserialized = new SysTextSerializer().Deserialize<string>(json) ?? "0:0";
// Перевожу строку в двумерный размер
TwoDimSize result = Parse(deserialized);
// Присваиваю длину
_pWidth = result.Width;
// Присваиваю ширину
_pHeight = result.Height;
}
#endregion
}

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Version>2024.8.18</Version>
<TargetFramework>net7.0</TargetFramework>
<Version>2023.1101.1</Version>
<Authors>Александр Бабаев</Authors>
<Product>Набор компонентов ANB Software</Product>
<Description>Библиотека полезных методов языка C#</Description>
@ -22,7 +22,6 @@
<AnalysisLevel>6.0</AnalysisLevel>
<RepositoryType>git</RepositoryType>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>Библиотека полезных методов и классов от ANB</Title>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@ -38,11 +37,15 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MimeTypes" Version="2.5.2">
<PackageReference Include="MimeTypes" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<Folder Include="Enums\" />
</ItemGroup>
</Project>

View File

@ -1,2 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp110</s:String></wpf:ResourceDictionary>

View File

@ -6,16 +6,18 @@ using MySqlConnector;
namespace anbs_cp.Database.Classes;
/// <summary>
/// База данных MySQL
/// </summary>
/// <param name="connectionString">Строка подключения базы данных</param>
public class MySqlEngine (string connectionString): IDbEngine
public class MySqlEngine: IDbEngine
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="connectionString">Строка подключения базы данных</param>
public MySqlEngine (string connectionString) => ConnectionString = connectionString;
/// <summary>
/// Строка подключения базы данных
/// </summary>
public string ConnectionString { get; set; } = connectionString;
public string ConnectionString { get; set; }
#region Базовые операции
/// <summary>

View File

@ -1,4 +1,6 @@
namespace anbs_cp.Database.Interfaces;
using System.Transactions;
namespace anbs_cp.Database.Interfaces;
/// <summary>
/// Интерфейс для работы с базой данных

View File

@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>anbs_cp_db</AssemblyName>
<RootNamespace>anbs_cp.Database</RootNamespace>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>ANBSoftware.ComponentsPack.Database</PackageId>
<Version>2024.4.26</Version>
<Version>2023.08.27.0</Version>
<Company>Александр Бабаев</Company>
<Product>Набор компонентов ANB Software для работы с БД</Product>
<Description>Библиотека полезных методов языка C# для работы с базами данных</Description>
@ -16,12 +16,11 @@
<PackageProjectUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</PackageProjectUrl>
<RepositoryUrl>https://git.babaev-an.ru/babaev-an/anbsoftware_componentspack</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Authors>Александр Бабаев</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="MySqlConnector" Version="2.3.7" />
<PackageReference Include="Dapper" Version="2.1.11" />
<PackageReference Include="MySqlConnector" Version="2.2.7" />
</ItemGroup>
</Project>

View File

@ -1,2 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>

View File

@ -1,23 +0,0 @@
using Microsoft.Extensions.Configuration;
namespace anbs_cp.ForNet.Classes;
/// <summary>
/// Класс-поддержки для доступа к файлу "appsettings.json" в любом месте сайта классах.
/// Взято с: https://stackoverflow.com/a/69111159/16469671
/// </summary>
public static class AppSettings
{
// ReSharper disable once NotAccessedField.Global
// ReSharper disable once NotNullOrRequiredMemberIsNotInitialized
public static IConfiguration? Config { get; private set; }
/// <summary>
/// Инициализация настроек. Она проводится в файле Program.cs.
/// </summary>
/// <param name="configuration">Параметры из "appsettings.json"</param>
public static void Initialize (IConfiguration configuration)
{
Config = configuration;
}
}

View File

@ -1,118 +0,0 @@
using System.ComponentModel.DataAnnotations;
using anbs_cp.Classes;
using anbs_cp.ForNet.Constants;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
namespace anbs_cp.ForNet.Classes;
/// <summary>
/// Кастомные сообщения валидации формы
/// </summary>
/// <param name="messageList">Кастомный список сообщений формы</param>
public class CustomValidationMessages (KeyValueOrderedList<string>? messageList): IValidationMetadataProvider
{
/// <summary>
/// Список сообщений формы
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
public readonly KeyValueOrderedList<string> MessageList = messageList ?? ValidationMessagesConstants.English;
/// <summary>
/// Создаёт данные для локализации сообщений валидации
/// </summary>
/// <param name="context">Контекст</param>
public void CreateValidationMetadata (ValidationMetadataProviderContext context)
{
// Если context = null, то прерываем с ошибкой
ArgumentNullException.ThrowIfNull(context);
// Получаю мета-данные
IList<object>? validators = context.ValidationMetadata.ValidatorMetadata;
// Получаю тип модели
Type? theType = context.Key.ModelType;
// Получаю фундаментальный тип
Type? underlyingType = Nullable.GetUnderlyingType(theType);
// Проверяю получение и соответствие
if (theType.IsValueType && underlyingType == null &&
validators.All(m => m.GetType() != typeof(RequiredAttribute)))
// - задаю валидацию
validators.Add(new RequiredAttribute());
// Для каждого объекта валидации
foreach (object? obj in validators)
{
// - если он не атрибут
if (obj is not ValidationAttribute attribute)
// -- то продолжаю
continue;
// RequiredAttribute
FillErrorMessage<RequiredAttribute>(attribute);
// MinLengthAttribute
FillErrorMessage<MinLengthAttribute>(attribute);
// MaxLengthAttribute
FillErrorMessage<MaxLengthAttribute>(attribute);
// EmailAddressAttribute
FillErrorMessage<EmailAddressAttribute>(attribute);
// RangeAttribute
FillErrorMessage<RangeAttribute>(attribute);
// CompareAttribute
FillErrorMessage<CompareAttribute>(attribute);
// RegularExpressionAttribute
FillErrorMessage<RegularExpressionAttribute>(attribute);
// PhoneAttribute
FillErrorMessage<PhoneAttribute>(attribute);
// CreditCardAttribute
FillErrorMessage<CreditCardAttribute>(attribute);
}
}
/// <summary>
/// Устанавливает сообщение об ошибке валидации
/// </summary>
/// <typeparam name="T">Тип атрибута валидации</typeparam>
/// <param name="attribute">Атрибут</param>
private void FillErrorMessage<T> (object attribute) where T : ValidationAttribute
{
// Проверяю на соответствие типа
if (attribute is not T validationAttribute)
// - и прерываю, если не соответствует
return;
// Если нет сообщения об ошибке
if (validationAttribute.ErrorMessage == null && validationAttribute.ErrorMessageResourceName == null)
{
// - получаю имя аттрибута
string attributeTypeName = typeof(T).Name;
// - если список сообщений не содержит ключа с таким именем аттрибута
if (MessageList.Keys.All(s => s != attributeTypeName))
// -- то прерываю
return;
// - получаю предопределённое сообщение об ошибке
string? errorMessage = MessageList.GetValue(attributeTypeName);
// - если предопределённое сообщение пусто
if (errorMessage == null)
// -- то прерываю
return;
// - задаю значение
validationAttribute.ErrorMessage = errorMessage;
}
}
}

View File

@ -12,6 +12,6 @@ public class NetFileExtension
/// </summary>
/// <param name="file">Загружаемый файл</param>
/// <returns>MIME-тип файла</returns>
public static string MimeType (IFormFile file) =>
public static string MIMEType (IFormFile file) =>
file.ContentType;
}

View File

@ -16,11 +16,8 @@ public sealed class PasswordEncrypt: IEncryptor
/// </summary>
/// <param name="password">Пароль</param>
/// <param name="salt">Хэш-код пароля</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>Зашифрованный пароль</returns>
public string Encrypt (string password, string salt, string valueIfFail)
{
try
public string Encrypt (string password, string salt)
{
// Получаю byte-массив из хэш-кода пароля
byte[] saltBytes = Encoding.UTF8.GetBytes(salt);
@ -31,11 +28,6 @@ public sealed class PasswordEncrypt: IEncryptor
// Возвращаю зашифрованный пароль
return Convert.ToBase64String(encryptedPassword);
}
catch (FormatException)
{
return valueIfFail;
}
}
/// <summary>
/// Этот метод не требует реализации в этом классе!
@ -43,28 +35,22 @@ public sealed class PasswordEncrypt: IEncryptor
/// <param name="encryptedValue">НЕ РАБОТАЕТ</param>
/// <param name="salt">НЕ РАБОТАЕТ</param>
/// <returns>НЕ РАБОТАЕТ</returns>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <exception cref="NotImplementedException">Этот метод не требует реализации в этом классе!</exception>
public string Decrypt (string encryptedValue, string salt, string valueIfFail) =>
throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
/// <summary>
/// Этот метод не требует реализации в этом классе!
/// </summary>
/// <param name="text">НЕ РАБОТАЕТ</param>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <returns>НЕ РАБОТАЕТ</returns>
/// <exception cref="NotImplementedException">Этот метод не требует реализации в этом классе!</exception>
public string Base64UrlEncode (string text, string valueIfFail) =>
throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
public string Decrypt (string encryptedValue, string salt) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
/// <summary>
/// Этот метод не требует реализации в этом классе!
/// </summary>
/// <param name="text">НЕ РАБОТАЕТ</param>
/// <returns>НЕ РАБОТАЕТ</returns>
/// <param name="valueIfFail">Значение, если неудача</param>
/// <exception cref="NotImplementedException">Этот метод не требует реализации в этом классе!</exception>
public string Base64UrlDecode (string text, string valueIfFail) =>
throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
public string Base64UrlEncode (string text) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
/// <summary>
/// Этот метод не требует реализации в этом классе!
/// </summary>
/// <param name="text">НЕ РАБОТАЕТ</param>
/// <returns>НЕ РАБОТАЕТ</returns>
/// <exception cref="NotImplementedException">Этот метод не требует реализации в этом классе!</exception>
public string Base64UrlDecode (string text) => throw new NotImplementedException("Этот метод не требует реализации в этом классе!");
}

View File

@ -1,208 +0,0 @@
using anbs_cp.ForNet.Enums;
using Ganss.Xss;
namespace anbs_cp.ForNet.Classes;
/// <summary>
/// Очистка текста от лишних HTML-тегов
/// </summary>
public static class Sanitizer
{
#region Свойства
/// <summary>
/// Все теги запрещены
/// </summary>
public static SanitizerAllowedHtml AllowedNone => GetNone();
/// <summary>
/// Все теги разрешены
/// </summary>
public static SanitizerAllowedHtml AllowedAll => GetAll();
/// <summary>
/// Оставлены только текстовые теги
/// </summary>
public static SanitizerAllowedHtml AllowedTextOnly => GetTextFormatOnly();
/// <summary>
/// Оставлены только текстовые теги, а также img и a
/// </summary>
public static SanitizerAllowedHtml AllowedImageAndLinks => GetImageAndLinks();
/// <summary>
/// Применяются все теги, кроме iframe
/// </summary>
public static SanitizerAllowedHtml AllowedAllExceptIFrame => GetAllExceptIFrame();
#endregion
#region Методы
/// <summary>
/// Очистка html-кода <paramref name="html" /> согласно параметрам <paramref name="allowedHtml" />
/// </summary>
/// <param name="html">HTML-код</param>
/// <param name="allowedHtml">Параметры очистки</param>
/// <returns>Очищенный html-кода</returns>
public static string SanitizeHtml (string html, SanitizerAllowedHtml allowedHtml)
{
// Создаю очиститель
HtmlSanitizer sanitizer = new()
{
// - сохраняю дочерние удалённых
KeepChildNodes = true
};
// Выключаю все параметры HTML
sanitizer.AllowedTags.Clear();
sanitizer.AllowedSchemes.Clear();
sanitizer.AllowedCssProperties.Clear();
sanitizer.AllowedClasses.Clear();
sanitizer.AllowedAttributes.Clear();
sanitizer.AllowedAtRules.Clear();
sanitizer.AllowDataAttributes = false;
// Загружаю параметры
sanitizer.AllowedTags.UnionWith(allowedHtml.AllowedTags);
sanitizer.AllowedSchemes.UnionWith(allowedHtml.AllowedSchemes);
sanitizer.AllowedCssProperties.UnionWith(allowedHtml.AllowedCssProperties);
sanitizer.AllowedClasses.UnionWith(allowedHtml.AllowedClasses);
sanitizer.AllowedAttributes.UnionWith(allowedHtml.AllowedAttributes);
sanitizer.AllowDataAttributes = allowedHtml.AllowDataAttributes;
// Очищаю html согласно правилам
return sanitizer.Sanitize(html);
}
/// <summary>
/// Очистка html-кода по уровню очистки
/// </summary>
/// <param name="html">HTML-код</param>
/// <param name="level">Уровень очистка</param>
/// <returns>Очищенный html-код</returns>
public static string SanitizeHtml (string html, ESanitizerLevel level)
{
// Получаю параметры очистки
SanitizerAllowedHtml allowedHtml = level switch
{
ESanitizerLevel.NoTags => AllowedNone,
ESanitizerLevel.TextFormatOnly => AllowedTextOnly,
ESanitizerLevel.ImageAndLinks => AllowedImageAndLinks,
ESanitizerLevel.AllExceptIFrame => AllowedAllExceptIFrame,
ESanitizerLevel.All => AllowedAll,
var _ => AllowedAll
};
// Очищаю код и возвращаю результат очистки
return SanitizeHtml(html, allowedHtml);
}
#endregion
#region Вспомогателдьные методы
/// <summary>
/// Получаю параметры, удаляющие все теги
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetNone () =>
new()
{
AllowedTags = [],
AllowedAttributes = [],
AllowedCssProperties = [],
AllowedClasses = [],
AllowedSchemes = [],
AllowDataAttributes = false
};
/// <summary>
/// Получаю параметры по умолчанию (разрешающие все теги)
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetAll ()
{
// Создаю очиститель
HtmlSanitizer sanitizer = new();
// Создаю модель
return new()
{
AllowedTags = sanitizer.AllowedTags.ToList(),
AllowedAttributes = sanitizer.AllowedAttributes.ToList(),
AllowedCssProperties = sanitizer.AllowedCssProperties.ToList(),
AllowedClasses = sanitizer.AllowedClasses.ToList(),
AllowedSchemes = sanitizer.AllowedSchemes.ToList(),
AllowDataAttributes = true
};
}
/// <summary>
/// Параметры, оставляющие только текстовые теги
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetTextFormatOnly () =>
new()
{
AllowedTags =
[
"strong", "b", "em", "i", "u", "hr", "strike", "div", "ol", "ul", "li", "p", "span", "h1", "h2", "h3",
"h4"
],
// ReSharper disable StringLiteralTypo
AllowedAttributes =
[
"align", "bgcolor", "border", "cellpadding", "cellspacing", "charset", "checked", "class", "clear",
"color",
"cols", "colspan", "datetime", "disabled", "headers", "height", "high", "hspace", "label", "lang",
"list",
"low", "max", "maxlength", "min", "name", "nowrap", "placeholder", "required", "rev", "rows", "rowspan",
"rules", "selected", "size", "span", "spellcheck", "style", "summary", "tabindex", "title", "type",
"valign",
"value", "vspace", "width", "wrap"
]
// ReSharper restore StringLiteralTypo
};
/// <summary>
/// Параметры, оставляющие только текстовые теги, а также img и a
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetImageAndLinks ()
{
// Получаю текстовые параметры
SanitizerAllowedHtml result = AllowedTextOnly;
// Добавляю теги
result.AllowedTags.AddRange(["a", "img"]);
// Добавляю параметры
// ReSharper disable StringLiteralTypo
result.AllowedAttributes.AddRange(["alt", "href", "hreflang", "nohref", "rel", "src", "target"]);
// ReSharper restore StringLiteralTypo
// Возвращаю результат
return result;
}
/// <summary>
/// Применяются все теги, кроме iframe
/// </summary>
/// <returns>Параметры очистки</returns>
private static SanitizerAllowedHtml GetAllExceptIFrame ()
{
// Получаю все параметры
SanitizerAllowedHtml result = AllowedAll;
// Удаляю iframe
result.AllowedTags.Remove("iframe");
// Возвращаю результат
return result;
}
#endregion
}

View File

@ -1,37 +0,0 @@
namespace anbs_cp.ForNet.Classes;
/// <summary>
/// Допустимые параметры для очистки HTML
/// </summary>
public sealed class SanitizerAllowedHtml
{
/// <summary>
/// Допустимые теги
/// </summary>
public List<string> AllowedTags { get; set; } = [];
/// <summary>
/// Допустимые аттрибуты
/// </summary>
public List<string> AllowedAttributes { get; set; } = [];
/// <summary>
/// Допустимые параметры css
/// </summary>
public List<string> AllowedCssProperties { get; set; } = [];
/// <summary>
/// Допустимые классы
/// </summary>
public List<string> AllowedClasses { get; set; } = [];
/// <summary>
/// Допустимые схемы
/// </summary>
public List<string> AllowedSchemes { get; set; } = [];
/// <summary>
/// Допустимы ли data-атрибуты
/// </summary>
public bool AllowDataAttributes { get; set; } = false;
}

View File

@ -1,41 +0,0 @@
using anbs_cp.Classes;
namespace anbs_cp.ForNet.Constants;
/// <summary>
/// Сообщения валидации
/// </summary>
public static class ValidationMessagesConstants
{
/// <summary>
/// Сообщения на русском языке
/// </summary>
public static readonly KeyValueOrderedList<string> Russian =
[
new("RequiredAttribute", "Поле '{0}' обязательно к заполнению."),
new("MinLengthAttribute", "Минимальная длина поля '{0}' от {1} символа(-ов)."),
new("MaxLengthAttribute", "Максимальная длина поля '{0}' до {1} символа(-ов)."),
new("EmailAddressAttribute", "Адрес email некорректен."),
new("RangeAttribute", "Значение поля '{0}' должно быть между {1} и {2}."),
new("CompareAttribute", "Значение поля '{0}' не совпадаем с требуемым."),
new("RegularExpressionAttribute", "Значение поля '{0}' не удовлетворяет шаблону."),
new ("PhoneAttribute", "Значение поля '{0}' не является номером телефона."),
new ("CreditCardAttribute", "Значение поля '{0}' не является номером кредитной карты.")
];
/// <summary>
/// Сообщения на английском языке
/// </summary>
public static readonly KeyValueOrderedList<string> English =
[
new("RequiredAttribute", "You must fill in '{0}'."),
new("MinLengthAttribute", "Min length of '{0}' is {1}."),
new("MaxLengthAttribute", "Max length of '{0}' is {1}."),
new("EmailAddressAttribute", "Invalid email address."),
new("RangeAttribute", "The value of the field '{0}' must be between {1} and {2}."),
new("CompareAttribute", "Unmatched field '{0}' value."),
new("RegularExpressionAttribute", "Invalid field '{0}' value."),
new ("PhoneAttribute", "The value of the field '{0}' is not valid phone number."),
new ("CreditCardAttribute", "The value of the field '{0}' is not valid credit card number.")
];
}

View File

@ -1,38 +0,0 @@
namespace anbs_cp.ForNet.Enums;
/// <summary>
/// Уровень очистки текста
/// атрибуты описаны на стр. https://github.com/mganss/HtmlSanitizer/wiki/Options
/// </summary>
public enum ESanitizerLevel
{
/// <summary>
/// Все html-теги под запретом
/// </summary>
NoTags = 0,
/// <summary>
/// Доступны только:
/// * теги формата шрифта (жирный, курсив, подчёркнутый, зачёркнутый)
/// * теги расположения текста (слева, по центру, справа)
/// </summary>
TextFormatOnly = 1,
/// <summary>
/// Доступны только:
/// * все теги уровня lvlTextFormatOnly
/// * теги ссылки
/// * теги изображения
/// </summary>
ImageAndLinks = 2,
/// <summary>
/// Доступны все теги, кроме вставки с другого сайта
/// </summary>
AllExceptIFrame = 3,
/// <summary>
/// Доступны все теги
/// </summary>
All = 4
}

View File

@ -1,108 +0,0 @@
using System.Text.RegularExpressions;
using ImageMagick;
using Microsoft.AspNetCore.Http;
using static System.Text.RegularExpressions.Regex;
namespace anbs_cp.ForNet.Extensions;
/// <summary>
/// Расширение интерфейса IFormFile
/// </summary>
public static class FormFileExtension
{
#region Константы
/// <summary>
/// Минимальный размер изображения (в байтах)
/// </summary>
private const int ImageMinimumBytes = 512;
/// <summary>
/// Список поддерживаемых Mime-типов
/// </summary>
private static readonly List<string> AllowedMimeTypes =
["image/jpg", "image/jpeg", "image/pjpeg", "image/gif", "image/x-png", "image/png"];
/// <summary>
/// Список поддерживаемых расширений файлов
/// </summary>
private static readonly List<string> AllowedExtensions = [".jpg", ".png", ".gif", ".jpeg"];
#endregion
/// <summary>
/// Получение содержимого файла
/// </summary>
/// <param name="file">Файл из формы</param>
/// <returns>Содержимое файла</returns>
public static byte[] GetFileContent (this IFormFile file)
{
// Читаем содержимое файла
using BinaryReader binaryReader = new(file.OpenReadStream());
// Создаю контент изображения
byte[] content = binaryReader.ReadBytes((int)file.Length);
// Вывожу результат
return content;
}
/// <summary>
/// Проверка, является ли файл изображением
/// </summary>
/// <param name="postedFile">Файл из формы</param>
/// <returns>Является ли файл изображением</returns>
public static bool IsImage (this IFormFile postedFile)
{
// Проверяю Mime-тип
if (!AllowedMimeTypes.Contains(postedFile.ContentType.ToLower()))
return false;
// Проверяю расширение
if (!AllowedExtensions.Contains(Path.GetExtension(postedFile.FileName).ToLower()))
return false;
// Пытаюсь прочитать файл и проверить первые байты
try
{
if (!postedFile.OpenReadStream().CanRead)
return false;
// Проверяю, не меньше ли размер изображения установленного предела
if (postedFile.Length < ImageMinimumBytes)
return false;
byte[] buffer = new byte[ImageMinimumBytes];
int _ = postedFile.OpenReadStream().Read(buffer, 0, ImageMinimumBytes);
string content = System.Text.Encoding.UTF8.GetString(buffer);
if (IsMatch(content,
@"<script|<html|<head|<title|<body|<pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline))
return false;
}
catch (Exception)
{
// - если .NET выдаст исключение, то можно предположить, что это недопустимое изображение
return false;
}
// Попробую создать экземпляр MagickImageCollection,
try
{
using MagickImageCollection images = new(postedFile.OpenReadStream());
}
catch (Exception)
{
// - если .NET выдаст исключение, то можно предположить, что это недопустимое изображение
return false;
}
finally
{
postedFile.OpenReadStream().Position = 0;
}
// Возвращаю, что это изображение
return true;
}
}

View File

@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>ANBSoftware.ComponentsPackForNet</PackageId>
<Version>2024.9.1</Version>
<Version>2023.09.08.0</Version>
<Authors>Александр Бабаев</Authors>
<Product>Набор компонентов ANB Software для ASP.NET Core</Product>
<Description>Библиотека полезных методов языка C# для ASP.NET Core</Description>
@ -20,18 +20,19 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlSanitizer" Version="8.1.870" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="13.10.0" />
<PackageReference Include="Magick.NET.Core" Version="13.10.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="7.0.12" />
<PackageReference Include="Microsoft.AspNetCore.Html.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.TagHelpers" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\anbs_cp\anbs_cp.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Extensions\" />
</ItemGroup>
</Project>

View File

@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>anbs_cp.OsInfo</RootNamespace>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>ANBSoftware.ComponentsPackOsInfo</PackageId>
<Version>2023.11.14</Version>
<Version>2023.8.11</Version>
<Authors>Александр Бабаев</Authors>
<Product>Набор компонентов ANB Software для получения информации о Windows</Product>
<Description>Библиотека полезных методов языка C# для получения информации об Windows</Description>
@ -18,11 +18,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\anbs_cp\anbs_cp.csproj" />
<PackageReference Include="ANBSoftware.ComponentsPack" Version="2023.811.0" />
<PackageReference Include="System.Management" Version="7.0.2" />
</ItemGroup>
</Project>

View File

@ -1,2 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>

View File

@ -11,18 +11,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "demo", "demo\demo.csproj",
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpfn", "anbs_cpfn\anbs_cpfn.csproj", "{EDED871B-8A96-4A2F-83CF-AD40FF66F6E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cposinfo", "anbs_cposinfo\anbs_cposinfo.csproj", "{80E1FEA9-EEDA-4411-8EBA-11991432E98E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "anbs_cpdb", "anbs_cpdb\anbs_cpdb.csproj", "{3796862F-F181-4A27-92D8-8BF13C4FD711}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "demo2", "demo2\demo2.csproj", "{ED9A2B81-5060-4906-AAC4-88ED1C70211E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F9AFD424-6FCE-465A-8EEF-DA99D3350696}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
ProjectSection(ProjectDependencies) = postProject
{442A56CC-1061-4EB5-8B67-3E3D997976D7} = {442A56CC-1061-4EB5-8B67-3E3D997976D7}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cposinfo", "anbs_cposinfo\anbs_cposinfo.csproj", "{80E1FEA9-EEDA-4411-8EBA-11991432E98E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "anbs_cpdb", "anbs_cpdb\anbs_cpdb.csproj", "{3796862F-F181-4A27-92D8-8BF13C4FD711}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -48,10 +44,6 @@ Global
{3796862F-F181-4A27-92D8-8BF13C4FD711}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3796862F-F181-4A27-92D8-8BF13C4FD711}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3796862F-F181-4A27-92D8-8BF13C4FD711}.Release|Any CPU.Build.0 = Release|Any CPU
{ED9A2B81-5060-4906-AAC4-88ED1C70211E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED9A2B81-5060-4906-AAC4-88ED1C70211E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED9A2B81-5060-4906-AAC4-88ED1C70211E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED9A2B81-5060-4906-AAC4-88ED1C70211E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -2,54 +2,27 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CD/@EntryIndexedValue">CD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HD/@EntryIndexedValue">HD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HDD/@EntryIndexedValue">HDD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RA/@EntryIndexedValue">RA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RAM/@EntryIndexedValue">RAM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=URL/@EntryIndexedValue">URL</s:String>
<s:Boolean x:Key="/Default/GrammarAndSpelling/GrammarChecking/Exceptions/=_0412_044B_0447_0438_0441_043B_044F_0435_0442_002C_0020_0435_0441_0442_044C_0020_043B_0438_0020_0445_043E_0442_044F_0020_0431_044B_0020_043E_0434_043D_043E_0020_0438_0437_0020_0431_0443_043B_0435_0432_044B_0445_0020_043F_0435_0440_0435_043C_0435_043D_043D_044B_0445_0020reference_0432_0020_0437_043D_0430_0447_0435_043D_0438_0438/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=abcdefghijkmnopqrstuvwxyz/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ABCDEFGHJKLMNOPQRSTUVWXYZ/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=anbs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=appsettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=C_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_044F/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Darkseal/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=delim/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Encryptor/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Glendower/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=pjpeg/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=splited/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0412_0435_0440_043D_0451_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0412_0438_0434_0435_043E_043A_0430_0440_0442_0430/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0414_0435_0441_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_044B_0439/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0414_0435_0441_0435_0440_0438_0430_043B_0438_0437_0443_0435_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0414_0435_0441_0435_0440_0438_0430_043B_0438_0437_0443_044E/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_041F_0430_0440_0441_0435_0440/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0421_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_0430_044F/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0421_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_044B_0435/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0421_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_0442_044C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0421_0435_0440_0438_0430_043B_0438_0437_0443_0435_043C_043E_0435/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0421_043E_0437_0434_0430_0451_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0432_0432_0435_0434_0451_043D/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0432_0438_0434_0435_043E_043A_0430_0440_0442_0435/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_0435_0439/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_0438/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_044F/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0448_0438_0444_0440_043E_0432_0430_043D_0438_044F/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0448_0438_0444_0440_043E_0432_0447_0438_043A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0437_0430_0447_0451_0440_043A_043D_0443_0442_044B_0439/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0438_043C_0451_043D/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043A_0440_0438_043F_0442_043E_0433_0440_0430_0444/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043F_043E_0434_0447_0451_0440_043A_043D_0443_0442_044B_0439/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043F_0443_0442_0451_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0440_0435_0433_0438_0441_0442_0440_043E_0437_0430_0432_0438_0441_0438_043C_043E_0441_0442_044C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0430_0442_043E_0440_0430/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_0438/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_044F/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_043E_0433_043E/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_043E_0435/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_0443_044E/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0443_0435_043C/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0443_044E/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0447_0451_0442/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0447_0451_0442_0447_0438_043A/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0445_044D_0448_0430/@EntryIndexedValue">True</s:Boolean>

View File

@ -1,92 +0,0 @@
namespace demo;
sealed partial class ActionStateSerialize
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent ()
{
textBox1 = new TextBox();
textBox2 = new TextBox();
label1 = new Label();
button1 = new Button();
SuspendLayout();
//
// textBox1
//
textBox1.Location = new Point(24, 12);
textBox1.Name = "textBox1";
textBox1.Size = new Size(209, 23);
textBox1.TabIndex = 0;
//
// textBox2
//
textBox2.Location = new Point(312, 6);
textBox2.Multiline = true;
textBox2.Name = "textBox2";
textBox2.Size = new Size(463, 225);
textBox2.TabIndex = 1;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(24, 65);
label1.Name = "label1";
label1.Size = new Size(38, 15);
label1.TabIndex = 2;
label1.Text = "label1";
//
// button1
//
button1.Location = new Point(24, 111);
button1.Name = "button1";
button1.Size = new Size(75, 23);
button1.TabIndex = 3;
button1.Text = "button1";
button1.UseVisualStyleBackColor = true;
button1.Click += button1_Click;
//
// ActionStateSerialize
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 250);
Controls.Add(button1);
Controls.Add(label1);
Controls.Add(textBox2);
Controls.Add(textBox1);
Name = "ActionStateSerialize";
Text = "Тест сериализации ActionState";
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBox1;
private TextBox textBox2;
private Label label1;
private Button button1;
}

View File

@ -1,34 +0,0 @@
using anbs_cp.Classes;
namespace demo;
public sealed partial class ActionStateSerialize: Form
{
public ActionStateSerialize ()
{
InitializeComponent();
}
private void button1_Click (object sender, EventArgs e)
{
DemoClass demoClass = new()
{
Name = textBox1.Text.Length > 0 ? textBox1.Text : string.Empty
};
ActionState<DemoClass> state = new()
{
Value = demoClass
};
state.AddError("ОШИБКА, ШЕФ!");
textBox2.Text = state.Serialize();
ActionState<DemoClass> state2 = new();
state2.Deserialize(textBox2.Text);
label1.Text = state2.Value?.Name ?? "НЕТ ЗНАЧЕНИЯ";
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,8 +0,0 @@
namespace demo;
public class DemoClass
{
public int Num { get; set; } = 5;
public string Name { get; set; } = "";
public bool NotB { get; set; } = true;
}

View File

@ -1,6 +1,4 @@
using anbs_cp.Classes;
using anbs_cp.Extensions;
// ReSharper disable LocalizableElement
namespace demo;
@ -17,7 +15,7 @@ public sealed partial class FileHashAndMimeType: Form
openFileDialog.ShowDialog();
}
private void GetFileHashAndMimeType ()
private void GetFileHashAndMimeType()
{
if (string.IsNullOrEmpty(fileNameEdt.Text))
{
@ -26,7 +24,7 @@ public sealed partial class FileHashAndMimeType: Form
}
string fileHash = new FileHash(fileNameEdt.Text).ToString();
string fileType = FileExtension.MimeType(fileNameEdt.Text);
string fileType = FileExtension.MIMEType(fileNameEdt.Text);
ResultLabel.Text =
$"Ïîëó÷åíû ñëåäóþùèå äàííûå äëÿ ôàéëà\r\n{fileNameEdt.Text}\r\nÕýø ôàéëà:\r\n{fileHash}\r\nÒèï ôàéëà:\r\n{fileType}";

View File

@ -28,95 +28,69 @@ sealed partial class MainMenu
/// </summary>
private void InitializeComponent ()
{
CountValueTest = new Button();
SimpleMapperTest = new Button();
FileExtensionTest = new Button();
OsInfoBtn = new Button();
actionStateSerializerTestBtn = new Button();
stringExtensionTestButton = new Button();
SuspendLayout();
this.CountValueTest = new System.Windows.Forms.Button();
this.SimpleMapperTest = new System.Windows.Forms.Button();
this.FileExtensionTest = new System.Windows.Forms.Button();
this.OsInfoBtn = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// CountValueTest
//
CountValueTest.Location = new Point(12, 12);
CountValueTest.Name = "CountValueTest";
CountValueTest.Size = new Size(337, 53);
CountValueTest.TabIndex = 0;
CountValueTest.Text = "Новый тест модуля форматирования строки";
CountValueTest.UseVisualStyleBackColor = true;
CountValueTest.Click += button1_Click;
this.CountValueTest.Location = new System.Drawing.Point(12, 12);
this.CountValueTest.Name = "CountValueTest";
this.CountValueTest.Size = new System.Drawing.Size(337, 53);
this.CountValueTest.TabIndex = 0;
this.CountValueTest.Text = "Новый тест модуля форматирования строки";
this.CountValueTest.UseVisualStyleBackColor = true;
this.CountValueTest.Click += new System.EventHandler(this.button1_Click);
//
// SimpleMapperTest
//
SimpleMapperTest.Location = new Point(12, 71);
SimpleMapperTest.Name = "SimpleMapperTest";
SimpleMapperTest.Size = new Size(335, 51);
SimpleMapperTest.TabIndex = 1;
SimpleMapperTest.Text = "Новый тест модуля SimpleMapper";
SimpleMapperTest.UseVisualStyleBackColor = true;
SimpleMapperTest.Click += SimpleMapperTest_Click;
this.SimpleMapperTest.Location = new System.Drawing.Point(12, 71);
this.SimpleMapperTest.Name = "SimpleMapperTest";
this.SimpleMapperTest.Size = new System.Drawing.Size(335, 51);
this.SimpleMapperTest.TabIndex = 1;
this.SimpleMapperTest.Text = "Новый тест модуля SimpleMapper";
this.SimpleMapperTest.UseVisualStyleBackColor = true;
this.SimpleMapperTest.Click += new System.EventHandler(this.SimpleMapperTest_Click);
//
// FileExtensionTest
//
FileExtensionTest.Location = new Point(12, 128);
FileExtensionTest.Name = "FileExtensionTest";
FileExtensionTest.Size = new Size(335, 51);
FileExtensionTest.TabIndex = 2;
FileExtensionTest.Text = "Новый тест модуля FileExtension";
FileExtensionTest.UseVisualStyleBackColor = true;
FileExtensionTest.Click += FileExtensionTest_Click;
this.FileExtensionTest.Location = new System.Drawing.Point(12, 128);
this.FileExtensionTest.Name = "FileExtensionTest";
this.FileExtensionTest.Size = new System.Drawing.Size(335, 51);
this.FileExtensionTest.TabIndex = 2;
this.FileExtensionTest.Text = "Новый тест модуля FileExtension";
this.FileExtensionTest.UseVisualStyleBackColor = true;
this.FileExtensionTest.Click += new System.EventHandler(this.FileExtensionTest_Click);
//
// OsInfoBtn
//
OsInfoBtn.Location = new Point(12, 185);
OsInfoBtn.Name = "OsInfoBtn";
OsInfoBtn.Size = new Size(335, 51);
OsInfoBtn.TabIndex = 3;
OsInfoBtn.Text = "Информация о системе";
OsInfoBtn.UseVisualStyleBackColor = true;
OsInfoBtn.Click += OsInfoBtn_Click;
//
// actionStateSerializerTestBtn
//
actionStateSerializerTestBtn.Location = new Point(12, 242);
actionStateSerializerTestBtn.Name = "actionStateSerializerTestBtn";
actionStateSerializerTestBtn.Size = new Size(335, 51);
actionStateSerializerTestBtn.TabIndex = 4;
actionStateSerializerTestBtn.Text = "Тест сериализации ActionState";
actionStateSerializerTestBtn.UseVisualStyleBackColor = true;
actionStateSerializerTestBtn.Click += actionStateSerializerTestBtn_Click;
//
// stringExtensionTestButton
//
stringExtensionTestButton.Location = new Point(12, 299);
stringExtensionTestButton.Name = "stringExtensionTestButton";
stringExtensionTestButton.Size = new Size(335, 51);
stringExtensionTestButton.TabIndex = 5;
stringExtensionTestButton.Text = "Тест расширения класса string";
stringExtensionTestButton.UseVisualStyleBackColor = true;
stringExtensionTestButton.Click += stringExtensionTestButton_Click;
this.OsInfoBtn.Location = new System.Drawing.Point(12, 185);
this.OsInfoBtn.Name = "OsInfoBtn";
this.OsInfoBtn.Size = new System.Drawing.Size(335, 51);
this.OsInfoBtn.TabIndex = 3;
this.OsInfoBtn.Text = "Информация о системе";
this.OsInfoBtn.UseVisualStyleBackColor = true;
this.OsInfoBtn.Click += new System.EventHandler(this.OsInfoBtn_Click);
//
// MainMenu
//
AutoScaleDimensions = new SizeF(10F, 21F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(361, 361);
Controls.Add(stringExtensionTestButton);
Controls.Add(actionStateSerializerTestBtn);
Controls.Add(OsInfoBtn);
Controls.Add(FileExtensionTest);
Controls.Add(SimpleMapperTest);
Controls.Add(CountValueTest);
Font = new Font("Times New Roman", 14.25F);
FormBorderStyle = FormBorderStyle.FixedSingle;
Margin = new Padding(4);
MaximizeBox = false;
MinimizeBox = false;
Name = "MainMenu";
ShowIcon = false;
StartPosition = FormStartPosition.CenterScreen;
Text = "Главное меню";
ResumeLayout(false);
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(361, 252);
this.Controls.Add(this.OsInfoBtn);
this.Controls.Add(this.FileExtensionTest);
this.Controls.Add(this.SimpleMapperTest);
this.Controls.Add(this.CountValueTest);
this.Font = new System.Drawing.Font("Times New Roman", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Margin = new System.Windows.Forms.Padding(4);
this.Name = "MainMenu";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Главное меню";
this.ResumeLayout(false);
}
#endregion
@ -125,6 +99,4 @@ sealed partial class MainMenu
private Button SimpleMapperTest;
private Button FileExtensionTest;
private Button OsInfoBtn;
private Button actionStateSerializerTestBtn;
private Button stringExtensionTestButton;
}

View File

@ -1,6 +1,4 @@
using demo.TestForms;
namespace demo;
namespace demo;
public sealed partial class MainMenu: Form
{
public MainMenu ()
@ -31,16 +29,4 @@ public sealed partial class MainMenu: Form
OsInfoFrm formTest = new();
formTest.ShowDialog();
}
private void actionStateSerializerTestBtn_Click (object sender, EventArgs e)
{
ActionStateSerialize form = new();
form.ShowDialog();
}
private void stringExtensionTestButton_Click (object sender, EventArgs e)
{
StringExtensionTest form = new();
form.ShowDialog();
}
}

View File

@ -1,64 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">

View File

@ -1,5 +1,6 @@
using anbs_cp.Classes;
using anbs_cp.OsInfo.Classes;
using anbs_cp.OsInfo.Classes;
using Newtonsoft.Json;
namespace demo;
public sealed partial class OsInfoFrm: Form
@ -12,16 +13,16 @@ public sealed partial class OsInfoFrm: Form
private void OsInfoFrm_Load (object sender, EventArgs e)
{
textBox.Text = @"Процессор(ы) | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Processors);
textBox.Text += JsonConvert.SerializeObject(OsInfo.Processors);
textBox.Text += @"Оперативная память | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.RAM);
textBox.Text += JsonConvert.SerializeObject(OsInfo.RAM);
textBox.Text += @"Видеокарта | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Videos);
textBox.Text += JsonConvert.SerializeObject(OsInfo.Videos);
textBox.Text += @"Диски | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Drives);
textBox.Text += JsonConvert.SerializeObject(OsInfo.Drives);
textBox.Text += @"Windows | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Windows);
textBox.Text += JsonConvert.SerializeObject(OsInfo.Windows);
textBox.Text += @"Net | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Net);
textBox.Text += JsonConvert.SerializeObject(OsInfo.Net);
}
}

View File

@ -1,4 +1,5 @@
using anbs_cp.Classes;
using Newtonsoft.Json;
namespace demo;
public sealed partial class SampleMapperTest: Form
@ -25,7 +26,7 @@ public sealed partial class SampleMapperTest: Form
DemoDateTime = default
};
string serialize1 = new SysTextSerializer().Serialize(demo2);
string serialize1 = JsonConvert.SerializeObject(demo2);
SimpleMapper.MapMode mode = MapModeEdit.SelectedIndex switch
{
@ -38,7 +39,7 @@ public sealed partial class SampleMapperTest: Form
SimpleMapper.MapEx(demo1, ref demo2, mode, new List<string>());
string serialize2 = new SysTextSerializer().Serialize(demo2);
string serialize2 = JsonConvert.SerializeObject(demo2);
// ReSharper disable once LocalizableElement
ResultArea.Text = $"Класс Demo2 до связывания:\r\n{serialize1}\r\nи после:\r\n{serialize2}";

View File

@ -1,92 +0,0 @@
namespace demo.TestForms;
sealed partial class ActionStateSerialize
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent ()
{
textBox1 = new TextBox();
textBox2 = new TextBox();
label1 = new Label();
button1 = new Button();
SuspendLayout();
//
// textBox1
//
textBox1.Location = new Point(24, 12);
textBox1.Name = "textBox1";
textBox1.Size = new Size(209, 23);
textBox1.TabIndex = 0;
//
// textBox2
//
textBox2.Location = new Point(312, 6);
textBox2.Multiline = true;
textBox2.Name = "textBox2";
textBox2.Size = new Size(463, 225);
textBox2.TabIndex = 1;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(24, 65);
label1.Name = "label1";
label1.Size = new Size(38, 15);
label1.TabIndex = 2;
label1.Text = "label1";
//
// button1
//
button1.Location = new Point(24, 111);
button1.Name = "button1";
button1.Size = new Size(75, 23);
button1.TabIndex = 3;
button1.Text = "button1";
button1.UseVisualStyleBackColor = true;
button1.Click += button1_Click;
//
// ActionStateSerialize
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 250);
Controls.Add(button1);
Controls.Add(label1);
Controls.Add(textBox2);
Controls.Add(textBox1);
Name = "ActionStateSerialize";
Text = "Тест сериализации ActionState";
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBox1;
private TextBox textBox2;
private Label label1;
private Button button1;
}

View File

@ -1,34 +0,0 @@
using anbs_cp.Classes;
namespace demo.TestForms;
public sealed partial class ActionStateSerialize: Form
{
public ActionStateSerialize ()
{
InitializeComponent();
}
private void button1_Click (object sender, EventArgs e)
{
DemoClass demoClass = new()
{
Name = textBox1.Text.Length > 0 ? textBox1.Text : string.Empty
};
ActionState<DemoClass> state = new()
{
Value = demoClass
};
state.AddError("ОШИБКА, ШЕФ!");
textBox2.Text = state.Serialize();
ActionState<DemoClass> state2 = new();
state2.Deserialize(textBox2.Text);
label1.Text = state2.Value?.Name ?? "НЕТ ЗНАЧЕНИЯ";
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,147 +0,0 @@
namespace demo.TestForms;
sealed partial class CountValueTest
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent ()
{
this.InsertDataLabel = new System.Windows.Forms.Label();
this.InsertDataBox = new System.Windows.Forms.TextBox();
this.ResultLabel = new System.Windows.Forms.Label();
this.CalculateButton = new System.Windows.Forms.Button();
this.SelectFormatterLabel = new System.Windows.Forms.Label();
this.SelectFormatterBox = new System.Windows.Forms.ComboBox();
this.calculateConvButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// InsertDataLabel
//
this.InsertDataLabel.AutoSize = true;
this.InsertDataLabel.Location = new System.Drawing.Point(12, 66);
this.InsertDataLabel.Name = "InsertDataLabel";
this.InsertDataLabel.Size = new System.Drawing.Size(341, 17);
this.InsertDataLabel.TabIndex = 0;
this.InsertDataLabel.Text = "&Введите любое целочисленное значение:";
//
// InsertDataBox
//
this.InsertDataBox.Location = new System.Drawing.Point(12, 86);
this.InsertDataBox.Name = "InsertDataBox";
this.InsertDataBox.Size = new System.Drawing.Size(457, 24);
this.InsertDataBox.TabIndex = 1;
this.InsertDataBox.TextChanged += new System.EventHandler(this.InsertDataBox_TextChanged);
//
// ResultLabel
//
this.ResultLabel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ResultLabel.Location = new System.Drawing.Point(0, 143);
this.ResultLabel.Margin = new System.Windows.Forms.Padding(5);
this.ResultLabel.Name = "ResultLabel";
this.ResultLabel.Padding = new System.Windows.Forms.Padding(5);
this.ResultLabel.Size = new System.Drawing.Size(478, 79);
this.ResultLabel.TabIndex = 2;
this.ResultLabel.Text = "&Вставьте любое целочисленное значение в поле выше и нажмите кнопку \"Вычислить\", " +
"чтобы увидеть результат...";
this.ResultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// CalculateButton
//
this.CalculateButton.Location = new System.Drawing.Point(12, 116);
this.CalculateButton.Name = "CalculateButton";
this.CalculateButton.Size = new System.Drawing.Size(234, 23);
this.CalculateButton.TabIndex = 3;
this.CalculateButton.Text = "В&ычислить обработчиком";
this.CalculateButton.UseVisualStyleBackColor = true;
this.CalculateButton.Click += new System.EventHandler(this.CalculateButton_Click);
//
// SelectFormatterLabel
//
this.SelectFormatterLabel.AutoSize = true;
this.SelectFormatterLabel.Location = new System.Drawing.Point(12, 9);
this.SelectFormatterLabel.Name = "SelectFormatterLabel";
this.SelectFormatterLabel.Size = new System.Drawing.Size(188, 17);
this.SelectFormatterLabel.TabIndex = 4;
this.SelectFormatterLabel.Text = "В&ыберете обработчик:";
//
// SelectFormatterBox
//
this.SelectFormatterBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.SelectFormatterBox.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.SelectFormatterBox.FormattingEnabled = true;
this.SelectFormatterBox.Items.AddRange(new object[] {
"Обработчик счёта",
"Обработчик размера файла"});
this.SelectFormatterBox.Location = new System.Drawing.Point(12, 29);
this.SelectFormatterBox.Name = "SelectFormatterBox";
this.SelectFormatterBox.Size = new System.Drawing.Size(457, 25);
this.SelectFormatterBox.TabIndex = 5;
//
// calculateConvButton
//
this.calculateConvButton.Location = new System.Drawing.Point(252, 116);
this.calculateConvButton.Name = "calculateConvButton";
this.calculateConvButton.Size = new System.Drawing.Size(217, 23);
this.calculateConvButton.TabIndex = 6;
this.calculateConvButton.Text = "&Вычислить конвертером";
this.calculateConvButton.UseVisualStyleBackColor = true;
this.calculateConvButton.Click += new System.EventHandler(this.calculateConvButton_Click);
//
// CountValueTest
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(478, 222);
this.Controls.Add(this.calculateConvButton);
this.Controls.Add(this.SelectFormatterBox);
this.Controls.Add(this.SelectFormatterLabel);
this.Controls.Add(this.CalculateButton);
this.Controls.Add(this.ResultLabel);
this.Controls.Add(this.InsertDataBox);
this.Controls.Add(this.InsertDataLabel);
this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "CountValueTest";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Тест модуля форматирования строки";
this.Load += new System.EventHandler(this.CountValueTest_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Label InsertDataLabel;
private TextBox InsertDataBox;
private Label ResultLabel;
private Button CalculateButton;
private Label SelectFormatterLabel;
private ComboBox SelectFormatterBox;
private Button calculateConvButton;
}

View File

@ -1,56 +0,0 @@
using anbs_cp.Classes;
using anbs_cp.Interfaces;
namespace demo.TestForms;
public sealed partial class CountValueTest: Form
{
public CountValueTest ()
{
InitializeComponent();
}
private void CalculateButton_Click (object sender, EventArgs e)
{
if (string.IsNullOrEmpty(InsertDataBox.Text))
return;
long value = TypeConverter.StrToInt64(InsertDataBox.Text);
IValueFormatter formatter = SelectFormatterBox.SelectedIndex switch
{
0 => new CountFormatter(),
1 => new FileSizeFormatter(),
_ => new CountFormatter(),
};
ResultLabel.Text = formatter.Format(value);
}
private void CountValueTest_Load (object sender, EventArgs e)
{
SelectFormatterBox.SelectedIndex = 0;
}
private void InsertDataBox_TextChanged (object sender, EventArgs e)
{
ulong value = TypeConverter.StrToUInt64(InsertDataBox.Text);
if (value > long.MaxValue)
InsertDataBox.Text = long.MaxValue.ToString();
}
private void calculateConvButton_Click (object sender, EventArgs e)
{
if (string.IsNullOrEmpty(InsertDataBox.Text))
return;
long value = TypeConverter.StrToInt64(InsertDataBox.Text);
ResultLabel.Text = SelectFormatterBox.SelectedIndex switch
{
0 => new CountConverter(CountConverter.DefaultNames).Convert(value),
1 => new FileSizeConverter(FileSizeConverter.DefaultNames).Convert(value),
_ => new CountConverter(CountConverter.DefaultNames).Convert(value)
};
}
}

View File

@ -1,60 +0,0 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,125 +0,0 @@
namespace demo.TestForms;
sealed partial class FileHashAndMimeType
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent ()
{
this.ResultLabel = new System.Windows.Forms.Label();
this.SelectFileLabel = new System.Windows.Forms.Label();
this.fileNameEdt = new System.Windows.Forms.TextBox();
this.ViewButton = new System.Windows.Forms.Button();
this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
this.topPanel = new System.Windows.Forms.Panel();
this.topPanel.SuspendLayout();
this.SuspendLayout();
//
// ResultLabel
//
this.ResultLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.ResultLabel.Location = new System.Drawing.Point(0, 0);
this.ResultLabel.Margin = new System.Windows.Forms.Padding(5);
this.ResultLabel.Name = "ResultLabel";
this.ResultLabel.Padding = new System.Windows.Forms.Padding(5);
this.ResultLabel.Size = new System.Drawing.Size(412, 428);
this.ResultLabel.TabIndex = 2;
this.ResultLabel.Text = "В&ыберете файл (введите ипя файла с полным путём вверху или с помощью диалога, на" +
"жав \"Обзор\")...";
this.ResultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// SelectFileLabel
//
this.SelectFileLabel.AutoSize = true;
this.SelectFileLabel.Location = new System.Drawing.Point(3, 11);
this.SelectFileLabel.Name = "SelectFileLabel";
this.SelectFileLabel.Size = new System.Drawing.Size(134, 17);
this.SelectFileLabel.TabIndex = 4;
this.SelectFileLabel.Text = "В&ыберете файл:";
//
// fileNameEdt
//
this.fileNameEdt.Location = new System.Drawing.Point(3, 38);
this.fileNameEdt.Name = "fileNameEdt";
this.fileNameEdt.Size = new System.Drawing.Size(288, 24);
this.fileNameEdt.TabIndex = 5;
this.fileNameEdt.TextChanged += new System.EventHandler(this.fileNameEdt_TextChanged);
//
// ViewButton
//
this.ViewButton.Location = new System.Drawing.Point(297, 39);
this.ViewButton.Name = "ViewButton";
this.ViewButton.Size = new System.Drawing.Size(103, 23);
this.ViewButton.TabIndex = 3;
this.ViewButton.Text = "&Обзор";
this.ViewButton.UseVisualStyleBackColor = true;
this.ViewButton.Click += new System.EventHandler(this.ViewButton_Click);
//
// openFileDialog
//
this.openFileDialog.AddToRecent = false;
this.openFileDialog.Filter = "Все файлы|*.*";
this.openFileDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.openFileDialog_FileOk);
//
// topPanel
//
this.topPanel.Controls.Add(this.SelectFileLabel);
this.topPanel.Controls.Add(this.ViewButton);
this.topPanel.Controls.Add(this.fileNameEdt);
this.topPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.topPanel.Location = new System.Drawing.Point(0, 0);
this.topPanel.Name = "topPanel";
this.topPanel.Size = new System.Drawing.Size(412, 74);
this.topPanel.TabIndex = 6;
//
// FileHashAndMimeType
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(412, 428);
this.Controls.Add(this.topPanel);
this.Controls.Add(this.ResultLabel);
this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FileHashAndMimeType";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Получение хэша и MIME-типа файла";
this.topPanel.ResumeLayout(false);
this.topPanel.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private Label ResultLabel;
private Label SelectFileLabel;
private TextBox fileNameEdt;
private Button ViewButton;
private OpenFileDialog openFileDialog;
private Panel topPanel;
}

View File

@ -1,44 +0,0 @@
using anbs_cp.Classes;
using anbs_cp.Extensions;
// ReSharper disable LocalizableElement
namespace demo.TestForms;
public sealed partial class FileHashAndMimeType: Form
{
public FileHashAndMimeType ()
{
InitializeComponent();
}
private void ViewButton_Click (object sender, EventArgs e)
{
openFileDialog.ShowDialog();
}
private void GetFileHashAndMimeType ()
{
if (string.IsNullOrEmpty(fileNameEdt.Text))
{
ResultLabel.Text = "Ôàéë íå âûáðàí èëè ââåä¸í íåñóùåñòâóþùèé ôàéë!";
return;
}
string fileHash = new FileHash(fileNameEdt.Text).ToString();
string fileType = FileExtension.MimeType(fileNameEdt.Text);
ResultLabel.Text =
$"Ïîëó÷åíû ñëåäóþùèå äàííûå äëÿ ôàéëà\r\n{fileNameEdt.Text}\r\nÕýø ôàéëà:\r\n{fileHash}\r\nÒèï ôàéëà:\r\n{fileType}";
}
private void openFileDialog_FileOk (object sender, System.ComponentModel.CancelEventArgs e)
{
fileNameEdt.Text = openFileDialog.FileName;
}
private void fileNameEdt_TextChanged (object sender, EventArgs e)
{
GetFileHashAndMimeType();
}
}

View File

@ -1,63 +0,0 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -1,65 +0,0 @@
namespace demo.TestForms;
sealed partial class OsInfoFrm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent ()
{
this.textBox = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox
//
this.textBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBox.Location = new System.Drawing.Point(0, 0);
this.textBox.Multiline = true;
this.textBox.Name = "textBox";
this.textBox.Size = new System.Drawing.Size(1029, 510);
this.textBox.TabIndex = 0;
//
// OsInfoFrm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1029, 510);
this.Controls.Add(this.textBox);
this.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "OsInfoFrm";
this.Text = "Информация о системе";
this.Load += new System.EventHandler(this.OsInfoFrm_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private TextBox textBox;
}

View File

@ -1,27 +0,0 @@
using anbs_cp.Classes;
using anbs_cp.OsInfo.Classes;
namespace demo.TestForms;
public sealed partial class OsInfoFrm: Form
{
public OsInfoFrm ()
{
InitializeComponent();
}
private void OsInfoFrm_Load (object sender, EventArgs e)
{
textBox.Text = @"Процессор(ы) | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Processors);
textBox.Text += @"Оперативная память | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.RAM);
textBox.Text += @"Видеокарта | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Videos);
textBox.Text += @"Диски | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Drives);
textBox.Text += @"Windows | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Windows);
textBox.Text += @"Net | ";
textBox.Text += new SysTextSerializer().Serialize(OsInfo.Net);
}
}

View File

@ -1,60 +0,0 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,189 +0,0 @@
namespace demo.TestForms;
sealed partial class SampleMapperTest
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent ()
{
this.DemoBoolEdt = new System.Windows.Forms.CheckBox();
this.DemoStringEdt = new System.Windows.Forms.TextBox();
this.DemoIntEdt = new System.Windows.Forms.NumericUpDown();
this.DemoDateTimeEdt = new System.Windows.Forms.DateTimePicker();
this.MapBtn = new System.Windows.Forms.Button();
this.ResultArea = new System.Windows.Forms.TextBox();
this.DemoStringLabel = new System.Windows.Forms.Label();
this.DemoIntLabel = new System.Windows.Forms.Label();
this.DemoDateTimeLabel = new System.Windows.Forms.Label();
this.MapModeEdit = new System.Windows.Forms.ComboBox();
this.MapModeLabel = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.DemoIntEdt)).BeginInit();
this.SuspendLayout();
//
// DemoBoolEdt
//
this.DemoBoolEdt.AutoSize = true;
this.DemoBoolEdt.Location = new System.Drawing.Point(32, 144);
this.DemoBoolEdt.Name = "DemoBoolEdt";
this.DemoBoolEdt.Size = new System.Drawing.Size(65, 25);
this.DemoBoolEdt.TabIndex = 0;
this.DemoBoolEdt.Text = "Bool";
this.DemoBoolEdt.UseVisualStyleBackColor = true;
//
// DemoStringEdt
//
this.DemoStringEdt.Location = new System.Drawing.Point(32, 42);
this.DemoStringEdt.Name = "DemoStringEdt";
this.DemoStringEdt.Size = new System.Drawing.Size(737, 29);
this.DemoStringEdt.TabIndex = 1;
//
// DemoIntEdt
//
this.DemoIntEdt.Location = new System.Drawing.Point(32, 109);
this.DemoIntEdt.Name = "DemoIntEdt";
this.DemoIntEdt.Size = new System.Drawing.Size(737, 29);
this.DemoIntEdt.TabIndex = 2;
//
// DemoDateTimeEdt
//
this.DemoDateTimeEdt.CustomFormat = "dd.MM.yyyy HH:mm:ss";
this.DemoDateTimeEdt.Format = System.Windows.Forms.DateTimePickerFormat.Custom;
this.DemoDateTimeEdt.Location = new System.Drawing.Point(32, 193);
this.DemoDateTimeEdt.Name = "DemoDateTimeEdt";
this.DemoDateTimeEdt.Size = new System.Drawing.Size(737, 29);
this.DemoDateTimeEdt.TabIndex = 3;
//
// MapBtn
//
this.MapBtn.Location = new System.Drawing.Point(32, 306);
this.MapBtn.Name = "MapBtn";
this.MapBtn.Size = new System.Drawing.Size(737, 57);
this.MapBtn.TabIndex = 5;
this.MapBtn.Text = "СВЯЗАТЬ";
this.MapBtn.UseVisualStyleBackColor = true;
this.MapBtn.Click += new System.EventHandler(this.MapBtn_Click);
//
// ResultArea
//
this.ResultArea.Dock = System.Windows.Forms.DockStyle.Right;
this.ResultArea.Location = new System.Drawing.Point(819, 0);
this.ResultArea.Multiline = true;
this.ResultArea.Name = "ResultArea";
this.ResultArea.ReadOnly = true;
this.ResultArea.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.ResultArea.Size = new System.Drawing.Size(332, 378);
this.ResultArea.TabIndex = 6;
//
// DemoStringLabel
//
this.DemoStringLabel.AutoSize = true;
this.DemoStringLabel.Location = new System.Drawing.Point(32, 18);
this.DemoStringLabel.Name = "DemoStringLabel";
this.DemoStringLabel.Size = new System.Drawing.Size(54, 21);
this.DemoStringLabel.TabIndex = 7;
this.DemoStringLabel.Text = "String";
//
// DemoIntLabel
//
this.DemoIntLabel.AutoSize = true;
this.DemoIntLabel.Location = new System.Drawing.Point(32, 85);
this.DemoIntLabel.Name = "DemoIntLabel";
this.DemoIntLabel.Size = new System.Drawing.Size(30, 21);
this.DemoIntLabel.TabIndex = 8;
this.DemoIntLabel.Text = "Int";
//
// DemoDateTimeLabel
//
this.DemoDateTimeLabel.AutoSize = true;
this.DemoDateTimeLabel.Location = new System.Drawing.Point(32, 169);
this.DemoDateTimeLabel.Name = "DemoDateTimeLabel";
this.DemoDateTimeLabel.Size = new System.Drawing.Size(81, 21);
this.DemoDateTimeLabel.TabIndex = 9;
this.DemoDateTimeLabel.Text = "DateTime";
//
// MapModeEdit
//
this.MapModeEdit.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.MapModeEdit.FormattingEnabled = true;
this.MapModeEdit.Items.AddRange(new object[] {
"Full",
"Not null",
"Not default",
"Not null or default"});
this.MapModeEdit.Location = new System.Drawing.Point(32, 254);
this.MapModeEdit.Name = "MapModeEdit";
this.MapModeEdit.Size = new System.Drawing.Size(737, 29);
this.MapModeEdit.TabIndex = 10;
//
// MapModeLabel
//
this.MapModeLabel.AutoSize = true;
this.MapModeLabel.Location = new System.Drawing.Point(32, 230);
this.MapModeLabel.Name = "MapModeLabel";
this.MapModeLabel.Size = new System.Drawing.Size(167, 21);
this.MapModeLabel.TabIndex = 11;
this.MapModeLabel.Text = "Режим связывания:";
//
// SampleMapperTest
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1151, 378);
this.Controls.Add(this.MapModeLabel);
this.Controls.Add(this.MapModeEdit);
this.Controls.Add(this.DemoDateTimeLabel);
this.Controls.Add(this.DemoIntLabel);
this.Controls.Add(this.DemoStringLabel);
this.Controls.Add(this.ResultArea);
this.Controls.Add(this.MapBtn);
this.Controls.Add(this.DemoDateTimeEdt);
this.Controls.Add(this.DemoIntEdt);
this.Controls.Add(this.DemoStringEdt);
this.Controls.Add(this.DemoBoolEdt);
this.Font = new System.Drawing.Font("Times New Roman", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.Margin = new System.Windows.Forms.Padding(4);
this.Name = "SampleMapperTest";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Тест класса SampleMapper";
((System.ComponentModel.ISupportInitialize)(this.DemoIntEdt)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private CheckBox DemoBoolEdt;
private TextBox DemoStringEdt;
private NumericUpDown DemoIntEdt;
private DateTimePicker DemoDateTimeEdt;
private Button MapBtn;
private TextBox ResultArea;
private Label DemoStringLabel;
private Label DemoIntLabel;
private Label DemoDateTimeLabel;
private ComboBox MapModeEdit;
private Label MapModeLabel;
}

View File

@ -1,70 +0,0 @@
using anbs_cp.Classes;
namespace demo.TestForms;
public sealed partial class SampleMapperTest: Form
{
public SampleMapperTest ()
{
InitializeComponent();
}
private void MapBtn_Click (object sender, EventArgs e)
{
Demo1Class demo1 = new()
{
DemoString = DemoStringEdt.Text,
DemoInt = (int)DemoIntEdt.Value,
DemoBool = DemoBoolEdt.Checked,
DemoDateTime = DemoDateTimeEdt.Value
};
Demo1Class demo2 = new()
{
DemoInt = 20220224,
DemoBool = true,
DemoDateTime = default
};
string serialize1 = new SysTextSerializer().Serialize(demo2);
SimpleMapper.MapMode mode = MapModeEdit.SelectedIndex switch
{
0 => SimpleMapper.MapMode.MapFull,
1 => SimpleMapper.MapMode.MapNotNull,
2 => SimpleMapper.MapMode.MapNotDefault,
3 => SimpleMapper.MapMode.MapNotNullOrDefault,
_ => SimpleMapper.MapMode.MapFull
};
SimpleMapper.MapEx(demo1, ref demo2, mode, new List<string>());
string serialize2 = new SysTextSerializer().Serialize(demo2);
// ReSharper disable once LocalizableElement
ResultArea.Text = $"Класс Demo2 до связывания:\r\n{serialize1}\r\nи после:\r\n{serialize2}";
}
}
public sealed class Demo1Class
{
public string? DemoString { get; set; }
public int DemoInt { get; set; }
public bool DemoBool { get; set; }
public DateTime DemoDateTime { get; set; }
}
public class Demo2Class
{
public string? DemoString { get; set; }
public int DemoInt { get; set; }
public bool DemoBool { get; set; }
public DateTime DemoDateTime { get; set; }
public string? DemoStringNotMapped { get; set; }
}

View File

@ -1,60 +0,0 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,125 +0,0 @@
namespace demo.TestForms;
partial class StringExtensionTest
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose (bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent ()
{
stringInputLabel = new Label();
stringInput = new TextBox();
replaceInput = new TextBox();
replaceInputLabel = new Label();
resultLabel = new Label();
doItButton = new Button();
SuspendLayout();
//
// stringInputLabel
//
stringInputLabel.AutoSize = true;
stringInputLabel.Location = new Point(12, 9);
stringInputLabel.Name = "stringInputLabel";
stringInputLabel.Size = new Size(119, 17);
stringInputLabel.TabIndex = 0;
stringInputLabel.Text = "&Введите строку:";
//
// stringInput
//
stringInput.Location = new Point(12, 29);
stringInput.Name = "stringInput";
stringInput.Size = new Size(1005, 26);
stringInput.TabIndex = 1;
//
// replaceInput
//
replaceInput.Location = new Point(12, 89);
replaceInput.Multiline = true;
replaceInput.Name = "replaceInput";
replaceInput.Size = new Size(1005, 307);
replaceInput.TabIndex = 2;
//
// replaceInputLabel
//
replaceInputLabel.AutoSize = true;
replaceInputLabel.Location = new Point(12, 69);
replaceInputLabel.Name = "replaceInputLabel";
replaceInputLabel.Size = new Size(235, 17);
replaceInputLabel.TabIndex = 3;
replaceInputLabel.Text = "&Введите массив замен (что=чем):";
//
// resultLabel
//
resultLabel.Dock = DockStyle.Bottom;
resultLabel.Location = new Point(0, 454);
resultLabel.Name = "resultLabel";
resultLabel.Padding = new Padding(10);
resultLabel.Size = new Size(1025, 184);
resultLabel.TabIndex = 4;
resultLabel.Text = "&Введите данные и нажмите кнопку «Преобразовать», чтобы увидеть здесь резкльтат...";
//
// doItButton
//
doItButton.Location = new Point(12, 402);
doItButton.Name = "doItButton";
doItButton.Size = new Size(1005, 43);
doItButton.TabIndex = 5;
doItButton.Text = "&Преобразовать";
doItButton.UseVisualStyleBackColor = true;
doItButton.Click += doItButton_Click;
//
// StringExtensionTest
//
AutoScaleDimensions = new SizeF(9F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1025, 638);
Controls.Add(doItButton);
Controls.Add(resultLabel);
Controls.Add(replaceInputLabel);
Controls.Add(replaceInput);
Controls.Add(stringInput);
Controls.Add(stringInputLabel);
Font = new Font("XO Thames", 12F, FontStyle.Regular, GraphicsUnit.Point, 204);
FormBorderStyle = FormBorderStyle.Fixed3D;
Margin = new Padding(4, 3, 4, 3);
MaximizeBox = false;
MinimizeBox = false;
Name = "StringExtensionTest";
ShowIcon = false;
ShowInTaskbar = false;
StartPosition = FormStartPosition.CenterScreen;
Text = "Тест расширения класса string";
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label stringInputLabel;
private TextBox stringInput;
private TextBox replaceInput;
private Label replaceInputLabel;
private Label resultLabel;
private Button doItButton;
}

View File

@ -1,47 +0,0 @@
using anbs_cp.Classes;
using anbs_cp.Extensions;
namespace demo.TestForms;
public partial class StringExtensionTest: Form
{
public StringExtensionTest ()
{
InitializeComponent();
}
private void doItButton_Click (object sender, EventArgs e)
{
if (stringInput.Text.IsNullOrWhiteSpace())
{
resultLabel.Text = @"Ошибка! Не заполнено поле ввода строки на замену!";
return;
}
if (replaceInput.Text.IsNullOrWhiteSpace())
{
resultLabel.Text = @"Ошибка! Не заполнено поле ввода списка замен!";
return;
}
string[] lines = replaceInput.Text.ReplaceLineEndings(";").Split(';');
KeyValueOrderedList<string> replaceList = [];
foreach (string line in lines)
{
string[] splitLine = line.Split('=');
if (splitLine.Length < 2)
continue;
string key = splitLine[0];
string value = splitLine[1];
replaceList.Add(new(key, value));
}
resultLabel.Text = stringInput.Text.Format(replaceList, StringComparison.CurrentCultureIgnoreCase);
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
@ -24,7 +24,9 @@
</ItemGroup>
<ItemGroup>
<Compile Update="TestForms\FileHashAndMimeTypeTest.cs" />
<Compile Update="FileHashAndMimeTypeTest.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>

View File

@ -1,2 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp100</s:String></wpf:ResourceDictionary>

View File

@ -1,49 +0,0 @@
using anbs_cp.Classes;
using anbs_cp.Enums;
using anbs_cp.Extensions;
// KeyValueOrderedTest
void DoTest1 ()
{
Console.WriteLine("Вы выбрали тест KeyValueOrdered. В список будут по очереди добавляться данные.");
KeyValueOrderedList<string> kv = [];
Console.WriteLine("Добавляю данные: я=>Вася");
kv.Add(new("я", "Вася"));
Console.WriteLine(kv.Serialize());
Console.WriteLine("Добавляю данные: он=>Петя");
kv.Add(new("он", "Петя"));
Console.WriteLine(kv.Serialize());
Console.WriteLine("Добавляю данные: я=>Саша");
kv.Add(new("я", "Саша"));
Console.WriteLine(kv.Serialize());
Console.ReadLine();
}
// StringExtensions 1
void DoTest2 ()
{
Console.WriteLine("Вы выбрали тест StringExtensions 1. Введите предложение:");
string str = Console.ReadLine() ?? string.Empty;
Console.WriteLine($"None: {str.Transform(ETextTransform.None)}");
Console.WriteLine($"LowerCase: {str.Transform(ETextTransform.LowerCase)}");
Console.WriteLine($"UpperCase: {str.Transform(ETextTransform.UpperCase)}");
Console.WriteLine($"FirstUpper: {str.Transform(ETextTransform.FirstUpper)}");
Console.ReadLine();
}
Console.WriteLine("Выберете тест:");
if (!int.TryParse(Console.ReadLine(), out int testNum))
testNum = 0;
switch (testNum)
{
case 0:
break;
case 1:
DoTest1();
break;
case 2:
DoTest2();
break;
}

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