annotate src/zlib-1.2.8/contrib/dotzlib/DotZLib/GZipStream.cs @ 56:af97cad61ff0

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