diff --git a/SabreTools.DatFiles.Test/DatFileTests.cs b/SabreTools.DatFiles.Test/DatFileTests.cs index 960ed013..93f845ba 100644 --- a/SabreTools.DatFiles.Test/DatFileTests.cs +++ b/SabreTools.DatFiles.Test/DatFileTests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using SabreTools.DatFiles.Formats; using SabreTools.DatItems; using SabreTools.DatItems.Formats; using SabreTools.Hashing; @@ -64,6 +65,48 @@ namespace SabreTools.DatFiles.Test #endregion + #region ClearEmpty + + [Fact] + public void ClearEmpty_Items() + { + Source source = new Source(0, source: null); + + Machine machine = new Machine(); + machine.SetFieldValue(Models.Metadata.Machine.NameKey, "game-1"); + + DatItem datItem = new Rom(); + datItem.SetFieldValue(DatItem.SourceKey, source); + datItem.SetFieldValue(DatItem.MachineKey, machine); + + DatFile datFile = new Logiqx(datFile: null, deprecated: false); + datFile.AddItem(datItem, statsOnly: false); + + datFile.ClearEmpty(); + Assert.Single(datFile.Items.SortedKeys); + } + + [Fact] + public void ClearEmpty_ItemsDB() + { + Source source = new Source(0, source: null); + + Machine machine = new Machine(); + machine.SetFieldValue(Models.Metadata.Machine.NameKey, "game-1"); + + DatItem datItem = new Rom(); + + DatFile datFile = new Logiqx(datFile: null, deprecated: false); + long sourceIndex = datFile.AddSourceDB(source); + long machineIndex = datFile.AddMachineDB(machine); + _ = datFile.AddItemDB(datItem, machineIndex, sourceIndex, statsOnly: false); + + datFile.ClearEmpty(); + Assert.Single(datFile.ItemsDB.SortedKeys); + } + + #endregion + #region FillHeaderFromPath [Fact] @@ -188,6 +231,24 @@ namespace SabreTools.DatFiles.Test #endregion + #region SetHeader + + [Fact] + public void SetHeaderTest() + { + DatHeader datHeader = new DatHeader(); + datHeader.SetFieldValue(Models.Metadata.Header.NameKey, "name"); + + DatFile? datFile = new Formats.Logiqx(datFile: null, deprecated: false); + datFile.Header.SetFieldValue(Models.Metadata.Header.NameKey, "notname"); + + datFile.SetHeader(datHeader); + Assert.NotNull(datFile.Header); + Assert.Equal("name", datFile.Header.GetStringFieldValue(Models.Metadata.Header.NameKey)); + } + + #endregion + #region ResetDictionary [Fact] @@ -209,24 +270,6 @@ namespace SabreTools.DatFiles.Test #endregion - #region SetHeader - - [Fact] - public void SetHeaderTest() - { - DatHeader datHeader = new DatHeader(); - datHeader.SetFieldValue(Models.Metadata.Header.NameKey, "name"); - - DatFile? datFile = new Formats.Logiqx(datFile: null, deprecated: false); - datFile.Header.SetFieldValue(Models.Metadata.Header.NameKey, "notname"); - - datFile.SetHeader(datHeader); - Assert.NotNull(datFile.Header); - Assert.Equal("name", datFile.Header.GetStringFieldValue(Models.Metadata.Header.NameKey)); - } - - #endregion - #region ProcessItemName [Theory] @@ -1952,7 +1995,7 @@ namespace SabreTools.DatFiles.Test [Fact] public void ShouldIgnore_UnsupportedType_True() { - DatItem? datItem = new SoftwareList(); + DatItem? datItem = new DatItems.Formats.SoftwareList(); DatFile datFile = new Formats.Logiqx(null, deprecated: false); bool actual = datFile.ShouldIgnore(datItem, ignoreBlanks: true); diff --git a/SabreTools.DatFiles/DatFile.cs b/SabreTools.DatFiles/DatFile.cs index 03f41249..2092fe72 100644 --- a/SabreTools.DatFiles/DatFile.cs +++ b/SabreTools.DatFiles/DatFile.cs @@ -128,6 +128,15 @@ namespace SabreTools.DatFiles #region Accessors + /// + /// Remove any keys that have null or empty values + /// + public void ClearEmpty() + { + ClearEmptyImpl(); + ClearEmptyImplDB(); + } + /// /// Set the internal header /// @@ -138,6 +147,42 @@ namespace SabreTools.DatFiles Header = datHeader; } + /// + /// Remove any keys that have null or empty values + /// + private void ClearEmptyImpl() + { + foreach (string key in Items.SortedKeys) + { + // If the value is empty, remove + List value = GetItemsForBucket(key); + if (value.Count == 0) + RemoveBucket(key); + + // If there are no non-blank items, remove + else if (value.FindIndex(i => i != null && i is not Blank) == -1) + RemoveBucket(key); + } + } + + /// + /// Remove any keys that have null or empty values + /// + private void ClearEmptyImplDB() + { + foreach (string key in ItemsDB.SortedKeys) + { + // If the value is empty, remove + List value = [.. GetItemsForBucketDB(key).Values]; + if (value.Count == 0) + RemoveBucketDB(key); + + // If there are no non-blank items, remove + else if (value.FindIndex(i => i != null && i is not Blank) == -1) + RemoveBucketDB(key); + } + } + #endregion #region Item Dictionary Passthrough - Accessors @@ -182,15 +227,6 @@ namespace SabreTools.DatFiles return ItemsDB.AddSource(source); } - /// - /// Remove any keys that have null or empty values - /// - public void ClearEmpty() - { - Items.ClearEmpty(); - ItemsDB.ClearEmpty(); - } - /// /// Remove all items marked for removal /// @@ -227,6 +263,15 @@ namespace SabreTools.DatFiles return Items.RemoveBucket(key); } + /// + /// Remove a key from the file dictionary if it exists + /// + /// Key in the dictionary to remove + public bool RemoveBucketDB(string key) + { + return ItemsDB.RemoveBucket(key); + } + /// /// Remove the first instance of a value from the file dictionary if it exists /// diff --git a/SabreTools.DatFiles/ItemDictionary.cs b/SabreTools.DatFiles/ItemDictionary.cs index f4dc26b2..41bf67ba 100644 --- a/SabreTools.DatFiles/ItemDictionary.cs +++ b/SabreTools.DatFiles/ItemDictionary.cs @@ -190,45 +190,10 @@ namespace SabreTools.DatFiles return key; } - /// - /// Remove any keys that have null or empty values - /// - internal void ClearEmpty() - { - foreach (string key in SortedKeys) - { -#if NET40_OR_GREATER || NETCOREAPP - // If the key doesn't exist, skip - if (!_items.TryGetValue(key, out var value)) - continue; - - // If the value is null, remove - else if (value == null) - _items.TryRemove(key, out _); - - // If there are no non-blank items, remove - else if (value!.FindIndex(i => i != null && i is not Blank) == -1) - _items.TryRemove(key, out _); -#else - // If the key doesn't exist, skip - if (!_items.ContainsKey(key)) - continue; - - // If the value is null, remove - else if (_items[key] == null) - _items.Remove(key); - - // If there are no non-blank items, remove - else if (_items[key]!.FindIndex(i => i != null && i is not Blank) == -1) - _items.Remove(key); -#endif - } - } - /// /// Remove all items marked for removal /// - internal void ClearMarked() + public void ClearMarked() { foreach (string key in SortedKeys) { diff --git a/SabreTools.DatFiles/ItemDictionaryDB.cs b/SabreTools.DatFiles/ItemDictionaryDB.cs index a37db95a..a55100aa 100644 --- a/SabreTools.DatFiles/ItemDictionaryDB.cs +++ b/SabreTools.DatFiles/ItemDictionaryDB.cs @@ -300,36 +300,10 @@ namespace SabreTools.DatFiles #endif } - /// - /// Remove any keys that have null or empty values - /// - internal void ClearEmpty() - { - var keys = Array.FindAll(SortedKeys, k => k != null); - foreach (string key in keys) - { - // Get items for the bucket - var items = GetItemsForBucket(key); - if (items == null || items.Count == 0) - continue; - - // Convert to list of indices for ease of access - List itemsList = [.. items.Values]; - - // If there are no non-blank items, remove - if (!itemsList.Exists(i => i != null && i is not Blank)) -#if NET40_OR_GREATER || NETCOREAPP - _buckets.TryRemove(key, out _); -#else - _buckets.Remove(key); -#endif - } - } - /// /// Remove all items marked for removal /// - internal void ClearMarked() + public void ClearMarked() { var itemIndices = _items.Keys; foreach (long itemIndex in itemIndices) @@ -565,6 +539,24 @@ namespace SabreTools.DatFiles } } + /// + /// Remove a key from the file dictionary if it exists + /// + /// Key in the dictionary to remove + public bool RemoveBucket(string key) + { +#if NET40_OR_GREATER || NETCOREAPP + return _buckets.TryRemove(key, out var list); +#else + if (!_buckets.ContainsKey(key)) + return false; + + var list = _buckets[key]; + _buckets.Remove(key); + return true; +#endif + } + /// /// Remove an item, returning if it could be removed /// diff --git a/SabreTools.Test/DatFiles/ItemDictionaryTests.cs b/SabreTools.Test/DatFiles/ItemDictionaryTests.cs index 9c60210e..51889524 100644 --- a/SabreTools.Test/DatFiles/ItemDictionaryTests.cs +++ b/SabreTools.Test/DatFiles/ItemDictionaryTests.cs @@ -61,17 +61,6 @@ namespace SabreTools.Test.DatFiles Assert.Equal(expected, dict.SortedKeys.Length); } - [Fact] - public void ClearEmptyTest() - { - // Setup the dictionary - var dict = new ItemDictionary(); - dict.AddItem("game-1", new Rom()); - - dict.ClearEmpty(); - Assert.Single(dict.SortedKeys); - } - [Fact] public void ClearMarkedTest() {