protected override void ProcessInputFile(ArcArchive archive, InputFileInfo fileInfo, IProgress?progress) { if (archive.TryGetEntry(fileInfo.EntryName, out var entry)) { if (entry.LastWriteTime < fileInfo.LastWriteTime) { { using var entryStream = entry.OpenWrite(); CopyFileToStream(fileInfo.FileName, entryStream, progress); } entry.LastWriteTime = fileInfo.LastWriteTime; // TODO: Console.Out.WriteLine("Added: " + inputFileInfo.EntryName); } } else { entry = archive.CreateEntry(fileInfo.EntryName); { using var entryStream = entry.OpenWrite(); CopyFileToStream(fileInfo.FileName, entryStream, progress); } entry.LastWriteTime = fileInfo.LastWriteTime; // TODO: Console.Out.WriteLine("Added: " + inputFileInfo.EntryName); } }
private void ListArchive(ArcArchive archive) { foreach (var entry in archive.GetEntries()) { Console.Out.WriteLine(entry.Name); } }
private bool VerifyArchive(ArcArchive archive, IProgress?progress) { if (progress != null) { long totalLength = 0; foreach (var entry in archive.GetEntries()) { totalLength += entry.Length; } progress.SetMaxValue(totalLength); } var numberOfErrors = 0; foreach (var entry in archive.GetEntries()) { progress?.SetMessage(entry.Name); var result = VerifyEntry(entry, progress); if (result) { // Console.Out.WriteLine("[ OK ] " + entry.Name); } else { Console.Error.WriteLine(string.Format("Invalid hash for entry: {0}", entry.Name)); numberOfErrors++; } } return(numberOfErrors == 0); }
private void ExtractArchive(ArcArchive archive) { using var progressBar = CreateProgressBar(); progressBar.Title = "Extracting..."; long totalLength = 0; foreach (var entry in archive.GetEntries()) { totalLength += entry.Length; } progressBar?.SetMaxValue(totalLength); foreach (var entry in archive.GetEntries()) { progressBar?.SetMessage(entry.Name); // Assuming what validated entry name is safe to use in path // (with combining). EntryNameUtilities.Validate(entry.Name); var outputPath = Path.Combine(OutputPath, entry.Name); var directoryPath = Path.GetDirectoryName(outputPath); Directory.CreateDirectory(directoryPath); using var inputStream = entry.Open(); DateTimeOffset?lastWriteTime = SetLastWriteTime ? entry.LastWriteTime : (DateTimeOffset?)null; WriteFile(outputPath, inputStream, lastWriteTime, progressBar); } }
private void ItmFileOpenConfig_Click(object sender, EventArgs e) { if (Directory.Exists(ArcArchive.ExtractDir)) { if (Directory.GetFiles(ArcArchive.ExtractDir).Length > 0) { if (UiMessages.Question(@"You already have an extracted config file; load it instead?")) { LoadTreeView(ArcArchive.ExtractDir); return; } } } var filePath = GetFileName(); if (!string.IsNullOrEmpty(filePath)) { CurrentFile = filePath; //decrypt and extract ArcArchive.ProcessConfigArchive(filePath); //UI setup LoadTreeView(ArcArchive.ExtractDir); itmRefreshConfig.Enabled = true; } }
private void ItmRefreshConfig_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(CurrentFile)) { ArcArchive.ProcessConfigArchive(CurrentFile); } }
protected override void ProcessInputFile(ArcArchive archive, InputFileInfo fileInfo, IProgress?progress) { if (archive.Exists(fileInfo.EntryName)) { _entryNamesToKeep.Add(fileInfo.EntryName); } }
private bool VerifyArchive(string path) { using var progressBar = CreateProgressBar(); progressBar.SetTitle("Verifying..."); using var archive = ArcArchive.Open(path); return(VerifyArchive(archive, progressBar)); }
private void RebuildArchive(string path) { var archiveOptions = new ArcArchiveOptions { Mode = ArcArchiveMode.Create, // Layout = Format, CompressionLevel = CompressionLevel, SafeWrite = false, HeaderAreaLength = HeaderAreaSize, ChunkLength = ChunkSize, // TODO: UseLibDeflate = setup from global option }; using var progressBar = CreateProgressBar(); using var inputArchive = ArcArchive.Open(ArchivePath, ArcArchiveMode.Read); if (Format == default) { archiveOptions.Format = inputArchive.GetFormat(); } else { archiveOptions.Format = Format; } long totalLength = 0; foreach (var entry in inputArchive.GetEntries()) { totalLength += entry.Length; } progressBar.SetMaxValue(totalLength); if (true || SafeWrite) { var outputStream = new MemoryStream(); using var outputArchive = ArcArchive.Open(outputStream, archiveOptions); CopyEntries(inputArchive, outputArchive, progressBar); outputArchive.Dispose(); inputArchive.Dispose(); Utilities.ReplaceFile(ArchivePath, outputStream, progressBar); } else { // TODO: implement writing into different file throw Error.NotImplemented(); } }
private void ProcessArchive(string path) { if (SafeWrite) { MemoryStream archiveStream; { using var progressBar = CreateProgressBar(); progressBar.Title = "Reading..."; //progressBar.Message = path; archiveStream = Utilities.ReadFile(path, progressBar); } var inputLength = archiveStream.Length; // TODO: use short Open method with only mode as parameter bool wasModified; { using var progressBar = CreateProgressBar(); using var archive = ArcArchive.Open(archiveStream, new ArcArchiveOptions { Mode = ArcArchiveMode.Update }); ProcessArchive(archive, progressBar); wasModified = archive.Modified; } var outputLength = archiveStream.Length; // Save... if (wasModified) { // TODO: Write to the temp file, and then rename/replace file. using var progressBar = CreateProgressBar(); progressBar.Title = "Writing..."; //progressBar.Message = path; Utilities.ReplaceFile(path, archiveStream, progressBar); } // TODO: Customize output. var percentageWin = (double)outputLength / inputLength * 100.0; Console.Out.WriteLine($"[done] Processed: {path}"); Console.Out.WriteLine($" {outputLength - inputLength:N0} bytes, {percentageWin:N1}%"); } else { // TODO: Open stream using var progressBar = CreateProgressBar(); using var archive = ArcArchive.Open(path, new ArcArchiveOptions { Mode = ArcArchiveMode.Update }); ProcessArchive(archive, progress: null); // TODO: InputLength, OutputLength properties } }
protected override void PostProcessArchive(ArcArchive archive, IProgress?progress) { progress?.SetMaxValue(archive.Count); foreach (var entry in archive.GetEntries()) { if (!_entryNamesToKeep.Contains(entry.Name)) { entry.Remove(); // TODO: Write action into log } progress?.AddValue(1); } }
private void InfoArchive(ArcArchive archive) { var sb = new StringBuilder(); var format = archive.GetFormat(); sb.AppendFormat(" Format: {0} ({1}) ({2})\n", format.Version, FormatTag(format), FormatCapabilities(format)); sb.AppendFormat("\n"); int nonCompressedEntryCount = 0; long totalLength = 0; long totalCompressedLength = 0; foreach (var entry in archive.GetEntries()) { totalLength += entry.Length; totalCompressedLength += entry.CompressedLength; nonCompressedEntryCount += (int)entry.EntryType == 1 ? 1 : 0; } double totalCompressedLengthPercentage = 0; if (totalCompressedLength > 0) { totalCompressedLengthPercentage = (double)totalCompressedLength / totalLength * 100.0; } var li = archive.GetLayoutInfo(); sb.AppendFormat(" # of Entries: {0:N0}\n", li.EntryCount); sb.AppendFormat(" Total Length: {0:N0} bytes\n", totalLength); sb.AppendFormat(" Total Compressed Length: {0:N0} bytes ({1:N1}%)\n", totalCompressedLength, totalCompressedLengthPercentage); sb.AppendFormat(" # of Non-Compressed Entries: {0:N0}\n", nonCompressedEntryCount); sb.AppendFormat(" # of Removed Entries: {0:N0}\n", li.RemovedEntryCount); sb.AppendFormat("\n"); sb.AppendFormat(" # of Chunks: {0:N0}\n", li.ChunkCount); sb.AppendFormat(" # of Used Chunks: {0:N0}\n", li.LiveChunkCount); sb.AppendFormat(" # of Unordered Chunks: {0:N0}\n", li.UnorderedChunkCount); sb.AppendFormat("\n"); sb.AppendFormat(" # of Free Segments: {0:N0}\n", li.FreeSegmentCount); sb.AppendFormat(" Free Segment Space: {0:N0} bytes\n", li.FreeSegmentBytes); sb.AppendFormat("\n"); sb.AppendFormat(" Can Compact: {0}\n", li.CanCompact ? "Yes" : "No"); sb.AppendFormat(" Can Defragment: {0}\n", li.CanDefragment ? "Yes" : "No"); Console.Out.Write(sb.ToString()); }
public int Run() { if (!File.Exists(ArchivePath)) { // TODO: Use common error helpers, or validators. Console.Error.WriteLine("File does not exist: " + ArchivePath); return(1); } Check.That(EntryNames.Count > 0); { using var progressBar = CreateProgressBar(); progressBar.Title = "Removing..."; using var archive = ArcArchive.Open(ArchivePath, new ArcArchiveOptions { Mode = ArcArchiveMode.Update, SafeWrite = SafeWrite, }); progressBar.SetMaxValue(EntryNames.Count); // TODO: Glob support needed. foreach (var entryName in EntryNames) { progressBar.Message = entryName; // TODO: Use common helper. var normalizedEntryName = entryName.Replace('\\', '/'); if (!PreserveCase) { normalizedEntryName = normalizedEntryName.ToLowerInvariant(); } if (archive.TryGetEntry(normalizedEntryName, out var entry)) { entry.Remove(); // TODO: Log result } } } return(0); }
private void ItmFetchFromModem_Click(object sender, EventArgs e) { try { //test authentication var success = ArcLogin.IsAuthenticated(); if (success) { var cfg = new CgiConfigFile(); var file = cfg.GrabFile(); if (file != null) { if (file.Length > 0) { ArcArchive.ProcessConfigArchive(file); //update UI LoadTreeView(ArcArchive.ExtractDir); } else { UiMessages.Warning(@"Configuration file from modem returned 0 bytes; operation failed.", @"Data Error"); } } else { UiMessages.Warning(@"Configuration file from modem returned null bytes; operation failed.", @"Data Error"); } } else { UiMessages.Warning(@"Authentication required; please authenticate first."); } } catch (Exception ex) { UiMessages.Error(ex.ToString()); } }
protected override void ProcessArchive(ArcArchive archive, IProgress?progress) { if (_defragment) { progress?.SetTitle("Defragmenting..."); archive.Defragment(progress); } if (_repack) { progress?.SetTitle("Repacking..."); archive.Repack(_compressionLevel, progress); } else { progress?.SetTitle("Compacting..."); archive.Compact(progress); } }
private void CopyEntries(ArcArchive inputArchive, ArcArchive outputArchive, IProgress?progress) { foreach (var inputEntry in inputArchive.GetEntries()) { progress?.SetMessage(inputEntry.Name); CompressionLevel?compressionLevel = PreserveStore && (int)inputEntry.EntryType == 1 ? CompressionLevel.NoCompression : (CompressionLevel?)null; var outputEntry = outputArchive.CreateEntry(inputEntry.Name); { using var inputStream = inputEntry.Open(); using var outputStream = outputEntry.OpenWrite(compressionLevel); CopyStream(inputStream, outputStream, progress); } outputEntry.Timestamp = inputEntry.Timestamp; } }
protected abstract void ProcessInputFile(ArcArchive archive, InputFileInfo fileInfo, IProgress?progress);
protected override void PostProcessArchive(ArcArchive archive, IProgress?progress) { }
private void ExtractArchive(string path) { using var archive = ArcArchive.Open(path); ExtractArchive(archive); }
private void InfoArchive(string path) { using var archive = ArcArchive.Open(path); InfoArchive(archive); }
protected abstract void PostProcessArchive(ArcArchive archive, IProgress?progress);
public int Run() { Check.True(InputPaths.Count > 0); var archiveOptions = new ArcArchiveOptions { // Mode Format = Format, CompressionLevel = CompressionLevel, SafeWrite = SafeWrite, HeaderAreaLength = HeaderAreaSize, ChunkLength = ChunkSize, // TODO: UseLibDeflate = setup from global option }; var archiveExist = File.Exists(ArchivePath); archiveOptions.Mode = archiveExist ? ArcArchiveMode.Update : ArcArchiveMode.Create; long totalInputLength = 0; var inputFileInfos = new List <InputFileInfo>(); { using var progressBar = CreateProgressBar(); progressBar.Title = "Gathering input files..."; var inputs = GetAllInputs(); foreach (var inputFile in inputs) { progressBar.Message = inputFile; var fileInfo = new FileInfo(inputFile); totalInputLength += fileInfo.Length; var info = new InputFileInfo { FileName = inputFile, EntryName = CreateEntryName(inputFile), LastWriteTime = new DateTimeOffset(fileInfo.LastWriteTimeUtc), }; inputFileInfos.Add(info); } if (!PreserveCase) { var hashSet = new HashSet <string>(StringComparer.Ordinal); foreach (var x in inputFileInfos) { if (!hashSet.Add(x.EntryName)) { throw Error.InvalidOperation("Invalid casing. Final entry names must be unique."); } } } // Validate Entry Names foreach (var x in inputFileInfos) { EntryNameUtilities.Validate(x.EntryName); } } { using var progressBar = CreateProgressBar(); progressBar.Title = GetProcessInputFilesTitle(); using var archive = ArcArchive.Open(ArchivePath, archiveOptions); progressBar.SetMaxValue(totalInputLength); foreach (var inputFileInfo in inputFileInfos) { progressBar.Message = inputFileInfo.FileName; ProcessInputFile(archive, inputFileInfo, progressBar); } PostProcessArchive(archive, progressBar); } return(0); }
private void ListArchive(string path) { using var archive = ArcArchive.Open(path); ListArchive(archive); }