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