1*44bedb31SLionel Sambuc // 2*44bedb31SLionel Sambuc // � Copyright Henrik Ravn 2004 3*44bedb31SLionel Sambuc // 4*44bedb31SLionel Sambuc // Use, modification and distribution are subject to the Boost Software License, Version 1.0. 5*44bedb31SLionel Sambuc // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6*44bedb31SLionel Sambuc // 7*44bedb31SLionel Sambuc 8*44bedb31SLionel Sambuc using System; 9*44bedb31SLionel Sambuc using System.IO; 10*44bedb31SLionel Sambuc using System.Runtime.InteropServices; 11*44bedb31SLionel Sambuc using System.Text; 12*44bedb31SLionel Sambuc 13*44bedb31SLionel Sambuc 14*44bedb31SLionel Sambuc namespace DotZLib 15*44bedb31SLionel Sambuc { 16*44bedb31SLionel Sambuc 17*44bedb31SLionel Sambuc #region Internal types 18*44bedb31SLionel Sambuc 19*44bedb31SLionel Sambuc /// <summary> 20*44bedb31SLionel Sambuc /// Defines constants for the various flush types used with zlib 21*44bedb31SLionel Sambuc /// </summary> 22*44bedb31SLionel Sambuc internal enum FlushTypes 23*44bedb31SLionel Sambuc { 24*44bedb31SLionel Sambuc None, Partial, Sync, Full, Finish, Block 25*44bedb31SLionel Sambuc } 26*44bedb31SLionel Sambuc 27*44bedb31SLionel Sambuc #region ZStream structure 28*44bedb31SLionel Sambuc // internal mapping of the zlib zstream structure for marshalling 29*44bedb31SLionel Sambuc [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)] 30*44bedb31SLionel Sambuc internal struct ZStream 31*44bedb31SLionel Sambuc { 32*44bedb31SLionel Sambuc public IntPtr next_in; 33*44bedb31SLionel Sambuc public uint avail_in; 34*44bedb31SLionel Sambuc public uint total_in; 35*44bedb31SLionel Sambuc 36*44bedb31SLionel Sambuc public IntPtr next_out; 37*44bedb31SLionel Sambuc public uint avail_out; 38*44bedb31SLionel Sambuc public uint total_out; 39*44bedb31SLionel Sambuc 40*44bedb31SLionel Sambuc [MarshalAs(UnmanagedType.LPStr)] 41*44bedb31SLionel Sambuc string msg; 42*44bedb31SLionel Sambuc uint state; 43*44bedb31SLionel Sambuc 44*44bedb31SLionel Sambuc uint zalloc; 45*44bedb31SLionel Sambuc uint zfree; 46*44bedb31SLionel Sambuc uint opaque; 47*44bedb31SLionel Sambuc 48*44bedb31SLionel Sambuc int data_type; 49*44bedb31SLionel Sambuc public uint adler; 50*44bedb31SLionel Sambuc uint reserved; 51*44bedb31SLionel Sambuc } 52*44bedb31SLionel Sambuc 53*44bedb31SLionel Sambuc #endregion 54*44bedb31SLionel Sambuc 55*44bedb31SLionel Sambuc #endregion 56*44bedb31SLionel Sambuc 57*44bedb31SLionel Sambuc #region Public enums 58*44bedb31SLionel Sambuc /// <summary> 59*44bedb31SLionel Sambuc /// Defines constants for the available compression levels in zlib 60*44bedb31SLionel Sambuc /// </summary> 61*44bedb31SLionel Sambuc public enum CompressLevel : int 62*44bedb31SLionel Sambuc { 63*44bedb31SLionel Sambuc /// <summary> 64*44bedb31SLionel Sambuc /// The default compression level with a reasonable compromise between compression and speed 65*44bedb31SLionel Sambuc /// </summary> 66*44bedb31SLionel Sambuc Default = -1, 67*44bedb31SLionel Sambuc /// <summary> 68*44bedb31SLionel Sambuc /// No compression at all. The data are passed straight through. 69*44bedb31SLionel Sambuc /// </summary> 70*44bedb31SLionel Sambuc None = 0, 71*44bedb31SLionel Sambuc /// <summary> 72*44bedb31SLionel Sambuc /// The maximum compression rate available. 73*44bedb31SLionel Sambuc /// </summary> 74*44bedb31SLionel Sambuc Best = 9, 75*44bedb31SLionel Sambuc /// <summary> 76*44bedb31SLionel Sambuc /// The fastest available compression level. 77*44bedb31SLionel Sambuc /// </summary> 78*44bedb31SLionel Sambuc Fastest = 1 79*44bedb31SLionel Sambuc } 80*44bedb31SLionel Sambuc #endregion 81*44bedb31SLionel Sambuc 82*44bedb31SLionel Sambuc #region Exception classes 83*44bedb31SLionel Sambuc /// <summary> 84*44bedb31SLionel Sambuc /// The exception that is thrown when an error occurs on the zlib dll 85*44bedb31SLionel Sambuc /// </summary> 86*44bedb31SLionel Sambuc public class ZLibException : ApplicationException 87*44bedb31SLionel Sambuc { 88*44bedb31SLionel Sambuc /// <summary> 89*44bedb31SLionel Sambuc /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified 90*44bedb31SLionel Sambuc /// error message and error code 91*44bedb31SLionel Sambuc /// </summary> 92*44bedb31SLionel Sambuc /// <param name="errorCode">The zlib error code that caused the exception</param> 93*44bedb31SLionel Sambuc /// <param name="msg">A message that (hopefully) describes the error</param> ZLibException(int errorCode, string msg)94*44bedb31SLionel Sambuc public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg)) 95*44bedb31SLionel Sambuc { 96*44bedb31SLionel Sambuc } 97*44bedb31SLionel Sambuc 98*44bedb31SLionel Sambuc /// <summary> 99*44bedb31SLionel Sambuc /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified 100*44bedb31SLionel Sambuc /// error code 101*44bedb31SLionel Sambuc /// </summary> 102*44bedb31SLionel Sambuc /// <param name="errorCode">The zlib error code that caused the exception</param> ZLibException(int errorCode)103*44bedb31SLionel Sambuc public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode)) 104*44bedb31SLionel Sambuc { 105*44bedb31SLionel Sambuc } 106*44bedb31SLionel Sambuc } 107*44bedb31SLionel Sambuc #endregion 108*44bedb31SLionel Sambuc 109*44bedb31SLionel Sambuc #region Interfaces 110*44bedb31SLionel Sambuc 111*44bedb31SLionel Sambuc /// <summary> 112*44bedb31SLionel Sambuc /// Declares methods and properties that enables a running checksum to be calculated 113*44bedb31SLionel Sambuc /// </summary> 114*44bedb31SLionel Sambuc public interface ChecksumGenerator 115*44bedb31SLionel Sambuc { 116*44bedb31SLionel Sambuc /// <summary> 117*44bedb31SLionel Sambuc /// Gets the current value of the checksum 118*44bedb31SLionel Sambuc /// </summary> 119*44bedb31SLionel Sambuc uint Value { get; } 120*44bedb31SLionel Sambuc 121*44bedb31SLionel Sambuc /// <summary> 122*44bedb31SLionel Sambuc /// Clears the current checksum to 0 123*44bedb31SLionel Sambuc /// </summary> Reset()124*44bedb31SLionel Sambuc void Reset(); 125*44bedb31SLionel Sambuc 126*44bedb31SLionel Sambuc /// <summary> 127*44bedb31SLionel Sambuc /// Updates the current checksum with an array of bytes 128*44bedb31SLionel Sambuc /// </summary> 129*44bedb31SLionel Sambuc /// <param name="data">The data to update the checksum with</param> Update(byte[] data)130*44bedb31SLionel Sambuc void Update(byte[] data); 131*44bedb31SLionel Sambuc 132*44bedb31SLionel Sambuc /// <summary> 133*44bedb31SLionel Sambuc /// Updates the current checksum with part of an array of bytes 134*44bedb31SLionel Sambuc /// </summary> 135*44bedb31SLionel Sambuc /// <param name="data">The data to update the checksum with</param> 136*44bedb31SLionel Sambuc /// <param name="offset">Where in <c>data</c> to start updating</param> 137*44bedb31SLionel Sambuc /// <param name="count">The number of bytes from <c>data</c> to use</param> 138*44bedb31SLionel Sambuc /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception> 139*44bedb31SLionel Sambuc /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception> 140*44bedb31SLionel Sambuc /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception> Update(byte[] data, int offset, int count)141*44bedb31SLionel Sambuc void Update(byte[] data, int offset, int count); 142*44bedb31SLionel Sambuc 143*44bedb31SLionel Sambuc /// <summary> 144*44bedb31SLionel Sambuc /// Updates the current checksum with the data from a string 145*44bedb31SLionel Sambuc /// </summary> 146*44bedb31SLionel Sambuc /// <param name="data">The string to update the checksum with</param> 147*44bedb31SLionel Sambuc /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks> Update(string data)148*44bedb31SLionel Sambuc void Update(string data); 149*44bedb31SLionel Sambuc 150*44bedb31SLionel Sambuc /// <summary> 151*44bedb31SLionel Sambuc /// Updates the current checksum with the data from a string, using a specific encoding 152*44bedb31SLionel Sambuc /// </summary> 153*44bedb31SLionel Sambuc /// <param name="data">The string to update the checksum with</param> 154*44bedb31SLionel Sambuc /// <param name="encoding">The encoding to use</param> Update(string data, Encoding encoding)155*44bedb31SLionel Sambuc void Update(string data, Encoding encoding); 156*44bedb31SLionel Sambuc } 157*44bedb31SLionel Sambuc 158*44bedb31SLionel Sambuc 159*44bedb31SLionel Sambuc /// <summary> 160*44bedb31SLionel Sambuc /// Represents the method that will be called from a codec when new data 161*44bedb31SLionel Sambuc /// are available. 162*44bedb31SLionel Sambuc /// </summary> 163*44bedb31SLionel Sambuc /// <paramref name="data">The byte array containing the processed data</paramref> 164*44bedb31SLionel Sambuc /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref> 165*44bedb31SLionel Sambuc /// <paramref name="count">The number of processed bytes available</paramref> 166*44bedb31SLionel Sambuc /// <remarks>On return from this method, the data may be overwritten, so grab it while you can. 167*44bedb31SLionel Sambuc /// You cannot assume that startIndex will be zero. 168*44bedb31SLionel Sambuc /// </remarks> DataAvailableHandler(byte[] data, int startIndex, int count)169*44bedb31SLionel Sambuc public delegate void DataAvailableHandler(byte[] data, int startIndex, int count); 170*44bedb31SLionel Sambuc 171*44bedb31SLionel Sambuc /// <summary> 172*44bedb31SLionel Sambuc /// Declares methods and events for implementing compressors/decompressors 173*44bedb31SLionel Sambuc /// </summary> 174*44bedb31SLionel Sambuc public interface Codec 175*44bedb31SLionel Sambuc { 176*44bedb31SLionel Sambuc /// <summary> 177*44bedb31SLionel Sambuc /// Occurs when more processed data are available. 178*44bedb31SLionel Sambuc /// </summary> 179*44bedb31SLionel Sambuc event DataAvailableHandler DataAvailable; 180*44bedb31SLionel Sambuc 181*44bedb31SLionel Sambuc /// <summary> 182*44bedb31SLionel Sambuc /// Adds more data to the codec to be processed. 183*44bedb31SLionel Sambuc /// </summary> 184*44bedb31SLionel Sambuc /// <param name="data">Byte array containing the data to be added to the codec</param> 185*44bedb31SLionel Sambuc /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> Add(byte[] data)186*44bedb31SLionel Sambuc void Add(byte[] data); 187*44bedb31SLionel Sambuc 188*44bedb31SLionel Sambuc /// <summary> 189*44bedb31SLionel Sambuc /// Adds more data to the codec to be processed. 190*44bedb31SLionel Sambuc /// </summary> 191*44bedb31SLionel Sambuc /// <param name="data">Byte array containing the data to be added to the codec</param> 192*44bedb31SLionel Sambuc /// <param name="offset">The index of the first byte to add from <c>data</c></param> 193*44bedb31SLionel Sambuc /// <param name="count">The number of bytes to add</param> 194*44bedb31SLionel Sambuc /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> Add(byte[] data, int offset, int count)195*44bedb31SLionel Sambuc void Add(byte[] data, int offset, int count); 196*44bedb31SLionel Sambuc 197*44bedb31SLionel Sambuc /// <summary> 198*44bedb31SLionel Sambuc /// Finishes up any pending data that needs to be processed and handled. 199*44bedb31SLionel Sambuc /// </summary> Finish()200*44bedb31SLionel Sambuc void Finish(); 201*44bedb31SLionel Sambuc 202*44bedb31SLionel Sambuc /// <summary> 203*44bedb31SLionel Sambuc /// Gets the checksum of the data that has been added so far 204*44bedb31SLionel Sambuc /// </summary> 205*44bedb31SLionel Sambuc uint Checksum { get; } 206*44bedb31SLionel Sambuc 207*44bedb31SLionel Sambuc 208*44bedb31SLionel Sambuc } 209*44bedb31SLionel Sambuc 210*44bedb31SLionel Sambuc #endregion 211*44bedb31SLionel Sambuc 212*44bedb31SLionel Sambuc #region Classes 213*44bedb31SLionel Sambuc /// <summary> 214*44bedb31SLionel Sambuc /// Encapsulates general information about the ZLib library 215*44bedb31SLionel Sambuc /// </summary> 216*44bedb31SLionel Sambuc public class Info 217*44bedb31SLionel Sambuc { 218*44bedb31SLionel Sambuc #region DLL imports 219*44bedb31SLionel Sambuc [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] zlibCompileFlags()220*44bedb31SLionel Sambuc private static extern uint zlibCompileFlags(); 221*44bedb31SLionel Sambuc 222*44bedb31SLionel Sambuc [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] zlibVersion()223*44bedb31SLionel Sambuc private static extern string zlibVersion(); 224*44bedb31SLionel Sambuc #endregion 225*44bedb31SLionel Sambuc 226*44bedb31SLionel Sambuc #region Private stuff 227*44bedb31SLionel Sambuc private uint _flags; 228*44bedb31SLionel Sambuc 229*44bedb31SLionel Sambuc // helper function that unpacks a bitsize mask bitSize(uint bits)230*44bedb31SLionel Sambuc private static int bitSize(uint bits) 231*44bedb31SLionel Sambuc { 232*44bedb31SLionel Sambuc switch (bits) 233*44bedb31SLionel Sambuc { 234*44bedb31SLionel Sambuc case 0: return 16; 235*44bedb31SLionel Sambuc case 1: return 32; 236*44bedb31SLionel Sambuc case 2: return 64; 237*44bedb31SLionel Sambuc } 238*44bedb31SLionel Sambuc return -1; 239*44bedb31SLionel Sambuc } 240*44bedb31SLionel Sambuc #endregion 241*44bedb31SLionel Sambuc 242*44bedb31SLionel Sambuc /// <summary> 243*44bedb31SLionel Sambuc /// Constructs an instance of the <c>Info</c> class. 244*44bedb31SLionel Sambuc /// </summary> Info()245*44bedb31SLionel Sambuc public Info() 246*44bedb31SLionel Sambuc { 247*44bedb31SLionel Sambuc _flags = zlibCompileFlags(); 248*44bedb31SLionel Sambuc } 249*44bedb31SLionel Sambuc 250*44bedb31SLionel Sambuc /// <summary> 251*44bedb31SLionel Sambuc /// True if the library is compiled with debug info 252*44bedb31SLionel Sambuc /// </summary> 253*44bedb31SLionel Sambuc public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } } 254*44bedb31SLionel Sambuc 255*44bedb31SLionel Sambuc /// <summary> 256*44bedb31SLionel Sambuc /// True if the library is compiled with assembly optimizations 257*44bedb31SLionel Sambuc /// </summary> 258*44bedb31SLionel Sambuc public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } } 259*44bedb31SLionel Sambuc 260*44bedb31SLionel Sambuc /// <summary> 261*44bedb31SLionel Sambuc /// Gets the size of the unsigned int that was compiled into Zlib 262*44bedb31SLionel Sambuc /// </summary> 263*44bedb31SLionel Sambuc public int SizeOfUInt { get { return bitSize(_flags & 3); } } 264*44bedb31SLionel Sambuc 265*44bedb31SLionel Sambuc /// <summary> 266*44bedb31SLionel Sambuc /// Gets the size of the unsigned long that was compiled into Zlib 267*44bedb31SLionel Sambuc /// </summary> 268*44bedb31SLionel Sambuc public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } } 269*44bedb31SLionel Sambuc 270*44bedb31SLionel Sambuc /// <summary> 271*44bedb31SLionel Sambuc /// Gets the size of the pointers that were compiled into Zlib 272*44bedb31SLionel Sambuc /// </summary> 273*44bedb31SLionel Sambuc public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } } 274*44bedb31SLionel Sambuc 275*44bedb31SLionel Sambuc /// <summary> 276*44bedb31SLionel Sambuc /// Gets the size of the z_off_t type that was compiled into Zlib 277*44bedb31SLionel Sambuc /// </summary> 278*44bedb31SLionel Sambuc public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } } 279*44bedb31SLionel Sambuc 280*44bedb31SLionel Sambuc /// <summary> 281*44bedb31SLionel Sambuc /// Gets the version of ZLib as a string, e.g. "1.2.1" 282*44bedb31SLionel Sambuc /// </summary> 283*44bedb31SLionel Sambuc public static string Version { get { return zlibVersion(); } } 284*44bedb31SLionel Sambuc } 285*44bedb31SLionel Sambuc 286*44bedb31SLionel Sambuc #endregion 287*44bedb31SLionel Sambuc 288*44bedb31SLionel Sambuc } 289