internal  ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream, UInt32 expectedCrc)
        { 
            Debug.Assert(underlyingStream != null);
            Debug.Assert(blockManager != null); 
 
            _blockManager = blockManager;
            _underlyingStream = underlyingStream; 
            _validateCrcWithExpectedCrc = true;
            _expectedCrc = expectedCrc;
            _highWaterMark = -1;
        } 
        //----------------------------------------------------- 
        //
        //  Internal Methods
        //
        //----------------------------------------------------- 
        internal static ZipIORawDataFileBlock Assign(ZipIOBlockManager blockManager, long offset, long size)
        { 
            if (size <= 0) 
            {
                throw new ArgumentOutOfRangeException ("size"); 
            }

            if (offset < 0)
            { 
                throw new ArgumentOutOfRangeException ("offset");
            } 
 
            ZipIORawDataFileBlock block = new ZipIORawDataFileBlock(blockManager);
            block._persistedOffset = offset; 
            block._offset = offset;
            block._size = size;

            return block; 
        }
 //------------------------------------------------------
 //
 //  Private Methods
 //
 //------------------------------------------------------
 private ZipIOCentralDirectoryBlock(ZipIOBlockManager blockManager)
 {
     _blockManager = blockManager;
 }
 /////////////////////////////
 // Internal Constructor 
 /////////////////////////////
 internal  ProgressiveCrcCalculatingStream(ZipIOBlockManager blockManager, Stream underlyingStream) : 
     this(blockManager, underlyingStream, 0) 
 {
     _validateCrcWithExpectedCrc = false; 
 }
        internal static ZipIOZip64EndOfCentralDirectoryBlock CreateNew(ZipIOBlockManager blockManager) 
        {
            ZipIOZip64EndOfCentralDirectoryBlock block = new ZipIOZip64EndOfCentralDirectoryBlock(blockManager); 
 
            block._size = 0; // brand new created records are optional by definition untill UpdateReferences is called, so size must be 0
            block._offset = 0; 
            block._dirtyFlag = false;

            // initialize fields with ythe data from the EOCD
            block.InitializeFromEndOfCentralDirectory(blockManager.EndOfCentralDirectoryBlock); 

            return block; 
        } 
        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 bool SniffTheBlockSignature(ZipIOBlockManager blockManager)
        {
            long suspectPos = checked(blockManager.EndOfCentralDirectoryBlock.Offset - _fixedMinimalRecordSize);

            // let's check that EndOfCentralDirectoryBlock.Offset is not too close to the start of the stream
            // for the record to fit there 

            // the second check isn't required, strictily speaking, as we are stepping back from the  EOCD.offset
            // however in some theoretical cases EOCD might not be trustable so to ensure that  ReadUInt32
            // isn't going to throw we do additional check
            if ((suspectPos < 0) ||
                (checked(suspectPos + sizeof(UInt32)) > blockManager.Stream.Length))  
            {
                return false;
            }

            blockManager.Stream.Seek(suspectPos, SeekOrigin.Begin);
                
            UInt32 signature = blockManager.BinaryReader.ReadUInt32();
            return (signature == _signatureConstant);
        }
        //------------------------------------------------------
        //
        //  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 static ZipIOZip64EndOfCentralDirectoryLocatorBlock SeekableLoad (ZipIOBlockManager blockManager)  
        {
            // This Debug assert is a secondary check in debug builds, callers are responcible for verifying condition 
            // in both retail and debug builds
            Debug.Assert(SniffTheBlockSignature(blockManager));
            
            long blockPosition = checked(blockManager.EndOfCentralDirectoryBlock.Offset - _fixedMinimalRecordSize);
            
            blockManager.Stream.Seek(blockPosition, SeekOrigin.Begin);

            ZipIOZip64EndOfCentralDirectoryLocatorBlock block = new ZipIOZip64EndOfCentralDirectoryLocatorBlock(blockManager);
            
            block.ParseRecord(blockManager.BinaryReader, blockPosition);
            return block;
        }
        internal static ZipIOZip64EndOfCentralDirectoryLocatorBlock CreateNew(ZipIOBlockManager blockManager)          
        {
            // This Debug assert is a secondary check in debug builds, callers are responcible for verifying condition 
            // in both retail and debug builds
            Debug.Assert(!SniffTheBlockSignature(blockManager));

            ZipIOZip64EndOfCentralDirectoryLocatorBlock block = new ZipIOZip64EndOfCentralDirectoryLocatorBlock(blockManager);

            block._offset = 0;
            block._size = 0;
            block._dirtyFlag = false;
            
            return block;
        }
        internal static ZipIOEndOfCentralDirectoryBlock CreateNew(ZipIOBlockManager blockManager, long offset)          
        {
            ZipIOEndOfCentralDirectoryBlock block = new ZipIOEndOfCentralDirectoryBlock(blockManager);

            block._offset = offset;
            block._dirtyFlag = true;

            return block;
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        internal static ZipIOEndOfCentralDirectoryBlock SeekableLoad (ZipIOBlockManager blockManager)  
        {
            // perform custom serach for record 
            long blockPosition = FindPosition(blockManager.Stream);
            blockManager.Stream.Seek(blockPosition, SeekOrigin.Begin);

            ZipIOEndOfCentralDirectoryBlock block = new ZipIOEndOfCentralDirectoryBlock(blockManager);
            
            block.ParseRecord(blockManager.BinaryReader, blockPosition);
            return block;
        }
Example #13
0
 //----------------------------------------------------- 
 // 
 //  Private Methods
 // 
 //------------------------------------------------------
 private ZipIOLocalFileBlock(ZipIOBlockManager blockManager,
                                                 bool folderFlag,
                                                 bool volumeLabelFlag) 
 {
     _blockManager = blockManager; 
     _folderFlag = folderFlag; 
     _volumeLabelFlag = volumeLabelFlag;
 } 
 //-----------------------------------------------------
 // 
 //  Private Methods 
 //
 //------------------------------------------------------ 
 private ZipIORawDataFileBlock(ZipIOBlockManager blockManager)
 {
     _blockManager = blockManager;
 } 
Example #15
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;
 }
        //------------------------------------------------------
        //
        // Internal NON API Methods (these methods are marked as 
        // Internal, and they are trully internal and not the part of the 
        // internal ZIP IO API surface 
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Private Constructors
        //
        //------------------------------------------------------
        /// <summary>
        /// This private constructor isonly supposed to be called by the 
        /// OpenOnFile and OpenOnStream static members. 
        /// </summary>         
        /// <param name="archiveStream"></param>
        /// <param name="mode"></param>
        /// <param name="access"></param>
        /// <param name="streaming"></param>
        /// <param name="ownStream">true if this class is responsible for closing the archiveStream</param>
        private ZipArchive(Stream archiveStream, FileMode mode, FileAccess access, bool streaming, bool ownStream)
        {
            // as this contructor is only called from the static member 
            // all checks should have been done before 

            _blockManager = new ZipIOBlockManager(archiveStream, streaming, ownStream);

            _openMode = mode;
            _openAccess = access;

            // In case of "create" we also need to create at least an end of Central Directory Record.
            // For FileMode OpenOrCreate we use stream Length to distinguish open and create scenarios.
            // Implications of this decision is that existing file of size 0 opened in OpenOrCreate Mode 
            // will be treated as a newly/created file.
            if ((_openMode == FileMode.CreateNew) ||
               (_openMode == FileMode.Create) ||
               ((_openMode == FileMode.OpenOrCreate) && archiveStream.Length == 0))
            {
                _blockManager.CreateEndOfCentralDirectoryBlock();
            }
            else
            {
                _blockManager.LoadEndOfCentralDirectoryBlock();
            }
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------
        internal static ZipIOCentralDirectoryBlock SeekableLoad(ZipIOBlockManager blockManager)
        {
            // get proper values from  zip 64 records request will be redirected to the 
            // regular EOCD if ZIP 64 record wasn't originated from the parsing 

            ZipIOZip64EndOfCentralDirectoryBlock zip64EOCD = blockManager.Zip64EndOfCentralDirectoryBlock;
        
            blockManager.Stream.Seek(zip64EOCD.OffsetOfStartOfCentralDirectory, SeekOrigin.Begin);

            ZipIOCentralDirectoryBlock block = new ZipIOCentralDirectoryBlock(blockManager);
            
            block.ParseRecord(blockManager.BinaryReader, 
                                            zip64EOCD.OffsetOfStartOfCentralDirectory, 
                                            zip64EOCD.TotalNumberOfEntriesInTheCentralDirectory,
                                            zip64EOCD.SizeOfCentralDirectory);

            return block;
        }
        internal static ZipIOZip64EndOfCentralDirectoryBlock SeekableLoad (ZipIOBlockManager blockManager)
        { 
            ZipIOZip64EndOfCentralDirectoryLocatorBlock zip64endOfCentralDirectoryLocator = 
                                                blockManager.Zip64EndOfCentralDirectoryLocatorBlock;
 
            long zip64EndOfCentralDirectoryOffset =
                                                zip64endOfCentralDirectoryLocator.OffsetOfZip64EndOfCentralDirectoryRecord;

            ZipIOZip64EndOfCentralDirectoryBlock block = new ZipIOZip64EndOfCentralDirectoryBlock(blockManager); 

            blockManager.Stream.Seek(zip64EndOfCentralDirectoryOffset, SeekOrigin.Begin); 
 
            block.ParseRecord(blockManager.BinaryReader, zip64EndOfCentralDirectoryOffset);
 
            return block;
        }
        internal static ZipIOCentralDirectoryBlock CreateNew(ZipIOBlockManager blockManager)          
        {
            ZipIOCentralDirectoryBlock block = new ZipIOCentralDirectoryBlock(blockManager);

            block._offset = 0;              // it just an initial value, that will be adjusted later 
                                                   // it doesn't matter whether this offset overlaps anything or not 
                                                            
            block._dirtyFlag = true;

            // this dig sig is optional if we ever wanted to make this record, we would need to call
            //       ZipIOCentralDirectoryDigitalSignature.CreateNew();
            block._centralDirectoryDigitalSignature = null;  

            return block;
        }
 private ZipIOZip64EndOfCentralDirectoryBlock(ZipIOBlockManager blockManager) 
 { 
     Debug.Assert(blockManager != null);
     _blockManager= blockManager; 
 }
Example #21
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;
        }