/// <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); }
// this function is sets the sizes into the either 64 or 32 bit structures based on values of the fields // It used in 2 places by the MoveReference and by the UpdateFromLocalFileBlock private void UpdateZip64Structures (long compressedSize, long uncompressedSize, long offset) { Debug.Assert((compressedSize >= 0) && (uncompressedSize >= 0) && (offset >= 0)); // according to the appnote central directory extra field might be a mix of any values based on escaping // we will fully (without disk number) use it every time we are building a ZIP 64 arhichive // we also trying to stay on the safe side and treeat the boundary case of 32 escape values // as a zip 64 scenrio if ((compressedSize >= UInt32.MaxValue) || (uncompressedSize >= UInt32.MaxValue) || (offset >= UInt32.MaxValue)) { // Zip 64 case _extraField.CompressedSize = compressedSize; _extraField.UncompressedSize = uncompressedSize; _extraField.OffsetOfLocalHeader = offset; //set proper escape values _compressedSize = UInt32.MaxValue; _uncompressedSize = UInt32.MaxValue; _relativeOffsetOfLocalHeader = UInt32.MaxValue; // update version needed to extract to 4.5 _versionNeededToExtract = (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat; } else { // 32 bit case _compressedSize = checked ((UInt32)compressedSize); _uncompressedSize = checked ((UInt32)uncompressedSize); _relativeOffsetOfLocalHeader = checked ((UInt32)offset); // reset the extra ZIP 64 field to empty _extraField.Zip64ExtraFieldUsage = ZipIOZip64ExtraFieldUsage.None; // version needed to extract needs to be recalculated from scratch based on compression _versionNeededToExtract = (UInt16)ZipIOBlockManager.CalcVersionNeededToExtractFromCompression ((CompressionMethodEnum)_compressionMethod); } }
internal void UpdateZip64Structures(long compressedSize, long uncompressedSize, long offset) { // according to the appnote local file header ZIP 64 extra field if used must contain both // compressed and uncompressed size // we also trying to stay on the safe side and treeat the boundary case of 32 escape values // as a zip 64 scenario // we will also make this ZIP64 file if it is small but positioned beyond Uint32.MaxValue offset if ((compressedSize >= UInt32.MaxValue) || (uncompressedSize >= UInt32.MaxValue) || (offset >= UInt32.MaxValue)) { // Zip 64 case _extraField.CompressedSize = compressedSize; _extraField.UncompressedSize = uncompressedSize; //set proper escape values _compressedSize = UInt32.MaxValue; _uncompressedSize = UInt32.MaxValue; // update version needed to extract to 4.5 _versionNeededToExtract = (UInt16)ZipIOVersionNeededToExtract.Zip64FileFormat; } else { // 32 bit case _compressedSize = (UInt32)compressedSize; // checked{} isn't required because of the checks above _uncompressedSize = (UInt32)uncompressedSize; // reset the extra ZIP 64 field to empty _extraField.Zip64ExtraFieldUsage = ZipIOZip64ExtraFieldUsage.None; // version needed to extract needs to be recalculated from scratch based on compression _versionNeededToExtract = (UInt16)ZipIOBlockManager.CalcVersionNeededToExtractFromCompression(CompressionMethod); } }