@@ -15,13 +15,13 @@ public partial class ISO9660 : IExtractable
1515 /// <summary>
1616 /// List of extracted files by their sector offset
1717 /// </summary>
18- private Dictionary < int , int > extractedFiles = [ ] ;
18+ private readonly Dictionary < int , int > extractedFiles = [ ] ;
1919
2020 /// <summary>
2121 /// List of multi-extent files written, by their FileIdentifier
2222 /// </summary>
2323 /// <remarks>Used as last-extent has mutli-extent flag=0</remarks>
24- private List < byte [ ] > multiExtentFiles = [ ] ;
24+ private readonly List < byte [ ] > multiExtentFiles = [ ] ;
2525
2626 #endregion
2727
@@ -32,6 +32,10 @@ public virtual bool Extract(string outputDirectory, bool includeDebug)
3232 if ( VolumeDescriptorSet . Length == 0 || DirectoryDescriptors . Count == 0 )
3333 return true ;
3434
35+ // Clear the extraction state
36+ extractedFiles . Clear ( ) ;
37+ multiExtentFiles . Clear ( ) ;
38+
3539 bool allExtracted = true ;
3640
3741 // Determine and validate sector length, default to 2048
@@ -43,25 +47,25 @@ public virtual bool Extract(string outputDirectory, bool includeDebug)
4347 // Note: This will prioritize the last volume descriptor directory hierarchies first (prioritises those filenames)
4448 for ( int i = VolumeDescriptorSet . Length - 1 ; i >= 0 ; i -- )
4549 {
46- if ( VolumeDescriptorSet [ i ] is BaseVolumeDescriptor bvd )
50+ if ( VolumeDescriptorSet [ i ] is not BaseVolumeDescriptor bvd )
51+ continue ;
52+
53+ var rootDir = bvd . RootDirectoryRecord ;
54+ var blockLength = bvd . GetLogicalBlockSize ( sectorLength ) ;
55+
56+ // TODO: Better encoding detection (EscapeSequences)
57+ var encoding = Encoding . UTF8 ;
58+ if ( bvd is SupplementaryVolumeDescriptor )
59+ encoding = Encoding . BigEndianUnicode ;
60+
61+ // Extract all files within root directory hierarchy
62+ allExtracted &= ExtractExtent ( rootDir . ExtentLocation . LittleEndian , encoding , blockLength , outputDirectory , includeDebug ) ;
63+
64+ // If Big Endian extent location differs from Little Endian extent location, also extract that directory hierarchy
65+ if ( ! rootDir . ExtentLocation . IsValid )
4766 {
48- var rootDir = bvd . RootDirectoryRecord ;
49-
50- var blockLength = bvd . GetLogicalBlockSize ( sectorLength ) ;
51-
52- // TODO: Better encoding detection (EscapeSequences)
53- var encoding = Encoding . UTF8 ;
54- if ( bvd is SupplementaryVolumeDescriptor svd )
55- encoding = Encoding . BigEndianUnicode ;
56-
57- // Extract all files within root directory hierarchy
58- allExtracted &= ExtractExtent ( rootDir . ExtentLocation . LittleEndian , encoding , blockLength , outputDirectory , includeDebug ) ;
59- // If Big Endian extent location differs from Little Endian extent location, also extract that directory hierarchy
60- if ( ! rootDir . ExtentLocation . IsValid )
61- {
62- if ( includeDebug ) Console . WriteLine ( $ "Extracting from volume descriptor (big endian root dir location)") ;
63- allExtracted &= ExtractExtent ( rootDir . ExtentLocation . BigEndian , encoding , blockLength , outputDirectory , includeDebug ) ;
64- }
67+ if ( includeDebug ) Console . WriteLine ( $ "Extracting from volume descriptor (big endian root dir location)") ;
68+ allExtracted &= ExtractExtent ( rootDir . ExtentLocation . BigEndian , encoding , blockLength , outputDirectory , includeDebug ) ;
6569 }
6670 }
6771
@@ -78,36 +82,41 @@ private bool ExtractExtent(int extentLocation, Encoding encoding, int blockLengt
7882 return false ;
7983
8084 bool succeeded = true ;
81- if ( DirectoryDescriptors [ extentLocation ] is DirectoryExtent dir )
85+ if ( DirectoryDescriptors [ extentLocation ] is not DirectoryExtent dir )
86+ return succeeded ;
87+
88+ foreach ( var dr in dir . DirectoryRecords )
8289 {
83- foreach ( var dr in dir . DirectoryRecords )
90+ // Recurse if record is directory
91+ #if NET20 || NET35
92+ if ( ( dr . FileFlags & FileFlags . DIRECTORY ) != 0 )
93+ #else
94+ if ( dr . FileFlags . HasFlag ( FileFlags . DIRECTORY ) )
95+ #endif
8496 {
85- // Recurse if record is directory
86- if ( ( dr . FileFlags & FileFlags . DIRECTORY ) == FileFlags . DIRECTORY )
87- {
88- // Don't recurse up or self
89- if ( dr . FileIdentifier . EqualsExactly ( Constants . CurrentDirectory ) || dr . FileIdentifier . EqualsExactly ( Constants . ParentDirectory ) )
90- continue ;
91-
92- // Append directory name
93- string outDirTemp = Path . Combine ( outputDirectory , encoding . GetString ( dr . FileIdentifier ) ) ;
94- if ( includeDebug ) Console . WriteLine ( $ "Extracting to directory: { outDirTemp } ") ;
95-
96- // Recursively extract from LittleEndian extent location
97- ExtractExtent ( dr . ExtentLocation . LittleEndian , encoding , blockLength , outDirTemp , includeDebug ) ;
98-
99- // Also extract from BigEndian values if ambiguous
100- if ( ! dr . ExtentLocation . IsValid ! )
101- ExtractExtent ( dr . ExtentLocation . BigEndian , encoding , blockLength , outDirTemp , includeDebug ) ;
102- }
103- else
104- {
105- // Record is a simple file extent, extract file
106- succeeded &= ExtractFile ( dr , encoding , blockLength , false , outputDirectory , includeDebug ) ;
107- // Also extract from BigEndian values if ambiguous
108- if ( ! dr . ExtentLocation . IsValid ! )
109- succeeded &= ExtractFile ( dr , encoding , blockLength , true , outputDirectory , includeDebug ) ;
110- }
97+ // Don't recurse up or self
98+ if ( dr . FileIdentifier . EqualsExactly ( Constants . CurrentDirectory ) || dr . FileIdentifier . EqualsExactly ( Constants . ParentDirectory ) )
99+ continue ;
100+
101+ // Append directory name
102+ string outDirTemp = Path . Combine ( outputDirectory , encoding . GetString ( dr . FileIdentifier ) ) ;
103+ if ( includeDebug ) Console . WriteLine ( $ "Extracting to directory: { outDirTemp } ") ;
104+
105+ // Recursively extract from LittleEndian extent location
106+ ExtractExtent ( dr . ExtentLocation . LittleEndian , encoding , blockLength , outDirTemp , includeDebug ) ;
107+
108+ // Also extract from BigEndian values if ambiguous
109+ if ( ! dr . ExtentLocation . IsValid )
110+ ExtractExtent ( dr . ExtentLocation . BigEndian , encoding , blockLength , outDirTemp , includeDebug ) ;
111+ }
112+ else
113+ {
114+ // Record is a simple file extent, extract file
115+ succeeded &= ExtractFile ( dr , encoding , blockLength , false , outputDirectory , includeDebug ) ;
116+
117+ // Also extract from BigEndian values if ambiguous
118+ if ( ! dr . ExtentLocation . IsValid )
119+ succeeded &= ExtractFile ( dr , encoding , blockLength , true , outputDirectory , includeDebug ) ;
111120 }
112121 }
113122
@@ -120,7 +129,11 @@ private bool ExtractExtent(int extentLocation, Encoding encoding, int blockLengt
120129 private bool ExtractFile ( DirectoryRecord dr , Encoding encoding , int blockLength , bool bigEndian , string outputDirectory , bool includeDebug )
121130 {
122131 // Cannot extract file if it is a directory
123- if ( ( dr . FileFlags & FileFlags . DIRECTORY ) == FileFlags . DIRECTORY )
132+ #if NET20 || NET35
133+ if ( ( dr . FileFlags & FileFlags . DIRECTORY ) != 0 )
134+ #else
135+ if ( dr . FileFlags . HasFlag ( FileFlags . DIRECTORY ) )
136+ #endif
124137 return false ;
125138
126139 int extentLocation = bigEndian ? dr . ExtentLocation . BigEndian : dr . ExtentLocation . LittleEndian ;
@@ -142,9 +155,13 @@ private bool ExtractFile(DirectoryRecord dr, Encoding encoding, int blockLength,
142155 Directory . CreateDirectory ( directoryName ) ;
143156
144157 bool multiExtent = false ;
145-
158+
146159 // Currently cannot extract multi-extent or interleaved files
160+ #if NET20 || NET35
147161 if ( ( dr . FileFlags & FileFlags . MULTI_EXTENT ) != 0 )
162+ #else
163+ if ( dr . FileFlags . HasFlag ( FileFlags . MULTI_EXTENT ) )
164+ #endif
148165 {
149166 if ( includeDebug ) Console . WriteLine ( $ "Extraction of multi-extent files is currently WIP: { filename } ") ;
150167 multiExtentFiles . Add ( dr . FileIdentifier ) ;
@@ -171,7 +188,7 @@ private bool ExtractFile(DirectoryRecord dr, Encoding encoding, int blockLength,
171188 const int chunkSize = 2048 * 1024 ;
172189 lock ( _dataSourceLock )
173190 {
174- long fileOffset = ( ( long ) dr . ExtentLocation + ( long ) dr . ExtendedAttributeRecordLength ) * ( long ) blockLength ;
191+ long fileOffset = ( ( long ) dr . ExtentLocation + dr . ExtendedAttributeRecordLength ) * blockLength ;
175192 _dataSource . SeekIfPossible ( fileOffset , SeekOrigin . Begin ) ;
176193
177194 // Get the length, and make sure it won't EOF
@@ -184,7 +201,7 @@ private bool ExtractFile(DirectoryRecord dr, Encoding encoding, int blockLength,
184201 using var fs = File . Open ( filepath , FileMode . Append , FileAccess . Write , FileShare . ReadWrite ) ;
185202 while ( length > 0 )
186203 {
187- int bytesToRead = ( int ) Math . Min ( length , chunkSize ) ;
204+ int bytesToRead = Math . Min ( length , chunkSize ) ;
188205
189206 byte [ ] buffer = _dataSource . ReadBytes ( bytesToRead ) ;
190207 fs . Write ( buffer , 0 , bytesToRead ) ;
0 commit comments