2010-07-08 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System / System.IO.Compression / DefalteStream.jvm.cs
1 // 
2 // DeflateStream.cs
3 //
4 // Authors:
5 //      Konstantin Triger <kostat@mainsoft.com>
6 //
7 // (c) 2008 Mainsoft corp. <http://www.mainsoft.com>
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 //#if NET_2_0
30 using System;
31 using System.IO;
32 using System.Runtime.InteropServices;
33 using System.Runtime.Remoting.Messaging;
34 using java.io;
35 using java.util.zip;
36 using vmw.common;
37
38 namespace System.IO.Compression
39 {
40         public class DeflateStream : Stream
41         {
42                 readonly Stream _baseStream;
43                 readonly InflaterInputStream _reader;
44                 readonly DeflaterOutputStream _writer;
45
46                 readonly bool _leaveOpen;
47                 bool _open;
48
49                 delegate int ReadMethod (byte [] array, int offset, int count);
50                 delegate void WriteMethod (byte [] array, int offset, int count);
51
52                 internal DeflateStream (Stream compressedStream, CompressionMode mode, bool leaveOpen, bool gzip) {
53                         if (compressedStream == null)
54                                 throw new ArgumentNullException ("compressedStream");
55
56                         switch (mode) {
57                         case CompressionMode.Compress:
58                                 if (!compressedStream.CanWrite)
59                                         throw new ArgumentException ("The base stream is not writeable.");
60                                 OutputStream outStream = new OutputStreamImpl(compressedStream);
61                                 _writer = gzip ? new GZIPOutputStream (outStream) : new DeflaterOutputStream (outStream, new Deflater (Deflater.DEFAULT_COMPRESSION, true));
62                                 break;
63                         case CompressionMode.Decompress:
64                                 if (!compressedStream.CanRead)
65                                         throw new ArgumentException ("The base stream is not readable.");
66                                 InputStream inStream = new InputStreamImpl (compressedStream);
67                                 _reader = gzip ? new GZIPInputStream (inStream) : new InflaterInputStream (inStream, new Inflater (true));
68                                 break;
69                         default:
70                                 throw new ArgumentException ("mode");
71                         }
72
73                         _baseStream = compressedStream;
74                         _leaveOpen = leaveOpen;
75                         _open = true;
76                 }
77
78                 public DeflateStream (Stream compressedStream, CompressionMode mode)
79                         :
80                         this (compressedStream, mode, false, false) { }
81
82                 public DeflateStream (Stream compressedStream, CompressionMode mode, bool leaveOpen)
83                         :
84                         this (compressedStream, mode, leaveOpen, false) { }
85
86                 protected override void Dispose (bool disposing) {
87                         if (!_open) {
88                                 base.Dispose (disposing);
89                                 return;
90                         }
91
92                         try {
93                                 FlushInternal (true);
94                                 base.Dispose (disposing);
95                         }
96                         finally {
97                                 _open = false;
98                                 if (!_leaveOpen)
99                                         _baseStream.Close ();
100                         }
101                 }
102
103                 private int ReadInternal (byte [] array, int offset, int count) {
104                         int r = _reader.read (TypeUtils.ToSByteArray (array), offset, count);
105                         return r < 0 ? 0 : r;
106                 }
107
108                 public override int Read (byte [] dest, int dest_offset, int count) {
109                         if (!_open)
110                                 throw new ObjectDisposedException ("DeflateStream");
111                         if (dest == null)
112                                 throw new ArgumentNullException ("Destination array is null.");
113                         if (!CanRead)
114                                 throw new InvalidOperationException ("Stream does not support reading.");
115                         int len = dest.Length;
116                         if (dest_offset < 0 || count < 0)
117                                 throw new ArgumentException ("Dest or count is negative.");
118                         if (dest_offset > len)
119                                 throw new ArgumentException ("destination offset is beyond array size");
120                         if ((dest_offset + count) > len)
121                                 throw new ArgumentException ("Reading would overrun buffer");
122
123                         return ReadInternal (dest, dest_offset, count);
124                 }
125
126                 private void WriteInternal (byte [] array, int offset, int count) {
127                         _writer.write (TypeUtils.ToSByteArray (array), offset, count);
128                 }
129
130                 public override void Write (byte [] src, int src_offset, int count) {
131                         if (!_open)
132                                 throw new ObjectDisposedException ("DeflateStream");
133
134                         if (src == null)
135                                 throw new ArgumentNullException ("src");
136
137                         if (src_offset < 0)
138                                 throw new ArgumentOutOfRangeException ("src_offset");
139
140                         if (count < 0)
141                                 throw new ArgumentOutOfRangeException ("count");
142
143                         if (!CanWrite)
144                                 throw new NotSupportedException ("Stream does not support writing");
145
146                         WriteInternal (src, src_offset, count);
147                 }
148
149                 private void FlushInternal (bool finish) {
150                         if (!_open)
151                                 throw new ObjectDisposedException ("DeflateStream");
152
153                         if (_writer != null) {
154                                 _writer.flush ();
155
156                                 if (finish)
157                                         _writer.finish ();
158                         }
159                 }
160
161                 public override void Flush () {
162                         FlushInternal (false);
163                 }
164
165                 public override long Seek (long offset, SeekOrigin origin) {
166                         throw new System.NotSupportedException ();
167                 }
168
169                 public override void SetLength (long value) {
170                         throw new System.NotSupportedException ();
171                 }
172
173                 public override IAsyncResult BeginRead (byte [] buffer, int offset, int count,
174                                                         AsyncCallback cback, object state) {
175                         if (!_open)
176                                 throw new ObjectDisposedException ("DeflateStream");
177
178                         if (!CanRead)
179                                 throw new NotSupportedException ("This stream does not support reading");
180
181                         if (buffer == null)
182                                 throw new ArgumentNullException ("buffer");
183
184                         if (count < 0)
185                                 throw new ArgumentOutOfRangeException ("count", "Must be >= 0");
186
187                         if (offset < 0)
188                                 throw new ArgumentOutOfRangeException ("offset", "Must be >= 0");
189
190                         if (count + offset > buffer.Length)
191                                 throw new ArgumentException ("Buffer too small. count/offset wrong.");
192
193                         ReadMethod r = new ReadMethod (ReadInternal);
194                         return r.BeginInvoke (buffer, offset, count, cback, state);
195                 }
196
197                 public override IAsyncResult BeginWrite (byte [] buffer, int offset, int count,
198                                                         AsyncCallback cback, object state) {
199                         if (!_open)
200                                 throw new ObjectDisposedException ("DeflateStream");
201
202                         if (!CanWrite)
203                                 throw new InvalidOperationException ("This stream does not support writing");
204
205                         if (buffer == null)
206                                 throw new ArgumentNullException ("buffer");
207
208                         if (count < 0)
209                                 throw new ArgumentOutOfRangeException ("count", "Must be >= 0");
210
211                         if (offset < 0)
212                                 throw new ArgumentOutOfRangeException ("offset", "Must be >= 0");
213
214                         if (count + offset > buffer.Length)
215                                 throw new ArgumentException ("Buffer too small. count/offset wrong.");
216
217                         WriteMethod w = new WriteMethod (WriteInternal);
218                         return w.BeginInvoke (buffer, offset, count, cback, state);
219                 }
220
221                 public override int EndRead (IAsyncResult async_result) {
222                         if (async_result == null)
223                                 throw new ArgumentNullException ("async_result");
224
225                         AsyncResult ares = async_result as AsyncResult;
226                         if (ares == null)
227                                 throw new ArgumentException ("Invalid IAsyncResult", "async_result");
228
229                         ReadMethod r = ares.AsyncDelegate as ReadMethod;
230                         if (r == null)
231                                 throw new ArgumentException ("Invalid IAsyncResult", "async_result");
232
233                         return r.EndInvoke (async_result);
234                 }
235
236                 public override void EndWrite (IAsyncResult async_result) {
237                         if (async_result == null)
238                                 throw new ArgumentNullException ("async_result");
239
240                         AsyncResult ares = async_result as AsyncResult;
241                         if (ares == null)
242                                 throw new ArgumentException ("Invalid IAsyncResult", "async_result");
243
244                         WriteMethod w = ares.AsyncDelegate as WriteMethod;
245                         if (w == null)
246                                 throw new ArgumentException ("Invalid IAsyncResult", "async_result");
247
248                         w.EndInvoke (async_result);
249                 }
250
251                 public Stream BaseStream {
252                         get {
253                                 return _baseStream;
254                         }
255                 }
256                 public override bool CanRead {
257                         get {
258                                 return _open && _reader != null;
259                         }
260                 }
261                 public override bool CanSeek {
262                         get {
263                                 return false;
264                         }
265                 }
266                 public override bool CanWrite {
267                         get {
268                                 return _open && _writer != null;
269                         }
270                 }
271                 public override long Length {
272                         get {
273                                 throw new NotSupportedException ();
274                         }
275                 }
276                 public override long Position {
277                         get {
278                                 throw new NotSupportedException ();
279                         }
280                         set {
281                                 throw new NotSupportedException ();
282                         }
283                 }
284
285                 #region InputStreamImpl
286
287                 sealed class InputStreamImpl : InputStream
288                 {
289                         readonly Stream _stream;
290
291                         public InputStreamImpl (Stream stream) {
292                                 _stream = stream;
293                         }
294
295                         public override void close () {
296                                 BaseStream.Close ();
297                         }
298
299                         public override int read () {
300                                 return BaseStream.ReadByte ();
301                         }
302
303                         public override int read (sbyte [] b, int off, int len) {
304                                 int r = BaseStream.Read ((byte []) TypeUtils.ToByteArray (b), off, len);
305                                 return r == 0 ? -1 : r;
306                         }
307
308                         public override long skip (long n) {
309                                 return BaseStream.Seek (n, SeekOrigin.Current);
310                         }
311
312                         public override bool Equals (object obj) {
313                                 return (obj is InputStreamImpl) &&
314                                         BaseStream.Equals (((InputStreamImpl) obj).BaseStream);
315                         }
316
317                         public override int GetHashCode () {
318                                 return _stream.GetHashCode ();
319                         }
320
321                         public Stream BaseStream {
322                                 get { return _stream; }
323                         }
324                 }
325
326                 #endregion
327
328                 #region OutputStreamImpl
329
330                 sealed class OutputStreamImpl : OutputStream
331                 {
332                         readonly Stream _stream;
333
334                         public OutputStreamImpl (Stream stream) {
335                                 _stream = stream;
336                         }
337
338                         public override void close () {
339                                 BaseStream.Close ();
340                         }
341
342                         public override void flush () {
343                                 BaseStream.Flush ();
344                         }
345
346                         public override void write (int b) {
347                                 BaseStream.WriteByte ((byte) (b & 0xFF));
348                         }
349
350                         public override void write (sbyte [] b, int off, int len) {
351                                 BaseStream.Write ((byte []) TypeUtils.ToByteArray (b), off, len);
352                         }
353
354                         public override bool Equals (object obj) {
355                                 return (obj is OutputStreamImpl) &&
356                                         BaseStream.Equals (((OutputStreamImpl) obj).BaseStream);
357                         }
358
359                         public override int GetHashCode () {
360                                 return _stream.GetHashCode ();
361                         }
362
363                         public Stream BaseStream {
364                                 get { return _stream; }
365                         }
366                 }
367
368                 #endregion
369         }
370 }
371 //#endif