using System.CodeDom; using System.Text; using ProjectCruiser.DrawningSamples; namespace ProjectCruiser.CollectionGenericObj; public class StorageCollection where T : DrawningBase // class { private readonly string _separatorForKeyValue = "|"; private readonly string _separatorItems = ";"; private readonly string _collectionKey = "CollectionsStorage"; // Словарь (хранилище) с коллекциями < CollectionInfo, type (class) > readonly Dictionary> _storages; // Возвращение списка коллекций public List Keys => _storages.Keys.ToList(); public StorageCollection() { _storages = new Dictionary>(); } // Добавление коллекции в хранилище public void AddCollection(string name, CollectionType collType) { // descroption [ ? ] >>> CollectionInfo coll = new CollectionInfo(name, collType, string.Empty); if (name == null || _storages.ContainsKey(coll) || collType == CollectionType.None) { throw new NullReferenceException("> Not enough information to save"); } _storages.Add(coll, CreateCollection(collType)); } // Удаление коллекции ( по ключу-строке - её имени ) public void DelCollection(string name) { // descroption [ ? ] >>> CollectionInfo coll = new CollectionInfo(name, CollectionType.None, string.Empty); if (_storages.ContainsKey(coll)) _storages.Remove(coll); else throw new NullReferenceException("> No such key in the list"); } // Доступ к коллекции , индексатор [!!!] public ICollectionGenObj? this[string name] { get => _storages.ContainsKey(new CollectionInfo(name, CollectionType.None, string.Empty)) ? _storages[new CollectionInfo(name, CollectionType.None, string.Empty)] : null; } /// Сохранение информации по автомобилям в хранилище в файл /// Путь и имя файла /// true - сохранение прошло успешно, /// false - ошибка при сохранении данных 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> pair in _storages) { sb.Append(Environment.NewLine); // не сохраняем пустые коллекции if (pair.Value.Count == 0) { continue; } sb.Append(pair.Key); 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? CreateCollection(CollectionType collectionType) { return collectionType switch { CollectionType.Array => new ArrayGenObj(), CollectionType.List => new ListGenObj(), _ => null, }; } // Загрузка информации по кораблям в хранилище из файла public void LoadData(string filename) { if (!File.Exists(filename)) throw new FileNotFoundException("> No such file"); 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 != 3) // > // [key + collType] | maxcount | all next inf > 4 { continue; } CollectionInfo? collInfo = CollectionInfo.GetCollectionInfo(record[0]) ?? throw new Exception("[!] Failed to decode information : " + record[0]); ICollectionGenObj? collection = StorageCollection.CreateCollection( collInfo.CollectionType) ?? throw new Exception("[!] Failed to create a collection"); collection.MaxCount = Convert.ToInt32(record[1]); string[] set = record[2].Split(_separatorItems, StringSplitOptions.RemoveEmptyEntries); foreach (string elem in set) { if (elem?.CreateDrawningCar() is T ship) { try { collection.Insert(ship); } catch (Exception e) { throw new Exception(e.Message); } } } _storages.Add(collInfo, collection); } } }