public bool IsUncompressed() { foreach (ArchiveEntryBase child in Childs) { if (child.Type == ArchiveEntryType.Archive) { ArchiveArchiveEntry archiveEntry = (ArchiveArchiveEntry)child; if (archiveEntry.MetricsEntry.Compression != Compression.None || archiveEntry.ListingEntry.Compression != Compression.None || archiveEntry.ContentEntry.Compression != Compression.None) { return(false); } } else if (child.Type == ArchiveEntryType.File) { ArchiveFileEntry fileEntry = (ArchiveFileEntry)child; if (fileEntry.Compression != Compression.None) { return(false); } } } return(true); }
private bool TryAddChildArchive(string path, ArchiveFileEntry entry, ArchiveArchiveEntry parentArchive) { Action <ArchiveArchiveEntry, ArchiveFileEntry> valueSetter; switch (Path.GetExtension(entry.Name)) { case ".fs": valueSetter = (a, e) => a.ContentEntry = e; break; case ".fl": valueSetter = (a, e) => a.ListingEntry = e; break; case ".fi": valueSetter = (a, e) => a.MetricsEntry = e; break; default: return(false); } path = Path.ChangeExtension(path, null); ArchiveArchiveEntry archive = _childArchives.GetOrAdd(path, p => new ArchiveArchiveEntry(Path.ChangeExtension(entry.Name, null))); valueSetter(archive, entry); if (archive.IsComplete) { _childArchives.TryRemove(path, out archive); parentArchive.AddEntry(archive); } return(true); }
public SortedList <int, ArchiveFileEntry> GetOrderedFileEntries() { SortedList <int, ArchiveFileEntry> list = new SortedList <int, ArchiveFileEntry>(); foreach (ArchiveEntryBase entry in Childs) { switch (entry.Type) { case ArchiveEntryType.Archive: { ArchiveArchiveEntry archiveEntry = (ArchiveArchiveEntry)entry; list.Add(archiveEntry.MetricsEntry.Index, archiveEntry.MetricsEntry); list.Add(archiveEntry.ListingEntry.Index, archiveEntry.ListingEntry); list.Add(archiveEntry.ContentEntry.Index, archiveEntry.ContentEntry); break; } case ArchiveEntryType.File: { ArchiveFileEntry fileEntry = (ArchiveFileEntry)entry; list.Add(fileEntry.Index, fileEntry); break; } } } return(list); }
private void MoveContent(ArchiveArchiveEntry[] oldArchives, ArchiveArchiveEntry[] newArchives, ArchiveFileEntry[] newMetrics, ArchiveFileEntry[] newListing, ArchiveArchiveEntry newParent, ArchiveDirectoryEntry newDirectory) { for (int i = 0; i < oldArchives.Length; i++) { ArchiveArchiveEntry oldArchive = oldArchives[i]; ArchiveArchiveEntry newArchive = newArchives[i]; ArchiveFileEntry newContent = oldArchive.ContentEntry.Clone(); { newContent.Compression = Compression.None; newContent.ContentOffset = newParent.CurrentPosition; newArchive.ContentEntry = newContent; } newArchive.MetricsEntry = newMetrics[i]; newArchive.ListingEntry = newListing[i]; newArchive.ContentEntry = newContent; foreach (ArchiveFileEntry oldChild in oldArchive.Childs.OfType <ArchiveFileEntry>()) { MoveFile(oldChild, newArchive, newDirectory); } foreach (ArchiveArchiveEntry oldChild in oldArchive.Childs.OfType <ArchiveArchiveEntry>()) { MoveArchive(oldChild, newArchive, newDirectory); } newContent.UncompressedContentSize = newArchive.CurrentPosition; SetCapacity(newContent); newParent.CurrentPosition += newContent.ContentCapacity; } }
private void MoveFile(ArchiveFileEntry oldFile, ArchiveArchiveEntry newParent, ArchiveDirectoryEntry newDirectory) { ArchiveFileEntry newFile = oldFile.Clone(); { newFile.Compression = Compression.None; newFile.ContentOffset = newParent.CurrentPosition; SetCapacity(newFile); newParent.CurrentPosition += newFile.ContentCapacity; } newParent.AddEntry(newFile); newDirectory.AddEntry(oldFile.GetFullPath(), newFile); }
private void Uncompress(ArchiveFileEntry file) { _input.Position = file.ContentOffset; file.ContentOffset = (int)_output.Position; Progress.NullSafeInvoke(this, new ProgressArgs(file, 0, file.UncompressedContentSize)); if (file.Compression == Compression.None) { _input.CopyTo(_output, file.UncompressedContentSize, _buff); } else { _input.Seek(4, SeekOrigin.Current); LZSStream lzs = new LZSStream(_input, _output); lzs.Decompress(file.UncompressedContentSize); } Progress.NullSafeInvoke(this, new ProgressArgs(file, file.UncompressedContentSize, file.UncompressedContentSize)); }
private ArchiveFileEntry[] MoveListing(ArchiveArchiveEntry[] oldArchives, ArchiveArchiveEntry[] newArchives, ArchiveArchiveEntry newParent) { List <ArchiveFileEntry> result = new List <ArchiveFileEntry>(oldArchives.Length); for (int i = 0; i < oldArchives.Length; i++) { ArchiveArchiveEntry oldArchive = oldArchives[i]; ArchiveArchiveEntry newArchive = newArchives[i]; ArchiveFileEntry newListing = oldArchive.ListingEntry.Clone(); { newListing.Compression = Compression.None; newListing.ContentOffset = newParent.CurrentPosition; newArchive.ListingEntry = newListing; SetCapacity(newListing); newParent.CurrentPosition += newListing.ContentCapacity; } result.Add(newListing); } return(result.ToArray()); }
private void ReadInformation(ArchiveArchiveEntry parentArchive, Stream metricsStream, Stream listingStream) { _childArchives.Clear(); using (BinaryReader mbr = new BinaryReader(metricsStream)) using (StreamReader lsr = new StreamReader(listingStream, Encoding.GetEncoding(1251))) { int index = 0; while (!lsr.EndOfStream) { string path = lsr.ReadLine(); if (string.IsNullOrEmpty(path)) { break; } int uncompressedContentSize = mbr.ReadInt32(); int contentOffset = mbr.ReadInt32(); int compression = mbr.ReadInt32(); ArchiveFileEntry entry = new ArchiveFileEntry(Path.GetFileName(path)) { Index = index++, UncompressedContentSize = uncompressedContentSize, ContentOffset = contentOffset, Compression = (Compression)compression }; if (TryAddChildArchive(path, entry, parentArchive)) { continue; } parentArchive.AddEntry(entry); _info.RootDirectory.AddEntry(path, entry); } } }
private void WriteContent(MemoryMappedFile memoryFile, Stream outputStream, ArchiveInformation inputInfo, ArchiveInformation outputInfo) { List <ArchiveFileEntry> inputFiles = inputInfo.RootArchive.Expand(); List <ArchiveFileEntry> outputFiles = outputInfo.RootArchive.Expand(); for (int i = 0; i < inputFiles.Count; i++) { ArchiveFileEntry inputEntry = inputFiles[i]; ArchiveFileEntry outputEntry = outputFiles[i]; if (inputEntry.Name != outputEntry.Name) { throw new Exception("Порядок элементов в иерархиях изменился."); } using (Stream inputStream = memoryFile.CreateViewStream(inputEntry.GetAbsoluteOffset(), inputEntry.UncompressedContentSize)) { outputStream.Seek(outputEntry.GetAbsoluteOffset(), SeekOrigin.Begin); inputStream.CopyTo(outputStream); } Progress.NullSafeInvoke(this, new ProgressArgs(_info.ContentFilePath, Interlocked.Add(ref _processedSize, inputEntry.UncompressedContentSize), _totalProgress)); } }
private void SetCapacity(ArchiveFileEntry entry) { entry.ContentCapacity = (int)(Options.AbsoluteReserve + Options.RelativeReserve * entry.UncompressedContentSize / 100 + entry.UncompressedContentSize); }