Example #1
0
        public void Save(Stream output, IProgress <ProgressReport> progress)
        {
            CheckDisposed();

            using (var archiveStream = CreateTemporaryStream())
            {
                using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true))
                {
                    BuildArchive(archive, progress);
                }  // close archive

                archiveStream.Seek(0, SeekOrigin.Begin);

                CompressionUtility.Compress(archiveStream, output, progress);
            }  // close archiveStream
        }
        public void Save(string archivePath, IProgress <ProgressReport> progress)
        {
            CheckDisposed();

            using (var archiveStream = CreateTemporaryStream())
            {
                using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true))
                {
                    BuildArchive(archive, progress);
                }  // close archive

                archiveStream.Seek(0, SeekOrigin.Begin);

                using (var lzmaStream = File.Create(archivePath))
                {
                    CompressionUtility.Compress(archiveStream, lzmaStream, progress);
                }
            }  // close archiveStream
        }
        public void Extract(string compressedArchivePath, string outputDirectory, IProgress <ProgressReport> progress)
        {
            using (var archiveStream = CreateTemporaryFileStream())
            {
                // decompress the LZMA stream
                using (var lzmaStream = File.OpenRead(compressedArchivePath))
                {
                    CompressionUtility.Decompress(lzmaStream, archiveStream, progress);
                }

                var archivePath = ((FileStream)archiveStream).Name;

                // reset the uncompressed stream
                archiveStream.Seek(0, SeekOrigin.Begin);

                // read as a zip archive
                using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Read))
                    using (var tlArchive = new ThreadLocalZipArchive(archivePath, archive))
                    {
                        List <ExtractOperation>            extractOperations = new List <ExtractOperation>();
                        Dictionary <string, ExtractSource> sourceCache       = new Dictionary <string, ExtractSource>();

                        // process the index to determine all extraction operations
                        var indexEntry = archive.GetEntry(IndexFileName);
                        using (var indexReader = new StreamReader(indexEntry.Open()))
                        {
                            Dictionary <string, ZipOperation> zipOperations = new Dictionary <string, ZipOperation>(StringComparer.OrdinalIgnoreCase);
                            for (var line = indexReader.ReadLine(); line != null; line = indexReader.ReadLine())
                            {
                                var lineParts = line.Split(pipeSeperator);
                                if (lineParts.Length != 2)
                                {
                                    throw new Exception("Unexpected index line format, too many '|'s.");
                                }

                                string target = lineParts[0];
                                string source = lineParts[1];

                                ExtractSource extractSource;
                                if (!sourceCache.TryGetValue(source, out extractSource))
                                {
                                    sourceCache[source] = extractSource = new ExtractSource(source, _externalFiles, tlArchive);
                                }

                                var zipSeperatorIndex = target.IndexOf("::", StringComparison.OrdinalIgnoreCase);

                                if (zipSeperatorIndex != -1)
                                {
                                    string zipRelativePath = target.Substring(0, zipSeperatorIndex);
                                    string zipEntryName    = target.Substring(zipSeperatorIndex + 2);
                                    string destinationPath = Path.Combine(outputDirectory, zipRelativePath);

                                    // operations on a zip file will be sequential
                                    ZipOperation currentZipOperation;

                                    if (!zipOperations.TryGetValue(destinationPath, out currentZipOperation))
                                    {
                                        extractOperations.Add(currentZipOperation = new ZipOperation(destinationPath));
                                        zipOperations.Add(destinationPath, currentZipOperation);
                                    }
                                    currentZipOperation.AddEntry(zipEntryName, extractSource);
                                }
                                else
                                {
                                    string destinationPath = Path.Combine(outputDirectory, target);
                                    extractOperations.Add(new CopyOperation(extractSource, destinationPath));
                                }
                            }
                        }

                        int opsExecuted = 0;
                        // execute all operations
                        //foreach(var extractOperation in extractOperations)
                        extractOperations.AsParallel().ForAll(extractOperation =>
                        {
                            extractOperation.DoOperation();
                            progress.Report(LocalizableStrings.Expanding, Interlocked.Increment(ref opsExecuted), extractOperations.Count);
                        });
                    }
            }
        }