GDROMExplorer/Formats/GDI/GDImageBuilder.cs
2021-07-26 13:04:16 -07:00

117 lines
5.9 KiB
C#

// Decompiled with JetBrains decompiler
// Type: GDRomExplorer.ImageFileFormat.GDI.GDImageBuilder
// Assembly: GDI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
// MVID: F4295E7C-8421-4324-B5B1-F38932DD6235
// Assembly location: Formats\GDI.dll
using ImageReader.DiscSectors;
using SEGATools.DiscFileSystem;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
namespace GDRomExplorer.ImageFileFormat.GDI
{
public class GDImageBuilder : IDiscFileSystemConverter
{
private static readonly Regex gdiRegex = new Regex("^(?<index>[1-9]|[1-9][0-9]?)[ \\t]+(?<lba>[0-9]{1,6}?)[ \\t]+(?<type>0|4?)[ \\t]+(?<mode>2352|2048?)[ \\t]+(?<filename>\".+\\.\\S{1,4}\"|\\S+\\.\\S{1,4}?)[ \\t]+(?<offset>[+-]*[0-9]{1,6}?)[ \\t]*$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant);
private static readonly string FIRST_SESSION_NAME = "Single Density";
private static readonly string SECOND_SESSION_NAME = "High Density";
private static readonly int HIGH_DENSITY_START_LBA = 45000;
private static readonly bool SUPPORT_DATA_EXTRACTION = true;
private static readonly bool SUPPORT_CUE_EXPORT = true;
private static readonly bool SUPPORT_GDI_EXPORT = true;
protected IGDIFileSystemValidator Validator;
protected IInitialProgramProvider IpProvider;
public GDImageBuilder()
{
this.IpProvider = (IInitialProgramProvider) new InitialProgramProvider();
this.Validator = (IGDIFileSystemValidator) new GDIFileSystemValidator(this.IpProvider);
}
public IDiscFileSystem ToDiscFileSystem(string imageFileName)
{
short result1 = 0;
short num1 = 0;
List<IDiscTrack> tracks1 = new List<IDiscTrack>();
List<IDiscTrack> tracks2 = new List<IDiscTrack>();
short num2 = 1;
using (StreamReader streamReader = new StreamReader(imageFileName))
{
if (!short.TryParse(streamReader.ReadLine().Trim(), out result1))
throw new DiscFormatException(string.Format("Wrong track index at line {0}", (object) num2));
short num3 = (short) ((int) num2 + 1);
if (result1 > (short) 99)
throw new DiscFormatException(string.Format("Too many tracks: maximum is 99, got {0}", (object) result1));
while (!streamReader.EndOfStream)
{
string input = streamReader.ReadLine().Trim();
if (string.IsNullOrEmpty(input))
{
++num3;
}
else
{
Match match = GDImageBuilder.gdiRegex.Match(input);
if (!match.Success)
throw new DiscFormatException(string.Format("Unable to parse track at line {0}", (object) num3));
TrackModeType trackData;
if (match.Groups["type"].Value == "4")
{
trackData = TrackModeType.Data;
}
else
{
if (!(match.Groups["type"].Value == "0"))
throw new DiscFormatException(string.Format("Wrong track type: got {0} whereas 0 for audio or 4 for data was expected", (object) match.Groups["type"].Value));
trackData = TrackModeType.Audio;
}
IDiscSector trackSector;
if (match.Groups["mode"].Value == "2352")
{
trackSector = trackData != TrackModeType.Data ? (IDiscSector) new RawSector() : (IDiscSector) new CDROMMode1RawSector();
}
else
{
if (!(match.Groups["mode"].Value == "2048"))
throw new DiscFormatException(string.Format("Wrong track mode: got {0} whereas 2352 or 2048 was expected", (object) match.Groups["mode"].Value));
trackSector = (IDiscSector) new ISO9660Sector();
}
int result2;
if (!int.TryParse(match.Groups["index"].Value, out result2))
throw new DiscFormatException(string.Format("Wrong track index: {0}", (object) match.Groups["index"].Value));
uint result3;
if (!uint.TryParse(match.Groups["lba"].Value, out result3))
throw new DiscFormatException(string.Format("Wrong logical block address: {0}", (object) match.Groups["lba"].Value));
int result4;
if (!int.TryParse(match.Groups["offset"].Value, out result4))
throw new DiscFormatException(string.Format("Wrong offset: {0}", (object) match.Groups["offset"].Value));
string str = match.Groups["filename"].Value.Trim().Replace("\"", "");
if (!Path.IsPathRooted(str))
str = Path.Combine(Path.GetDirectoryName(imageFileName), str);
FileInfo fileInfo = File.Exists(str) ? new FileInfo(str) : throw new DiscFormatException(string.Format("File missing: {0}", (object) str));
IDiscTrack track = (IDiscTrack) new DiscTrack(str, (long) result4, fileInfo.Length, result3, result2, trackData, trackSector);
this.Validator.CheckDiscTrackSize(track);
if ((long) track.LogicalBlockAddress < (long) GDImageBuilder.HIGH_DENSITY_START_LBA)
tracks1.Add(track);
else
tracks2.Add(track);
++num1;
++num3;
}
}
if ((int) result1 != (int) num1)
throw new DiscFormatException(string.Format("Number of tracks doesn't match: expected {0}, got {1}", (object) result1, (object) num1));
}
List<IDiscSession> sessions = new List<IDiscSession>()
{
(IDiscSession) new DiscSession(1, GDImageBuilder.FIRST_SESSION_NAME, tracks1),
(IDiscSession) new DiscSession(2, GDImageBuilder.SECOND_SESSION_NAME, tracks2)
};
SEGATools.DiscFileSystem.DiscFileSystem discFileSystem = new SEGATools.DiscFileSystem.DiscFileSystem(imageFileName, sessions, GDImageBuilder.SUPPORT_DATA_EXTRACTION, GDImageBuilder.SUPPORT_CUE_EXPORT, GDImageBuilder.SUPPORT_GDI_EXPORT);
this.Validator.CheckDiscFileSystem((IDiscFileSystem) discFileSystem);
return (IDiscFileSystem) discFileSystem;
}
}
}