Beispiel #1
0
		int WriteCentralDirectoryHeader( BlubbZipEntry entry ) {
			if( entry.CompressedSize < 0 ) {
				throw new BlubbZipException( "Attempt to write central directory entry with unknown csize" );
			}

			if( entry.Size < 0 ) {
				throw new BlubbZipException( "Attempt to write central directory entry with unknown size" );
			}

			if( entry.Crc < 0 ) {
				throw new BlubbZipException( "Attempt to write central directory entry with unknown crc" );
			}

			// Write the central file header
			WriteLEInt( BlubbZipConstants.CentralHeaderSignature );

			// Version made by
			WriteLEShort( BlubbZipConstants.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.IsBlubb64Forced() ) || ( entry.CompressedSize >= 0xffffffff ) ) {
				WriteLEInt( -1 );
			} else {
				WriteLEInt( (int)( entry.CompressedSize & 0xffffffff ) );
			}

			if( ( entry.IsBlubb64Forced() ) || ( entry.Size >= 0xffffffff ) ) {
				WriteLEInt( -1 );
			} else {
				WriteLEInt( (int)entry.Size );
			}

			byte[] name = BlubbZipConstants.ConvertToArray( entry.Flags, entry.Name );

			if( name.Length > 0xFFFF ) {
				throw new BlubbZipException( "Entry name is too long." );
			}

			WriteLEShort( name.Length );

			// Central header extra data is different to local header version so regenerate.
			BlubbZipExtraData ed = new BlubbZipExtraData( entry.ExtraData );

			if( entry.CentralHeaderRequiresBlubb64 ) {
				ed.StartNewEntry();

				if( ( entry.Size >= 0xffffffff ) || ( useBlubb64_ == UseBlubb64.On ) ) {
					ed.AddLeLong( entry.Size );
				}

				if( ( entry.CompressedSize >= 0xffffffff ) || ( useBlubb64_ == UseBlubb64.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 BlubbZipConstants.CentralHeaderBaseSize + name.Length + centralExtraData.Length + rawComment.Length;
		}