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