annotate src/zlib-1.2.8/contrib/dotzlib/DotZLib/GZipStream.cs @ 148:b4bfdf10c4b3

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