PIbd-14_Pruidze_I.K_Simple_.../ProjectCruiser/CollectionGenericObj/StorageCollection.cs

182 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Text;
using ProjectCruiser.DrawningSamples;
using ProjectCruiser.Exceptions;
namespace ProjectCruiser.CollectionGenericObj;
public class StorageCollection<T>
where T : DrawningBase // class
{
// Разделитель для записи ключа и значения элемента словаря
private readonly string _separatorForKeyValue = "|";
// Разделитель для записей коллекции данных в файл
private readonly string _separatorItems = ";";
// Ключевое слово, с которого должен начинаться файл
private readonly string _collectionKey = "CollectionsStorage";
// Словарь (хранилище) с коллекциями < name, type (class) >
readonly Dictionary<string, ICollectionGenObj<T>> _storages;
// Возвращение списка названий коллекций
public List<string> Keys => _storages.Keys.ToList();
public StorageCollection()
{
_storages = new Dictionary<string, ICollectionGenObj<T>>();
}
// Добавление коллекции в хранилище
public void AddCollection(string name, CollectionType collType)
{
if (name == null || _storages.ContainsKey(name)
|| collType == CollectionType.None)
{
return;
}
ICollectionGenObj<T> collection = CreateCollection(collType);
_storages.Add(name, collection);
}
// Удаление коллекции ( по ключу-строке - её имени )
public void DelCollection(string name)
{
if (_storages.ContainsKey(name)) _storages.Remove(name);
return;
}
// Доступ к коллекции ( по ключу-строке - её имени ) - индексатор [!!!]
public ICollectionGenObj<T>? this[string name]
{
get => _storages.ContainsKey(name) ? _storages[name] : null;
}
/// Сохранение информации по автомобилям в хранилище в файл
/// <param name="filename">Путь и имя файла</param>
/// <returns>true - сохранение прошло успешно,
/// false - ошибка при сохранении данных</returns>
public void SaveData(string filename)
{
if (_storages.Count == 0)
throw new NullReferenceException(" > No existing collections to save");
if (File.Exists(filename)) { File.Delete(filename); }
StringBuilder sb = new();
sb.Append(_collectionKey); // const
foreach (KeyValuePair<string, ICollectionGenObj<T>> pair in _storages)
{
sb.Append(Environment.NewLine); // не сохраняем пустые коллекции
if (pair.Value.Count == 0) { continue; }
sb.Append(pair.Key);
sb.Append(_separatorForKeyValue);
sb.Append(pair.Value.GetCollectionType);
sb.Append(_separatorForKeyValue);
sb.Append(pair.Value.MaxCount);
sb.Append(_separatorForKeyValue);
foreach (T? item in pair.Value.GetItems())
{
string data = item?.GetDataForSave() ?? string.Empty;
if (string.IsNullOrEmpty(data))
{
continue;
}
sb.Append(data);
sb.Append(_separatorItems);
}
}
using FileStream fs = new(filename, FileMode.Create);
byte[] info = new UTF8Encoding(true).GetBytes(sb.ToString());
fs.Write(info, 0, info.Length);
}
// Создание коллекции по типу
private static ICollectionGenObj<T>? CreateCollection(CollectionType collectionType)
{
return collectionType switch
{
CollectionType.Array => new ArrayGenObj<T>(),
CollectionType.List => new ListGenObj<T>(),
_ => null,
};
}
// Загрузка информации по кораблям в хранилище из файла
public void LoadData(string filename)
{
if (!File.Exists(filename)) throw new FileNotFoundException();
string bufferTextFromFile = "";
using (FileStream fs = new(filename, FileMode.Open))
{
byte[] b = new byte[fs.Length];
UTF8Encoding temp = new(true);
while (fs.Read(b, 0, b.Length) > 0)
{
bufferTextFromFile += temp.GetString(b);
}
}
string[] strs = bufferTextFromFile.Split(
new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
if (strs == null || strs.Length == 0)
throw new NullReferenceException("> No data to decode");
if (!strs[0].Equals(_collectionKey))
throw new InvalidDataException("> Incorrect data");
string[] companies = new string[strs.Length - 1];
for (int k = 1; k < strs.Length; k++)
{
companies[k - 1] = strs[k];
}
_storages.Clear();
foreach (string data in companies)
{
string[] record = data.Split(_separatorForKeyValue, StringSplitOptions.RemoveEmptyEntries);
if (record.Length != 4) // >
// key | collType | maxcount | all next inf > 4
{
continue;
}
CollectionType collectionType = (CollectionType)Enum.Parse(typeof(CollectionType), record[1]);
ICollectionGenObj<T>? collection = StorageCollection<T>.CreateCollection(collectionType);
if (collection == null)
throw new NullReferenceException("> Failed to create collection");
collection.MaxCount = Convert.ToInt32(record[2]);
string[] set = record[3].Split(_separatorItems,
StringSplitOptions.RemoveEmptyEntries);
foreach (string elem in set)
{
if (elem?.CreateDrawningCar() is T ship)
{
try
{
if (collection.Insert(ship) == -1)
throw new IndexOutOfRangeException(
"> Failed to add to collection : " + record[3]);
}
catch (CollectionOverflowException e)
{
throw new CollectionOverflowException("Collection overflowed", e);
}
}
}
_storages.Add(record[0], collection);
}
}
}