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