1275793eaSopenharmony_ci// 2275793eaSopenharmony_ci// � Copyright Henrik Ravn 2004 3275793eaSopenharmony_ci// 4275793eaSopenharmony_ci// Use, modification and distribution are subject to the Boost Software License, Version 1.0. 5275793eaSopenharmony_ci// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6275793eaSopenharmony_ci// 7275793eaSopenharmony_ci 8275793eaSopenharmony_ciusing System; 9275793eaSopenharmony_ciusing System.Diagnostics; 10275793eaSopenharmony_ciusing System.Runtime.InteropServices; 11275793eaSopenharmony_ci 12275793eaSopenharmony_cinamespace DotZLib 13275793eaSopenharmony_ci{ 14275793eaSopenharmony_ci 15275793eaSopenharmony_ci /// <summary> 16275793eaSopenharmony_ci /// Implements a data decompressor, using the inflate algorithm in the ZLib dll 17275793eaSopenharmony_ci /// </summary> 18275793eaSopenharmony_ci public class Inflater : CodecBase 19275793eaSopenharmony_ci { 20275793eaSopenharmony_ci #region Dll imports 21275793eaSopenharmony_ci [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] 22275793eaSopenharmony_ci private static extern int inflateInit_(ref ZStream sz, string vs, int size); 23275793eaSopenharmony_ci 24275793eaSopenharmony_ci [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] 25275793eaSopenharmony_ci private static extern int inflate(ref ZStream sz, int flush); 26275793eaSopenharmony_ci 27275793eaSopenharmony_ci [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] 28275793eaSopenharmony_ci private static extern int inflateReset(ref ZStream sz); 29275793eaSopenharmony_ci 30275793eaSopenharmony_ci [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] 31275793eaSopenharmony_ci private static extern int inflateEnd(ref ZStream sz); 32275793eaSopenharmony_ci #endregion 33275793eaSopenharmony_ci 34275793eaSopenharmony_ci /// <summary> 35275793eaSopenharmony_ci /// Constructs an new instance of the <c>Inflater</c> 36275793eaSopenharmony_ci /// </summary> 37275793eaSopenharmony_ci public Inflater() : base() 38275793eaSopenharmony_ci { 39275793eaSopenharmony_ci int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream)); 40275793eaSopenharmony_ci if (retval != 0) 41275793eaSopenharmony_ci throw new ZLibException(retval, "Could not initialize inflater"); 42275793eaSopenharmony_ci 43275793eaSopenharmony_ci resetOutput(); 44275793eaSopenharmony_ci } 45275793eaSopenharmony_ci 46275793eaSopenharmony_ci 47275793eaSopenharmony_ci /// <summary> 48275793eaSopenharmony_ci /// Adds more data to the codec to be processed. 49275793eaSopenharmony_ci /// </summary> 50275793eaSopenharmony_ci /// <param name="data">Byte array containing the data to be added to the codec</param> 51275793eaSopenharmony_ci /// <param name="offset">The index of the first byte to add from <c>data</c></param> 52275793eaSopenharmony_ci /// <param name="count">The number of bytes to add</param> 53275793eaSopenharmony_ci /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> 54275793eaSopenharmony_ci public override void Add(byte[] data, int offset, int count) 55275793eaSopenharmony_ci { 56275793eaSopenharmony_ci if (data == null) throw new ArgumentNullException(); 57275793eaSopenharmony_ci if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); 58275793eaSopenharmony_ci if ((offset+count) > data.Length) throw new ArgumentException(); 59275793eaSopenharmony_ci 60275793eaSopenharmony_ci int total = count; 61275793eaSopenharmony_ci int inputIndex = offset; 62275793eaSopenharmony_ci int err = 0; 63275793eaSopenharmony_ci 64275793eaSopenharmony_ci while (err >= 0 && inputIndex < total) 65275793eaSopenharmony_ci { 66275793eaSopenharmony_ci copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); 67275793eaSopenharmony_ci err = inflate(ref _ztream, (int)FlushTypes.None); 68275793eaSopenharmony_ci if (err == 0) 69275793eaSopenharmony_ci while (_ztream.avail_out == 0) 70275793eaSopenharmony_ci { 71275793eaSopenharmony_ci OnDataAvailable(); 72275793eaSopenharmony_ci err = inflate(ref _ztream, (int)FlushTypes.None); 73275793eaSopenharmony_ci } 74275793eaSopenharmony_ci 75275793eaSopenharmony_ci inputIndex += (int)_ztream.total_in; 76275793eaSopenharmony_ci } 77275793eaSopenharmony_ci setChecksum( _ztream.adler ); 78275793eaSopenharmony_ci } 79275793eaSopenharmony_ci 80275793eaSopenharmony_ci 81275793eaSopenharmony_ci /// <summary> 82275793eaSopenharmony_ci /// Finishes up any pending data that needs to be processed and handled. 83275793eaSopenharmony_ci /// </summary> 84275793eaSopenharmony_ci public override void Finish() 85275793eaSopenharmony_ci { 86275793eaSopenharmony_ci int err; 87275793eaSopenharmony_ci do 88275793eaSopenharmony_ci { 89275793eaSopenharmony_ci err = inflate(ref _ztream, (int)FlushTypes.Finish); 90275793eaSopenharmony_ci OnDataAvailable(); 91275793eaSopenharmony_ci } 92275793eaSopenharmony_ci while (err == 0); 93275793eaSopenharmony_ci setChecksum( _ztream.adler ); 94275793eaSopenharmony_ci inflateReset(ref _ztream); 95275793eaSopenharmony_ci resetOutput(); 96275793eaSopenharmony_ci } 97275793eaSopenharmony_ci 98275793eaSopenharmony_ci /// <summary> 99275793eaSopenharmony_ci /// Closes the internal zlib inflate stream 100275793eaSopenharmony_ci /// </summary> 101275793eaSopenharmony_ci protected override void CleanUp() { inflateEnd(ref _ztream); } 102275793eaSopenharmony_ci 103275793eaSopenharmony_ci 104275793eaSopenharmony_ci } 105275793eaSopenharmony_ci} 106