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; }
//----------------------------------------------------- // // Private Methods // //------------------------------------------------------ private ZipIOLocalFileBlock(ZipIOBlockManager blockManager, bool folderFlag, bool volumeLabelFlag) { _blockManager = blockManager; _folderFlag = folderFlag; _volumeLabelFlag = volumeLabelFlag; }
//----------------------------------------------------- // // Private Methods // //------------------------------------------------------ private ZipIORawDataFileBlock(ZipIOBlockManager blockManager) { _blockManager = blockManager; }
///////////////////////////// // 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; }
//----------------------------------------------------- // // 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; }