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.IO;
10275793eaSopenharmony_ciusing System.Runtime.InteropServices;
11275793eaSopenharmony_ciusing System.Text;
12275793eaSopenharmony_ci
13275793eaSopenharmony_ci
14275793eaSopenharmony_cinamespace DotZLib
15275793eaSopenharmony_ci{
16275793eaSopenharmony_ci
17275793eaSopenharmony_ci    #region Internal types
18275793eaSopenharmony_ci
19275793eaSopenharmony_ci    /// <summary>
20275793eaSopenharmony_ci    /// Defines constants for the various flush types used with zlib
21275793eaSopenharmony_ci    /// </summary>
22275793eaSopenharmony_ci    internal enum FlushTypes
23275793eaSopenharmony_ci    {
24275793eaSopenharmony_ci        None,  Partial,  Sync,  Full,  Finish,  Block
25275793eaSopenharmony_ci    }
26275793eaSopenharmony_ci
27275793eaSopenharmony_ci    #region ZStream structure
28275793eaSopenharmony_ci    // internal mapping of the zlib zstream structure for marshalling
29275793eaSopenharmony_ci    [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]
30275793eaSopenharmony_ci    internal struct ZStream
31275793eaSopenharmony_ci    {
32275793eaSopenharmony_ci        public IntPtr next_in;
33275793eaSopenharmony_ci        public uint avail_in;
34275793eaSopenharmony_ci        public uint total_in;
35275793eaSopenharmony_ci
36275793eaSopenharmony_ci        public IntPtr next_out;
37275793eaSopenharmony_ci        public uint avail_out;
38275793eaSopenharmony_ci        public uint total_out;
39275793eaSopenharmony_ci
40275793eaSopenharmony_ci        [MarshalAs(UnmanagedType.LPStr)]
41275793eaSopenharmony_ci        string msg;
42275793eaSopenharmony_ci        uint state;
43275793eaSopenharmony_ci
44275793eaSopenharmony_ci        uint zalloc;
45275793eaSopenharmony_ci        uint zfree;
46275793eaSopenharmony_ci        uint opaque;
47275793eaSopenharmony_ci
48275793eaSopenharmony_ci        int data_type;
49275793eaSopenharmony_ci        public uint adler;
50275793eaSopenharmony_ci        uint reserved;
51275793eaSopenharmony_ci    }
52275793eaSopenharmony_ci
53275793eaSopenharmony_ci    #endregion
54275793eaSopenharmony_ci
55275793eaSopenharmony_ci    #endregion
56275793eaSopenharmony_ci
57275793eaSopenharmony_ci    #region Public enums
58275793eaSopenharmony_ci    /// <summary>
59275793eaSopenharmony_ci    /// Defines constants for the available compression levels in zlib
60275793eaSopenharmony_ci    /// </summary>
61275793eaSopenharmony_ci    public enum CompressLevel : int
62275793eaSopenharmony_ci    {
63275793eaSopenharmony_ci        /// <summary>
64275793eaSopenharmony_ci        /// The default compression level with a reasonable compromise between compression and speed
65275793eaSopenharmony_ci        /// </summary>
66275793eaSopenharmony_ci        Default = -1,
67275793eaSopenharmony_ci        /// <summary>
68275793eaSopenharmony_ci        /// No compression at all. The data are passed straight through.
69275793eaSopenharmony_ci        /// </summary>
70275793eaSopenharmony_ci        None = 0,
71275793eaSopenharmony_ci        /// <summary>
72275793eaSopenharmony_ci        /// The maximum compression rate available.
73275793eaSopenharmony_ci        /// </summary>
74275793eaSopenharmony_ci        Best = 9,
75275793eaSopenharmony_ci        /// <summary>
76275793eaSopenharmony_ci        /// The fastest available compression level.
77275793eaSopenharmony_ci        /// </summary>
78275793eaSopenharmony_ci        Fastest = 1
79275793eaSopenharmony_ci    }
80275793eaSopenharmony_ci    #endregion
81275793eaSopenharmony_ci
82275793eaSopenharmony_ci    #region Exception classes
83275793eaSopenharmony_ci    /// <summary>
84275793eaSopenharmony_ci    /// The exception that is thrown when an error occurs on the zlib dll
85275793eaSopenharmony_ci    /// </summary>
86275793eaSopenharmony_ci    public class ZLibException : ApplicationException
87275793eaSopenharmony_ci    {
88275793eaSopenharmony_ci        /// <summary>
89275793eaSopenharmony_ci        /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
90275793eaSopenharmony_ci        /// error message and error code
91275793eaSopenharmony_ci        /// </summary>
92275793eaSopenharmony_ci        /// <param name="errorCode">The zlib error code that caused the exception</param>
93275793eaSopenharmony_ci        /// <param name="msg">A message that (hopefully) describes the error</param>
94275793eaSopenharmony_ci        public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))
95275793eaSopenharmony_ci        {
96275793eaSopenharmony_ci        }
97275793eaSopenharmony_ci
98275793eaSopenharmony_ci        /// <summary>
99275793eaSopenharmony_ci        /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
100275793eaSopenharmony_ci        /// error code
101275793eaSopenharmony_ci        /// </summary>
102275793eaSopenharmony_ci        /// <param name="errorCode">The zlib error code that caused the exception</param>
103275793eaSopenharmony_ci        public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))
104275793eaSopenharmony_ci        {
105275793eaSopenharmony_ci        }
106275793eaSopenharmony_ci    }
107275793eaSopenharmony_ci    #endregion
108275793eaSopenharmony_ci
109275793eaSopenharmony_ci    #region Interfaces
110275793eaSopenharmony_ci
111275793eaSopenharmony_ci    /// <summary>
112275793eaSopenharmony_ci    /// Declares methods and properties that enables a running checksum to be calculated
113275793eaSopenharmony_ci    /// </summary>
114275793eaSopenharmony_ci    public interface ChecksumGenerator
115275793eaSopenharmony_ci    {
116275793eaSopenharmony_ci        /// <summary>
117275793eaSopenharmony_ci        /// Gets the current value of the checksum
118275793eaSopenharmony_ci        /// </summary>
119275793eaSopenharmony_ci        uint Value { get; }
120275793eaSopenharmony_ci
121275793eaSopenharmony_ci        /// <summary>
122275793eaSopenharmony_ci        /// Clears the current checksum to 0
123275793eaSopenharmony_ci        /// </summary>
124275793eaSopenharmony_ci        void Reset();
125275793eaSopenharmony_ci
126275793eaSopenharmony_ci        /// <summary>
127275793eaSopenharmony_ci        /// Updates the current checksum with an array of bytes
128275793eaSopenharmony_ci        /// </summary>
129275793eaSopenharmony_ci        /// <param name="data">The data to update the checksum with</param>
130275793eaSopenharmony_ci        void Update(byte[] data);
131275793eaSopenharmony_ci
132275793eaSopenharmony_ci        /// <summary>
133275793eaSopenharmony_ci        /// Updates the current checksum with part of an array of bytes
134275793eaSopenharmony_ci        /// </summary>
135275793eaSopenharmony_ci        /// <param name="data">The data to update the checksum with</param>
136275793eaSopenharmony_ci        /// <param name="offset">Where in <c>data</c> to start updating</param>
137275793eaSopenharmony_ci        /// <param name="count">The number of bytes from <c>data</c> to use</param>
138275793eaSopenharmony_ci        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
139275793eaSopenharmony_ci        /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>
140275793eaSopenharmony_ci        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
141275793eaSopenharmony_ci        void Update(byte[] data, int offset, int count);
142275793eaSopenharmony_ci
143275793eaSopenharmony_ci        /// <summary>
144275793eaSopenharmony_ci        /// Updates the current checksum with the data from a string
145275793eaSopenharmony_ci        /// </summary>
146275793eaSopenharmony_ci        /// <param name="data">The string to update the checksum with</param>
147275793eaSopenharmony_ci        /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
148275793eaSopenharmony_ci        void Update(string data);
149275793eaSopenharmony_ci
150275793eaSopenharmony_ci        /// <summary>
151275793eaSopenharmony_ci        /// Updates the current checksum with the data from a string, using a specific encoding
152275793eaSopenharmony_ci        /// </summary>
153275793eaSopenharmony_ci        /// <param name="data">The string to update the checksum with</param>
154275793eaSopenharmony_ci        /// <param name="encoding">The encoding to use</param>
155275793eaSopenharmony_ci        void Update(string data, Encoding encoding);
156275793eaSopenharmony_ci    }
157275793eaSopenharmony_ci
158275793eaSopenharmony_ci
159275793eaSopenharmony_ci    /// <summary>
160275793eaSopenharmony_ci    /// Represents the method that will be called from a codec when new data
161275793eaSopenharmony_ci    /// are available.
162275793eaSopenharmony_ci    /// </summary>
163275793eaSopenharmony_ci    /// <paramref name="data">The byte array containing the processed data</paramref>
164275793eaSopenharmony_ci    /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>
165275793eaSopenharmony_ci    /// <paramref name="count">The number of processed bytes available</paramref>
166275793eaSopenharmony_ci    /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.
167275793eaSopenharmony_ci    /// You cannot assume that startIndex will be zero.
168275793eaSopenharmony_ci    /// </remarks>
169275793eaSopenharmony_ci    public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);
170275793eaSopenharmony_ci
171275793eaSopenharmony_ci    /// <summary>
172275793eaSopenharmony_ci    /// Declares methods and events for implementing compressors/decompressors
173275793eaSopenharmony_ci    /// </summary>
174275793eaSopenharmony_ci    public interface Codec
175275793eaSopenharmony_ci    {
176275793eaSopenharmony_ci        /// <summary>
177275793eaSopenharmony_ci        /// Occurs when more processed data are available.
178275793eaSopenharmony_ci        /// </summary>
179275793eaSopenharmony_ci        event DataAvailableHandler DataAvailable;
180275793eaSopenharmony_ci
181275793eaSopenharmony_ci        /// <summary>
182275793eaSopenharmony_ci        /// Adds more data to the codec to be processed.
183275793eaSopenharmony_ci        /// </summary>
184275793eaSopenharmony_ci        /// <param name="data">Byte array containing the data to be added to the codec</param>
185275793eaSopenharmony_ci        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
186275793eaSopenharmony_ci        void Add(byte[] data);
187275793eaSopenharmony_ci
188275793eaSopenharmony_ci        /// <summary>
189275793eaSopenharmony_ci        /// Adds more data to the codec to be processed.
190275793eaSopenharmony_ci        /// </summary>
191275793eaSopenharmony_ci        /// <param name="data">Byte array containing the data to be added to the codec</param>
192275793eaSopenharmony_ci        /// <param name="offset">The index of the first byte to add from <c>data</c></param>
193275793eaSopenharmony_ci        /// <param name="count">The number of bytes to add</param>
194275793eaSopenharmony_ci        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
195275793eaSopenharmony_ci        void Add(byte[] data, int offset, int count);
196275793eaSopenharmony_ci
197275793eaSopenharmony_ci        /// <summary>
198275793eaSopenharmony_ci        /// Finishes up any pending data that needs to be processed and handled.
199275793eaSopenharmony_ci        /// </summary>
200275793eaSopenharmony_ci        void Finish();
201275793eaSopenharmony_ci
202275793eaSopenharmony_ci        /// <summary>
203275793eaSopenharmony_ci        /// Gets the checksum of the data that has been added so far
204275793eaSopenharmony_ci        /// </summary>
205275793eaSopenharmony_ci        uint Checksum { get; }
206275793eaSopenharmony_ci
207275793eaSopenharmony_ci
208275793eaSopenharmony_ci    }
209275793eaSopenharmony_ci
210275793eaSopenharmony_ci    #endregion
211275793eaSopenharmony_ci
212275793eaSopenharmony_ci    #region Classes
213275793eaSopenharmony_ci    /// <summary>
214275793eaSopenharmony_ci    /// Encapsulates general information about the ZLib library
215275793eaSopenharmony_ci    /// </summary>
216275793eaSopenharmony_ci    public class Info
217275793eaSopenharmony_ci    {
218275793eaSopenharmony_ci        #region DLL imports
219275793eaSopenharmony_ci        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
220275793eaSopenharmony_ci        private static extern uint zlibCompileFlags();
221275793eaSopenharmony_ci
222275793eaSopenharmony_ci        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
223275793eaSopenharmony_ci        private static extern string zlibVersion();
224275793eaSopenharmony_ci        #endregion
225275793eaSopenharmony_ci
226275793eaSopenharmony_ci        #region Private stuff
227275793eaSopenharmony_ci        private uint _flags;
228275793eaSopenharmony_ci
229275793eaSopenharmony_ci        // helper function that unpacks a bitsize mask
230275793eaSopenharmony_ci        private static int bitSize(uint bits)
231275793eaSopenharmony_ci        {
232275793eaSopenharmony_ci            switch (bits)
233275793eaSopenharmony_ci            {
234275793eaSopenharmony_ci                case 0: return 16;
235275793eaSopenharmony_ci                case 1: return 32;
236275793eaSopenharmony_ci                case 2: return 64;
237275793eaSopenharmony_ci            }
238275793eaSopenharmony_ci            return -1;
239275793eaSopenharmony_ci        }
240275793eaSopenharmony_ci        #endregion
241275793eaSopenharmony_ci
242275793eaSopenharmony_ci        /// <summary>
243275793eaSopenharmony_ci        /// Constructs an instance of the <c>Info</c> class.
244275793eaSopenharmony_ci        /// </summary>
245275793eaSopenharmony_ci        public Info()
246275793eaSopenharmony_ci        {
247275793eaSopenharmony_ci            _flags = zlibCompileFlags();
248275793eaSopenharmony_ci        }
249275793eaSopenharmony_ci
250275793eaSopenharmony_ci        /// <summary>
251275793eaSopenharmony_ci        /// True if the library is compiled with debug info
252275793eaSopenharmony_ci        /// </summary>
253275793eaSopenharmony_ci        public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }
254275793eaSopenharmony_ci
255275793eaSopenharmony_ci        /// <summary>
256275793eaSopenharmony_ci        /// True if the library is compiled with assembly optimizations
257275793eaSopenharmony_ci        /// </summary>
258275793eaSopenharmony_ci        public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }
259275793eaSopenharmony_ci
260275793eaSopenharmony_ci        /// <summary>
261275793eaSopenharmony_ci        /// Gets the size of the unsigned int that was compiled into Zlib
262275793eaSopenharmony_ci        /// </summary>
263275793eaSopenharmony_ci        public int SizeOfUInt { get { return bitSize(_flags & 3); } }
264275793eaSopenharmony_ci
265275793eaSopenharmony_ci        /// <summary>
266275793eaSopenharmony_ci        /// Gets the size of the unsigned long that was compiled into Zlib
267275793eaSopenharmony_ci        /// </summary>
268275793eaSopenharmony_ci        public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }
269275793eaSopenharmony_ci
270275793eaSopenharmony_ci        /// <summary>
271275793eaSopenharmony_ci        /// Gets the size of the pointers that were compiled into Zlib
272275793eaSopenharmony_ci        /// </summary>
273275793eaSopenharmony_ci        public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }
274275793eaSopenharmony_ci
275275793eaSopenharmony_ci        /// <summary>
276275793eaSopenharmony_ci        /// Gets the size of the z_off_t type that was compiled into Zlib
277275793eaSopenharmony_ci        /// </summary>
278275793eaSopenharmony_ci        public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }
279275793eaSopenharmony_ci
280275793eaSopenharmony_ci        /// <summary>
281275793eaSopenharmony_ci        /// Gets the version of ZLib as a string, e.g. "1.2.1"
282275793eaSopenharmony_ci        /// </summary>
283275793eaSopenharmony_ci        public static string Version { get { return zlibVersion(); } }
284275793eaSopenharmony_ci    }
285275793eaSopenharmony_ci
286275793eaSopenharmony_ci    #endregion
287275793eaSopenharmony_ci
288275793eaSopenharmony_ci}
289