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