Mercurial > hg > sv-dependency-builds
comparison src/zlib-1.2.7/contrib/dotzlib/DotZLib/GZipStream.cs @ 4:e13257ea84a4
Add bzip2, zlib, liblo, portaudio sources
author | Chris Cannam |
---|---|
date | Wed, 20 Mar 2013 13:59:52 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:6c505a35919a | 4:e13257ea84a4 |
---|---|
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 | |
8 using System; | |
9 using System.IO; | |
10 using System.Runtime.InteropServices; | |
11 | |
12 namespace 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 > 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 > 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 } |