diff --git a/SabreTools.Library/DatFiles/AttractMode.cs b/SabreTools.Library/DatFiles/AttractMode.cs index dfb50cc3..1146dc3b 100644 --- a/SabreTools.Library/DatFiles/AttractMode.cs +++ b/SabreTools.Library/DatFiles/AttractMode.cs @@ -121,10 +121,13 @@ namespace SabreTools.Library.DatFiles return false; } - StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false)); + SeparatedValueWriter svw = new SeparatedValueWriter(fs, new UTF8Encoding(false)); + svw.Quotes = false; + svw.Separator = ";"; + svw.VerifyFieldCount = true; // Write out the header - WriteHeader(sw); + WriteHeader(svw); // Write out each of the machines and roms string lastgame = null; @@ -153,7 +156,7 @@ namespace SabreTools.Library.DatFiles // If we have a new game, output the beginning of the new item if (lastgame == null || lastgame.ToLowerInvariant() != item.MachineName.ToLowerInvariant()) - WriteDatItem(sw, item, ignoreblanks); + WriteDatItem(svw, item, ignoreblanks); // If we have a "null" game (created by DATFromDir or something similar), log it to file if (item.ItemType == ItemType.Rom @@ -172,7 +175,7 @@ namespace SabreTools.Library.DatFiles } Globals.Logger.Verbose($"File written!{Environment.NewLine}"); - sw.Dispose(); + svw.Dispose(); fs.Dispose(); } catch (Exception ex) @@ -187,31 +190,36 @@ namespace SabreTools.Library.DatFiles /// /// Write out DAT header using the supplied StreamWriter /// - /// StreamWriter to output to + /// SeparatedValueWriter to output to /// True if the data was written, false on error - private bool WriteHeader(StreamWriter sw) + private bool WriteHeader(SeparatedValueWriter svw) { try { - sw.Write("#Title;"); - sw.Write("Name;"); - sw.Write("Emulator;"); - sw.Write("CloneOf"); - sw.Write("Year;"); - sw.Write("Manufacturer;"); - sw.Write("Category;"); - sw.Write("Players;"); - sw.Write("Rotation;"); - sw.Write("Control;"); - sw.Write("Status;"); - sw.Write("DisplayCount;"); - sw.Write("DisplayType;"); - sw.Write("AltRomname;"); - sw.Write("AltTitle;"); - sw.Write("Extra;"); - sw.Write("Buttons\n"); + string[] headers = new string[] + { + "#Title", + "Name", + "Emulator", + "CloneOf", + "Year", + "Manufacturer", + "Category", + "Players", + "Rotation", + "Control", + "Status", + "DisplayCount", + "DisplayType", + "AltRomname", + "AltTitle", + "Extra", + "Buttons", + }; - sw.Flush(); + svw.WriteHeader(headers); + + svw.Flush(); } catch (Exception ex) { @@ -225,11 +233,11 @@ namespace SabreTools.Library.DatFiles /// /// Write out Game start using the supplied StreamWriter /// - /// StreamWriter to output to + /// SeparatedValueWriter to output to /// DatItem object to be output /// True if blank roms should be skipped on output, false otherwise (default) /// True if the data was written, false on error - private bool WriteDatItem(StreamWriter sw, DatItem datItem, bool ignoreblanks = false) + private bool WriteDatItem(SeparatedValueWriter svw, DatItem datItem, bool ignoreblanks = false) { // If we are in ignore blanks mode AND we have a blank (0-size) rom, skip if (ignoreblanks && (datItem.ItemType == ItemType.Rom && (((Rom)datItem).Size == 0 || ((Rom)datItem).Size == -1))) @@ -243,25 +251,30 @@ namespace SabreTools.Library.DatFiles // Pre-process the item name ProcessItemName(datItem, true); - sw.Write($"{datItem.GetField(Field.MachineName, ExcludeFields)};"); - sw.Write($"{datItem.GetField(Field.Description, ExcludeFields)};"); - sw.Write($"{FileName};"); - sw.Write($"{datItem.GetField(Field.CloneOf, ExcludeFields)};"); - sw.Write($"{datItem.GetField(Field.Year, ExcludeFields)};"); - sw.Write($"{datItem.GetField(Field.Manufacturer, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.Category, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.Players, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.Rotation, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.Control, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.Status, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.DisplayCount, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.DisplayType, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.AltRomname, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.AltTitle, ExcludeFields)};"); - sw.Write($"{datItem.GetField(Field.Comment, ExcludeFields)};"); - sw.Write(";"); // $"{datItem.GetField(Field.Buttons, ExcludeFields)};"); + string[] fields = new string[] + { + datItem.GetField(Field.MachineName, ExcludeFields), + datItem.GetField(Field.Description, ExcludeFields), + FileName, + datItem.GetField(Field.CloneOf, ExcludeFields), + datItem.GetField(Field.Year, ExcludeFields), + datItem.GetField(Field.Manufacturer, ExcludeFields), + string.Empty, // datItem.GetField(Field.Category, ExcludeFields) + string.Empty, // datItem.GetField(Field.Players, ExcludeFields) + string.Empty, // datItem.GetField(Field.Rotation, ExcludeFields) + string.Empty, // datItem.GetField(Field.Control, ExcludeFields) + string.Empty, // datItem.GetField(Field.Status, ExcludeFields) + string.Empty, // datItem.GetField(Field.DisplayCount, ExcludeFields) + string.Empty, // datItem.GetField(Field.DisplayType, ExcludeFields) + string.Empty, // datItem.GetField(Field.AltRomname, ExcludeFields) + string.Empty, // datItem.GetField(Field.AltTitle, ExcludeFields) + datItem.GetField(Field.Comment, ExcludeFields), + string.Empty, // datItem.GetField(Field.Buttons, ExcludeFields) + }; - sw.Flush(); + svw.WriteValues(fields); + + svw.Flush(); } catch (Exception ex) { diff --git a/SabreTools.Library/DatFiles/EverdriveSmdb.cs b/SabreTools.Library/DatFiles/EverdriveSmdb.cs index bdfeff54..30d71761 100644 --- a/SabreTools.Library/DatFiles/EverdriveSmdb.cs +++ b/SabreTools.Library/DatFiles/EverdriveSmdb.cs @@ -105,7 +105,10 @@ namespace SabreTools.Library.DatFiles return false; } - StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false)); + SeparatedValueWriter svw = new SeparatedValueWriter(fs, new UTF8Encoding(false)); + svw.Quotes = false; + svw.Separator = "\t"; + svw.VerifyFieldCount = true; // Get a properly sorted set of keys List keys = Keys; @@ -140,12 +143,12 @@ namespace SabreTools.Library.DatFiles ((Rom)item).Size = Constants.SizeZero; } - WriteDatItem(sw, item, ignoreblanks); + WriteDatItem(svw, item, ignoreblanks); } } Globals.Logger.Verbose($"File written!{Environment.NewLine}"); - sw.Dispose(); + svw.Dispose(); fs.Dispose(); } catch (Exception ex) @@ -160,10 +163,10 @@ namespace SabreTools.Library.DatFiles /// /// Write out Game start using the supplied StreamWriter /// - /// StreamWriter to output to + /// SeparatedValueWriter to output to /// DatItem object to be output /// True if the data was written, false on error - private bool WriteDatItem(StreamWriter sw, DatItem datItem, bool ignoreblanks = false) + private bool WriteDatItem(SeparatedValueWriter svw, DatItem datItem, bool ignoreblanks = false) { // If we are in ignore blanks mode AND we have a blank (0-size) rom, skip if (ignoreblanks && (datItem.ItemType == ItemType.Rom && ((datItem as Rom).Size == 0 || (datItem as Rom).Size == -1))) @@ -182,17 +185,23 @@ namespace SabreTools.Library.DatFiles { case ItemType.Rom: var rom = datItem as Rom; - sw.Write($"{rom.GetField(Field.SHA256, ExcludeFields)}\t"); - sw.Write($"{rom.GetField(Field.MachineName, ExcludeFields)}/\t"); - sw.Write($"{rom.GetField(Field.Name, ExcludeFields)}\t"); - sw.Write($"{rom.GetField(Field.SHA1, ExcludeFields)}\t"); - sw.Write($"{rom.GetField(Field.MD5, ExcludeFields)}\t"); - sw.Write($"{rom.GetField(Field.CRC, ExcludeFields)}"); - sw.Write("\n"); + + string[] fields = new string[] + { + rom.GetField(Field.SHA256, ExcludeFields), + $"{rom.GetField(Field.MachineName, ExcludeFields)}/", + rom.GetField(Field.Name, ExcludeFields), + rom.GetField(Field.SHA1, ExcludeFields), + rom.GetField(Field.MD5, ExcludeFields), + rom.GetField(Field.CRC, ExcludeFields), + }; + + svw.WriteValues(fields); + break; } - sw.Flush(); + svw.Flush(); } catch (Exception ex) { diff --git a/SabreTools.Library/DatFiles/Hashfile.cs b/SabreTools.Library/DatFiles/Hashfile.cs index fef382a7..9acd1197 100644 --- a/SabreTools.Library/DatFiles/Hashfile.cs +++ b/SabreTools.Library/DatFiles/Hashfile.cs @@ -121,7 +121,10 @@ namespace SabreTools.Library.DatFiles return false; } - StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false)); + SeparatedValueWriter svw = new SeparatedValueWriter(fs, new UTF8Encoding(false)); + svw.Quotes = false; + svw.Separator = " "; + svw.VerifyFieldCount = true; // Get a properly sorted set of keys List keys = Keys; @@ -154,12 +157,12 @@ namespace SabreTools.Library.DatFiles } // Now, output the rom data - WriteDatItem(sw, rom, ignoreblanks); + WriteDatItem(svw, rom, ignoreblanks); } } Globals.Logger.Verbose($"File written!{Environment.NewLine}"); - sw.Dispose(); + svw.Dispose(); fs.Dispose(); } catch (Exception ex) @@ -174,11 +177,11 @@ namespace SabreTools.Library.DatFiles /// /// Write out DatItem using the supplied StreamWriter /// - /// StreamWriter to output to + /// SeparatedValueWriter to output to /// DatItem object to be output /// True if blank roms should be skipped on output, false otherwise (default) /// True if the data was written, false on error - private bool WriteDatItem(StreamWriter sw, DatItem datItem, bool ignoreblanks = false) + private bool WriteDatItem(SeparatedValueWriter svw, DatItem datItem, bool ignoreblanks = false) { // If we are in ignore blanks mode AND we have a blank (0-size) rom, skip if (ignoreblanks && (datItem.ItemType == ItemType.Rom && ((datItem as Rom).Size == 0 || (datItem as Rom).Size == -1))) @@ -186,10 +189,8 @@ namespace SabreTools.Library.DatFiles try { - // Pre-process the item name - ProcessItemName(datItem, true); - // Build the state based on excluded fields + string[] fields = new string[2]; switch (_hash) { case Hash.CRC: @@ -197,11 +198,11 @@ namespace SabreTools.Library.DatFiles { case ItemType.Rom: var rom = datItem as Rom; + fields[0] = string.Empty; if (GameName) - sw.Write($"{rom.GetField(Field.MachineName, ExcludeFields)}{Path.DirectorySeparatorChar}"); - sw.Write($"{rom.GetField(Field.Name, ExcludeFields)}"); - sw.Write($"{rom.GetField(Field.CRC, ExcludeFields)}"); - sw.Write("\n"); + fields[0] = $"{rom.GetField(Field.MachineName, ExcludeFields)}{Path.DirectorySeparatorChar}"; + fields[0] += rom.GetField(Field.Name, ExcludeFields); + fields[1] = rom.GetField(Field.CRC, ExcludeFields); break; } break; @@ -218,26 +219,30 @@ namespace SabreTools.Library.DatFiles { case ItemType.Disk: var disk = datItem as Disk; - sw.Write($"{disk.GetField(hashField, ExcludeFields)}"); + fields[0] = disk.GetField(hashField, ExcludeFields); + fields[1] = string.Empty; if (GameName) - sw.Write($"{disk.GetField(Field.MachineName, ExcludeFields)}{Path.DirectorySeparatorChar}"); - sw.Write($"{disk.GetField(Field.Name, ExcludeFields)}"); - sw.Write("\n"); + fields[1] = $"{disk.GetField(Field.MachineName, ExcludeFields)}{Path.DirectorySeparatorChar}"; + fields[1] += disk.GetField(Field.Name, ExcludeFields); break; case ItemType.Rom: var rom = datItem as Rom; - sw.Write($"{rom.GetField(hashField, ExcludeFields)}"); + fields[0] = rom.GetField(hashField, ExcludeFields); + fields[1] = string.Empty; if (GameName) - sw.Write($"{rom.GetField(Field.MachineName, ExcludeFields)}{Path.DirectorySeparatorChar}"); - sw.Write($"{rom.GetField(Field.Name, ExcludeFields)}"); - sw.Write("\n"); + fields[1] = $"{rom.GetField(Field.MachineName, ExcludeFields)}{Path.DirectorySeparatorChar}"; + fields[1] += rom.GetField(Field.Name, ExcludeFields); break; } break; } - sw.Flush(); + // If we had at least one field filled in + if (!string.IsNullOrEmpty(fields[0]) || !string.IsNullOrEmpty(fields[1])) + svw.WriteValues(fields); + + svw.Flush(); } catch (Exception ex) { diff --git a/SabreTools.Library/DatFiles/SeparatedValue.cs b/SabreTools.Library/DatFiles/SeparatedValue.cs index ec441d86..a83df200 100644 --- a/SabreTools.Library/DatFiles/SeparatedValue.cs +++ b/SabreTools.Library/DatFiles/SeparatedValue.cs @@ -394,10 +394,13 @@ namespace SabreTools.Library.DatFiles return false; } - StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false)); + SeparatedValueWriter svw = new SeparatedValueWriter(fs, new UTF8Encoding(false)); + svw.Quotes = true; + svw.Separator = this._delim.ToString(); + svw.VerifyFieldCount = true; // Write out the header - WriteHeader(sw); + WriteHeader(svw); // Get a properly sorted set of keys List keys = Keys; @@ -430,12 +433,12 @@ namespace SabreTools.Library.DatFiles } // Now, output the rom data - WriteDatItem(sw, rom, ignoreblanks); + WriteDatItem(svw, rom, ignoreblanks); } } Globals.Logger.Verbose("File written!" + Environment.NewLine); - sw.Dispose(); + svw.Dispose(); fs.Dispose(); } catch (Exception ex) @@ -450,31 +453,36 @@ namespace SabreTools.Library.DatFiles /// /// Write out DAT header using the supplied StreamWriter /// - /// StreamWriter to output to + /// SeparatedValueWriter to output to /// True if the data was written, false on error - private bool WriteHeader(StreamWriter sw) + private bool WriteHeader(SeparatedValueWriter svw) { try { - sw.Write("\"File Name\"{_delim}"); - sw.Write("\"Internal Name\"{_delim}"); - sw.Write("\"Description\"{_delim}"); - sw.Write("\"Game Name\"{_delim}"); - sw.Write("\"Game Description\"{_delim}"); - sw.Write("\"Type\"{_delim}\""); - sw.Write("\"Rom Name\"{_delim}"); - sw.Write("\"Disk Name\"{_delim}"); - sw.Write("\"Size\"{_delim}"); - sw.Write("\"CRC\"{_delim}"); - sw.Write("\"MD5\"{_delim}"); - //sw.Write("\"RIPEMD160\"{_delim}"); - sw.Write("\"SHA1\"{_delim}"); - sw.Write("\"SHA256\"{_delim}"); - //sw.Write("\"SHA384\"{_delim}"); - //sw.Write("\"SHA512\"{_delim}"); - sw.Write("\"Nodump\"\n"); + string[] headers = new string[] + { + "File Name", + "Internal Name", + "Description", + "Game Name", + "Game Description", + "Type", + "Rom Name", + "Disk Name", + "Size", + "CRC", + "MD5", + //"RIPEMD160", + "SHA1", + "SHA256", + //"SHA384", + //"SHA512", + "Nodump", + }; - sw.Flush(); + svw.WriteHeader(headers); + + svw.Flush(); } catch (Exception ex) { @@ -488,11 +496,11 @@ namespace SabreTools.Library.DatFiles /// /// Write out DatItem using the supplied StreamWriter /// - /// StreamWriter to output to + /// SeparatedValueWriter to output to /// DatItem object to be output /// True if blank roms should be skipped on output, false otherwise (default) /// True if the data was written, false on error - private bool WriteDatItem(StreamWriter sw, DatItem datItem, bool ignoreblanks = false) + private bool WriteDatItem(SeparatedValueWriter svw, DatItem datItem, bool ignoreblanks = false) { // If we are in ignore blanks mode AND we have a blank (0-size) rom, skip if (ignoreblanks && (datItem.ItemType == ItemType.Rom && ((datItem as Rom).Size == 0 || (datItem as Rom).Size == -1))) @@ -504,52 +512,55 @@ namespace SabreTools.Library.DatFiles if (datItem.ItemType != ItemType.Disk && datItem.ItemType != ItemType.Rom) return true; - sw.Write(CreatePrefixPostfix(datItem, true)); - - sw.Write($"\"{FileName}\"{_delim}"); - sw.Write($"\"{Name}\"{_delim}"); - sw.Write($"\"{Description}\"{_delim}"); - sw.Write($"\"{datItem.GetField(Field.MachineName, ExcludeFields)}\"{_delim}"); - sw.Write($"\"{datItem.GetField(Field.Description, ExcludeFields)}\"{_delim}"); + // Build the state based on excluded fields + string[] fields = new string[14]; // 17; + fields[0] = FileName; + fields[1] = Name; + fields[2] = Description; + fields[3] = datItem.GetField(Field.MachineName, ExcludeFields); + fields[4] = datItem.GetField(Field.Description, ExcludeFields); switch (datItem.ItemType) { case ItemType.Disk: var disk = datItem as Disk; - sw.Write($"\"disk\"{_delim}"); - sw.Write($"\"\"{_delim}"); - sw.Write($"\"{disk.GetField(Field.Name, ExcludeFields)}\"{_delim}"); - sw.Write($"\"\"{_delim}"); - sw.Write($"\"\"{_delim}"); - sw.Write($"\"{disk.GetField(Field.MD5, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - //sw.Write($"\"{disk.GetField(Field.RIPEMD160, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - sw.Write($"\"{disk.GetField(Field.SHA1, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - sw.Write($"\"{disk.GetField(Field.SHA256, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - //sw.Write($"\"{disk.GetField(Field.SHA384, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - //sw.Write($"\"{disk.GetField(Field.SHA512, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - sw.Write($"\"{disk.GetField(Field.Status, ExcludeFields)}\"{_delim}"); + fields[5] = "disk"; + fields[6] = string.Empty; + fields[7] = disk.GetField(Field.Name, ExcludeFields); + fields[8] = string.Empty; + fields[9] = string.Empty; + fields[10] = disk.GetField(Field.MD5, ExcludeFields).ToLowerInvariant(); + //fields[11] = disk.GetField(Field.RIPEMD160, ExcludeFields).ToLowerInvariant(); + fields[11] = disk.GetField(Field.SHA1, ExcludeFields).ToLowerInvariant(); + fields[12] = disk.GetField(Field.SHA256, ExcludeFields).ToLowerInvariant(); + //fields[13] = disk.GetField(Field.SHA384, ExcludeFields).ToLowerInvariant(); + //fields[14] = disk.GetField(Field.SHA512, ExcludeFields).ToLowerInvariant(); + fields[13] = disk.GetField(Field.Status, ExcludeFields); break; case ItemType.Rom: var rom = datItem as Rom; - sw.Write($"\"rom\"{_delim}"); - sw.Write($"\"{rom.GetField(Field.Name, ExcludeFields)}\"{_delim}"); - sw.Write($"\"\"{_delim}"); - sw.Write($"\"{rom.GetField(Field.Size, ExcludeFields)}\"{_delim}"); - sw.Write($"\"{rom.GetField(Field.CRC, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - sw.Write($"\"{rom.GetField(Field.MD5, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - //sw.Write($"\"{rom.GetField(Field.RIPEMD160, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - sw.Write($"\"{rom.GetField(Field.SHA1, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - sw.Write($"\"{rom.GetField(Field.SHA256, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - //sw.Write($"\"{rom.GetField(Field.SHA384, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - //sw.Write($"\"{rom.GetField(Field.SHA512, ExcludeFields).ToLowerInvariant()}\"{_delim}"); - sw.Write($"\"{rom.GetField(Field.Status, ExcludeFields)}\"{_delim}"); + fields[5] = "rom"; + fields[6] = rom.GetField(Field.Name, ExcludeFields); + fields[7] = string.Empty; + fields[8] = rom.GetField(Field.Size, ExcludeFields); + fields[9] = rom.GetField(Field.CRC, ExcludeFields).ToLowerInvariant(); + fields[10] = rom.GetField(Field.MD5, ExcludeFields).ToLowerInvariant(); + //fields[11] = rom.GetField(Field.RIPEMD160, ExcludeFields).ToLowerInvariant(); + fields[11] = rom.GetField(Field.SHA1, ExcludeFields).ToLowerInvariant(); + fields[12] = rom.GetField(Field.SHA256, ExcludeFields).ToLowerInvariant(); + //fields[13] = rom.GetField(Field.SHA384, ExcludeFields).ToLowerInvariant(); + //fields[14] = rom.GetField(Field.SHA512, ExcludeFields).ToLowerInvariant(); + fields[13] = rom.GetField(Field.Status, ExcludeFields); break; } - sw.Write(CreatePrefixPostfix(datItem, false)); + svw.WriteString(CreatePrefixPostfix(datItem, true)); + svw.WriteValues(fields, false); + svw.WriteString(CreatePrefixPostfix(datItem, false)); + svw.WriteLine(); - sw.Flush(); + svw.Flush(); } catch (Exception ex) { diff --git a/SabreTools.Library/DatItems/DatItem.cs b/SabreTools.Library/DatItems/DatItem.cs index 065af240..3075e698 100644 --- a/SabreTools.Library/DatItems/DatItem.cs +++ b/SabreTools.Library/DatItems/DatItem.cs @@ -572,166 +572,191 @@ namespace SabreTools.Library.DatItems if (excludeFields[(int)field]) return string.Empty; + string fieldValue = null; switch (field) { case Field.Name: - return this.Name; + fieldValue = this.Name; + break; case Field.PartName: - return this.PartName; + fieldValue = this.PartName; + break; case Field.PartInterface: - return this.PartInterface; + fieldValue = this.PartInterface; + break; case Field.Features: - return string.Join(", ", this.Features.Select(f => $"{f.Item1}={f.Item2}")); + fieldValue = string.Join(", ", (this.Features ?? new List>()).Select(f => $"{f.Item1}={f.Item2}")); + break; case Field.AreaName: - return this.AreaName; + fieldValue = this.AreaName; + break; case Field.AreaSize: - return this.AreaSize?.ToString() ?? string.Empty; + fieldValue = this.AreaSize?.ToString(); + break; case Field.MachineName: - return this.MachineName; + fieldValue = this.MachineName; + break; case Field.Comment: - return this.Comment; + fieldValue = this.Comment; + break; case Field.Description: - return this.MachineDescription; + fieldValue = this.MachineDescription; + break; case Field.Year: - return this.Year; + fieldValue = this.Year; + break; case Field.Manufacturer: - return this.Manufacturer; + fieldValue = this.Manufacturer; + break; case Field.Publisher: - return this.Publisher; + fieldValue = this.Publisher; + break; case Field.RomOf: - return this.RomOf; + fieldValue = this.RomOf; + break; case Field.CloneOf: - return this.CloneOf; + fieldValue = this.CloneOf; + break; case Field.SampleOf: - return this.SampleOf; + fieldValue = this.SampleOf; + break; case Field.Supported: - return this.Supported?.ToString() ?? string.Empty; + fieldValue = this.Supported?.ToString(); + break; case Field.SourceFile: - return this.SourceFile; + fieldValue = this.SourceFile; + break; case Field.Runnable: - return this.Runnable?.ToString() ?? string.Empty; + fieldValue = this.Runnable?.ToString(); + break; case Field.Board: - return this.Board; + fieldValue = this.Board; + break; case Field.RebuildTo: - return this.RebuildTo; + fieldValue = this.RebuildTo; + break; case Field.Devices: - return string.Join(", ", this.Devices); + fieldValue = string.Join(", ", this.Devices ?? new List()); + break; case Field.SlotOptions: - return string.Join(", ", this.SlotOptions); + fieldValue = string.Join(", ", this.SlotOptions ?? new List()); + break; case Field.Infos: - return string.Join(", ", this.Infos.Select(i => $"{i.Item1}={i.Item2}")); + fieldValue = string.Join(", ", (this.Infos ?? new List>()).Select(i => $"{i.Item1}={i.Item2}")); + break; case Field.MachineType: - return this.MachineType.ToString(); + fieldValue = this.MachineType.ToString(); + break; case Field.Default: if (ItemType == ItemType.BiosSet) - return (this as BiosSet).Default?.ToString() ?? string.Empty; + fieldValue = (this as BiosSet).Default?.ToString(); else if (ItemType == ItemType.Release) - return (this as Release).Default?.ToString() ?? string.Empty; + fieldValue = (this as Release).Default?.ToString(); break; case Field.BiosDescription: if (ItemType == ItemType.BiosSet) - return (this as BiosSet).Description; + fieldValue = (this as BiosSet).Description; break; case Field.MD5: if (ItemType == ItemType.Disk) - return (this as Disk).MD5; + fieldValue = (this as Disk).MD5; else if (ItemType == ItemType.Rom) - return (this as Rom).MD5; + fieldValue = (this as Rom).MD5; break; case Field.RIPEMD160: if (ItemType == ItemType.Disk) - return (this as Disk).RIPEMD160; + fieldValue = (this as Disk).RIPEMD160; else if (ItemType == ItemType.Rom) - return (this as Rom).RIPEMD160; + fieldValue = (this as Rom).RIPEMD160; break; case Field.SHA1: if (ItemType == ItemType.Disk) - return (this as Disk).SHA1; + fieldValue = (this as Disk).SHA1; else if (ItemType == ItemType.Rom) - return (this as Rom).SHA1; + fieldValue = (this as Rom).SHA1; break; case Field.SHA256: if (ItemType == ItemType.Disk) - return (this as Disk).SHA256; + fieldValue = (this as Disk).SHA256; else if (ItemType == ItemType.Rom) - return (this as Rom).SHA256; + fieldValue = (this as Rom).SHA256; break; case Field.SHA384: if (ItemType == ItemType.Disk) - return (this as Disk).SHA384; + fieldValue = (this as Disk).SHA384; else if (ItemType == ItemType.Rom) - return (this as Rom).SHA384; + fieldValue = (this as Rom).SHA384; break; case Field.SHA512: if (ItemType == ItemType.Disk) - return (this as Disk).SHA512; + fieldValue = (this as Disk).SHA512; else if (ItemType == ItemType.Rom) - return (this as Rom).SHA512; + fieldValue = (this as Rom).SHA512; break; case Field.Merge: if (ItemType == ItemType.Disk) - return (this as Disk).MergeTag; + fieldValue = (this as Disk).MergeTag; else if (ItemType == ItemType.Rom) - return (this as Rom).MergeTag; + fieldValue = (this as Rom).MergeTag; break; case Field.Region: if (ItemType == ItemType.Disk) - return (this as Disk).Region; + fieldValue = (this as Disk).Region; else if (ItemType == ItemType.Release) - return (this as Release).Region; + fieldValue = (this as Release).Region; else if (ItemType == ItemType.Rom) - return (this as Rom).Region; + fieldValue = (this as Rom).Region; break; case Field.Index: if (ItemType == ItemType.Disk) - return (this as Disk).Index; + fieldValue = (this as Disk).Index; break; case Field.Writable: if (ItemType == ItemType.Disk) - return (this as Disk).Writable?.ToString() ?? string.Empty; + fieldValue = (this as Disk).Writable?.ToString(); break; case Field.Optional: if (ItemType == ItemType.Disk) - return (this as Disk).Optional?.ToString() ?? string.Empty; + fieldValue = (this as Disk).Optional?.ToString(); else if (ItemType == ItemType.Rom) - return (this as Rom).Optional?.ToString() ?? string.Empty; + fieldValue = (this as Rom).Optional?.ToString(); break; case Field.Status: if (ItemType == ItemType.Disk) - return (this as Disk).ItemStatus.ToString(); + fieldValue = (this as Disk).ItemStatus.ToString(); else if (ItemType == ItemType.Rom) - return (this as Rom).ItemStatus.ToString(); + fieldValue = (this as Rom).ItemStatus.ToString(); break; case Field.Language: if (ItemType == ItemType.Release) - return (this as Release).Language; + fieldValue = (this as Release).Language; break; case Field.Date: if (ItemType == ItemType.Release) - return (this as Release).Date; + fieldValue = (this as Release).Date; else if (ItemType == ItemType.Rom) - return (this as Rom).Date; + fieldValue = (this as Rom).Date; break; case Field.Bios: if (ItemType == ItemType.Rom) - return (this as Rom).Bios; + fieldValue = (this as Rom).Bios; break; case Field.Size: if (ItemType == ItemType.Rom) - return (this as Rom).Size.ToString(); + fieldValue = (this as Rom).Size.ToString(); break; case Field.CRC: if (ItemType == ItemType.Rom) - return (this as Rom).CRC; + fieldValue = (this as Rom).CRC; break; case Field.Offset: if (ItemType == ItemType.Rom) - return (this as Rom).Offset; + fieldValue = (this as Rom).Offset; break; case Field.NULL: @@ -739,7 +764,11 @@ namespace SabreTools.Library.DatItems return string.Empty; } - return string.Empty; + // Make sure we don't return null + if (string.IsNullOrEmpty(fieldValue)) + fieldValue = string.Empty; + + return fieldValue; } #endregion diff --git a/SabreTools.Library/Tools/SeparatedValueWriter.cs b/SabreTools.Library/Tools/SeparatedValueWriter.cs index a7a9f475..760cb475 100644 --- a/SabreTools.Library/Tools/SeparatedValueWriter.cs +++ b/SabreTools.Library/Tools/SeparatedValueWriter.cs @@ -72,7 +72,7 @@ namespace SabreTools.Library.Tools /// /// Write a value row /// - public void WriteValues(object[] values) + public void WriteValues(object[] values, bool newline = true) { // If the writer can't be used, we error if (sw == null || !sw.BaseStream.CanWrite) @@ -106,7 +106,7 @@ namespace SabreTools.Library.Tools if (Quotes) sw.Write("\""); - sw.Write(value.ToString()); + sw.Write(value?.ToString() ?? string.Empty); if (Quotes) sw.Write("\""); @@ -125,10 +125,35 @@ namespace SabreTools.Library.Tools } } - // Add a newline - sw.WriteLine(); + // Add a newline, if needed + if (newline) + sw.WriteLine(); + } - // Flush the buffer + /// + /// Write a generic string + /// + public void WriteString(string value) + { + if (string.IsNullOrEmpty(value)) + return; + + sw.Write(value); + } + + /// + /// Write a newline + /// + public void WriteLine() + { + sw.WriteLine(); + } + + /// + /// Flush the underlying writer + /// + public void Flush() + { sw.Flush(); }