88using System . Security . Policy ;
99using System . Threading . Tasks ;
1010using System . Windows . Forms ;
11- using static System . Net . WebRequestMethods ;
1211
1312namespace HPIZArchiver
1413{
@@ -20,6 +19,8 @@ public partial class MainForm : Form
2019 Dictionary < int , List < ListViewItem > > toHashCandidates = new Dictionary < int , List < ListViewItem > > ( ) ;
2120 Dictionary < string , List < ListViewItem > > sameContent = new Dictionary < string , List < ListViewItem > > ( ) ;
2221
22+ Dictionary < string , HpiArchive > cachedHPI = new Dictionary < string , HpiArchive > ( StringComparer . OrdinalIgnoreCase ) ;
23+
2324 Stopwatch timer = new Stopwatch ( ) ;
2425
2526 long totalSize = 0 ;
@@ -62,6 +63,7 @@ private void closeAllToolStripMenuItem_Click(object sender, EventArgs e)
6263 listViewFiles . Groups . Clear ( ) ;
6364 uniqueSources . Clear ( ) ;
6465 uniqueNames . Clear ( ) ;
66+ cachedHPI . Clear ( ) ;
6567 toHashCandidates . Clear ( ) ;
6668 sameContent . Clear ( ) ;
6769 totalSize = 0 ;
@@ -95,30 +97,18 @@ private void AddToListViewFiles(List<ListViewItem> itemList)
9597 }
9698
9799 foreach ( ListViewGroup group in listViewFiles . Groups )
98- if ( Directory . Exists ( group . Name ) )
99- {
100100 foreach ( var candidate in toHashCandidates . Values )
101101 if ( candidate . Count > 1 && candidate [ 0 ] . Group == group && candidate [ 0 ] . SubItems [ 8 ] . Text == string . Empty )
102102 {
103- candidate [ 0 ] . SubItems [ 8 ] . Text = Utils . CalculateSha256 ( ( string ) candidate [ 0 ] . SubItems [ 1 ] . Tag ) ;
104- if ( sameContent . ContainsKey ( candidate [ 0 ] . SubItems [ 8 ] . Text ) )
105- sameContent [ candidate [ 0 ] . SubItems [ 8 ] . Text ] . Add ( candidate [ 0 ] ) ;
106- else sameContent . Add ( candidate [ 0 ] . SubItems [ 8 ] . Text , new List < ListViewItem > ( ) { candidate [ 0 ] } ) ;
107- }
108- }
109- else
110- using ( HpiArchive hpia = HpiFile . Open ( group . Name ) )
111- foreach ( var candidate in toHashCandidates . Values )
112- if ( candidate . Count > 1 && candidate [ 0 ] . Group == group && candidate [ 0 ] . SubItems [ 8 ] . Text == string . Empty )
113- {
114- candidate [ 0 ] . SubItems [ 8 ] . Text = Utils . CalculateSha256 ( hpia . Entries [ candidate [ 0 ] . SubItems [ 1 ] . Text ] . Uncompress ( ) ) ;
103+ if ( Directory . Exists ( group . Name ) )
104+ candidate [ 0 ] . SubItems [ 8 ] . Text = Utils . CalculateSha256 ( Path . Combine ( group . Name , candidate [ 0 ] . SubItems [ 1 ] . Text ) ) ;
105+ else
106+ candidate [ 0 ] . SubItems [ 8 ] . Text = Utils . CalculateSha256 ( cachedHPI [ group . Name ] . Entries [ candidate [ 0 ] . SubItems [ 1 ] . Text ] . Uncompress ( ) ) ;
115107 if ( sameContent . ContainsKey ( candidate [ 0 ] . SubItems [ 8 ] . Text ) )
116108 sameContent [ candidate [ 0 ] . SubItems [ 8 ] . Text ] . Add ( candidate [ 0 ] ) ;
117109 else sameContent . Add ( candidate [ 0 ] . SubItems [ 8 ] . Text , new List < ListViewItem > ( ) { candidate [ 0 ] } ) ;
118110 }
119111
120-
121-
122112 SetRule ( dRules ) ;
123113 SetHighliths ( ) ;
124114 showHideColumns ( ) ;
@@ -163,6 +153,7 @@ internal async void openFilesStripMenuItem_Click(object sender, EventArgs e)
163153 if ( ! uniqueSources . Contains ( file ) )
164154 {
165155 uniqueSources . Add ( file ) ;
156+ cachedHPI . Add ( file , HpiFile . Open ( file ) ) ;
166157 var filesInfo = await Task . Run ( ( ) => GetListViewGroupItens ( file ) ) ;
167158 AddToListViewFiles ( filesInfo ) ;
168159 }
@@ -247,48 +238,45 @@ public List<ListViewItem> GetListViewGroupItens(string fullPath)
247238 else //HPI Files
248239 {
249240 var group = new ListViewGroup ( fullPath , Path . GetExtension ( fullPath ) . ToUpper ( ) + " File - " + fullPath ) ;
250- using ( HpiArchive hpia = HpiFile . Open ( fullPath ) )
241+ foreach ( var entry in cachedHPI [ fullPath ] . Entries )
251242 {
252- foreach ( var entry in hpia . Entries )
253- {
254- totalSize += entry . Value . UncompressedSize ;
255- totalCompressedSize += entry . Value . CompressedSizeCount ( ) ;
256-
257- ListViewItem lvItem = new ListViewItem ( new string [ ] {
258- String . Empty ,
259- entry . Key ,
260- Path . GetExtension ( entry . Key ) . ToUpper ( ) ,
261- entry . Value . UncompressedSize . ToString ( "N0" ) ,
262- entry . Value . CompressedSizeCount ( ) . ToString ( "N0" ) ,
263- entry . Value . Ratio ( ) . ToString ( "P1" ) ,
264- entry . Value . FlagCompression . ToString ( ) ,
265- entry . Value . OffsetOfCompressedData . ToString ( "X8" ) ,
266- String . Empty
267- } , group ) ;
243+ totalSize += entry . Value . UncompressedSize ;
244+ totalCompressedSize += entry . Value . CompressedSizeCount ( ) ;
268245
269- lvItem . SubItems [ 1 ] . Tag = fullPath ;
270- lvItem . SubItems [ 3 ] . Tag = entry . Value . UncompressedSize ;
271- lvItem . SubItems [ 4 ] . Tag = entry . Value . CompressedSizeCount ( ) ;
272- lvItem . SubItems [ 5 ] . Tag = entry . Value . Ratio ( ) ;
273- lvItem . SubItems [ 6 ] . Tag = entry . Value . FlagCompression ;
274- lvItem . Tag = fullPath ;
275- listColection . Add ( lvItem ) ;
246+ ListViewItem lvItem = new ListViewItem ( new string [ ] {
247+ String . Empty ,
248+ entry . Key ,
249+ Path . GetExtension ( entry . Key ) . ToUpper ( ) ,
250+ entry . Value . UncompressedSize . ToString ( "N0" ) ,
251+ entry . Value . CompressedSizeCount ( ) . ToString ( "N0" ) ,
252+ entry . Value . Ratio ( ) . ToString ( "P1" ) ,
253+ entry . Value . FlagCompression . ToString ( ) ,
254+ entry . Value . CompressedDataOffset . ToString ( "X8" ) ,
255+ String . Empty
256+ } , group ) ;
276257
277- if ( sha256ToolStripMenuItem . Checked || toHashCandidates . ContainsKey ( entry . Value . UncompressedSize ) )
278- {
279- var hash = Utils . CalculateSha256 ( entry . Value . Uncompress ( ) ) ;
280- lvItem . SubItems [ 8 ] . Text = hash ;
258+ lvItem . SubItems [ 1 ] . Tag = fullPath ;
259+ lvItem . SubItems [ 3 ] . Tag = entry . Value . UncompressedSize ;
260+ lvItem . SubItems [ 4 ] . Tag = entry . Value . CompressedSizeCount ( ) ;
261+ lvItem . SubItems [ 5 ] . Tag = entry . Value . Ratio ( ) ;
262+ lvItem . SubItems [ 6 ] . Tag = entry . Value . FlagCompression ;
263+ lvItem . Tag = fullPath ;
264+ listColection . Add ( lvItem ) ;
281265
282- if ( ! sha256ToolStripMenuItem . Checked )
283- toHashCandidates [ entry . Value . UncompressedSize ] . Add ( lvItem ) ;
266+ if ( sha256ToolStripMenuItem . Checked || toHashCandidates . ContainsKey ( entry . Value . UncompressedSize ) )
267+ {
268+ var hash = Utils . CalculateSha256 ( entry . Value . Uncompress ( ) ) ;
269+ lvItem . SubItems [ 8 ] . Text = hash ;
284270
285- if ( sameContent . ContainsKey ( hash ) )
286- sameContent [ hash ] . Add ( lvItem ) ;
287- else sameContent . Add ( hash , new List < ListViewItem > ( ) { lvItem } ) ;
288- }
289- else
290- toHashCandidates . Add ( entry . Value . UncompressedSize , new List < ListViewItem > ( ) { lvItem } ) ;
271+ if ( ! sha256ToolStripMenuItem . Checked )
272+ toHashCandidates [ entry . Value . UncompressedSize ] . Add ( lvItem ) ;
273+
274+ if ( sameContent . ContainsKey ( hash ) )
275+ sameContent [ hash ] . Add ( lvItem ) ;
276+ else sameContent . Add ( hash , new List < ListViewItem > ( ) { lvItem } ) ;
291277 }
278+ else
279+ toHashCandidates . Add ( entry . Value . UncompressedSize , new List < ListViewItem > ( ) { lvItem } ) ;
292280 }
293281 }
294282 return listColection ;
@@ -316,7 +304,7 @@ private async void toolStripExtractButton_Click(object sender, EventArgs e)
316304
317305 timer . Restart ( ) ;
318306
319- await Task . Run ( ( ) => HpiFile . DoExtraction ( sources , dialogExtractToFolder . SelectedPath , progress ) ) ;
307+ await Task . Run ( ( ) => HpiFile . DoExtraction ( sources , dialogExtractToFolder . SelectedPath , progress , cachedHPI ) ) ;
320308
321309 timer . Stop ( ) ;
322310
@@ -330,33 +318,25 @@ private async void toolStripExtractButton_Click(object sender, EventArgs e)
330318 }
331319 }
332320
333- public PathCollection GetCheckedFileNames ( )
321+ public FilePathCollection GetCheckedFileNames ( )
334322 {
335- PathCollection fileList = new PathCollection ( ) ;
323+ FilePathCollection fileList = new FilePathCollection ( ) ;
336324
337325 foreach ( ListViewItem item in listViewFiles . CheckedItems )
338- {
339- if ( fileList . ContainsKey ( item . Group . Name ) )
340- fileList [ item . Group . Name ] . Add ( item . SubItems [ 1 ] . Text ) ;
341- else
342- fileList . Add ( item . Group . Name , new SortedSet < string > ( ) { item . SubItems [ 1 ] . Text } ) ;
343- }
326+ fileList . AddOrReplace ( item . SubItems [ 1 ] . Text , item . Group . Name ) ;
344327
345328 return fileList ;
346329 }
347330
348- private async void compressCheckedFilesToolStripMenuItem_Click ( object sender , EventArgs e )
331+ public async void compressOrRepackCheckedFiles ( )
349332 {
350- if ( listViewFiles . CheckedItems . Count == 0 )
351- MessageBox . Show ( "Can't Compress: No files have been checked in the list." ) ;
352-
353- else if ( dialogSaveHpi . ShowDialog ( ) == DialogResult . OK )
333+ if ( dialogSaveHpi . ShowDialog ( ) == DialogResult . OK )
354334 {
355335 SetMode ( ArchiverMode . Busy ) ;
356336
357337 firstStatusLabel . Text = "Compressing... Last processed:" ;
358338
359- //Calculate total size and number of chunks
339+ //Calculate total size and number of chunks to max progressbar
360340 foreach ( ListViewItem item in listViewFiles . CheckedItems )
361341 progressBar . Maximum += FileEntry . CalculateChunkQuantity ( ( int ) item . SubItems [ 3 ] . Tag ) ;
362342
@@ -372,9 +352,29 @@ private async void compressCheckedFilesToolStripMenuItem_Click(object sender, Ev
372352
373353 var sources = GetCheckedFileNames ( ) ;
374354
375- timer . Restart ( ) ;
355+ var duplicateResults = new SortedDictionary < string , string > ( StringComparer . OrdinalIgnoreCase ) ;
356+
357+ foreach ( var sames in sameContent . Values )
358+ {
359+ string first = string . Empty ;
360+ SortedSet < string > orderedSames = new SortedSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
361+ foreach ( var item in sames )
362+ if ( item . Checked == true )
363+ orderedSames . Add ( item . SubItems [ 1 ] . Text ) ;
364+
365+ foreach ( var item in orderedSames )
366+ if ( first == string . Empty )
367+ first = item ;
368+ else if ( ! duplicateResults . ContainsKey ( item ) )
369+ duplicateResults . Add ( item , first ) ;
370+ }
371+
376372
377- await Task . Run ( ( ) => HpiFile . CreateFromManySources ( sources , dialogSaveHpi . FileName , flavor , progress ) ) ;
373+ duplicateResults = null ;
374+
375+ timer . Restart ( ) ;
376+
377+ await Task . Run ( ( ) => HpiFile . CreateFromManySources ( sources , dialogSaveHpi . FileName , flavor , progress , cachedHPI , duplicateResults ) ) ;
378378
379379 timer . Stop ( ) ;
380380
@@ -388,6 +388,22 @@ private async void compressCheckedFilesToolStripMenuItem_Click(object sender, Ev
388388 }
389389 }
390390
391+ private void compressCheckedFilesToolStripMenuItem_Click ( object sender , EventArgs e )
392+ {
393+ if ( listViewFiles . CheckedItems . Count == 0 )
394+ MessageBox . Show ( "Can't Compress: No files have been checked in the list." ) ;
395+ else
396+ compressOrRepackCheckedFiles ( ) ;
397+ }
398+
399+ private void mergeRepackCheckedFilesToolStripMenuItem_Click ( object sender , EventArgs e )
400+ {
401+ if ( listViewFiles . CheckedItems . Count == 0 )
402+ MessageBox . Show ( "Can't Merge/Repack: No files have been checked in the list." ) ;
403+ else
404+ compressOrRepackCheckedFiles ( ) ;
405+ }
406+
391407 private void selectAllToolStripMenuItem_Click ( object sender , EventArgs e )
392408 {
393409 for ( int i = 0 ; i < listViewFiles . Items . Count ; i ++ )
@@ -429,49 +445,6 @@ private void listViewFiles_ColumnClick(object sender, ColumnClickEventArgs e)
429445 }
430446 }
431447
432- private async void mergeRepackCheckedFilesToolStripMenuItem_Click ( object sender , EventArgs e )
433- {
434- if ( listViewFiles . CheckedItems . Count == 0 )
435- MessageBox . Show ( "Can't Merge/Repack: No files have been checked in the list." ) ;
436-
437- else if ( dialogSaveHpi . ShowDialog ( ) == DialogResult . OK )
438- {
439- SetMode ( ArchiverMode . Busy ) ;
440-
441- firstStatusLabel . Text = "Compressing... Last processed:" ;
442-
443- CompressionMethod flavor ;
444- Enum . TryParse ( flavorLevelComboBox . Text , out flavor ) ;
445-
446- //Calculate total size and number of chunks to max progressbar
447- foreach ( ListViewItem item in listViewFiles . CheckedItems )
448- progressBar . Maximum += FileEntry . CalculateChunkQuantity ( ( int ) item . SubItems [ 3 ] . Tag ) ;
449-
450- var progress = new Progress < string > ( last =>
451- {
452- secondStatusLabel . Text = last ;
453- progressBar . PerformStep ( ) ;
454- TaskbarProgress . SetValue ( this . Handle , progressBar . Value , progressBar . Maximum ) ;
455- } ) ;
456-
457- var sources = GetCheckedFileNames ( ) ;
458-
459- timer . Restart ( ) ;
460-
461- await Task . Run ( ( ) => HpiFile . CreateFromManySources ( sources , dialogSaveHpi . FileName , flavor , progress ) ) ;
462-
463- timer . Stop ( ) ;
464-
465- firstStatusLabel . Text = String . Format ( "Done! Elapsed time: {0}h {1}m {2}s {3}ms" , timer . Elapsed . Hours , timer . Elapsed . Minutes ,
466- timer . Elapsed . Seconds , timer . Elapsed . Milliseconds ) ;
467- progressBar . Value = progressBar . Maximum ;
468- secondStatusLabel . Text = dialogSaveHpi . FileName ;
469- secondStatusLabel . IsLink = true ;
470- TaskbarProgress . FlashWindow ( this . Handle , true ) ;
471- SetMode ( ArchiverMode . Finish ) ;
472- }
473- }
474-
475448 private void SetRule ( DuplicateRules rule )
476449 {
477450 dRules = rule ;
@@ -589,7 +562,7 @@ void SetHighliths()
589562
590563
591564 foreach ( ListViewItem item in listViewFiles . Items )
592- if ( ! FolderExtension . CheckKnow ( item . SubItems [ 1 ] . Text ) )
565+ if ( ! DirectoryExtensionPair . IsDirectoryExtensionKnow ( item . SubItems [ 1 ] . Text ) )
593566 if ( unknowFoldersExtensionToolStripMenuItem . Checked )
594567 item . BackColor = unknowFoldersExtensionToolStripMenuItem . BackColor ;
595568 else if ( item . BackColor == unknowFoldersExtensionToolStripMenuItem . BackColor )
0 commit comments