Simplify ISO9660 namespaces.

This commit is contained in:
2019-07-22 02:58:56 +01:00
parent 49e5ebc22a
commit 4d7bf51e1d
5 changed files with 36 additions and 101 deletions

View File

@@ -43,11 +43,7 @@ namespace DiscImageChef.Filesystems.ISO9660
Normal, Normal,
Vms, Vms,
Joliet, Joliet,
JolietNormal, Rrip
Rrip,
RripNormal,
RripJoliet,
RripJolietNormal
} }
} }
} }

View File

@@ -86,42 +86,20 @@ namespace DiscImageChef.Filesystems.ISO9660
switch(@namespace) switch(@namespace)
{ {
case Namespace.Normal: case Namespace.Normal:
contents.Add(entry.IsoFilename.EndsWith(";1", StringComparison.Ordinal) contents.Add(entry.Filename.EndsWith(";1", StringComparison.Ordinal)
? entry.IsoFilename.Substring(0, entry.IsoFilename.Length - 2) ? entry.Filename.Substring(0, entry.Filename.Length - 2)
: entry.IsoFilename); : entry.Filename);
break; break;
case Namespace.Vms: case Namespace.Vms:
contents.Add(entry.IsoFilename); contents.Add(entry.Filename);
break; break;
case Namespace.Joliet: case Namespace.Joliet:
// TODO: Implement Joliet // TODO: Implement Joliet
break; break;
case Namespace.JolietNormal:
// TODO: Implement Joliet
contents.Add(entry.IsoFilename.EndsWith(";1", StringComparison.Ordinal)
? entry.IsoFilename.Substring(0, entry.IsoFilename.Length - 2)
: entry.IsoFilename);
break;
case Namespace.Rrip: case Namespace.Rrip:
// TODO: Implement RRIP // TODO: Implement RRIP
break; break;
case Namespace.RripNormal:
// TODO: Implement RRIP
contents.Add(entry.IsoFilename.EndsWith(";1", StringComparison.Ordinal)
? entry.IsoFilename.Substring(0, entry.IsoFilename.Length - 2)
: entry.IsoFilename);
break;
case Namespace.RripJoliet:
// TODO: Implement RRIP
// TODO: Implement Joliet
break;
case Namespace.RripJolietNormal:
// TODO: Implement RRIP
// TODO: Implement Joliet
contents.Add(entry.IsoFilename.EndsWith(";1", StringComparison.Ordinal)
? entry.IsoFilename.Substring(0, entry.IsoFilename.Length - 2)
: entry.IsoFilename);
break; break;
default: throw new ArgumentOutOfRangeException(); default: throw new ArgumentOutOfRangeException();
} }
@@ -161,12 +139,12 @@ namespace DiscImageChef.Filesystems.ISO9660
Flags = record.flags, Flags = record.flags,
Interleave = record.interleave, Interleave = record.interleave,
VolumeSequenceNumber = record.volume_sequence_number, VolumeSequenceNumber = record.volume_sequence_number,
IsoFilename = Filename =
Encoding.ASCII.GetString(data, entryOff + DirectoryRecordSize, record.name_len), Encoding.ASCII.GetString(data, entryOff + DirectoryRecordSize, record.name_len),
Timestamp = DecodeHighSierraDateTime(record.date) Timestamp = DecodeHighSierraDateTime(record.date)
}; };
if(!entries.ContainsKey(entry.IsoFilename)) entries.Add(entry.IsoFilename, entry); if(!entries.ContainsKey(entry.Filename)) entries.Add(entry.Filename, entry);
entryOff += record.length; entryOff += record.length;
} }
@@ -175,7 +153,7 @@ namespace DiscImageChef.Filesystems.ISO9660
} }
// TODO: Implement system area // TODO: Implement system area
Dictionary<string, DecodedDirectoryEntry> DecodeIsoDirectory(byte[] data, bool joliet = false) Dictionary<string, DecodedDirectoryEntry> DecodeIsoDirectory(byte[] data)
{ {
Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>(); Dictionary<string, DecodedDirectoryEntry> entries = new Dictionary<string, DecodedDirectoryEntry>();
int entryOff = 0; int entryOff = 0;
@@ -201,28 +179,25 @@ namespace DiscImageChef.Filesystems.ISO9660
Extent = record.size == 0 ? 0 : record.extent, Extent = record.size == 0 ? 0 : record.extent,
Size = record.size, Size = record.size,
Flags = record.flags, Flags = record.flags,
Filename =
joliet
? Encoding.BigEndianUnicode.GetString(data, entryOff + DirectoryRecordSize,
record.name_len)
: Encoding.ASCII.GetString(data, entryOff + DirectoryRecordSize, record.name_len),
FileUnitSize = record.file_unit_size, FileUnitSize = record.file_unit_size,
Interleave = record.interleave, Interleave = record.interleave,
VolumeSequenceNumber = record.volume_sequence_number, VolumeSequenceNumber = record.volume_sequence_number,
Timestamp = DecodeIsoDateTime(record.date) Timestamp = DecodeIsoDateTime(record.date)
}; };
if(joliet)
entry.JolietFilename =
Encoding.BigEndianUnicode.GetString(data, entryOff + DirectoryRecordSize, record.name_len);
else
entry.IsoFilename = Encoding.ASCII.GetString(data, entryOff + DirectoryRecordSize, record.name_len);
// TODO: Multi-extent files // TODO: Multi-extent files
if(entry.Flags.HasFlag(FileFlags.Associated)) if(entry.Flags.HasFlag(FileFlags.Associated))
{ {
// TODO: Detect if Apple extensions, as associated files contain the resource fork there // TODO: Detect if Apple extensions, as associated files contain the resource fork there
if(entries.ContainsKey(joliet ? entry.JolietFilename : entry.IsoFilename)) if(entries.ContainsKey(entry.Filename)) entries[entry.Filename].AssociatedFile = entry;
entries[joliet ? entry.JolietFilename : entry.IsoFilename].AssociatedFile = entry;
else else
{ entries[entry.Filename] = new DecodedDirectoryEntry
entries[joliet ? entry.JolietFilename : entry.IsoFilename] = new DecodedDirectoryEntry
{ {
Extent = 0, Extent = 0,
Size = 0, Size = 0,
@@ -230,27 +205,21 @@ namespace DiscImageChef.Filesystems.ISO9660
FileUnitSize = 0, FileUnitSize = 0,
Interleave = 0, Interleave = 0,
VolumeSequenceNumber = record.volume_sequence_number, VolumeSequenceNumber = record.volume_sequence_number,
IsoFilename = Filename = joliet
Encoding.ASCII.GetString(data, entryOff + DirectoryRecordSize, record.name_len), ? Encoding.BigEndianUnicode.GetString(data,
entryOff + DirectoryRecordSize,
record.name_len)
: Encoding.ASCII.GetString(data, entryOff + DirectoryRecordSize,
record.name_len),
Timestamp = DecodeIsoDateTime(record.date), Timestamp = DecodeIsoDateTime(record.date),
AssociatedFile = entry AssociatedFile = entry
}; };
if(joliet)
entries[entry.JolietFilename].JolietFilename =
Encoding.BigEndianUnicode.GetString(data, entryOff + DirectoryRecordSize,
record.name_len);
else
entries[entry.IsoFilename].IsoFilename =
Encoding.ASCII.GetString(data, entryOff + DirectoryRecordSize, record.name_len);
}
} }
else else
{ {
if(entries.ContainsKey(joliet ? entry.JolietFilename : entry.IsoFilename)) if(entries.ContainsKey(entry.Filename))
entry.AssociatedFile = entry.AssociatedFile = entries[entry.Filename].AssociatedFile;
entries[joliet ? entry.JolietFilename : entry.IsoFilename].AssociatedFile; entries[entry.Filename] = entry;
entries[joliet ? entry.JolietFilename : entry.IsoFilename] = entry;
} }
entryOff += record.length; entryOff += record.length;

