//if saveExtraFieldsAndComments is false, FileComment and ExtraFields will be null
//in either case, the zip64 extra field info will be incorporated into other fields
static public Boolean TryReadBlock(BinaryReader reader, Boolean saveExtraFieldsAndComments, out ZipCentralDirectoryFileHeader header)
{
header = new ZipCentralDirectoryFileHeader();
if (reader.ReadUInt32() != SignatureConstant)
{
return(false);
}
header.VersionMadeBy = reader.ReadUInt16();
header.VersionNeededToExtract = reader.ReadUInt16();
header.GeneralPurposeBitFlag = reader.ReadUInt16();
header.CompressionMethod = reader.ReadUInt16();
header.LastModified = reader.ReadUInt32();
header.Crc32 = reader.ReadUInt32();
UInt32 compressedSizeSmall = reader.ReadUInt32();
UInt32 uncompressedSizeSmall = reader.ReadUInt32();
header.FilenameLength = reader.ReadUInt16();
header.ExtraFieldLength = reader.ReadUInt16();
header.FileCommentLength = reader.ReadUInt16();
UInt16 diskNumberStartSmall = reader.ReadUInt16();
header.InternalFileAttributes = reader.ReadUInt16();
header.ExternalFileAttributes = reader.ReadUInt32();
UInt32 relativeOffsetOfLocalHeaderSmall = reader.ReadUInt32();
header.Filename = reader.ReadBytes(header.FilenameLength);
Boolean uncompressedSizeInZip64 = uncompressedSizeSmall == ZipHelper.Mask32Bit;
Boolean compressedSizeInZip64 = compressedSizeSmall == ZipHelper.Mask32Bit;
Boolean relativeOffsetInZip64 = relativeOffsetOfLocalHeaderSmall == ZipHelper.Mask32Bit;
Boolean diskNumberStartInZip64 = diskNumberStartSmall == ZipHelper.Mask16Bit;
Zip64ExtraField zip64;
using (Stream str = new SubReadStream(reader.BaseStream, reader.BaseStream.Position, header.ExtraFieldLength))
{
if (saveExtraFieldsAndComments)
{
header.ExtraFields = ZipGenericExtraField.ParseExtraField(str);
zip64 = Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields,
uncompressedSizeInZip64, compressedSizeInZip64,
relativeOffsetInZip64, diskNumberStartInZip64);
}
else
{
header.ExtraFields = null;
zip64 = Zip64ExtraField.GetJustZip64Block(str,
uncompressedSizeInZip64, compressedSizeInZip64,
relativeOffsetInZip64, diskNumberStartInZip64);
}
}
if (saveExtraFieldsAndComments)
{
header.FileComment = reader.ReadBytes(header.FileCommentLength);
}
else
{
reader.BaseStream.Position += header.FileCommentLength;
header.FileComment = null;
}
header.UncompressedSize = zip64.UncompressedSize == null
? uncompressedSizeSmall
: zip64.UncompressedSize.Value;
header.CompressedSize = zip64.CompressedSize == null
? compressedSizeSmall
: zip64.CompressedSize.Value;
header.RelativeOffsetOfLocalHeader = zip64.LocalHeaderOffset == null
? relativeOffsetOfLocalHeaderSmall
: zip64.LocalHeaderOffset.Value;
header.DiskNumberStart = zip64.StartDiskNumber == null
? diskNumberStartSmall
: zip64.StartDiskNumber.Value;
return(true);
}