DotZLib.cs 9.7 KB

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