예제 #1
0
        /// <summary>
        /// Processes a data block in a JPA file located in the current file position
        /// </summary>
        /// <param name="dataBlockHeader">The header of the block being processed</param>
        /// <param name="token">A cancellation token, allowing the called to cancel the processing</param>
        public void ProcessDataBlock(ZipLocalFileHeader dataBlockHeader, CancellationToken token)
        {
            // Get the compression type
            TCompressionType CompressionType = TCompressionType.Uncompressed;

            switch (dataBlockHeader.CompressionMethod)
            {
            case 0:
                CompressionType = TCompressionType.Uncompressed;
                break;

            case 8:
                CompressionType = TCompressionType.GZip;
                break;

            case 12:
                CompressionType = TCompressionType.BZip2;
                break;

            default:
                throw new InvalidArchiveException(Language.ResourceManager.GetString("ERR_FORMAT_INVALID_COMPRESSION_METHOD"));
            }

            // Decide on the file type
            TEntityType EntityType = TEntityType.File;

            if (dataBlockHeader.Filename.EndsWith("/"))
            {
                EntityType = TEntityType.Directory;
            }
            else if (dataBlockHeader.VersionToExtract == BitConverter.ToUInt16(new byte[] { 0x10, 0x03 }, 0))
            {
                EntityType = TEntityType.Symlink;
            }

            // Process the data block
            ProcessDataBlock(dataBlockHeader.CompressedSize, dataBlockHeader.UncompressedSize, CompressionType,
                             EntityType, dataBlockHeader.Filename, token);
        }
예제 #2
0
        protected void ProcessDataBlock(ulong CompressedSize, ulong UncompressedSize, TCompressionType CompressionType, TEntityType EntityType, string EntityPath, CancellationToken token)
        {
            // Update the archive's progress record
            Progress.FilePosition         = (ulong)(SizesOfPartsAlreadyRead + InputStream.Position);
            Progress.RunningCompressed   += CompressedSize;
            Progress.RunningUncompressed += UncompressedSize;
            Progress.Status = ExtractionStatus.Running;

            // Create the event arguments we'll use when invoking the event
            ProgressEventArgs args = new ProgressEventArgs(Progress);

            // If we don't have a data writer we just need to skip over the data
            if (DataWriter == null)
            {
                if (CompressedSize > 0)
                {
                    SkipBytes((long)CompressedSize);

                    Progress.FilePosition += CompressedSize;
                }

                return;
            }

            // Is this a directory?
            switch (EntityType)
            {
            case TEntityType.Directory:
                DataWriter.MakeDirRecursive(DataWriter.GetAbsoluteFilePath(EntityPath));

                return;

            case TEntityType.Symlink:
                if (CompressedSize > 0)
                {
                    string strTarget = ReadUtf8String((int)CompressedSize);
                    DataWriter.MakeSymlink(strTarget, DataWriter.GetAbsoluteFilePath(EntityPath));
                }

                return;
            }

            // Begin writing to file
            DataWriter.StartFile(EntityPath);

            // Is this a zero length file?
            if (CompressedSize == 0)
            {
                DataWriter.StopFile();
                return;
            }

            switch (CompressionType)
            {
            case TCompressionType.Uncompressed:
                ProcessUncompressedDataBlock(CompressedSize, token);
                break;

            case TCompressionType.GZip:
                ProcessGZipDataBlock(CompressedSize, token);
                break;

            case TCompressionType.BZip2:
                ProcessBZip2DataBlock(CompressedSize, token);
                break;
            }

            // Stop writing data to the file
            DataWriter.StopFile();

            Progress.FilePosition += CompressedSize;
        }