Home | History | Annotate | Line # | Download | only in DotZLib
Deflater.cs revision 1.1
      1  1.1  christos //
      2  1.1  christos //  Copyright Henrik Ravn 2004
      3  1.1  christos //
      4  1.1  christos // 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  christos 
     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  christos             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