View File

@@ -46,7 +46,7 @@ namespace DiscImageChef.Filesystems.ISO9660
bool debug; bool debug;
bool highSierra; bool highSierra;
IMediaImage image; IMediaImage image;
Dictionary<string, DecodedDirectoryEntry> jolietRootDirectoryCache; bool joliet;
bool mounted; bool mounted;
Namespace @namespace; Namespace @namespace;
Dictionary<string, DecodedDirectoryEntry> rootDirectoryCache; Dictionary<string, DecodedDirectoryEntry> rootDirectoryCache;
@@ -67,11 +67,7 @@ namespace DiscImageChef.Filesystems.ISO9660
{"normal", "Primary Volume Descriptor, ignoring ;1 suffixes"}, {"normal", "Primary Volume Descriptor, ignoring ;1 suffixes"},
{"vms", "Primary Volume Descriptor, showing version suffixes"}, {"vms", "Primary Volume Descriptor, showing version suffixes"},
{"joliet", "Joliet Volume Descriptor"}, {"joliet", "Joliet Volume Descriptor"},
{"joliet+normal", "Joliet with fallback to normal"}, {"rrip", "Rock Ridge"}
{"rrip", "Rock Ridge"},
{"rrip+normal", "Rock Ridge with fallback to normal"},
{"rrip+joliet", "Rock Ridge with fallback to Joliet"},
{"rrip+joliet+normal", "Rock Ridge with fallback to Joliet and then to normal (default)"}
}; };
public Errno ReadLink(string path, out string dest) public Errno ReadLink(string path, out string dest)

