コード例 #1
0
        public void InputStreamOwnership()
        {
            TrackedMemoryStream memStream = new TrackedMemoryStream();
            LzwInputStream      s         = new LzwInputStream(memStream);

            Assert.IsFalse(memStream.IsClosed, "Shouldnt be closed initially");
            Assert.IsFalse(memStream.IsDisposed, "Shouldnt be disposed initially");

            s.Close();

            Assert.IsTrue(memStream.IsClosed, "Should be closed after parent owner close");
            Assert.IsTrue(memStream.IsDisposed, "Should be disposed after parent owner close");

            memStream = new TrackedMemoryStream();
            s         = new LzwInputStream(memStream);

            Assert.IsFalse(memStream.IsClosed, "Shouldnt be closed initially");
            Assert.IsFalse(memStream.IsDisposed, "Shouldnt be disposed initially");

            s.IsStreamOwner = false;
            s.Close();

            Assert.IsFalse(memStream.IsClosed, "Should not be closed after parent owner close");
            Assert.IsFalse(memStream.IsDisposed, "Should not be disposed after parent owner close");
        }
コード例 #2
0
        /// <summary>
        /// Create Lzw file provider from byte[].
        ///
        /// Has one entry by name of <paramref name="entryName"/>.
        /// Reads the whole stream once just to get the entry length.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="entryName"></param>
        /// <param name="hintPath">(optional) clue of the file that is being opened</param>
        /// <param name="lastModified">Date time for folder entries</param>
        /// <exception cref="IOException"></exception>
        public LzwFileProvider(byte[] data, string entryName, string hintPath = null, DateTimeOffset?lastModified = default) : base(hintPath, lastModified)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            // Mutable long, and object to take closure reference to.
            long[] lengthContainer = new long[] { -1 };

            Stream opener()
            {
                MemoryStream ms = new MemoryStream(data);

                try
                {
                    LzwInputStream lzis = new LzwInputStream(ms)
                    {
                        IsStreamOwner = true
                    };
                    return(lengthContainer[0] < 0L ? lzis : (Stream) new LzwStreamFix(lzis, null, null, lengthContainer[0]));
                }
                catch (Exception) when(_closeStream(ms))
                {
                    throw new IOException($"Failed to read .Lzw from byte[]");
                }
            }

            // Calculate length by reading the whole thing.
            lengthContainer[0] = CalculateLength(opener);

            this.streamProvider        = new StreamOpener(opener, entryName, belatedDisposeList);
            this.root.files[entryName] = new ArchiveFileEntry(this.streamProvider, entryName, entryName, lengthContainer[0], lastModified ?? DateTimeOffset.MinValue);
        }
コード例 #3
0
        /// <summary>
        /// Create Lzw file provider from .z file.
        ///
        /// Has one entry by name of <paramref name="entryName"/>.
        /// Reads the whole stream once just to get the entry length.
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="entryName"></param>
        /// <param name="hintPath">(optional) clue of the file that is being opened</param>
        /// <param name="lastModified">Date time for folder entries</param>
        /// <exception cref="IOException"></exception>
        public LzwFileProvider(string filepath, string entryName, string hintPath = null, DateTimeOffset?lastModified = default) : base(hintPath, lastModified)
        {
            // Mutable long, and object to take closure reference to.
            long[] lengthContainer = new long[] { -1 };

            Func <Stream> opener = () =>
            {
                FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
                try
                {
                    LzwInputStream lzis = new LzwInputStream(fs);
                    lzis.IsStreamOwner = true;
                    return(lengthContainer[0] < 0L ? lzis : (Stream) new LzwStreamFix(lzis, null, null, lengthContainer[0]));
                }
                catch (Exception) when(_closeStream(fs))
                {
                    throw new IOException($"Failed to read .Lzw from {filepath}");
                }
            };

            // Calculate length by reading the whole thing.
            lengthContainer[0] = CalculateLength(opener);

            this.streamProvider        = new StreamOpener(opener, entryName, belatedDisposeList);
            this.root.files[entryName] = new ArchiveFileEntry(this.streamProvider, entryName, entryName, lengthContainer[0], lastModified ?? DateTimeOffset.MinValue);
        }
コード例 #4
0
        public void InputStreamOwnership()
        {
            var memStream = new TrackedMemoryStream();
            var s         = new LzwInputStream(memStream);

            Assert.IsFalse(memStream.IsClosed, "Shouldnt be closed initially");
            Assert.IsFalse(memStream.IsDisposed, "Shouldnt be disposed initially");

#if NET451
            s.Close();
#elif NETCOREAPP1_0
            s.Dispose();
#endif

            Assert.IsTrue(memStream.IsClosed, "Should be closed after parent owner close");
            Assert.IsTrue(memStream.IsDisposed, "Should be disposed after parent owner close");

            memStream = new TrackedMemoryStream();
            s         = new LzwInputStream(memStream);

            Assert.IsFalse(memStream.IsClosed, "Shouldnt be closed initially");
            Assert.IsFalse(memStream.IsDisposed, "Shouldnt be disposed initially");

            s.IsStreamOwner = false;
#if NET451
            s.Close();
#elif NETCOREAPP1_0
            s.Dispose();
#endif

            Assert.IsFalse(memStream.IsClosed, "Should not be closed after parent owner close");
            Assert.IsFalse(memStream.IsDisposed, "Should not be disposed after parent owner close");
        }
コード例 #5
0
        public void ZeroLengthInputStream()
        {
            LzwInputStream lis       = new LzwInputStream(new MemoryStream());
            bool           exception = false;

            try {
                lis.ReadByte();
            } catch {
                exception = true;
            }

            Assert.IsTrue(exception, "reading from an empty stream should cause an exception");
        }
