private int WriteCentralDirectoryHeader()

in src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs [2219:2369]


		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((entry.HostSystem << 8) | entry.VersionMadeBy);

			// Version required to extract
			WriteLEShort(entry.Version);

			WriteLEShort(entry.Flags);

			unchecked
			{
				WriteLEShort((byte)entry.CompressionMethodForHeader);
				WriteLEInt((int)entry.DosTime);
				WriteLEInt((int)entry.Crc);
			}

			bool useExtraCompressedSize = false; //Do we want to store the compressed size in the extra data?
			if ((entry.IsZip64Forced()) || (entry.CompressedSize >= 0xffffffff))
			{
				useExtraCompressedSize = true;
				WriteLEInt(-1);
			}
			else
			{
				WriteLEInt((int)(entry.CompressedSize & 0xffffffff));
			}

			bool useExtraUncompressedSize = false; //Do we want to store the uncompressed size in the extra data?
			if ((entry.IsZip64Forced()) || (entry.Size >= 0xffffffff))
			{
				useExtraUncompressedSize = true;
				WriteLEInt(-1);
			}
			else
			{
				WriteLEInt((int)entry.Size);
			}

			var entryEncoding = _stringCodec.ZipInputEncoding(entry.Flags);
			byte[] name = entryEncoding.GetBytes(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 (useExtraUncompressedSize)
				{
					ed.AddLeLong(entry.Size);
				}

				if (useExtraCompressedSize)
				{
					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) : Empty.Array<byte>();

			if (rawComment.Length > 0)
			{
				baseStream_.Write(rawComment, 0, rawComment.Length);
			}

			return ZipConstants.CentralHeaderBaseSize + name.Length + centralExtraData.Length + rawComment.Length;
		}