/// <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); }
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; }