symbian-qemu-0.9.1-12/zlib-1.2.3/contrib/dotzlib/DotZLib/GZipStream.cs
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 &gt; 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 &gt; 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 }