@@ -118,7 +118,8 @@ public MicrosoftCabinet(Cabinet? model, Stream? data)
118118 /// <param name="outDir">Path to the output directory</param>
119119 /// <param name="includeDebug">True to include debug data, false otherwise</param>
120120 /// <returns>Indicates if all files were able to be extracted</returns>
121- public static bool ExtractAll ( string filename , string outDir , bool includeDebug )
121+ /// <remarks>Will extract all items found in the set with forward-only reading</remarks>
122+ public static bool ExtractSet ( string filename , string outDir , bool includeDebug )
122123 {
123124 // Get a wrapper for the set
124125 var current = OpenSet ( filename ) ;
@@ -144,13 +145,24 @@ public static bool ExtractAll(string filename, string outDir, bool includeDebug)
144145 return true ;
145146 }
146147
148+ /// <summary>
149+ /// Extract a cabinet to an output directory, if possible
150+ /// </summary>
151+ /// <param name="filename">Filename for one cabinet in the set</param>
152+ /// <param name="outDir">Path to the output directory</param>
153+ /// <param name="includeDebug">True to include debug data, false otherwise</param>
154+ /// <returns>Indicates if all files were able to be extracted</returns>
155+ /// <remarks>Will read spanned folders but won't attempt to extract unrelated folders</remarks>
156+ public bool ExtractAll ( string filename , string outDir , bool includeDebug )
157+ => ExtractCabinet ( filename , outDir , forwardOnly : false , includeDebug ) ;
158+
147159 /// <summary>
148160 /// Extract a cabinet file to an output directory, if possible
149161 /// </summary>
150162 /// <param name="filename">Filename for one cabinet in the set</param>
151163 /// <param name="outDir">Path to the output directory</param>
152- /// <param name="forwardOnly">Indicates if the cabinet set should only be read forward</param>
153164 /// <param name="includeDebug">True to include debug data, false otherwise</param>
165+ /// <param name="forwardOnly">Indicates if decompression should be done forward-only</param>
154166 /// <returns>Indicates if all files were able to be extracted</returns>
155167 private bool ExtractCabinet ( string filename , string outDir , bool forwardOnly , bool includeDebug )
156168 {
@@ -183,9 +195,14 @@ private bool ExtractCabinet(string filename, string outDir, bool forwardOnly, bo
183195 /// <param name="outDir">Path to the output directory</param>
184196 /// <param name="folder">Folder containing the blocks to decompress</param>
185197 /// <param name="folderIndex">Index of the folder in the cabinet</param>
186- /// <param name="forwardOnly">Indicates if the cabinet set should only be read forward</param>
198+ /// <param name="forwardOnly">Indicates if decompression should be done forward-only </param>
187199 /// <param name="includeDebug">True to include debug data, false otherwise</param>
188- private void ExtractFolder ( string filename , string outDir , CFFOLDER ? folder , int folderIndex , bool forwardOnly , bool includeDebug )
200+ private void ExtractFolder ( string filename ,
201+ string outDir ,
202+ CFFOLDER ? folder ,
203+ int folderIndex ,
204+ bool forwardOnly ,
205+ bool includeDebug )
189206 {
190207 // Decompress the blocks, if possible
191208 using var blockStream = DecompressBlocks ( filename , folder , folderIndex , forwardOnly ) ;
@@ -448,12 +465,14 @@ private int GetFolderIndex(CFFILE file)
448465 /// <param name="filename">Filename for one cabinet in the set</param>
449466 /// <param name="folder">Folder containing the blocks to decompress</param>
450467 /// <param name="folderIndex">Index of the folder in the cabinet</param>
451- /// <param name="forwardOnly">Indicates if the cabinet set should only be read forward</param>
468+ /// <param name="forwardOnly">Indicates if decompression should be done forward-only </param>
452469 /// <returns>Stream representing the decompressed data on success, null otherwise</returns>
453470 public Stream ? DecompressBlocks ( string filename , CFFOLDER ? folder , int folderIndex , bool forwardOnly )
454471 {
455472 // Ensure data blocks
456- var dataBlocks = GetDataBlocks ( filename , folder , folderIndex , skipPrev : forwardOnly , skipNext : false ) ;
473+ var dataBlocks = forwardOnly
474+ ? GetDataBlocksForward ( filename , folder , folderIndex )
475+ : GetDataBlocks ( filename , folder , folderIndex ) ;
457476 if ( dataBlocks == null || dataBlocks . Length == 0 )
458477 return null ;
459478
@@ -481,15 +500,15 @@ private int GetFolderIndex(CFFILE file)
481500
482501 // MS-ZIP
483502 case CompressionType . TYPE_MSZIP :
484- long position = ms . Position ;
503+ long preMsZipPosition = ms . Position ;
485504 mszip . CopyTo ( db . CompressedData , ms ) ;
486- long decompressedSize = ms . Position - position ;
505+ long msZipDecompressedSize = ms . Position - preMsZipPosition ;
487506
488507 // Pad to the correct size but throw a warning about this
489- if ( decompressedSize < db . UncompressedSize )
508+ if ( msZipDecompressedSize < db . UncompressedSize )
490509 {
491- Console . Error . WriteLine ( $ "Data block { i } in folder { folderIndex } had mismatching sizes. Expected: { db . UncompressedSize } , Got: { decompressedSize } ") ;
492- byte [ ] padding = new byte [ db . UncompressedSize - decompressedSize ] ;
510+ Console . Error . WriteLine ( $ "Data block { i } in folder { folderIndex } had mismatching sizes. Expected: { db . UncompressedSize } , Got: { msZipDecompressedSize } ") ;
511+ byte [ ] padding = new byte [ db . UncompressedSize - msZipDecompressedSize ] ;
493512 ms . Write ( padding , 0 , padding . Length ) ;
494513 }
495514
@@ -580,6 +599,16 @@ private static CompressionType GetCompressionType(CFFOLDER folder)
580599 return [ .. prevBlocks , .. folder . DataBlocks , .. nextBlocks ] ;
581600 }
582601
602+ /// <summary>
603+ /// Get the set of data blocks for a folder using forward reading only
604+ /// </summary>
605+ /// <param name="filename">Filename for one cabinet in the set</param>
606+ /// <param name="folder">Folder containing the blocks to decompress</param>
607+ /// <param name="folderIndex">Index of the folder in the cabinet</param>
608+ /// <returns>Array of data blocks on success, null otherwise</returns>
609+ private CFDATA [ ] ? GetDataBlocksForward ( string filename , CFFOLDER ? folder , int folderIndex )
610+ => GetDataBlocks ( filename , folder , folderIndex , skipPrev : true , skipNext : false ) ;
611+
583612 /// <summary>
584613 /// Get all files for the current folder index
585614 /// </summary>
0 commit comments