private int WriteCentralDirectoryHeader(ZipEntry entry) {
if (entry.CompressedSize<0) {
throw new ZipException("Attempt to write central directory entry with unknown csize");
}
if (entry.Size<0) {
throw new ZipException("Attempt to write central directory entry with unknown size");
}
if (entry.Crc<0) {
throw new ZipException("Attempt to write central directory entry with unknown crc");
}
// Write the central file header
WriteLEInt(ZipConstants.CentralHeaderSignature);
// Version made by
WriteLEShort(ZipConstants.VersionMadeBy);
// Version required to extract
WriteLEShort(entry.Version);
WriteLEShort(entry.Flags);
unchecked {
WriteLEShort((byte)entry.CompressionMethod);
WriteLEInt((int)entry.DosTime);
WriteLEInt((int)entry.Crc);
}
if ((entry.IsZip64Forced())||(entry.CompressedSize>=0xffffffff)) {
WriteLEInt(-1);
} else {
WriteLEInt((int)(entry.CompressedSize&0xffffffff));
}
if ((entry.IsZip64Forced())||(entry.Size>=0xffffffff)) {
WriteLEInt(-1);
} else {
WriteLEInt((int)entry.Size);
}
byte[] name=ZipConstants.ConvertToArray(entry.Flags, entry.Name);
if (name.Length>0xFFFF) {
throw new ZipException("Entry name is too long.");
}
WriteLEShort(name.Length);
// Central header extra data is different to local header version so regenerate.
var ed=new ZipExtraData(entry.ExtraData);
if (entry.CentralHeaderRequiresZip64) {
ed.StartNewEntry();
if ((entry.Size>=0xffffffff)||(useZip64_==UseZip64.On)) {
ed.AddLeLong(entry.Size);
}
if ((entry.CompressedSize>=0xffffffff)||(useZip64_==UseZip64.On)) {
ed.AddLeLong(entry.CompressedSize);
}
if (entry.Offset>=0xffffffff) {
ed.AddLeLong(entry.Offset);
}
// Number of disk on which this file starts isnt supported and is never written here.
ed.AddNewEntry(1);
} else {
// Should have already be done when local header was added.
ed.Delete(1);
}
byte[] centralExtraData=ed.GetEntryData();
WriteLEShort(centralExtraData.Length);
WriteLEShort(entry.Comment!=null?entry.Comment.Length:0);
WriteLEShort(0); // disk number
WriteLEShort(0); // internal file attributes
// External file attributes...
if (entry.ExternalFileAttributes!=-1) {
WriteLEInt(entry.ExternalFileAttributes);
} else {
if (entry.IsDirectory) {
WriteLEUint(16);
} else {
WriteLEUint(0);
}
}
if (entry.Offset>=0xffffffff) {
WriteLEUint(0xffffffff);
} else {
WriteLEUint((uint)(int)entry.Offset);
}
if (name.Length>0) {
baseStream_.Write(name, 0, name.Length);
}
if (centralExtraData.Length>0) {
baseStream_.Write(centralExtraData, 0, centralExtraData.Length);
}
byte[] rawComment=(entry.Comment!=null)?Encoding.ASCII.GetBytes(entry.Comment):new byte[0];
if (rawComment.Length>0) {
baseStream_.Write(rawComment, 0, rawComment.Length);
}
return ZipConstants.CentralHeaderBaseSize+name.Length+centralExtraData.Length+rawComment.Length;
}