View File

@@ -59,16 +59,15 @@ namespace DiscImageChef.Filesystems.ISO9660
{ {
public DecodedDirectoryEntry AssociatedFile; public DecodedDirectoryEntry AssociatedFile;
public uint Extent; public uint Extent;
public string Filename;
public byte FileUnitSize; public byte FileUnitSize;
public FileFlags Flags; public FileFlags Flags;
public byte Interleave; public byte Interleave;
public string IsoFilename;
public uint Size; public uint Size;
public DateTime? Timestamp; public DateTime? Timestamp;
public ushort VolumeSequenceNumber; public ushort VolumeSequenceNumber;
public string JolietFilename;
public override string ToString() => JolietFilename ?? IsoFilename; public override string ToString() => Filename;
} }
} }
} }

View File

@@ -37,21 +37,9 @@ namespace DiscImageChef.Filesystems.ISO9660
case "joliet": case "joliet":
this.@namespace = Namespace.Joliet; this.@namespace = Namespace.Joliet;
break; break;
case "joliet+normal":
this.@namespace = Namespace.JolietNormal;
break;
case "rrip": case "rrip":
this.@namespace = Namespace.Rrip; this.@namespace = Namespace.Rrip;
break; break;
case "rrip+normal":
this.@namespace = Namespace.RripNormal;
break;
case "rrip+joliet":
this.@namespace = Namespace.RripJoliet;
break;
case "rrip+joliet+normal":
this.@namespace = Namespace.RripJolietNormal;
break;
default: return Errno.InvalidArgument; default: return Errno.InvalidArgument;
} }
@@ -183,20 +171,7 @@ namespace DiscImageChef.Filesystems.ISO9660
if((highSierra || cdi) && this.@namespace != Namespace.Normal && this.@namespace != Namespace.Vms) if((highSierra || cdi) && this.@namespace != Namespace.Normal && this.@namespace != Namespace.Vms)
this.@namespace = Namespace.Normal; this.@namespace = Namespace.Normal;
if(jolietvd is null) if(jolietvd is null && this.@namespace == Namespace.Joliet) this.@namespace = Namespace.Normal;
switch(this.@namespace)
{
case Namespace.Joliet:
case Namespace.JolietNormal:
this.@namespace = Namespace.Normal;
break;
case Namespace.RripJoliet:
this.@namespace = Namespace.Rrip;
break;
case Namespace.RripJolietNormal:
this.@namespace = Namespace.RripNormal;
break;
}
uint rootLocation = 0; uint rootLocation = 0;
uint rootSize = 0; uint rootSize = 0;
@@ -241,9 +216,7 @@ namespace DiscImageChef.Filesystems.ISO9660
XmlFsType.Type = fsFormat; XmlFsType.Type = fsFormat;
if(jolietvd != null && this.@namespace != Namespace.Normal && if(jolietvd != null && this.@namespace == Namespace.Joliet)
this.@namespace != Namespace.Vms &&
this.@namespace != Namespace.Rrip && this.@namespace != Namespace.RripNormal)
{ {
rootLocation = jolietvd.Value.root_directory_record.extent; rootLocation = jolietvd.Value.root_directory_record.extent;
@@ -253,9 +226,11 @@ namespace DiscImageChef.Filesystems.ISO9660
if(rootLocation + rootSize >= imagePlugin.Info.Sectors) return Errno.InvalidArgument; if(rootLocation + rootSize >= imagePlugin.Info.Sectors) return Errno.InvalidArgument;
joliet = true;
rootDir = imagePlugin.ReadSectors(rootLocation, rootSize); rootDir = imagePlugin.ReadSectors(rootLocation, rootSize);
jolietRootDirectoryCache = DecodeIsoDirectory(rootDir, true); rootDirectoryCache = DecodeIsoDirectory(rootDir);
XmlFsType.VolumeName = decodedJolietVd.VolumeIdentifier; XmlFsType.VolumeName = decodedJolietVd.VolumeIdentifier;