예제 #1
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        internal static ZipIOLocalFileBlock SeekableLoad(ZipIOBlockManager blockManager,
                                                         string fileName)
        {
            Debug.Assert(!blockManager.Streaming);
            Debug.Assert(blockManager.CentralDirectoryBlock.FileExists(fileName));

            // Get info from the central directory
            ZipIOCentralDirectoryBlock      centralDir           = blockManager.CentralDirectoryBlock;
            ZipIOCentralDirectoryFileHeader centralDirFileHeader = centralDir.GetCentralDirectoryFileHeader(fileName);

            long localHeaderOffset = centralDirFileHeader.OffsetOfLocalHeader;
            bool folderFlag        = centralDirFileHeader.FolderFlag;
            bool volumeLabelFlag   = centralDirFileHeader.VolumeLabelFlag;

            blockManager.Stream.Seek(localHeaderOffset, SeekOrigin.Begin);

            ZipIOLocalFileBlock block = new ZipIOLocalFileBlock(blockManager, folderFlag, volumeLabelFlag);

            block.ParseRecord(
                blockManager.BinaryReader,
                fileName,
                localHeaderOffset,
                centralDir,
                centralDirFileHeader);

            return(block);
        }
        private void  UpdateFromLocalFileBlock(ZipIOLocalFileBlock fileBlock)
        {
            Debug.Assert(DiskNumberStart == 0);

            _signature             = _signatureConstant;
            _generalPurposeBitFlag = fileBlock.GeneralPurposeBitFlag;
            _compressionMethod     = (UInt16)fileBlock.CompressionMethod;
            _lastModFileDateTime   = fileBlock.LastModFileDateTime;
            _crc32 = fileBlock.Crc32;

            // file name is easy to copy
            _fileNameLength = (UInt16)fileBlock.FileName.Length; // this is safe cast as file name is always validate for size
            _fileName       = _encoding.GetBytes(fileBlock.FileName);
            _stringFileName = fileBlock.FileName;

            // this will properly update the 32 or zip 64 fields
            UpdateZip64Structures(fileBlock.CompressedSize,
                                  fileBlock.UncompressedSize,
                                  fileBlock.Offset);

            // Previous instruction may determine that we don't really need 4.5, but we
            // want to ensure that the version is identical with what is stored in the local file header.
            Debug.Assert(_versionNeededToExtract <= fileBlock.VersionNeededToExtract, "Should never be making this smaller");

            _versionNeededToExtract = fileBlock.VersionNeededToExtract;

            // These fields are intentionally ignored, as they are not present in the local header
            //_fileCommentLength;
            //_fileComment;
            //_diskNumberStart;
            //_internalFileAttributes;
            //_externalFileAttributes;
        }
예제 #3
0
        //------------------------------------------------------
        // Internal NON API Constructor (this constructor is marked as internal
        // and isNOT part of the ZIP IO API surface)
        //  It supposed to be called only by the ZipArchive class
        //------------------------------------------------------
        internal ZipFileInfo(ZipArchive zipArchive, ZipIOLocalFileBlock fileBlock)
        {
            Debug.Assert((fileBlock != null) && (zipArchive != null));
            _fileBlock  = fileBlock;
            _zipArchive = zipArchive;
#if DEBUG
            // validate that date time is legal
            DateTime dt = LastModFileDateTime;
#endif
        }
예제 #4
0
        internal void AddFileBlock(ZipIOLocalFileBlock fileBlock)
        {
            _dirtyFlag = true;

            ZipIOCentralDirectoryFileHeader fileHeader =
                ZipIOCentralDirectoryFileHeader.CreateNew
                    (_blockManager.Encoding, fileBlock);

            CentralDirectoryDictionary.Add(fileHeader.FileName, fileHeader);
        }
