2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / ICSharpCode.SharpZipLib / ICSharpCode.SharpZipLib / GZip / GZipOutputStream.cs
1 // GzipOutputStream.cs\r
2 // Copyright (C) 2001 Mike Krueger\r
3 //\r
4 // This file was translated from java, it was part of the GNU Classpath\r
5 // Copyright (C) 2001 Free Software Foundation, Inc.\r
6 //\r
7 // This program is free software; you can redistribute it and/or\r
8 // modify it under the terms of the GNU General Public License\r
9 // as published by the Free Software Foundation; either version 2\r
10 // of the License, or (at your option) any later version.\r
11 //\r
12 // This program is distributed in the hope that it will be useful,\r
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 // GNU General Public License for more details.\r
16 //\r
17 // You should have received a copy of the GNU General Public License\r
18 // along with this program; if not, write to the Free Software\r
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
20 //\r
21 // Linking this library statically or dynamically with other modules is\r
22 // making a combined work based on this library.  Thus, the terms and\r
23 // conditions of the GNU General Public License cover the whole\r
24 // combination.\r
25 // \r
26 // As a special exception, the copyright holders of this library give you\r
27 // permission to link this library with independent modules to produce an\r
28 // executable, regardless of the license terms of these independent\r
29 // modules, and to copy and distribute the resulting executable under\r
30 // terms of your choice, provided that you also meet, for each linked\r
31 // independent module, the terms and conditions of the license of that\r
32 // module.  An independent module is a module which is not derived from\r
33 // or based on this library.  If you modify this library, you may extend\r
34 // this exception to your version of the library, but you are not\r
35 // obligated to do so.  If you do not wish to do so, delete this\r
36 // exception statement from your version.\r
37 \r
38 using System;\r
39 using System.IO;\r
40 \r
41 using ICSharpCode.SharpZipLib.Checksums;\r
42 using ICSharpCode.SharpZipLib.Zip.Compression;\r
43 using ICSharpCode.SharpZipLib.Zip.Compression.Streams;\r
44 \r
45 namespace ICSharpCode.SharpZipLib.GZip \r
46 {\r
47         \r
48         /// <summary>\r
49         /// This filter stream is used to compress a stream into a "GZIP" stream.\r
50         /// The "GZIP" format is described in RFC 1952.\r
51         ///\r
52         /// author of the original java version : John Leuner\r
53         /// </summary>\r
54         /// <example> This sample shows how to gzip a file\r
55         /// <code>\r
56         /// using System;\r
57         /// using System.IO;\r
58         /// \r
59         /// using ICSharpCode.SharpZipLib.GZip;    // -jr- corrected\r
60         /// \r
61         /// class MainClass\r
62         /// {\r
63         ///     public static void Main(string[] args)\r
64         ///     {\r
65         ///             Stream s = new GZipOutputStream(File.Create(args[0] + ".gz"));\r
66         ///             FileStream fs = File.OpenRead(args[0]);\r
67         ///             byte[] writeData = new byte[fs.Length];\r
68         ///             fs.Read(writeData, 0, (int)fs.Length);\r
69         ///             s.Write(writeData, 0, writeData.Length);\r
70         ///             s.Close();\r
71         ///     }\r
72         /// }   \r
73         /// </code>\r
74         /// </example>\r
75         public class GZipOutputStream : DeflaterOutputStream\r
76         {\r
77                 //Variables\r
78                 \r
79                 /// <summary>\r
80                 /// CRC-32 value for uncompressed data\r
81                 /// </summary>\r
82                 protected Crc32 crc = new Crc32();\r
83                 \r
84                 // Constructors\r
85                 \r
86                 /// <summary>\r
87                 /// Creates a GzipOutputStream with the default buffer size\r
88                 /// </summary>\r
89                 /// <param name="baseOutputStream">\r
90                 /// The stream to read data (to be compressed) from\r
91                 /// </param>\r
92                 public GZipOutputStream(Stream baseOutputStream) : this(baseOutputStream, 4096)\r
93                 {\r
94                 }\r
95                 \r
96                 /// <summary>\r
97                 /// Creates a GZIPOutputStream with the specified buffer size\r
98                 /// </summary>\r
99                 /// <param name="baseOutputStream">\r
100                 /// The stream to read data (to be compressed) from\r
101                 /// </param>\r
102                 /// <param name="size">\r
103                 /// Size of the buffer to use\r
104                 /// </param>\r
105                 public GZipOutputStream(Stream baseOutputStream, int size) : base(baseOutputStream, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size)\r
106                 {\r
107                         WriteHeader();\r
108                         //    System.err.println("wrote GZIP header (" + gzipHeader.length + " bytes )");\r
109                 }\r
110                 \r
111                 void WriteHeader()\r
112                 {\r
113                         int mod_time = (int)(DateTime.Now.Ticks / 10000L);  // Ticks give back 100ns intervals\r
114                         byte[] gzipHeader = {\r
115                                 /* The two magic bytes */\r
116                                 (byte) (GZipConstants.GZIP_MAGIC >> 8), (byte) GZipConstants.GZIP_MAGIC,\r
117                                 \r
118                                 /* The compression type */\r
119                                 (byte) Deflater.DEFLATED,\r
120                                 \r
121                                 /* The flags (not set) */\r
122                                 0,\r
123                                 \r
124                                 /* The modification time */\r
125                                 (byte) mod_time, (byte) (mod_time >> 8),\r
126                                 (byte) (mod_time >> 16), (byte) (mod_time >> 24),\r
127                                 \r
128                                 /* The extra flags */\r
129                                 0,\r
130                                 \r
131                                 /* The OS type (unknown) */\r
132                                 (byte) 255\r
133                         };\r
134                         baseOutputStream.Write(gzipHeader, 0, gzipHeader.Length);\r
135                 }\r
136                 \r
137                 public override void Write(byte[] buf, int off, int len)\r
138                 {\r
139                         crc.Update(buf, off, len);\r
140                         base.Write(buf, off, len);\r
141                 }\r
142                 \r
143                 /// <summary>\r
144                 /// Writes remaining compressed output data to the output stream\r
145                 /// and closes it.\r
146                 /// </summary>\r
147                 public override void Close()\r
148                 {\r
149                         Finish();\r
150                         baseOutputStream.Close();\r
151                 }\r
152                 \r
153                 public override void Finish()\r
154                 {\r
155                         base.Finish();\r
156                         \r
157                         int totalin = def.TotalIn;\r
158                         int crcval = (int) (crc.Value & 0xffffffff);\r
159                         \r
160                         //    System.err.println("CRC val is " + Integer.toHexString( crcval )                 + " and length " + Integer.toHexString(totalin));\r
161                         \r
162                         byte[] gzipFooter = {\r
163                                 (byte) crcval, (byte) (crcval >> 8),\r
164                                 (byte) (crcval >> 16), (byte) (crcval >> 24),\r
165                                 \r
166                                 (byte) totalin, (byte) (totalin >> 8),\r
167                                 (byte) (totalin >> 16), (byte) (totalin >> 24)\r
168                         };\r
169 \r
170                         baseOutputStream.Write(gzipFooter, 0, gzipFooter.Length);\r
171                         //    System.err.println("wrote GZIP trailer (" + gzipFooter.length + " bytes )");\r
172                 }\r
173         }\r
174 }\r