annotate src/zlib-1.2.7/contrib/dotzlib/DotZLib/GZipStream.cs @ 89:8a15ff55d9af

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