예제 #5
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        /// <summary>
        /// Constructor - streaming and non-streaming mode
        /// </summary>
        /// <param name="baseStream"></param>
        /// <param name="access"></param>
        /// <param name="blockManager">block manager</param>
        /// <param name="block">associated block</param>
        internal ZipIOModeEnforcingStream(Stream baseStream, FileAccess access,
                                          ZipIOBlockManager blockManager,
                                          ZipIOLocalFileBlock block)
        {
            Debug.Assert(baseStream != null);

            _baseStream   = baseStream;
            _access       = access;
            _blockManager = blockManager;
            _block        = block;
        }
 internal bool UpdateIfNeeded(ZipIOLocalFileBlock fileBlock)
 {
     if (CheckIfUpdateNeeded(fileBlock))
     {
         UpdateFromLocalFileBlock(fileBlock);
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #7
0
        public void UpdateReferences(bool closingFlag)
        {
            // we just need to ask Block Manager for the new Values for each header
            // there are 2 distinct cases here
            //    1. local file data is mapped . loaded and might have been changed in size and position
            //    2. local file data is not  loaded and might have been changed only in position (not in size)

            foreach (IZipIOBlock block in _blockManager)
            {
                ZipIOLocalFileBlock   localFileBlock   = block as ZipIOLocalFileBlock;
                ZipIORawDataFileBlock rawDataFileBlock = block as ZipIORawDataFileBlock;

                if (localFileBlock != null)
                {
                    // this is case 1 data is mapped and loaded, so we only need to find the matching
                    // Centraldirectory record and update it
                    Debug.Assert(CentralDirectoryDictionary.Contains(localFileBlock.FileName));

                    ZipIOCentralDirectoryFileHeader centralDirFileHeader =
                        (ZipIOCentralDirectoryFileHeader)CentralDirectoryDictionary[localFileBlock.FileName];

                    if (centralDirFileHeader.UpdateIfNeeded(localFileBlock))
                    {
                        //update was required let's mark ourselves as dirty
                        _dirtyFlag = true;
                    }
                }
                //check whether we deal with raw data block and it was moved
                else if (rawDataFileBlock != null)
                {
                    long diskImageShift = rawDataFileBlock.DiskImageShift;
                    if (diskImageShift != 0)
                    {
                        //this is case #2 data isn't loaded based on the shift in the RawData Block
                        // we need to move all overlapping central directory references
                        foreach (ZipIOCentralDirectoryFileHeader centralDirFileHeader in CentralDirectoryDictionary.Values)
                        {
                            // check whether central dir header points into the region of a moved RawDataBlock
                            if (rawDataFileBlock.DiskImageContains(centralDirFileHeader.OffsetOfLocalHeader))
                            {
                                centralDirFileHeader.MoveReference(diskImageShift);
                                _dirtyFlag = true;
                            }
                        }
                    }
                }
            }
        }
예제 #8
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 ZipIOCentralDirectoryFileHeader CreateNew(Encoding encoding, ZipIOLocalFileBlock fileBlock)
        {
            ZipIOCentralDirectoryFileHeader header = new ZipIOCentralDirectoryFileHeader(encoding);
 
            // initialize fields that are not duplicated in the local file block(header)
            header._fileCommentLength =0; 
            header._fileComment = null; 
            header._diskNumberStart = 0;
            header._internalFileAttributes = 0; 
            header._externalFileAttributes = 0;
            header._versionMadeBy = (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat;
            header._extraField = ZipIOExtraField.CreateNew(false /* no padding */);
 
            // update the rest of the fields based on the local file header
            header.UpdateFromLocalFileBlock(fileBlock); 
 
            return header;
        } 
        internal static ZipIOCentralDirectoryFileHeader CreateNew(Encoding encoding, ZipIOLocalFileBlock fileBlock)
        {
            ZipIOCentralDirectoryFileHeader header = new ZipIOCentralDirectoryFileHeader(encoding);

            // initialize fields that are not duplicated in the local file block(header)
            header._fileCommentLength      = 0;
            header._fileComment            = null;
            header._diskNumberStart        = 0;
            header._internalFileAttributes = 0;
            header._externalFileAttributes = 0;
            header._versionMadeBy          = (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat;
            header._extraField             = ZipIOExtraField.CreateNew(false /* no padding */);

            // update the rest of the fields based on the local file header
            header.UpdateFromLocalFileBlock(fileBlock);

            return(header);
        }
예제 #11
0
        /// <summary>
        ///  This method will result in a complete parsing of the EndOfCentralDirectory
        /// and CentralDirectory records (if it hasn't been done yet).
        /// After that (assuming no duplicates were found). It will create in appropriate
        /// in memory Local FileHeaders and Central Directory Headers.
        /// </summary>
        internal ZipFileInfo AddFile(string zipFileName, CompressionMethodEnum compressionMethod, DeflateOptionEnum deflateOption)
        {
            CheckDisposed();

            if (_openAccess == FileAccess.Read)
            {
                throw new InvalidOperationException(SR.Get(SRID.CanNotWriteInReadOnlyMode));
            }

            // Validate parameteres
            zipFileName = ZipIOBlockManager.ValidateNormalizeFileName(zipFileName);

            if ((compressionMethod != CompressionMethodEnum.Stored) &&
                (compressionMethod != CompressionMethodEnum.Deflated))
            {
                throw new ArgumentOutOfRangeException("compressionMethod");
            }

            // non-contiguous range requires more complex test
            if (deflateOption < DeflateOptionEnum.Normal || (
                    deflateOption > DeflateOptionEnum.SuperFast && deflateOption != DeflateOptionEnum.None))
            {
                throw new ArgumentOutOfRangeException("deflateOption");
            }

            // Check for duplicates ,
            if (FileExists(zipFileName))
            {
                throw new System.InvalidOperationException(SR.Get(SRID.AttemptedToCreateDuplicateFileName));
            }

            // Create Local File Block through Block Manager
            ZipIOLocalFileBlock fileBlock = _blockManager.CreateLocalFileBlock(zipFileName, compressionMethod, deflateOption);

            //build new ZipFileInfo and add reference to the collection, so we can keep track of the instances of the ZipFileInfo,
            // that were given out  and invalidate any collection that was returned on GetFiles calls
            ZipFileInfo zipFileInfo = new ZipFileInfo(this, fileBlock);

            ZipFileInfoDictionary.Add(zipFileInfo.Name, zipFileInfo);

            return(zipFileInfo);
        }
예제 #12
0
        /////////////////////////////
        // Internal Constructor
        /////////////////////////////
        internal ZipIOFileItemStream(ZipIOBlockManager blockManager,    // blockManager is only needed
                                                                        // to pass through to it Flush requests
                                     ZipIOLocalFileBlock block,         // our owning block - needed for Streaming scenarios
                                     long persistedOffset,              // to map to the stream
                                     long persistedSize)                // to map to the stream )
        {
            Debug.Assert(blockManager != null);
            Debug.Assert(persistedOffset >= 0);
            Debug.Assert(persistedSize >= 0);
            Debug.Assert(block != null);

            _persistedOffset = persistedOffset;
            _offset          = persistedOffset;
            _persistedSize   = persistedSize;

            _blockManager = blockManager;
            _block        = block;

            _currentStreamLength = persistedSize;
        }
        private bool CheckIfUpdateNeeded(ZipIOLocalFileBlock fileBlock)
        {
            // there is a special case for the _generalPurposeBitFlag.Bit #3
            // it could be set in the local file header indicating streaming
            // creation, while it doesn't need to be set in the Central directory
            // so having
            //  (fileBlock.GeneralPurposeBitFlag == 8 && and _generalPurposeBitFlag  == 0)
            // is a valid case when update is not required

            // let's compare the 3rd bit of the general purpose bit flag
            bool localFileHeaderStreamingFlag = (0 != (fileBlock.GeneralPurposeBitFlag & _streamingBitMask));
            bool centralDirStreamingFlag      = (0 != (_generalPurposeBitFlag & _streamingBitMask));

            if (!localFileHeaderStreamingFlag && centralDirStreamingFlag)
            {
                // the mismatch if local file header in non streaming but the central directory is in streaming mode
                // all the other combinations do not require an update and valid as is
                // this includes scenario when local file header is in streaming and central dir is not
                return(true);
            }

            Debug.Assert(String.CompareOrdinal(_stringFileName, fileBlock.FileName) == 0);

            return
                ((_signature != _signatureConstant) ||
                 (_versionNeededToExtract != fileBlock.VersionNeededToExtract) ||
                 (_generalPurposeBitFlag != fileBlock.GeneralPurposeBitFlag) ||
                 (_compressionMethod != (UInt16)fileBlock.CompressionMethod) ||
                 (_crc32 != fileBlock.Crc32) ||
                 (CompressedSize != fileBlock.CompressedSize) ||
                 (UncompressedSize != fileBlock.UncompressedSize) ||
                 (OffsetOfLocalHeader != fileBlock.Offset));

            // These fields are intentionally ignored, as they are not present in the local header
            //_fileCommentLength;
            //_fileComment;
            //_diskNumberStart;
            //_internalFileAttributes;
            //_externalFileAttributes;
        }
예제 #14
0
        /// <summary>
        ///  This method will result in a complete parsing of the EndOfCentralDirectory
        /// and CentralDirectory records (if it hasn't been done yet).
        /// After that (assuming the file was found). It will parse the apropriate local file block
        /// header and data descriptor (if present).
        /// </summary>
        internal ZipFileInfo GetFile(string zipFileName)
        {
            CheckDisposed();

            if (_openAccess == FileAccess.Write)
            {
                throw new InvalidOperationException(SR.Get(SRID.CanNotReadInWriteOnlyMode));
            }

            // Validate parameteres
            zipFileName = ZipIOBlockManager.ValidateNormalizeFileName(zipFileName);

            // try to get it from the ZipFileInfo dictionary
            if (ZipFileInfoDictionary.Contains(zipFileName))
            {
                // this ZipFileInfo was already built through AddFile or GetFile(s)
                // we have this cached
                return((ZipFileInfo)(ZipFileInfoDictionary[zipFileName]));
            }
            else
            {
                // we need to check whether it is present in the central directory
                if (!FileExists(zipFileName))
                {
                    throw new InvalidOperationException(SR.Get(SRID.FileDoesNotExists));
                }

                // Load Local File Block through Block Manager
                ZipIOLocalFileBlock fileBlock = _blockManager.LoadLocalFileBlock(zipFileName);

                // build new ZipFileInfo and add reference to the collection, so we can keep track of the instances of the ZipFileInfo,
                // that were given out  and invalidate any collection that was returned on GetFiles calls
                ZipFileInfo zipFileInfo = new ZipFileInfo(this, fileBlock);

                //this should invalidate any outstanding collections
                ZipFileInfoDictionary.Add(zipFileInfo.Name, zipFileInfo);

                return(zipFileInfo);
            }
        }
예제 #15
0
        //-----------------------------------------------------
        // Internal NON API Constructor (this constructor is marked as internal
        // and isNOT part of the ZIP IO API surface)
        //  It supposed to be called only by the ZipArchive class 
        //------------------------------------------------------
        internal ZipFileInfo(ZipArchive zipArchive, ZipIOLocalFileBlock fileBlock) 
        { 
            Debug.Assert((fileBlock != null) && (zipArchive != null));
            _fileBlock = fileBlock; 
            _zipArchive = zipArchive;
#if DEBUG
            // validate that date time is legal
            DateTime dt = LastModFileDateTime; 
#endif
        } 
예제 #16
0
        internal void RemoveLocalFileBlock(ZipIOLocalFileBlock localFileBlock) 
        {
            CheckDisposed(); 
 
            Debug.Assert(!_openStreaming, "Not legal in Streaming mode");
 
            Debug.Assert(localFileBlock != null, " At this point local File block must be preloaded");
            Debug.Assert(CentralDirectoryBlock.FileExists(localFileBlock.FileName),
                            " At this point local File block must be mapped in central directory");
 

            // remove it from our list 
            _blockList.Remove(localFileBlock); 

            // remove this from Central Directory 
            CentralDirectoryBlock.RemoveFileBlock(localFileBlock.FileName);
            DirtyFlag = true;

            // at this point we can Dispose it to make sure that any calls 
            // to this file block through outstanding indirect references will result in object Disposed exception
            localFileBlock.Dispose(); 
        } 
예제 #17
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        /// <summary>
        /// Constructor - streaming and non-streaming mode
        /// </summary>
        /// <param name="baseStream"></param>
        /// <param name="access"></param>
        /// <param name="blockManager">block manager</param>
        /// <param name="block">associated block</param>
        internal ZipIOModeEnforcingStream(Stream baseStream, FileAccess access,
            ZipIOBlockManager blockManager,
            ZipIOLocalFileBlock block)
        {
            Debug.Assert(baseStream != null);

            _baseStream = baseStream;
            _access = access;
            _blockManager = blockManager;
            _block = block;
        }
        internal void AddFileBlock(ZipIOLocalFileBlock fileBlock)
        {
            _dirtyFlag = true;

            ZipIOCentralDirectoryFileHeader fileHeader = 
                        ZipIOCentralDirectoryFileHeader.CreateNew
                                                            (_blockManager.Encoding, fileBlock);
            
            CentralDirectoryDictionary.Add(fileHeader.FileName, fileHeader);
        }
        private bool CheckIfUpdateNeeded(ZipIOLocalFileBlock fileBlock)
        { 
            // there is a special case for the _generalPurposeBitFlag.Bit #3
            // it could be set in the local file header indicating streaming 
            // creation, while it doesn't need to be set in the Central directory 
            // so having
            //  (fileBlock.GeneralPurposeBitFlag == 8 && and _generalPurposeBitFlag  == 0) 
            // is a valid case when update is not required

            // let's compare the 3rd bit of the general purpose bit flag
            bool localFileHeaderStreamingFlag = (0 != (fileBlock.GeneralPurposeBitFlag & _streamingBitMask)); 
            bool centralDirStreamingFlag = (0 != (_generalPurposeBitFlag & _streamingBitMask));
 
            if (!localFileHeaderStreamingFlag  && centralDirStreamingFlag) 
            {
                // the mismatch if local file header in non streaming but the central directory is in streaming mode 
                // all the other combinations do not require an update and valid as is
                // this includes scenario when local file header is in streaming and central dir is not
                return true;
            } 

            Debug.Assert(String.CompareOrdinal(_stringFileName, fileBlock.FileName) == 0); 
 
            return
                (_signature != _signatureConstant) || 
                (_versionNeededToExtract != fileBlock.VersionNeededToExtract) ||
                (_generalPurposeBitFlag != fileBlock.GeneralPurposeBitFlag) ||
                (_compressionMethod != (UInt16)fileBlock.CompressionMethod) ||
                (_crc32 != fileBlock.Crc32) || 
                (CompressedSize != fileBlock.CompressedSize) ||
                (UncompressedSize != fileBlock.UncompressedSize) || 
                (OffsetOfLocalHeader != fileBlock.Offset); 

                // These fields are intentionally ignored, as they are not present in the local header 
                            //_fileCommentLength;
                            //_fileComment;
                            //_diskNumberStart;
                            //_internalFileAttributes; 
                            //_externalFileAttributes;
        } 
        private void  UpdateFromLocalFileBlock(ZipIOLocalFileBlock fileBlock)
        { 
            Debug.Assert(DiskNumberStart == 0); 

            _signature = _signatureConstant; 
            _generalPurposeBitFlag = fileBlock.GeneralPurposeBitFlag;
            _compressionMethod = (UInt16)fileBlock.CompressionMethod;
            _lastModFileDateTime = fileBlock.LastModFileDateTime;
            _crc32 = fileBlock.Crc32; 

            // file name is easy to copy 
            _fileNameLength = (UInt16)fileBlock.FileName.Length; // this is safe cast as file name is always validate for size 
            _fileName = _encoding.GetBytes(fileBlock.FileName);
            _stringFileName = fileBlock.FileName; 

            // this will properly update the 32 or zip 64 fields
            UpdateZip64Structures(fileBlock.CompressedSize,
                                    fileBlock.UncompressedSize, 
                                    fileBlock.Offset);
 
            // Previous instruction may determine that we don't really need 4.5, but we 
            // want to ensure that the version is identical with what is stored in the local file header.
            Debug.Assert(_versionNeededToExtract <= fileBlock.VersionNeededToExtract, "Should never be making this smaller"); 

            _versionNeededToExtract = fileBlock.VersionNeededToExtract;

            // These fields are intentionally ignored, as they are not present in the local header 
                        //_fileCommentLength;
                        //_fileComment; 
                        //_diskNumberStart; 
                        //_internalFileAttributes;
                        //_externalFileAttributes; 
        }
예제 #21
0
        /// <summary>
        /// Save - stream level 
        /// </summary>
        /// <param name="blockRequestingFlush"></param> 
        /// <param name="closingFlag">closing or flushing</param> 
        internal void SaveStream(ZipIOLocalFileBlock blockRequestingFlush, bool closingFlag)
        { 
            // Prevent recursion when propagating Flush or Disposed to our minions
            // because ZipIOFileItemStream.Flush calls us.
            if (_propagatingFlushDisposed)
                return; 
            else
                _propagatingFlushDisposed = true;   // enter first time 
 
            try
            { 
                // redirect depending on our mode
                if (_openStreaming)
                {
                    StreamingSaveStream(blockRequestingFlush, closingFlag); 
                }
                else 
                    SaveContainer(false); 
            }
            finally 
            {
                // all done so restore state
                _propagatingFlushDisposed = false;
            } 
        }
 internal bool UpdateIfNeeded(ZipIOLocalFileBlock fileBlock)
 { 
     if (CheckIfUpdateNeeded(fileBlock))
     { 
         UpdateFromLocalFileBlock(fileBlock); 
         return true;
     } 
     else
     {
         return false;
     } 
 }
예제 #23
0
 /////////////////////////////
 // Internal Constructor
 /////////////////////////////        
 internal  ZipIOFileItemStream(ZipIOBlockManager blockManager,   // blockManager is only needed 
                                                                 // to pass through to it Flush requests 
                               ZipIOLocalFileBlock block,        // our owning block - needed for Streaming scenarios
                               long persistedOffset,             // to map to the stream 
                               long persistedSize)               // to map to the stream )
 {
     Debug.Assert(blockManager != null);
     Debug.Assert(persistedOffset >=0);
     Debug.Assert(persistedSize >= 0);
     Debug.Assert(block != null);
         
     _persistedOffset = persistedOffset; 
     _offset = persistedOffset; 
     _persistedSize = persistedSize;
         
     _blockManager = blockManager;
     _block = block;
     
     _currentStreamLength = persistedSize;
 }
예제 #24
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; 
        }
예제 #25
0
        /// <summary>
        /// Flush was called on a ZipIOFileItemStream
        /// </summary>
        /// <param name="blockRequestingFlush">block that owns the stream that Flush was called on</param> 
        /// <param name="closingFlag">close or dispose</param>
        private void StreamingSaveStream(ZipIOLocalFileBlock blockRequestingFlush, bool closingFlag) 
        { 
            // STREAMING MODE:
            // Flush will do one of two things, depending on the currently open stream: 
            // 1) If the currently open stream matches the one passed (or none is currently opened)
            //    then write will occur to the open stream.
            // 2) Otherwise, the currently opened stream will be flushed and closed, and the
            //    given stream will become the currently opened stream 
            // NOTE: _blockList is NOT in offset order except the last four blocks
            //      (CD, Zip64 EOCD, Zip64 EOCD Locator, and EOCD) 
 
            // different stream?
            if (_streamingCurrentlyOpenStreamBlock != blockRequestingFlush) 
            {
                // need to close the currently opened stream
                // unless its our first time through
                if (_streamingCurrentlyOpenStreamBlock != null) 
                {
                    _streamingCurrentlyOpenStreamBlock.SaveStreaming(true); 
                } 

                // Now make the given stream the new "currently opened stream". 
                _streamingCurrentlyOpenStreamBlock = blockRequestingFlush;
            }

            // this should now be flushable/closable 
            _streamingCurrentlyOpenStreamBlock.SaveStreaming(closingFlag);
 
            // if closing - discard the stream because it is now closed 
            if (closingFlag)
                _streamingCurrentlyOpenStreamBlock = null; 
        }
예제 #26
0
        //-----------------------------------------------------
        //
        //  Internal Methods 
        //
        //------------------------------------------------------ 
        internal static ZipIOLocalFileBlock SeekableLoad (ZipIOBlockManager blockManager, 
                                                            string fileName)
        { 
            Debug.Assert(!blockManager.Streaming);
            Debug.Assert(blockManager.CentralDirectoryBlock.FileExists(fileName));

            // Get info from the central directory 
            ZipIOCentralDirectoryBlock centralDir = blockManager.CentralDirectoryBlock;
            ZipIOCentralDirectoryFileHeader centralDirFileHeader = centralDir.GetCentralDirectoryFileHeader(fileName); 
 
            long localHeaderOffset = centralDirFileHeader.OffsetOfLocalHeader;
            bool folderFlag = centralDirFileHeader.FolderFlag; 
            bool volumeLabelFlag = centralDirFileHeader.VolumeLabelFlag;

            blockManager.Stream.Seek(localHeaderOffset, SeekOrigin.Begin);
 
            ZipIOLocalFileBlock block = new ZipIOLocalFileBlock(blockManager, folderFlag, volumeLabelFlag);
 
            block.ParseRecord( 
                    blockManager.BinaryReader,
                    fileName, 
                    localHeaderOffset,
                    centralDir,
                    centralDirFileHeader);
 
            return block;
        }