private void Init(IInArchive archive, Stream stream, int filesCount, uint fileIndex, SevenZipExtractor extractor)
 {
     CommonInit(archive, filesCount, extractor);
     _fileStream = new OutStreamWrapper(stream, false);
     _fileStream.BytesWritten += IntEventArgsHandler;
     _fileIndex = fileIndex;
 }
Exemple #2
0
            public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
            {
                var stream = _streams?.ElementAt((int)index);

                if (askExtractMode != AskMode.Extract || stream == null)
                {
                    outStream = null;
                    return(0);
                }

                outStream = new OutStreamWrapper(stream, true);
                return(0);
            }
        /// <summary>
        /// Called when the archive was extracted
        /// </summary>
        /// <param name="operationResult"></param>
        public void SetOperationResult(OperationResult operationResult)
        {
            if (operationResult != OperationResult.Ok && ReportErrors)
            {
                switch (operationResult)
                {
                case OperationResult.CrcError:
                    AddException(new ExtractionFailedException("File is corrupted. Crc check has failed."));
                    break;

                case OperationResult.DataError:
                    AddException(new ExtractionFailedException("File is corrupted. Data error has occured."));
                    break;

                case OperationResult.UnsupportedMethod:
                    AddException(new ExtractionFailedException("Unsupported method error has occured."));
                    break;
                }
            }
            else
            {
                if (_fileStream != null && !_fileIndex.HasValue)
                {
                    try
                    {
                        _fileStream.BytesWritten -= IntEventArgsHandler;
                        _fileStream.Dispose();
                    }
                    catch (ObjectDisposedException) { }
                    _fileStream = null;
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
                var iea = new FileInfoEventArgs(
                    _extractor.ArchiveFileData[_currentIndex], PercentDoneEventArgs.ProducePercentDone(_doneRate));
                OnFileExtractionFinished(iea);
                if (iea.Cancel)
                {
                    Canceled = true;
                }
            }
        }
        public void Dispose()
        {
            GC.RemoveMemoryPressure(MEMORY_PRESSURE);

            if (_fileStream != null)
            {
                try
                {
                    _fileStream.Dispose();
                }
                catch (ObjectDisposedException) { }
                _fileStream = null;
            }
            if (_fakeStream != null)
            {
                try
                {
                    _fakeStream.Dispose();
                }
                catch (ObjectDisposedException) { }
                _fakeStream = null;
            }
        }
        /// <summary>
        /// Called when the archive was extracted
        /// </summary>
        /// <param name="operationResult"></param>
        public void SetOperationResult(OperationResult operationResult)
        {
            if (operationResult != OperationResult.Ok && ReportErrors)
            {
                switch (operationResult)
                {
                case OperationResult.CrcError:
                    AddException(new ExtractionFailedException("File is corrupted. Crc check has failed."));
                    break;

                case OperationResult.DataError:
                    AddException(new ExtractionFailedException("File is corrupted. Data error has occured."));
                    break;

                case OperationResult.UnsupportedMethod:
                    AddException(new ExtractionFailedException("Unsupported method error has occured."));
                    break;

                case OperationResult.Unavailable:
                    AddException(new ExtractionFailedException("File is unavailable."));
                    break;

                case OperationResult.UnexpectedEnd:
                    AddException(new ExtractionFailedException("Unexpected end of file."));
                    break;

                case OperationResult.DataAfterEnd:
                    AddException(new ExtractionFailedException("Data after end of archive."));
                    break;

                case OperationResult.IsNotArc:
                    AddException(new ExtractionFailedException("File is not archive."));
                    break;

                case OperationResult.HeadersError:
                    AddException(new ExtractionFailedException("Archive headers error."));
                    break;

                case OperationResult.WrongPassword:
                    AddException(new ExtractionFailedException("Wrong password."));
                    break;

                default:
                    AddException(new ExtractionFailedException($"Unexpected operation result: {operationResult}"));
                    break;
                }
            }
            else
            {
                if (_fileStream != null && !_fileIndex.HasValue)
                {
                    try
                    {
                        _fileStream.BytesWritten -= IntEventArgsHandler;
                        _fileStream.Dispose();
                    }
                    catch (ObjectDisposedException) { }
                    _fileStream = null;
                }
                var iea = new FileInfoEventArgs(
                    _extractor.ArchiveFileData[_currentIndex], PercentDoneEventArgs.ProducePercentDone(_doneRate));
                OnFileExtractionFinished(iea);
                if (iea.Cancel)
                {
                    Canceled = true;
                }
            }
        }
        /// <summary>
        /// Sets output stream for writing unpacked data
        /// </summary>
        /// <param name="index">Current file index</param>
        /// <param name="outStream">Output stream pointer</param>
        /// <param name="askExtractMode">Extraction mode</param>
        /// <returns>0 if OK</returns>
        public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode)
        {
            outStream = null;

            if (Canceled)
            {
                return(-1);
            }
            _currentIndex = (int)index;
            if (askExtractMode == AskMode.Extract)
            {
                var fileName = _directory;
                if (!_fileIndex.HasValue)
                {
                    #region Extraction to a file

                    if (_actualIndexes == null || _actualIndexes.Contains(index))
                    {
                        var data = new PropVariant();
                        _archive.GetProperty(index, ItemPropId.Path, ref data);
                        string entryName = NativeMethods.SafeCast(data, "");

                        #region Get entryName

                        if (String.IsNullOrEmpty(entryName))
                        {
                            if (_filesCount == 1)
                            {
                                var archName = Path.GetFileName(_extractor.FileName);
                                archName = archName.Substring(0, archName.LastIndexOf('.'));
                                if (!archName.EndsWith(".tar", StringComparison.OrdinalIgnoreCase))
                                {
                                    archName += ".tar";
                                }
                                entryName = archName;
                            }
                            else
                            {
                                entryName = "[no name] " + index.ToString(CultureInfo.InvariantCulture);
                            }
                        }

                        #endregion

                        try
                        {
                            fileName = Path.Combine(RemoveIllegalCharacters(_directory, true), RemoveIllegalCharacters(_directoryStructure ? entryName : Path.GetFileName(entryName)));
                            ValidateFileNameAndCreateDirectory(fileName);
                        }
                        catch (Exception e)
                        {
                            AddException(e);
                            goto FileExtractionStartedLabel;
                        }

                        _archive.GetProperty(index, ItemPropId.IsDirectory, ref data);
                        if (!NativeMethods.SafeCast(data, false))
                        {
                            #region Branch

                            _archive.GetProperty(index, ItemPropId.LastWriteTime, ref data);
                            var time = NativeMethods.SafeCast(data, DateTime.MinValue);
                            if (File.Exists(fileName))
                            {
                                var fnea = new FileOverwriteEventArgs(fileName);
                                OnFileExists(fnea);
                                if (fnea.Cancel)
                                {
                                    Canceled = true;
                                    return(-1);
                                }
                                if (String.IsNullOrEmpty(fnea.FileName))
                                {
                                    outStream = _fakeStream;

                                    goto FileExtractionStartedLabel;
                                }
                                fileName = fnea.FileName;
                            }
                            try
                            {
                                _fileStream = new OutStreamWrapper(File.Create(fileName), fileName, time, true);
                            }
                            catch (Exception e)
                            {
                                if (e is FileNotFoundException)
                                {
                                    AddException(
                                        new IOException("The file \"" + fileName +
                                                        "\" was not extracted due to the File.Create fail."));
                                }
                                else
                                {
                                    AddException(e);
                                }
                                outStream = _fakeStream;
                                goto FileExtractionStartedLabel;
                            }
                            _fileStream.BytesWritten += IntEventArgsHandler;
                            outStream = _fileStream;

                            #endregion
                        }
                        else
                        {
                            #region Branch

                            if (!Directory.Exists(fileName))
                            {
                                try
                                {
                                    Directory.CreateDirectory(fileName);
                                }
                                catch (Exception e)
                                {
                                    AddException(e);
                                }
                                outStream = _fakeStream;
                            }

                            #endregion
                        }
                    }
                    else
                    {
                        outStream = _fakeStream;
                    }

                    #endregion
                }
                else
                {
                    #region Extraction to a stream

                    if (index == _fileIndex)
                    {
                        outStream  = _fileStream;
                        _fileIndex = null;
                    }
                    else
                    {
                        outStream = _fakeStream;
                    }

                    #endregion
                }

FileExtractionStartedLabel:
                _doneRate += 1.0f / _filesCount;
                var iea = new FileInfoEventArgs(
                    _extractor.ArchiveFileData[(int)index], PercentDoneEventArgs.ProducePercentDone(_doneRate));
                OnFileExtractionStarted(iea);
                if (iea.Cancel)
                {
                    if (!String.IsNullOrEmpty(fileName))
                    {
                        _fileStream.Dispose();
                        if (File.Exists(fileName))
                        {
                            try
                            {
                                File.Delete(fileName);
                            }
                            catch (Exception e)
                            {
                                AddException(e);
                            }
                        }
                    }
                    Canceled = true;
                    return(-1);
                }
            }
            return(0);
        }
 private void Init(IInArchive archive, Stream stream, int filesCount, uint fileIndex, SevenZipExtractor extractor)
 {
     CommonInit(archive, filesCount, extractor);
     _fileStream = new OutStreamWrapper(stream, false);
     _fileStream.BytesWritten += IntEventArgsHandler;
     _fileIndex = fileIndex;
 }
 public void Dispose()
 {
     #if !WINCE
     GC.RemoveMemoryPressure(MEMORY_PRESSURE);
     #endif
     if (_fileStream != null)
     {
         try
         {
             _fileStream.Dispose();
         }
         catch (ObjectDisposedException) { }
         _fileStream = null;
     }
     if (_fakeStream != null)
     {
         try
         {
             _fakeStream.Dispose();
         }
         catch (ObjectDisposedException) { }
         _fakeStream = null;
     }
 }