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