source: rtems/cpukit/zlib/contrib/dotzlib/DotZLib/GZipStream.cs @ b74f82b

4.104.114.84.95
Last change on this file since b74f82b was 959f7df2, checked in by Ralf Corsepius <ralf.corsepius@…>, on 10/28/05 at 07:22:42

Import of zlib-1.2.2.2.tar.gz

  • Property mode set to 100644
File size: 10.9 KB
Line 
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.IO;
10using System.Runtime.InteropServices;
11
12namespace DotZLib
13{
14        /// <summary>
15        /// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.
16        /// </summary>
17        public class GZipStream : Stream, IDisposable
18        {
19        #region Dll Imports
20        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
21        private static extern IntPtr gzopen(string name, string mode);
22
23        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
24        private static extern int gzclose(IntPtr gzFile);
25
26        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
27        private static extern int gzwrite(IntPtr gzFile, int data, int length);
28
29        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
30        private static extern int gzread(IntPtr gzFile, int data, int length);
31
32        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
33        private static extern int gzgetc(IntPtr gzFile);
34
35        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
36        private static extern int gzputc(IntPtr gzFile, int c);
37
38        #endregion
39
40        #region Private data
41        private IntPtr _gzFile;
42        private bool _isDisposed = false;
43        private bool _isWriting;
44        #endregion
45
46        #region Constructors
47        /// <summary>
48        /// Creates a new file as a writeable GZipStream
49        /// </summary>
50        /// <param name="fileName">The name of the compressed file to create</param>
51        /// <param name="level">The compression level to use when adding data</param>
52        /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
53                public GZipStream(string fileName, CompressLevel level)
54                {
55            _isWriting = true;
56            _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));
57            if (_gzFile == IntPtr.Zero)
58                throw new ZLibException(-1, "Could not open " + fileName);
59                }
60
61        /// <summary>
62        /// Opens an existing file as a readable GZipStream
63        /// </summary>
64        /// <param name="fileName">The name of the file to open</param>
65        /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
66        public GZipStream(string fileName)
67        {
68            _isWriting = false;
69            _gzFile = gzopen(fileName, "rb");
70            if (_gzFile == IntPtr.Zero)
71                throw new ZLibException(-1, "Could not open " + fileName);
72
73        }
74        #endregion
75
76        #region Access properties
77        /// <summary>
78        /// Returns true of this stream can be read from, false otherwise
79        /// </summary>
80        public override bool CanRead
81        {
82            get
83            {
84                return !_isWriting;
85            }
86        }
87   
88
89        /// <summary>
90        /// Returns false.
91        /// </summary>
92        public override bool CanSeek
93        {
94            get
95            {
96                return false;
97            }
98        }
99   
100        /// <summary>
101        /// Returns true if this tsream is writeable, false otherwise
102        /// </summary>
103        public override bool CanWrite
104        {
105            get
106            {
107                return _isWriting;
108            }
109        }
110        #endregion
111   
112        #region Destructor & IDispose stuff
113
114        /// <summary>
115        /// Destroys this instance
116        /// </summary>
117        ~GZipStream()
118        {
119            cleanUp(false);
120        }
121
122        /// <summary>
123        /// Closes the external file handle
124        /// </summary>
125        public void Dispose()
126        {
127            cleanUp(true);
128        }
129
130        // Does the actual closing of the file handle.
131        private void cleanUp(bool isDisposing)
132        {
133            if (!_isDisposed)
134            {
135                gzclose(_gzFile);
136                _isDisposed = true;
137            }
138        }
139        #endregion
140   
141        #region Basic reading and writing
142        /// <summary>
143        /// Attempts to read a number of bytes from the stream.
144        /// </summary>
145        /// <param name="buffer">The destination data buffer</param>
146        /// <param name="offset">The index of the first destination byte in <c>buffer</c></param>
147        /// <param name="count">The number of bytes requested</param>
148        /// <returns>The number of bytes read</returns>
149        /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
150        /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
151        /// <exception cref="ArgumentException">If <c>offset</c>  + <c>count</c> is &gt; buffer.Length</exception>
152        /// <exception cref="NotSupportedException">If this stream is not readable.</exception>
153        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
154        public override int Read(byte[] buffer, int offset, int count)
155        {
156            if (!CanRead) throw new NotSupportedException();
157            if (buffer == null) throw new ArgumentNullException();
158            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
159            if ((offset+count) > buffer.Length) throw new ArgumentException();
160            if (_isDisposed) throw new ObjectDisposedException("GZipStream");
161
162            GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
163            int result;
164            try
165            {
166                result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
167                if (result < 0)
168                    throw new IOException();
169            }
170            finally
171            {
172                h.Free();
173            }
174            return result;
175        }
176
177        /// <summary>
178        /// Attempts to read a single byte from the stream.
179        /// </summary>
180        /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>
181        public override int ReadByte()
182        {
183            if (!CanRead) throw new NotSupportedException();
184            if (_isDisposed) throw new ObjectDisposedException("GZipStream");
185            return gzgetc(_gzFile);
186        }
187
188        /// <summary>
189        /// Writes a number of bytes to the stream
190        /// </summary>
191        /// <param name="buffer"></param>
192        /// <param name="offset"></param>
193        /// <param name="count"></param>
194        /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
195        /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
196        /// <exception cref="ArgumentException">If <c>offset</c>  + <c>count</c> is &gt; buffer.Length</exception>
197        /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
198        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
199        public override void Write(byte[] buffer, int offset, int count)
200        {
201            if (!CanWrite) throw new NotSupportedException();
202            if (buffer == null) throw new ArgumentNullException();
203            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
204            if ((offset+count) > buffer.Length) throw new ArgumentException();
205            if (_isDisposed) throw new ObjectDisposedException("GZipStream");
206
207            GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
208            try
209            {
210                int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
211                if (result < 0)
212                    throw new IOException();
213            }
214            finally
215            {
216                h.Free();
217            }
218        }
219
220        /// <summary>
221        /// Writes a single byte to the stream
222        /// </summary>
223        /// <param name="value">The byte to add to the stream.</param>
224        /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
225        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
226        public override void WriteByte(byte value)
227        {
228            if (!CanWrite) throw new NotSupportedException();
229            if (_isDisposed) throw new ObjectDisposedException("GZipStream");
230
231            int result = gzputc(_gzFile, (int)value);
232            if (result < 0)
233                throw new IOException();
234        }
235        #endregion
236
237        #region Position & length stuff
238        /// <summary>
239        /// Not supported.
240        /// </summary>
241        /// <param name="value"></param>
242        /// <exception cref="NotSupportedException">Always thrown</exception>
243        public override void SetLength(long value)
244        {
245            throw new NotSupportedException();
246        }
247   
248        /// <summary>
249        ///  Not suppported.
250        /// </summary>
251        /// <param name="offset"></param>
252        /// <param name="origin"></param>
253        /// <returns></returns>
254        /// <exception cref="NotSupportedException">Always thrown</exception>
255        public override long Seek(long offset, SeekOrigin origin)
256        {
257            throw new NotSupportedException();
258        }
259   
260        /// <summary>
261        /// Flushes the <c>GZipStream</c>.
262        /// </summary>
263        /// <remarks>In this implementation, this method does nothing. This is because excessive
264        /// flushing may degrade the achievable compression rates.</remarks>
265        public override void Flush()
266        {
267            // left empty on purpose
268        }
269   
270        /// <summary>
271        /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.
272        /// </summary>
273        /// <remarks>In this implementation this property is not supported</remarks>
274        /// <exception cref="NotSupportedException">Always thrown</exception>
275        public override long Position
276        {
277            get
278            {
279                throw new NotSupportedException();
280            }
281            set
282            {
283                throw new NotSupportedException();
284            }
285        }
286   
287        /// <summary>
288        /// Gets the size of the stream. Not suppported.
289        /// </summary>
290        /// <remarks>In this implementation this property is not supported</remarks>
291        /// <exception cref="NotSupportedException">Always thrown</exception>
292        public override long Length
293        {
294            get
295            {
296                throw new NotSupportedException();
297            }
298        }
299        #endregion
300    }
301}
Note: See TracBrowser for help on using the repository browser.