Example #1
0
        private void ParseRecord(BinaryReader reader,
                                 string fileName,
                                 long position,
                                 ZipIOCentralDirectoryBlock centralDir,
                                 ZipIOCentralDirectoryFileHeader centralDirFileHeader)
        {
            CheckDisposed();
            Debug.Assert(!_blockManager.Streaming, "Not legal in Streaming mode");

            _localFileHeader = ZipIOLocalFileHeader.ParseRecord(reader, _blockManager.Encoding);

            // Let's find out whether local file descriptor is there or not
            if (_localFileHeader.StreamingCreationFlag)
            {
                // seek forward by the uncompressed size
                _blockManager.Stream.Seek(centralDirFileHeader.CompressedSize, SeekOrigin.Current);
                _localFileDataDescriptor = ZipIOLocalFileDataDescriptor.ParseRecord(reader,
                                                                                    centralDirFileHeader.CompressedSize,
                                                                                    centralDirFileHeader.UncompressedSize,
                                                                                    centralDirFileHeader.Crc32,
                                                                                    _localFileHeader.VersionNeededToExtract);
            }
            else
            {
                _localFileDataDescriptor = null;
            }

            _offset    = position;
            _dirtyFlag = false;

            checked
            {
                _fileItemStream = new ZipIOFileItemStream(_blockManager,
                                                          this,
                                                          position + _localFileHeader.Size,
                                                          centralDirFileHeader.CompressedSize);
            }

            // init deflate stream if necessary
            if ((CompressionMethodEnum)_localFileHeader.CompressionMethod == CompressionMethodEnum.Deflated)
            {
                Debug.Assert(_fileItemStream.Position == 0, "CompressStream assumes base stream is at position zero");
                _deflateStream = new CompressStream(_fileItemStream, centralDirFileHeader.UncompressedSize);

                _crcCalculatingStream = new ProgressiveCrcCalculatingStream(_blockManager, _deflateStream, Crc32);
            }
            else if ((CompressionMethodEnum)_localFileHeader.CompressionMethod == CompressionMethodEnum.Stored)
            {
                _crcCalculatingStream = new ProgressiveCrcCalculatingStream(_blockManager, _fileItemStream, Crc32);
            }
            else
            {
                throw new NotSupportedException(SR.Get(SRID.ZipNotSupportedCompressionMethod));
            }

            Validate(fileName, centralDir, centralDirFileHeader);
        }
        /// <summary>
        /// Create a new LocalFileHeader
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="encoding"></param>
        /// <param name="compressionMethod"></param>
        /// <param name="deflateOption"></param>
        /// <param name="streaming">true if in streaming mode</param>
        /// <returns></returns>
        internal static ZipIOLocalFileHeader CreateNew(string fileName, Encoding encoding,
                                                       CompressionMethodEnum compressionMethod, DeflateOptionEnum deflateOption, bool streaming)
        {
            //this should be ensured by the higher levels
            Debug.Assert(Enum.IsDefined(typeof(CompressionMethodEnum), compressionMethod));
            Debug.Assert(Enum.IsDefined(typeof(DeflateOptionEnum), deflateOption));

            byte[] asciiName = encoding.GetBytes(fileName);
            if (asciiName.Length > ZipIOBlockManager.MaxFileNameSize)
            {
                throw new ArgumentOutOfRangeException("fileName");
            }

            ZipIOLocalFileHeader header = new ZipIOLocalFileHeader();

            header._signature         = ZipIOLocalFileHeader._signatureConstant;
            header._compressionMethod = (ushort)compressionMethod;

            if (streaming)
            {
                header._versionNeededToExtract = (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat;
            }
            else
            {
                header._versionNeededToExtract = (UInt16)ZipIOBlockManager.CalcVersionNeededToExtractFromCompression(
                    compressionMethod);
            }

            if (compressionMethod != CompressionMethodEnum.Stored)
            {
                Debug.Assert(deflateOption != DeflateOptionEnum.None); //this should be ensured by the higher levels
                header.DeflateOption = deflateOption;
            }

            if (streaming)
            {
                // set bit 3
                header.StreamingCreationFlag = true;
            }

            header._lastModFileDateTime = ZipIOBlockManager.ToMsDosDateTime(DateTime.Now);

            header._fileNameLength = (UInt16)asciiName.Length;

            header._fileName         = asciiName;
            header._extraField       = ZipIOExtraField.CreateNew(!streaming /* creating padding if it is not in streaming creation mode */);
            header._extraFieldLength = header._extraField.Size;

            //populate frequently used field with user friendly data representations
            header._stringFileName = fileName;

            return(header);
        }
        /// <summary>
        /// Create a new LocalFileHeader
        /// </summary>
        /// <param name="fileName"></param> 
        /// <param name="encoding"></param>
        /// <param name="compressionMethod"></param> 
        /// <param name="deflateOption"></param> 
        /// <param name="streaming">true if in streaming mode</param>
        /// <returns></returns> 
        internal static ZipIOLocalFileHeader CreateNew(string fileName, Encoding encoding,
            CompressionMethodEnum compressionMethod, DeflateOptionEnum deflateOption, bool streaming)
        {
            //this should be ensured by the higher levels 
            Debug.Assert(Enum.IsDefined(typeof(CompressionMethodEnum), compressionMethod));
            Debug.Assert(Enum.IsDefined(typeof(DeflateOptionEnum), deflateOption)); 
 
            byte[] asciiName = encoding.GetBytes(fileName);
            if (asciiName.Length > ZipIOBlockManager.MaxFileNameSize) 
            {
                throw new ArgumentOutOfRangeException("fileName");
            }
 
            ZipIOLocalFileHeader header = new ZipIOLocalFileHeader();
            header._signature = ZipIOLocalFileHeader._signatureConstant; 
            header._compressionMethod = (ushort)compressionMethod; 

            if (streaming) 
                header._versionNeededToExtract = (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat;
            else
            {
                header._versionNeededToExtract = (UInt16)ZipIOBlockManager.CalcVersionNeededToExtractFromCompression( 
                                                    compressionMethod);
            } 
 
            if (compressionMethod != CompressionMethodEnum.Stored)
            { 
                Debug.Assert(deflateOption != DeflateOptionEnum.None); //this should be ensured by the higher levels
                header.DeflateOption =  deflateOption;
            }
 
            if (streaming)
            { 
                // set bit 3 
                header.StreamingCreationFlag = true;
            } 

            header._lastModFileDateTime = ZipIOBlockManager.ToMsDosDateTime(DateTime.Now);

            header._fileNameLength = (UInt16)asciiName.Length; 

            header._fileName = asciiName; 
            header._extraField = ZipIOExtraField.CreateNew(!streaming /* creating padding if it is not in streaming creation mode */); 
            header._extraFieldLength = header._extraField.Size;
 
            //populate frequently used field with user friendly data representations
            header._stringFileName = fileName;

            return header; 
        }
Example #4
0
        internal static ZipIOLocalFileBlock CreateNew(ZipIOBlockManager blockManager,
                                                      string fileName,
                                                      CompressionMethodEnum compressionMethod,
                                                      DeflateOptionEnum deflateOption)
        {
            //this should be ensured by the higher levels
            Debug.Assert(Enum.IsDefined(typeof(CompressionMethodEnum), compressionMethod));
            Debug.Assert(Enum.IsDefined(typeof(DeflateOptionEnum), deflateOption));

            ZipIOLocalFileBlock block = new ZipIOLocalFileBlock(blockManager, false, false);

            block._localFileHeader = ZipIOLocalFileHeader.CreateNew
                                         (fileName,
                                         blockManager.Encoding,
                                         compressionMethod,
                                         deflateOption, blockManager.Streaming);

            // if in streaming mode - force to Zip64 mode in case the streams get large
            if (blockManager.Streaming)
            {
                block._localFileDataDescriptor = ZipIOLocalFileDataDescriptor.CreateNew();
            }

            block._offset    = 0; // intial value, that is not too important for the brand new File item
            block._dirtyFlag = true;

            block._fileItemStream = new  ZipIOFileItemStream(blockManager,
                                                             block,
                                                             block._offset + block._localFileHeader.Size,
                                                             0);

            // create deflate wrapper if necessary
            if (compressionMethod == CompressionMethodEnum.Deflated)
            {
                Debug.Assert(block._fileItemStream.Position == 0, "CompressStream assumes base stream is at position zero");
                // Pass bool to indicate that this stream is "new" and must be dirty so that
                // the valid empty deflate stream is emitted (2-byte sequence - see CompressStream for details).
                block._deflateStream = new CompressStream(block._fileItemStream, 0, true);

                block._crcCalculatingStream = new ProgressiveCrcCalculatingStream(blockManager, block._deflateStream);
            }
            else
            {
                block._crcCalculatingStream = new ProgressiveCrcCalculatingStream(blockManager, block._fileItemStream);
            }

            return(block);
        }
        internal static ZipIOLocalFileHeader ParseRecord(BinaryReader reader, Encoding encoding)
        {
            ZipIOLocalFileHeader header = new ZipIOLocalFileHeader();

            header._signature = reader.ReadUInt32();
            header._versionNeededToExtract = reader.ReadUInt16();
            header._generalPurposeBitFlag  = reader.ReadUInt16();
            header._compressionMethod      = reader.ReadUInt16();
            header._lastModFileDateTime    = reader.ReadUInt32();
            header._crc32            = reader.ReadUInt32();
            header._compressedSize   = reader.ReadUInt32();
            header._uncompressedSize = reader.ReadUInt32();
            header._fileNameLength   = reader.ReadUInt16();
            header._extraFieldLength = reader.ReadUInt16();

            header._fileName = reader.ReadBytes(header._fileNameLength);

            // check for the ZIP 64 version and escaped values
            ZipIOZip64ExtraFieldUsage zip64extraFieldUsage = ZipIOZip64ExtraFieldUsage.None;

            if (header._versionNeededToExtract >= (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat)
            {
                if (header._compressedSize == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.CompressedSize;
                }
                if (header._uncompressedSize == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.UncompressedSize;
                }
            }

            // if the ZIP 64 record is missing from the Extra Field then the  zip64extraFieldUsage
            // value will be ignored and default ZipIOZip64ExtraFieldUsage.None value will be used/assumed
            header._extraField = ZipIOExtraField.ParseRecord(reader,
                                                             zip64extraFieldUsage,
                                                             header._extraFieldLength);

            //populate frequently used field with user friendly data representations
            header._stringFileName = ZipIOBlockManager.ValidateNormalizeFileName(encoding.GetString(header._fileName));

            header.Validate();

            return(header);
        }
        internal static ZipIOLocalFileHeader ParseRecord(BinaryReader reader, Encoding encoding) 
        {
            ZipIOLocalFileHeader header = new ZipIOLocalFileHeader(); 

            header._signature =  reader.ReadUInt32();
            header._versionNeededToExtract = reader.ReadUInt16();
            header._generalPurposeBitFlag = reader.ReadUInt16(); 
            header._compressionMethod = reader.ReadUInt16();
            header._lastModFileDateTime = reader.ReadUInt32(); 
            header._crc32 = reader.ReadUInt32(); 
            header._compressedSize = reader.ReadUInt32();
            header._uncompressedSize = reader.ReadUInt32(); 
            header._fileNameLength = reader.ReadUInt16();
            header._extraFieldLength = reader.ReadUInt16();

            header._fileName = reader.ReadBytes(header._fileNameLength); 

            // check for the ZIP 64 version and escaped values 
            ZipIOZip64ExtraFieldUsage zip64extraFieldUsage = ZipIOZip64ExtraFieldUsage.None; 
            if (header._versionNeededToExtract >= (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat)
            { 
                if (header._compressedSize == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.CompressedSize;
                } 
                if (header._uncompressedSize == UInt32.MaxValue)
                { 
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.UncompressedSize; 
                }
            } 

            // if the ZIP 64 record is missing from the Extra Field then the  zip64extraFieldUsage
            // value will be ignored and default ZipIOZip64ExtraFieldUsage.None value will be used/assumed
            header._extraField = ZipIOExtraField.ParseRecord(reader, 
                                             zip64extraFieldUsage,
                                            header._extraFieldLength); 
 
            //populate frequently used field with user friendly data representations
            header._stringFileName = ZipIOBlockManager.ValidateNormalizeFileName(encoding.GetString(header._fileName)); 

            header.Validate();

            return header; 
        }