internal static ZipIOCentralDirectoryFileHeader ParseRecord(BinaryReader reader, Encoding encoding)
        {
            ZipIOCentralDirectoryFileHeader header = new ZipIOCentralDirectoryFileHeader(encoding);

            header._signature              = reader.ReadUInt32();
            header._versionMadeBy          = reader.ReadUInt16();
            header._versionNeededToExtract = reader.ReadUInt16();
            header._generalPurposeBitFlag  = reader.ReadUInt16();
            header._compressionMethod      = reader.ReadUInt16();
            header._lastModFileDateTime    = reader.ReadUInt32();
            header._crc32                       = reader.ReadUInt32();
            header._compressedSize              = reader.ReadUInt32();
            header._uncompressedSize            = reader.ReadUInt32();
            header._fileNameLength              = reader.ReadUInt16();
            header._extraFieldLength            = reader.ReadUInt16();
            header._fileCommentLength           = reader.ReadUInt16();
            header._diskNumberStart             = reader.ReadUInt16();
            header._internalFileAttributes      = reader.ReadUInt16();
            header._externalFileAttributes      = reader.ReadUInt32();
            header._relativeOffsetOfLocalHeader = reader.ReadUInt32();

            header._fileName = reader.ReadBytes(header._fileNameLength);

            // check for the ZIP 64 version and escaped values
            ZipIOZip64ExtraFieldUsage zip64extraFieldUsage = ZipIOZip64ExtraFieldUsage.None;

            if (header._versionNeededToExtract >= (ushort)ZipIOVersionNeededToExtract.Zip64FileFormat)
            {
                if (header._compressedSize == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.CompressedSize;
                }
                if (header._uncompressedSize == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.UncompressedSize;
                }
                if (header._relativeOffsetOfLocalHeader == UInt32.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.OffsetOfLocalHeader;
                }
                if (header._diskNumberStart == UInt16.MaxValue)
                {
                    zip64extraFieldUsage |= ZipIOZip64ExtraFieldUsage.DiskNumber;
                }
            }

            // if the ZIP 64 record is missing the zip64extraFieldUsage value will be ignored
            header._extraField = ZipIOExtraField.ParseRecord(reader,
                                                             zip64extraFieldUsage,
                                                             header._extraFieldLength);

            header._fileComment = reader.ReadBytes(header._fileCommentLength);

            //populate frequently used field with user friendly data representations
            header._stringFileName = ZipIOBlockManager.ValidateNormalizeFileName(encoding.GetString(header._fileName));

            header.Validate();

            return(header);
        }