Home | History | Annotate | Line # | Download | only in DotZLib
Deflater.cs revision 1.1.1.1.76.1
      1           1.1  christos //
      2           1.1  christos //  Copyright Henrik Ravn 2004
      3           1.1  christos //
      4  1.1.1.1.76.1  pgoyette // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
      5           1.1  christos // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
      6           1.1  christos //
      7           1.1  christos 
      8           1.1  christos using System;
      9           1.1  christos using System.Diagnostics;
     10           1.1  christos using System.Runtime.InteropServices;
     11           1.1  christos 
     12           1.1  christos namespace DotZLib
     13           1.1  christos {
     14           1.1  christos 
     15           1.1  christos     /// <summary>
     16           1.1  christos     /// Implements a data compressor, using the deflate algorithm in the ZLib dll
     17           1.1  christos     /// </summary>
     18           1.1  christos 	public sealed class Deflater : CodecBase
     19           1.1  christos 	{
     20           1.1  christos         #region Dll imports
     21           1.1  christos         [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
     22           1.1  christos         private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
     23           1.1  christos 
     24           1.1  christos         [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
     25           1.1  christos         private static extern int deflate(ref ZStream sz, int flush);
     26           1.1  christos 
     27           1.1  christos         [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
     28           1.1  christos         private static extern int deflateReset(ref ZStream sz);
     29           1.1  christos 
     30           1.1  christos         [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
     31           1.1  christos         private static extern int deflateEnd(ref ZStream sz);
     32           1.1  christos         #endregion
     33           1.1  christos 
     34           1.1  christos         /// <summary>
     35           1.1  christos         /// Constructs an new instance of the <c>Deflater</c>
     36           1.1  christos         /// </summary>
     37           1.1  christos         /// <param name="level">The compression level to use for this <c>Deflater</c></param>
     38           1.1  christos 		public Deflater(CompressLevel level) : base()
     39           1.1  christos 		{
     40           1.1  christos             int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
     41           1.1  christos             if (retval != 0)
     42           1.1  christos                 throw new ZLibException(retval, "Could not initialize deflater");
     43           1.1  christos 
     44           1.1  christos             resetOutput();
     45           1.1  christos 		}
     46           1.1  christos 
     47           1.1  christos         /// <summary>
     48           1.1  christos         /// Adds more data to the codec to be processed.
     49           1.1  christos         /// </summary>
     50           1.1  christos         /// <param name="data">Byte array containing the data to be added to the codec</param>
     51           1.1  christos         /// <param name="offset">The index of the first byte to add from <c>data</c></param>
     52           1.1  christos         /// <param name="count">The number of bytes to add</param>
     53           1.1  christos         /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
     54           1.1  christos         public override void Add(byte[] data, int offset, int count)
     55           1.1  christos         {
     56           1.1  christos             if (data == null) throw new ArgumentNullException();
     57           1.1  christos             if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
     58           1.1  christos             if ((offset+count) > data.Length) throw new ArgumentException();
     59  1.1.1.1.76.1  pgoyette 
     60           1.1  christos             int total = count;
     61           1.1  christos             int inputIndex = offset;
     62           1.1  christos             int err = 0;
     63           1.1  christos 
     64           1.1  christos             while (err >= 0 && inputIndex < total)
     65           1.1  christos             {
     66           1.1  christos                 copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
     67           1.1  christos                 while (err >= 0 && _ztream.avail_in > 0)
     68           1.1  christos                 {
     69           1.1  christos                     err = deflate(ref _ztream, (int)FlushTypes.None);
     70           1.1  christos                     if (err == 0)
     71           1.1  christos                         while (_ztream.avail_out == 0)
     72           1.1  christos                         {
     73           1.1  christos                             OnDataAvailable();
     74           1.1  christos                             err = deflate(ref _ztream, (int)FlushTypes.None);
     75           1.1  christos                         }
     76           1.1  christos                     inputIndex += (int)_ztream.total_in;
     77           1.1  christos                 }
     78           1.1  christos             }
     79           1.1  christos             setChecksum( _ztream.adler );
     80           1.1  christos         }
     81           1.1  christos 
     82           1.1  christos 
     83           1.1  christos         /// <summary>
     84           1.1  christos         /// Finishes up any pending data that needs to be processed and handled.
     85           1.1  christos         /// </summary>
     86           1.1  christos         public override void Finish()
     87           1.1  christos         {
     88           1.1  christos             int err;
     89  1.1.1.1.76.1  pgoyette             do
     90           1.1  christos             {
     91           1.1  christos                 err = deflate(ref _ztream, (int)FlushTypes.Finish);
     92           1.1  christos                 OnDataAvailable();
     93           1.1  christos             }
     94           1.1  christos             while (err == 0);
     95           1.1  christos             setChecksum( _ztream.adler );
     96           1.1  christos             deflateReset(ref _ztream);
     97           1.1  christos             resetOutput();
     98           1.1  christos         }
     99           1.1  christos 
    100           1.1  christos         /// <summary>
    101           1.1  christos         /// Closes the internal zlib deflate stream
    102           1.1  christos         /// </summary>
    103           1.1  christos         protected override void CleanUp() { deflateEnd(ref _ztream); }
    104           1.1  christos 
    105           1.1  christos     }
    106           1.1  christos }
    107