da5d94f4104783dab29d78f2c3df0b4fb4be8ab4
[mono.git] / mcs / class / System.IO.Compression / SharpCompress / Writer / Zip / ZipCentralDirectoryEntry.cs
1 using System;
2 using System.IO;
3 using System.Text;
4 using SharpCompress.Common.Zip;
5 using SharpCompress.Common.Zip.Headers;
6
7 namespace SharpCompress.Writer.Zip
8 {
9     internal class ZipCentralDirectoryEntry
10     {
11         internal string FileName { get; set; }
12         internal DateTime? ModificationTime { get; set; }
13         internal string Comment { get; set; }
14         internal uint Crc { get; set; }
15         internal uint HeaderOffset { get; set; }
16         internal uint Compressed { get; set; }
17         internal uint Decompressed { get; set; }
18
19
20         internal uint Write(Stream outputStream, ZipCompressionMethod compression)
21         {
22             byte[] encodedFilename = Encoding.UTF8.GetBytes(FileName);
23             byte[] encodedComment = Encoding.UTF8.GetBytes(Comment);
24
25             outputStream.Write(new byte[] {80, 75, 1, 2, 0x3F, 0, 0x0A, 0}, 0, 8);
26             HeaderFlags flags = HeaderFlags.UTF8;
27             if (!outputStream.CanSeek)
28             {
29                 flags |= HeaderFlags.UsePostDataDescriptor;
30                 if (compression == ZipCompressionMethod.LZMA)
31                 {
32                     flags |= HeaderFlags.Bit1; // eos marker
33                 }
34             }
35             outputStream.Write(BitConverter.GetBytes((ushort) flags), 0, 2);
36             outputStream.Write(BitConverter.GetBytes((ushort) compression), 0, 2); // zipping method
37             outputStream.Write(BitConverter.GetBytes(ModificationTime.DateTimeToDosTime()), 0, 4);
38                 // zipping date and time
39             outputStream.Write(BitConverter.GetBytes(Crc), 0, 4); // file CRC
40             outputStream.Write(BitConverter.GetBytes(Compressed), 0, 4); // compressed file size
41             outputStream.Write(BitConverter.GetBytes(Decompressed), 0, 4); // uncompressed file size
42             outputStream.Write(BitConverter.GetBytes((ushort) encodedFilename.Length), 0, 2); // Filename in zip
43             outputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // extra length
44             outputStream.Write(BitConverter.GetBytes((ushort) encodedComment.Length), 0, 2);
45
46             outputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // disk=0
47             outputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // file type: binary
48             outputStream.Write(BitConverter.GetBytes((ushort) 0), 0, 2); // Internal file attributes
49             outputStream.Write(BitConverter.GetBytes((ushort) 0x8100), 0, 2);
50                 // External file attributes (normal/readable)
51             outputStream.Write(BitConverter.GetBytes(HeaderOffset), 0, 4); // Offset of header
52
53             outputStream.Write(encodedFilename, 0, encodedFilename.Length);
54             outputStream.Write(encodedComment, 0, encodedComment.Length);
55
56             return (uint) (8 + 2 + 2 + 4 + 4 + 4 + 4 + 2 + 2 + 2
57                            + 2 + 2 + 2 + 2 + 4 + encodedFilename.Length + encodedComment.Length);
58         }
59     }
60 }