From d1d4ff41c698fd06a57a762255d168267c82f879 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 16 Sep 2020 13:41:00 -0700 Subject: [PATCH] Fix reading (assumes reasonably sized cuesheets) --- DICUI.Library/CueSheets/CueFile.cs | 21 +++-- DICUI.Library/CueSheets/CueSheet.cs | 120 +++++++++++++++------------- DICUI.Library/CueSheets/CueTrack.cs | 17 ++-- 3 files changed, 87 insertions(+), 71 deletions(-) diff --git a/DICUI.Library/CueSheets/CueFile.cs b/DICUI.Library/CueSheets/CueFile.cs index bd0bfda3..80642e67 100644 --- a/DICUI.Library/CueSheets/CueFile.cs +++ b/DICUI.Library/CueSheets/CueFile.cs @@ -69,19 +69,23 @@ namespace DICUI.CueSheets /// /// File name to set /// File type to set - /// StreamReader to pull from - public CueFile(string fileName, string fileType, StreamReader sr) + /// Lines array to pull from + /// Reference to index in array + public CueFile(string fileName, string fileType, string[] cueLines, ref int i) { - if (sr == null) - return; + if (cueLines == null || i < 0 || i > cueLines.Length) + return; // TODO: Make this throw an exception // Set the current fields - this.FileName = fileName; + this.FileName = fileName.Trim('"'); this.FileType = GetFileType(fileType); - while (!sr.EndOfStream) + // Increment to start + i++; + + for (; i < cueLines.Length; i++) { - string line = sr.ReadLine().Trim(); + string line = cueLines[i].Trim(); string[] splitLine = line.Split(' '); // If we have an empty line, we skip @@ -103,7 +107,7 @@ namespace DICUI.CueSheets if (this.Tracks == null) this.Tracks = new List(); - var track = new CueTrack(splitLine[1], splitLine[2], sr); + var track = new CueTrack(splitLine[1], splitLine[2], cueLines, ref i); if (track == default) continue; // TODO: Make this throw an exception @@ -112,6 +116,7 @@ namespace DICUI.CueSheets // Default means return default: + i--; return; } } diff --git a/DICUI.Library/CueSheets/CueSheet.cs b/DICUI.Library/CueSheets/CueSheet.cs index 952d1ad7..e7e71241 100644 --- a/DICUI.Library/CueSheets/CueSheet.cs +++ b/DICUI.Library/CueSheets/CueSheet.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Text.RegularExpressions; /// /// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf @@ -68,79 +70,83 @@ namespace DICUI.CueSheets } // Open the file and begin reading - using (var sr = new StreamReader(filename)) + string[] cueLines = File.ReadAllLines(filename); + for (int i = 0; i < cueLines.Length; i++) { - while (!sr.EndOfStream) + string line = cueLines[i].Trim(); + + // http://stackoverflow.com/questions/554013/regular-expression-to-split-on-spaces-unless-in-quotes + string[] splitLine = Regex + .Matches(line, @"[^\s""]+|""[^""]*""") + .Cast() + .Select(m => m.Groups[0].Value) + .ToArray(); + + // If we have an empty line, we skip + if (string.IsNullOrWhiteSpace(line)) + continue; + + switch (splitLine[0]) { - string line = sr.ReadLine().Trim(); - string[] splitLine = line.Split(' '); + // Read comments + case "REM": + // We ignore all comments for now + break; - // If we have an empty line, we skip - if (string.IsNullOrWhiteSpace(line)) - continue; + // Read MCN + case "CATALOG": + if (splitLine.Length < 2) + continue; // TODO: Make this throw an exception - switch (splitLine[0]) - { - // Read comments - case "REM": - // We ignore all comments for now - break; + this.Catalog = splitLine[1]; + break; - // Read MCN - case "CATALOG": - if (splitLine.Length < 2) - continue; // TODO: Make this throw an exception + // Read external CD-Text file path + case "CDTEXTFILE": + if (splitLine.Length < 2) + continue; // TODO: Make this throw an exception - this.Catalog = splitLine[1]; - break; + this.CdTextFile = splitLine[1]; + break; - // Read external CD-Text file path - case "CDTEXTFILE": - if (splitLine.Length < 2) - continue; // TODO: Make this throw an exception + // Read CD-Text enhanced performer + case "PERFORMER": + if (splitLine.Length < 2) + continue; // TODO: Make this throw an exception - this.CdTextFile = splitLine[1]; - break; + this.Performer = splitLine[1]; + break; - // Read CD-Text enhanced performer - case "PERFORMER": - if (splitLine.Length < 2) - continue; // TODO: Make this throw an exception + // Read CD-Text enhanced songwriter + case "SONGWRITER": + if (splitLine.Length < 2) + continue; // TODO: Make this throw an exception - this.Performer = splitLine[1]; - break; + this.Songwriter = splitLine[1]; + break; - // Read CD-Text enhanced songwriter - case "SONGWRITER": - if (splitLine.Length < 2) - continue; // TODO: Make this throw an exception + // Read CD-Text enhanced title + case "TITLE": + if (splitLine.Length < 2) + continue; // TODO: Make this throw an exception - this.Songwriter = splitLine[1]; - break; + this.Title = splitLine[1]; + break; - // Read CD-Text enhanced title - case "TITLE": - if (splitLine.Length < 2) - continue; // TODO: Make this throw an exception + // Read file information + case "FILE": + if (splitLine.Length < 3) + continue; // TODO: Make this throw an exception - this.Title = splitLine[1]; - break; + if (this.Files == null) + this.Files = new List(); - // Read file information - case "FILE": - if (splitLine.Length < 3) - continue; // TODO: Make this throw an exception + var file = new CueFile(splitLine[1], splitLine[2], cueLines, ref i); + if (file == default) + continue; // TODO: Make this throw an exception - if (this.Files == null) - this.Files = new List(); - - var file = new CueFile(splitLine[1], splitLine[2], sr); - if (file == default) - continue; // TODO: Make this throw an exception - - this.Files.Add(file); - break; - } + this.Files.Add(file); + break; } } } diff --git a/DICUI.Library/CueSheets/CueTrack.cs b/DICUI.Library/CueSheets/CueTrack.cs index 72b46cb3..7f9b80f4 100644 --- a/DICUI.Library/CueSheets/CueTrack.cs +++ b/DICUI.Library/CueSheets/CueTrack.cs @@ -154,11 +154,12 @@ namespace DICUI.CueSheets /// /// Number to set /// Data type to set - /// StreamReader to pull from - public CueTrack(string number, string dataType, StreamReader sr) + /// Lines array to pull from + /// Reference to index in array + public CueTrack(string number, string dataType, string[] cueLines, ref int i) { - if (sr == null) - return; + if (cueLines == null || i < 0 || i > cueLines.Length) + return; // TODO: Make this throw an exception // Set the current fields if (!int.TryParse(number, out int parsedNumber)) @@ -169,9 +170,12 @@ namespace DICUI.CueSheets this.Number = parsedNumber; this.DataType = GetDataType(dataType); - while (!sr.EndOfStream) + // Increment to start + i++; + + for (; i < cueLines.Length; i++) { - string line = sr.ReadLine().Trim(); + string line = cueLines[i].Trim(); string[] splitLine = line.Split(' '); // If we have an empty line, we skip @@ -266,6 +270,7 @@ namespace DICUI.CueSheets // Default means return default: + i--; return; } }