Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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));
        }
Beispiel #7
0
        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());
        }
Beispiel #8
0
        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);
                    }
                }
        }
Beispiel #9
0
        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));
            }
        }
Beispiel #10
0
 private void SetCapacity(ArchiveFileEntry entry)
 {
     entry.ContentCapacity = (int)(Options.AbsoluteReserve + Options.RelativeReserve * entry.UncompressedContentSize / 100 + entry.UncompressedContentSize);
 }