From 0447c93479c398bb7b6cd3fb55a3efd94b87195f Mon Sep 17 00:00:00 2001 From: Alexey 'Cluster' Avdyukhin Date: Fri, 4 Nov 2022 17:15:02 +0400 Subject: Nullable types --- NesContainers.csproj | 2 +- UnifFile.cs | 68 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/NesContainers.csproj b/NesContainers.csproj index fbc4df3..81ec233 100644 --- a/NesContainers.csproj +++ b/NesContainers.csproj @@ -4,7 +4,7 @@ netstandard2.0 NesContainers com.clusterrr.Famicom.Containers - 11 + 10.0 embedded True NesContainers.xml diff --git a/UnifFile.cs b/UnifFile.cs index e1d9bad..58d25bb 100644 --- a/UnifFile.cs +++ b/UnifFile.cs @@ -29,30 +29,43 @@ namespace com.clusterrr.Famicom.Containers /// /// UNIF data block key /// - public IEnumerable? this[string key] + public IEnumerable this[string key] { get { if (key.Length != 4) throw new ArgumentException("UNIF data block key must be 4 characters long"); - if (!fields.ContainsKey(key)) return null; + if (!fields.ContainsKey(key)) throw new IndexOutOfRangeException($"There is not {key} field"); return Array.AsReadOnly(fields[key]); } set { if (key.Length != 4) throw new ArgumentException("UNIF data block key must be 4 characters long"); - if (value == null && fields.ContainsKey(key)) - fields.Remove(key); + if (value == null) + this.RemoveField(key); else fields[key] = (value ?? new byte[0]).ToArray(); } } + /// + /// Returns true if field exists in the UNIF + /// + /// Field code + /// True if field exists in the UNIF + public bool ContainsField(string fieldName) => fields.ContainsKey(fieldName); + + /// + /// Remove field from the UNIF + /// + /// + public void RemoveField(string fieldName) => fields.Remove(fieldName); + /// /// Returns enumerator that iterates throught fields /// /// IEnumerable object public IEnumerator>> GetEnumerator() - => fields.Select(kv => new KeyValuePair>(kv.Key, Array.AsReadOnly(kv.Value))).GetEnumerator(); + => fields.Select(kv => new KeyValuePair>(kv.Key, Array.AsReadOnly(kv.Value))).GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); @@ -151,9 +164,8 @@ namespace com.clusterrr.Famicom.Containers /// /// Input text /// Output byte[] array - private static byte[]? StringToUTF8N(string? text) + private static byte[] StringToUTF8N(string text) { - if (text == null) return null; var str = Encoding.UTF8.GetBytes(text); var result = new byte[str.Length + 1]; Array.Copy(str, result, str.Length); @@ -181,8 +193,13 @@ namespace com.clusterrr.Famicom.Containers /// public string? Mapper { - get => UTF8NToString(fields["MAPR"]); - set => fields["MAPR"] = value == null ? null : StringToUTF8N(value); + get => UTF8NToString(this["MAPR"]?.ToArray()); + set { + if (value == null) + RemoveField("MAPR"); + else + this["MAPR"] = StringToUTF8N(value); + } } /// @@ -194,7 +211,7 @@ namespace com.clusterrr.Famicom.Containers get => UTF8NToString(fields["DINF"], 100); set { - if (this["DINF"] == null) + if (!ContainsField("DINF")) this["DINF"] = new byte[204]; var data = this["DINF"].ToArray(); for (int i = 0; i < 100; i++) @@ -216,7 +233,7 @@ namespace com.clusterrr.Famicom.Containers get => UTF8NToString(fields["DINF"], 100, 104); set { - if (this["DINF"] == null) + if (!ContainsField("DINF")) this["DINF"] = new byte[204]; var data = this["DINF"].ToArray(); for (int i = 104; i < 104 + 100; i++) @@ -237,10 +254,8 @@ namespace com.clusterrr.Famicom.Containers { get { - var data = this["DINF"]?.ToArray(); - if (data == null) return null; - if (!fields.ContainsKey("DINF")) - return new DateTime(); + if (!ContainsField("DINF")) return null; + var data = this["DINF"].ToArray(); return new DateTime( year: data[102] | (data[103] << 8), month: data[101], @@ -249,7 +264,7 @@ namespace com.clusterrr.Famicom.Containers } set { - if (this["DINF"] == null) + if (!ContainsField("DINF")) this["DINF"] = new byte[204]; if (value != null) { @@ -269,7 +284,13 @@ namespace com.clusterrr.Famicom.Containers public string? GameName { get => UTF8NToString(this["NAME"]?.ToArray()); - set => this["NAME"] = StringToUTF8N(value); + set + { + if (value == null) + RemoveField("NAME"); + else + this["NAME"] = StringToUTF8N(value!); + } } /// @@ -279,9 +300,8 @@ namespace com.clusterrr.Famicom.Containers { get { - var data = this["TVCI"]; - if (data != null && data.Any()) - return (NesFile.Timing)data.First(); + if (ContainsField("TVCI") && this["TVCI"].Any()) + return (NesFile.Timing)this["TVCI"].First(); else return NesFile.Timing.Ntsc; } @@ -298,7 +318,7 @@ namespace com.clusterrr.Famicom.Containers { get { - if (this["CTRL"]?.Any() == true) + if (ContainsField("CTRL") && this["CTRL"].Any()) return (Controller)this["CTRL"].First(); else return Controller.None; @@ -316,7 +336,7 @@ namespace com.clusterrr.Famicom.Containers { get { - if (this["BATR"]?.Any() == true) + if (ContainsField("BATR") && this["BATR"].Any()) return this["BATR"].First() != 0; else return false; @@ -334,8 +354,8 @@ namespace com.clusterrr.Famicom.Containers { get { - if (this["MIRR"]?.Any() == true) - return (MirroringType)fields["MIRR"].First(); + if (ContainsField("MIRR") && this["MIRR"].Any()) + return (MirroringType)this["MIRR"].First(); else return MirroringType.Unknown; } -- cgit v1.2.3