Add throwability to cuesheet code

This commit is contained in:
Matt Nadareski
2021-06-03 21:58:52 -07:00
parent 1c9ebfd703
commit ab5869331b
6 changed files with 403 additions and 76 deletions

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
/// <remarks>
@@ -71,10 +72,23 @@ namespace MPF.CueSheets
/// <param name="fileType">File type to set</param>
/// <param name="cueLines">Lines array to pull from</param>
/// <param name="i">Reference to index in array</param>
public CueFile(string fileName, string fileType, string[] cueLines, ref int i)
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public CueFile(string fileName, string fileType, string[] cueLines, ref int i, bool throwOnError = false)
{
if (cueLines == null || i < 0 || i > cueLines.Length)
return; // TODO: Make this throw an exception
if (cueLines == null)
{
if (throwOnError)
throw new ArgumentNullException(nameof(cueLines));
return;
}
else if (i < 0 || i > cueLines.Length)
{
if (throwOnError)
throw new IndexOutOfRangeException();
return;
}
// Set the current fields
this.FileName = fileName.Trim('"');
@@ -102,14 +116,24 @@ namespace MPF.CueSheets
// Read track information
case "TRACK":
if (splitLine.Length < 3)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"TRACK line malformed: {line}");
continue;
}
if (this.Tracks == null)
this.Tracks = new List<CueTrack>();
var track = new CueTrack(splitLine[1], splitLine[2], cueLines, ref i);
if (track == default)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"TRACK line malformed: {line}");
continue;
}
this.Tracks.Add(track);
break;
@@ -126,11 +150,24 @@ namespace MPF.CueSheets
/// Write the FILE out to a stream
/// </summary>
/// <param name="sw">StreamWriter to write to</param>
public void Write(StreamWriter sw)
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public void Write(StreamWriter sw, bool throwOnError = false)
{
// If we don't have any tracks, it's invalid
if (this.Tracks == null || this.Tracks.Count == 0)
return; // TODO: Make this throw an exception
if (this.Tracks == null)
{
if (throwOnError)
throw new ArgumentNullException(nameof(this.Tracks));
return;
}
else if (this.Tracks.Count == 0)
{
if (throwOnError)
throw new ArgumentException("No tracks provided to write");
return;
}
sw.WriteLine($"FILE \"{this.FileName}\" {FromFileType(this.FileType)}");

View File

@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using System.Linq;
/// <remarks>
@@ -45,47 +46,103 @@ namespace MPF.CueSheets
/// </summary>
/// <param name="index">Index to set</param>
/// <param name="startTime">Start time to set</param>
public CueIndex(string index, string startTime)
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public CueIndex(string index, string startTime, bool throwOnError = false)
{
// Set the current fields
if (!int.TryParse(index, out int parsedIndex))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new ArgumentException($"Index was not a number: {index}");
return;
}
else if (parsedIndex < 0 || parsedIndex > 99)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Index must be between 0 and 99: {parsedIndex}");
return;
}
// Ignore empty lines
if (string.IsNullOrWhiteSpace(startTime))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new ArgumentException("Start time was null or whitespace");
return;
}
// Ignore lines that don't contain the correct information
if (startTime.Length != 8 || startTime.Count(c => c == ':') != 2)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Start time was not in a recognized format: {startTime}");
return;
}
// Split the line
string[] splitTime = startTime.Split(':');
if (splitTime.Length != 3)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Start time was not in a recognized format: {startTime}");
return;
}
// Parse the lengths
int[] lengthSegments = new int[3];
// Minutes
if (!int.TryParse(splitTime[0], out lengthSegments[0]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Minutes segment was not a number: {splitTime[0]}");
return;
}
else if (lengthSegments[0] < 0)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Minutes segment must be 0 or greater: {lengthSegments[0]}");
return;
}
// Seconds
if (!int.TryParse(splitTime[1], out lengthSegments[1]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Seconds segment was not a number: {splitTime[1]}");
return;
}
else if (lengthSegments[1] < 0 || lengthSegments[1] > 60)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Seconds segment must be between 0 and 60: {lengthSegments[1]}");
return;
}
// Frames
if (!int.TryParse(splitTime[2], out lengthSegments[2]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Frames segment was not a number: {splitTime[2]}");
return;
}
else if (lengthSegments[2] < 0 || lengthSegments[2] > 75)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Frames segment must be between 0 and 75: {lengthSegments[2]}");
return;
}
// Set the values
this.Index = parsedIndex;

View File