コード例 #6
0
ファイル: Lzw.cs プロジェクト: zer09/Cosmos
        public static byte[] Decompress(byte[] data)
        {
            MemoryStream   ot           = new MemoryStream();
            LzwInputStream CompInStream = new LzwInputStream(new MemoryStream(data));
            int            ch           = CompInStream.ReadByte();

            while (ch != -1)
            {
                ot.WriteByte((byte)ch);
                ch = CompInStream.ReadByte();
            }
            return(ot.GetBuffer());
        }
コード例 #7
0
 /// <summary>
 /// Create Length override.
 /// </summary>
 /// <param name="sourceStream"></param>
 /// <param name="disposeHandle"></param>
 /// <param name="disposeAction"></param>
 /// <param name="newLength"></param>
 public LzwStreamFix(LzwInputStream sourceStream, IDisposable disposeHandle, Action disposeAction, long newLength) : base(sourceStream, disposeHandle, disposeAction)
 {
     this.newLength = newLength;
 }
コード例 #8
0
        public static void ExtractArchive(string archivePath, string destinationDirectory, CancellationTokenEx cancellationToken,
                                          ReportCompressionStatus reportCompressionStatus, AddProcessingEntry addProcessingEntry)
        {
            bool   isTar;
            Stream inputStream = new FileStream(archivePath, FileMode.Open, FileAccess.Read);

            switch (Path.GetExtension(archivePath).ToUpper())
            {
            case ".ZIP":
                var fastZip = new FastZip();
                fastZip.ExtractZip(inputStream, destinationDirectory, FastZip.Overwrite.Always, null, null, null,
                                   true, true);
                //TODO: Add progress
                return;

            case ".TAR":
                isTar = true;
                break;

            case ".GZ":
                inputStream = new GZipInputStream(inputStream)
                {
                    IsStreamOwner = true
                };
                isTar = archivePath.EndsWith(".tar.gz", StringComparison.OrdinalIgnoreCase);
                break;

            case ".BZ2":
                inputStream = new BZip2InputStream(inputStream)
                {
                    IsStreamOwner = true
                };
                isTar = archivePath.EndsWith(".tar.bz2", StringComparison.OrdinalIgnoreCase);
                break;

            case ".LZW":
                inputStream = new LzwInputStream(inputStream)
                {
                    IsStreamOwner = true
                };
                isTar = archivePath.EndsWith(".tar.lzw", StringComparison.OrdinalIgnoreCase);
                break;

            default:
                inputStream.Dispose();
                return;
            }

            Directory.CreateDirectory(destinationDirectory);

            using (inputStream)
            {
                if (isTar)
                {
                    using (TarArchive tarArchive = TarArchive.CreateInputTarArchive(inputStream))
                    {
                        TarEntry        lastEntry           = null;
                        ProcessingEntry lastProcessingEntry = null;

                        tarArchive.ProgressMessageEvent += (archive, entry, message) =>
                        {
                            if (lastEntry != entry)
                            {
                                if (lastEntry != null)
                                {
                                    lastProcessingEntry.Progress = 1;
                                    lastProcessingEntry.Size     = entry.Size;
                                    ThreadPool.QueueUserWorkItem(state => reportCompressionStatus(lastProcessingEntry));
                                }

                                lastEntry           = entry;
                                lastProcessingEntry = new ProcessingEntry
                                {
                                    Action       = ProcessingEntryAction.Extracting,
                                    CreationTime = DateTime.UtcNow,
                                    Path         = entry.File,
                                    Progress     = 0,
                                    Name         = entry.Name
                                };
                                ThreadPool.QueueUserWorkItem(state => addProcessingEntry(lastProcessingEntry));
                            }
                        };
                        tarArchive.ExtractContents(destinationDirectory);
                    }
                }
                else
                {
                    var filename            = Path.GetFileNameWithoutExtension(archivePath);
                    var destinationFilePath = Path.Combine(destinationDirectory, filename);

                    var processingEntry = new ProcessingEntry
                    {
                        Action        = ProcessingEntryAction.Extracting,
                        CreationTime  = DateTime.UtcNow,
                        IsDirectory   = false,
                        IsInterminate = false,
                        LastAccess    = DateTime.UtcNow,
                        Path          = destinationFilePath,
                        Name          = filename
                    };

                    byte[] dataBuffer = new byte[4096];
                    using (var destinationFileStream = new FileStream(destinationFilePath, FileMode.Create, FileAccess.ReadWrite))
                    {
                        addProcessingEntry(processingEntry);

                        StreamUtils.Copy(inputStream, destinationFileStream, dataBuffer, (sender, args) =>
                        {
                            processingEntry.Progress = args.PercentComplete / 100;
                            processingEntry.Size     = destinationFileStream.Length;
                            args.ContinueRunning     = !cancellationToken.IsCanceled;
                            ThreadPool.QueueUserWorkItem(state => reportCompressionStatus.Invoke(processingEntry));
                        },
                                         TimeSpan.FromSeconds(1), null, null);

                        if (cancellationToken.IsCanceled)
                        {
                            processingEntry.Progress = -1;
                            ThreadPool.QueueUserWorkItem(state => reportCompressionStatus.Invoke(processingEntry));
                            return;
                        }

                        processingEntry.Progress = 1;
                        processingEntry.Size     = destinationFileStream.Length;
                        ThreadPool.QueueUserWorkItem(state => reportCompressionStatus.Invoke(processingEntry));
                    }
                }
            }
        }