@@ -56,7 +56,8 @@ namespace MPF.CueSheets
/// Create a cuesheet from a file, if possible
/// </summary>
/// <param name="filename"></param>
public CueSheet(string filename)
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public CueSheet(string filename, bool throwOnError = false)
{
// Check that the file exists
if (!File.Exists(filename))
@@ -97,7 +98,12 @@ namespace MPF.CueSheets
// Read MCN
case "CATALOG":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"CATALOG line malformed: {line}");
continue;
}
this.Catalog = splitLine[1];
break;
@@ -105,7 +111,12 @@ namespace MPF.CueSheets
// Read external CD-Text file path
case "CDTEXTFILE":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"CDTEXTFILE line malformed: {line}");
continue;
}
this.CdTextFile = splitLine[1];
break;
@@ -113,7 +124,12 @@ namespace MPF.CueSheets
// Read CD-Text enhanced performer
case "PERFORMER":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"PERFORMER line malformed: {line}");
continue;
}
this.Performer = splitLine[1];
break;
@@ -121,7 +137,12 @@ namespace MPF.CueSheets
// Read CD-Text enhanced songwriter
case "SONGWRITER":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"SONGWRITER line malformed: {line}");
continue;
}
this.Songwriter = splitLine[1];
break;
@@ -129,7 +150,12 @@ namespace MPF.CueSheets
// Read CD-Text enhanced title
case "TITLE":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"TITLE line malformed: {line}");
continue;
}
this.Title = splitLine[1];
break;
@@ -137,14 +163,24 @@ namespace MPF.CueSheets
// Read file information
case "FILE":
if (splitLine.Length < 3)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"FILE line malformed: {line}");
continue;
}
if (this.Files == null)
this.Files = new List<CueFile>();
var file = new CueFile(splitLine[1], splitLine[2], cueLines, ref i);
if (file == default)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"FILE line malformed: {line}");
continue;
}
this.Files.Add(file);
break;
@@ -168,11 +204,24 @@ namespace MPF.CueSheets
/// Write the cuesheet out to a stream
/// </summary>
/// <param name="stream">Stream to write to</param>
public void Write(Stream stream)
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public void Write(Stream stream, bool throwOnError = false)
{
// If we don't have any files, it's invalid
if (this.Files == null || this.Files.Count == 0)
return; // TODO: Make this throw an exception
if (this.Files == null)
{
if (throwOnError)
throw new ArgumentNullException(nameof(this.Files));
return;
}
else if (this.Files.Count == 0)
{
if (throwOnError)
throw new ArgumentException("No files provided to write");
return;
}
using (var sw = new StreamWriter(stream, Encoding.ASCII, 1024, true))
{

View File

@@ -156,16 +156,39 @@ namespace MPF.CueSheets
/// <param name="dataType">Data type to set</param>
/// <param name="cueLines">Lines array to pull from</param>
/// <param name="i">Reference to index in array</param>
public CueTrack(string number, string dataType, string[] cueLines, ref int i)
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public CueTrack(string number, string dataType, string[] cueLines, ref int i, bool throwOnError = false)
{
if (cueLines == null || i < 0 || i > cueLines.Length)
return; // TODO: Make this throw an exception
if (cueLines == null)
{
if (throwOnError)
throw new ArgumentNullException(nameof(cueLines));
return;
}
else if (i < 0 || i > cueLines.Length)
{
if (throwOnError)
throw new IndexOutOfRangeException();
return;
}
// Set the current fields
if (!int.TryParse(number, out int parsedNumber))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new ArgumentException($"Number was not a number: {number}");
return;
}
else if (parsedNumber < 1 || parsedNumber > 99)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Index must be between 1 and 99: {parsedNumber}");
return;
}
this.Number = parsedNumber;
this.DataType = GetDataType(dataType);
@@ -192,7 +215,12 @@ namespace MPF.CueSheets
// Read flag information
case "FLAGS":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"FLAGS line malformed: {line}");
continue;
}
this.Flags = GetFlags(splitLine);
break;
@@ -200,7 +228,12 @@ namespace MPF.CueSheets
// Read International Standard Recording Code
case "ISRC":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"ISRC line malformed: {line}");
continue;
}
this.ISRC = splitLine[1];
break;
@@ -208,7 +241,12 @@ namespace MPF.CueSheets
// Read CD-Text enhanced performer
case "PERFORMER":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"PERFORMER line malformed: {line}");
continue;
}
this.Performer = splitLine[1];
break;
@@ -216,7 +254,12 @@ namespace MPF.CueSheets
// Read CD-Text enhanced songwriter
case "SONGWRITER":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"SONGWRITER line malformed: {line}");
continue;
}
this.Songwriter = splitLine[1];
break;
@@ -224,7 +267,12 @@ namespace MPF.CueSheets
// Read CD-Text enhanced title
case "TITLE":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"TITLE line malformed: {line}");
continue;
}
this.Title = splitLine[1];
break;
@@ -232,11 +280,21 @@ namespace MPF.CueSheets
// Read pregap information
case "PREGAP":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"PREGAP line malformed: {line}");
continue;
}
var pregap = new PreGap(splitLine[1]);
if (pregap == default)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"PREGAP line malformed: {line}");
continue;
}
this.PreGap = pregap;
break;
@@ -244,14 +302,24 @@ namespace MPF.CueSheets
// Read index information
case "INDEX":
if (splitLine.Length < 3)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"INDEX line malformed: {line}");
continue;
}
if (this.Indices == null)
this.Indices = new List<CueIndex>();
var index = new CueIndex(splitLine[1], splitLine[2]);
if (index == default)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"INDEX line malformed: {line}");
continue;
}
this.Indices.Add(index);
break;
@@ -259,11 +327,21 @@ namespace MPF.CueSheets
// Read postgap information
case "POSTGAP":
if (splitLine.Length < 2)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"POSTGAP line malformed: {line}");
continue;
}
var postgap = new PostGap(splitLine[1]);
if (postgap == default)
continue; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"POSTGAP line malformed: {line}");
continue;
}
this.PostGap = postgap;
break;
@@ -279,12 +357,25 @@ namespace MPF.CueSheets
/// <summary>
/// Write the TRACK out to a stream
/// </summary>
/// <param name="sw">StreamWriter to write to</param>
public void Write(StreamWriter sw)
/// <param name="sw">StreamWriter to write to</param
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public void Write(StreamWriter sw, bool throwOnError = false)
{
// If we don't have any indices, it's invalid
if (this.Indices == null || this.Indices.Count == 0)
return; // TODO: Make this throw an exception
if (this.Indices == null)
{
if (throwOnError)
throw new ArgumentNullException(nameof(this.Indices));
return;
}
else if (this.Indices.Count == 0)
{
if (throwOnError)
throw new ArgumentException("No indices provided to write");
return;
}
sw.WriteLine($" TRACK {this.Number:D2} {FromDataType(this.DataType)}");
@@ -402,7 +493,6 @@ namespace MPF.CueSheets
foreach (string flagString in flagStrings)
{
// TODO: Make default throw an exception
switch (flagString.ToLowerInvariant())
{
case "flags":

View File

@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using System.Linq;
/// <remarks>
@@ -38,41 +39,87 @@ namespace MPF.CueSheets
/// Create a POSTGAP from a mm:ss:ff length
/// </summary>
/// <param name="length">String to get length information from</param>
public PostGap(string length)
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public PostGap(string length, bool throwOnError = false)
{
// Ignore empty lines
if (string.IsNullOrWhiteSpace(length))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new ArgumentException("Length was null or whitespace");
return;
}
// Ignore lines that don't contain the correct information
if (length.Length != 8 || length.Count(c => c == ':') != 2)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Length was not in a recognized format: {length}");
return;
}
// Split the line
string[] splitLength = length.Split(':');
if (splitLength.Length != 3)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Length was not in a recognized format: {length}");
return;
}
// Parse the lengths
int[] lengthSegments = new int[3];
// Minutes
if (!int.TryParse(splitLength[0], out lengthSegments[0]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Minutes segment was not a number: {splitLength[0]}");
return;
}
else if (lengthSegments[0] < 0)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Minutes segment must be 0 or greater: {lengthSegments[0]}");
return;
}
// Seconds
if (!int.TryParse(splitLength[1], out lengthSegments[1]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Seconds segment was not a number: {splitLength[1]}");
return;
}
else if (lengthSegments[1] < 0 || lengthSegments[1] > 60)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Seconds segment must be between 0 and 60: {lengthSegments[1]}");
return;
}
// Frames
if (!int.TryParse(splitLength[2], out lengthSegments[2]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Frames segment was not a number: {splitLength[2]}");
return;
}
else if (lengthSegments[2] < 0 || lengthSegments[2] > 75)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Frames segment must be between 0 and 75: {lengthSegments[2]}");
return;
}
// Set the values
this.Minutes = lengthSegments[0];

View File

@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using System.Linq;
/// <remarks>
@@ -39,41 +40,87 @@ namespace MPF.CueSheets
/// Create a PREGAP from a mm:ss:ff length
/// </summary>
/// <param name="length">String to get length information from</param>
public PreGap(string length)
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public PreGap(string length, bool throwOnError = false)
{
// Ignore empty lines
if (string.IsNullOrWhiteSpace(length))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new ArgumentException("Length was null or whitespace");
return;
}
// Ignore lines that don't contain the correct information
if (length.Length != 8 || length.Count(c => c == ':') != 2)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Length was not in a recognized format: {length}");
return;
}
// Split the line
string[] splitLength = length.Split(':');
if (splitLength.Length != 3)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Length was not in a recognized format: {length}");
return;
}
// Parse the lengths
int[] lengthSegments = new int[3];
// Minutes
if (!int.TryParse(splitLength[0], out lengthSegments[0]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Minutes segment was not a number: {splitLength[0]}");
return;
}
else if (lengthSegments[0] < 0)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Minutes segment must be 0 or greater: {lengthSegments[0]}");
return;
}
// Seconds
if (!int.TryParse(splitLength[1], out lengthSegments[1]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Seconds segment was not a number: {splitLength[1]}");
return;
}
else if (lengthSegments[1] < 0 || lengthSegments[1] > 60)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Seconds segment must be between 0 and 60: {lengthSegments[1]}");
return;
}
// Frames
if (!int.TryParse(splitLength[2], out lengthSegments[2]))
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new FormatException($"Frames segment was not a number: {splitLength[2]}");
return;
}
else if (lengthSegments[2] < 0 || lengthSegments[2] > 75)
return; // TODO: Make this throw an exception
{
if (throwOnError)
throw new IndexOutOfRangeException($"Frames segment must be between 0 and 75: {lengthSegments[2]}");
return;
}
// Set the values
this.Minutes = lengthSegments[0];