xref: /netbsd-src/common/dist/zlib/contrib/dotzlib/DotZLib/CodecBase.cs (revision b175d1c2a0d8a7ee59df83b5ae5f0bd11632ced6)
1aaf4ece6Schristos //
2aaf4ece6Schristos // � Copyright Henrik Ravn 2004
3aaf4ece6Schristos //
4aaf4ece6Schristos // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5aaf4ece6Schristos // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6aaf4ece6Schristos //
7aaf4ece6Schristos 
8aaf4ece6Schristos using System;
9aaf4ece6Schristos using System.Runtime.InteropServices;
10aaf4ece6Schristos 
11aaf4ece6Schristos namespace DotZLib
12aaf4ece6Schristos {
13aaf4ece6Schristos 	/// <summary>
14aaf4ece6Schristos 	/// Implements the common functionality needed for all <see cref="Codec"/>s
15aaf4ece6Schristos 	/// </summary>
16aaf4ece6Schristos 	public abstract class CodecBase : Codec, IDisposable
17aaf4ece6Schristos 	{
18aaf4ece6Schristos 
19aaf4ece6Schristos         #region Data members
20aaf4ece6Schristos 
21aaf4ece6Schristos         /// <summary>
22aaf4ece6Schristos         /// Instance of the internal zlib buffer structure that is
23aaf4ece6Schristos         /// passed to all functions in the zlib dll
24aaf4ece6Schristos         /// </summary>
25aaf4ece6Schristos         internal ZStream _ztream = new ZStream();
26aaf4ece6Schristos 
27aaf4ece6Schristos         /// <summary>
28aaf4ece6Schristos         /// True if the object instance has been disposed, false otherwise
29aaf4ece6Schristos         /// </summary>
30aaf4ece6Schristos         protected bool _isDisposed = false;
31aaf4ece6Schristos 
32aaf4ece6Schristos         /// <summary>
33aaf4ece6Schristos         /// The size of the internal buffers
34aaf4ece6Schristos         /// </summary>
35aaf4ece6Schristos         protected const int kBufferSize = 16384;
36aaf4ece6Schristos 
37aaf4ece6Schristos         private byte[] _outBuffer = new byte[kBufferSize];
38aaf4ece6Schristos         private byte[] _inBuffer = new byte[kBufferSize];
39aaf4ece6Schristos 
40aaf4ece6Schristos         private GCHandle _hInput;
41aaf4ece6Schristos         private GCHandle _hOutput;
42aaf4ece6Schristos 
43aaf4ece6Schristos         private uint _checksum = 0;
44aaf4ece6Schristos 
45aaf4ece6Schristos         #endregion
46aaf4ece6Schristos 
47aaf4ece6Schristos         /// <summary>
48aaf4ece6Schristos         /// Initializes a new instance of the <c>CodeBase</c> class.
49aaf4ece6Schristos         /// </summary>
50aaf4ece6Schristos 		public CodecBase()
51aaf4ece6Schristos 		{
52aaf4ece6Schristos             try
53aaf4ece6Schristos             {
54aaf4ece6Schristos                 _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
55aaf4ece6Schristos                 _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
56aaf4ece6Schristos             }
57aaf4ece6Schristos             catch (Exception)
58aaf4ece6Schristos             {
59aaf4ece6Schristos                 CleanUp(false);
60aaf4ece6Schristos                 throw;
61aaf4ece6Schristos             }
62aaf4ece6Schristos         }
63aaf4ece6Schristos 
64aaf4ece6Schristos 
65aaf4ece6Schristos         #region Codec Members
66aaf4ece6Schristos 
67aaf4ece6Schristos         /// <summary>
68aaf4ece6Schristos         /// Occurs when more processed data are available.
69aaf4ece6Schristos         /// </summary>
70aaf4ece6Schristos         public event DataAvailableHandler DataAvailable;
71aaf4ece6Schristos 
72aaf4ece6Schristos         /// <summary>
73aaf4ece6Schristos         /// Fires the <see cref="DataAvailable"/> event
74aaf4ece6Schristos         /// </summary>
75aaf4ece6Schristos         protected void OnDataAvailable()
76aaf4ece6Schristos         {
77aaf4ece6Schristos             if (_ztream.total_out > 0)
78aaf4ece6Schristos             {
79aaf4ece6Schristos                 if (DataAvailable != null)
80aaf4ece6Schristos                     DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
81aaf4ece6Schristos                 resetOutput();
82aaf4ece6Schristos             }
83aaf4ece6Schristos         }
84aaf4ece6Schristos 
85aaf4ece6Schristos         /// <summary>
86aaf4ece6Schristos         /// Adds more data to the codec to be processed.
87aaf4ece6Schristos         /// </summary>
88aaf4ece6Schristos         /// <param name="data">Byte array containing the data to be added to the codec</param>
89aaf4ece6Schristos         /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
90aaf4ece6Schristos         public void Add(byte[] data)
91aaf4ece6Schristos         {
92aaf4ece6Schristos             Add(data,0,data.Length);
93aaf4ece6Schristos         }
94aaf4ece6Schristos 
95aaf4ece6Schristos         /// <summary>
96aaf4ece6Schristos         /// Adds more data to the codec to be processed.
97aaf4ece6Schristos         /// </summary>
98aaf4ece6Schristos         /// <param name="data">Byte array containing the data to be added to the codec</param>
99aaf4ece6Schristos         /// <param name="offset">The index of the first byte to add from <c>data</c></param>
100aaf4ece6Schristos         /// <param name="count">The number of bytes to add</param>
101aaf4ece6Schristos         /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
102aaf4ece6Schristos         /// <remarks>This must be implemented by a derived class</remarks>
103aaf4ece6Schristos         public abstract void Add(byte[] data, int offset, int count);
104aaf4ece6Schristos 
105aaf4ece6Schristos         /// <summary>
106aaf4ece6Schristos         /// Finishes up any pending data that needs to be processed and handled.
107aaf4ece6Schristos         /// </summary>
108aaf4ece6Schristos         /// <remarks>This must be implemented by a derived class</remarks>
109aaf4ece6Schristos         public abstract void Finish();
110aaf4ece6Schristos 
111aaf4ece6Schristos         /// <summary>
112aaf4ece6Schristos         /// Gets the checksum of the data that has been added so far
113aaf4ece6Schristos         /// </summary>
114aaf4ece6Schristos         public uint Checksum { get { return _checksum; } }
115aaf4ece6Schristos 
116aaf4ece6Schristos         #endregion
117aaf4ece6Schristos 
118aaf4ece6Schristos         #region Destructor & IDisposable stuff
119aaf4ece6Schristos 
120aaf4ece6Schristos         /// <summary>
121aaf4ece6Schristos         /// Destroys this instance
122aaf4ece6Schristos         /// </summary>
123aaf4ece6Schristos         ~CodecBase()
124aaf4ece6Schristos         {
125aaf4ece6Schristos             CleanUp(false);
126aaf4ece6Schristos         }
127aaf4ece6Schristos 
128aaf4ece6Schristos         /// <summary>
129aaf4ece6Schristos         /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
130aaf4ece6Schristos         /// </summary>
131aaf4ece6Schristos         public void Dispose()
132aaf4ece6Schristos         {
133aaf4ece6Schristos             CleanUp(true);
134aaf4ece6Schristos         }
135aaf4ece6Schristos 
136aaf4ece6Schristos         /// <summary>
137aaf4ece6Schristos         /// Performs any codec specific cleanup
138aaf4ece6Schristos         /// </summary>
139aaf4ece6Schristos         /// <remarks>This must be implemented by a derived class</remarks>
140aaf4ece6Schristos         protected abstract void CleanUp();
141aaf4ece6Schristos 
142*b175d1c2Schristos         // performs the release of the handles and calls the derived CleanUp()
143aaf4ece6Schristos         private void CleanUp(bool isDisposing)
144aaf4ece6Schristos         {
145aaf4ece6Schristos             if (!_isDisposed)
146aaf4ece6Schristos             {
147aaf4ece6Schristos                 CleanUp();
148aaf4ece6Schristos                 if (_hInput.IsAllocated)
149aaf4ece6Schristos                     _hInput.Free();
150aaf4ece6Schristos                 if (_hOutput.IsAllocated)
151aaf4ece6Schristos                     _hOutput.Free();
152aaf4ece6Schristos 
153aaf4ece6Schristos                 _isDisposed = true;
154aaf4ece6Schristos             }
155aaf4ece6Schristos         }
156aaf4ece6Schristos 
157aaf4ece6Schristos 
158aaf4ece6Schristos         #endregion
159aaf4ece6Schristos 
160aaf4ece6Schristos         #region Helper methods
161aaf4ece6Schristos 
162aaf4ece6Schristos         /// <summary>
163*b175d1c2Schristos         /// Copies a number of bytes to the internal codec buffer - ready for processing
164aaf4ece6Schristos         /// </summary>
165aaf4ece6Schristos         /// <param name="data">The byte array that contains the data to copy</param>
166aaf4ece6Schristos         /// <param name="startIndex">The index of the first byte to copy</param>
167aaf4ece6Schristos         /// <param name="count">The number of bytes to copy from <c>data</c></param>
168aaf4ece6Schristos         protected void copyInput(byte[] data, int startIndex, int count)
169aaf4ece6Schristos         {
170aaf4ece6Schristos             Array.Copy(data, startIndex, _inBuffer,0, count);
171aaf4ece6Schristos             _ztream.next_in = _hInput.AddrOfPinnedObject();
172aaf4ece6Schristos             _ztream.total_in = 0;
173aaf4ece6Schristos             _ztream.avail_in = (uint)count;
174aaf4ece6Schristos 
175aaf4ece6Schristos         }
176aaf4ece6Schristos 
177aaf4ece6Schristos         /// <summary>
178aaf4ece6Schristos         /// Resets the internal output buffers to a known state - ready for processing
179aaf4ece6Schristos         /// </summary>
180aaf4ece6Schristos         protected void resetOutput()
181aaf4ece6Schristos         {
182aaf4ece6Schristos             _ztream.total_out = 0;
183aaf4ece6Schristos             _ztream.avail_out = kBufferSize;
184aaf4ece6Schristos             _ztream.next_out = _hOutput.AddrOfPinnedObject();
185aaf4ece6Schristos         }
186aaf4ece6Schristos 
187aaf4ece6Schristos         /// <summary>
188aaf4ece6Schristos         /// Updates the running checksum property
189aaf4ece6Schristos         /// </summary>
190aaf4ece6Schristos         /// <param name="newSum">The new checksum value</param>
191aaf4ece6Schristos         protected void setChecksum(uint newSum)
192aaf4ece6Schristos         {
193aaf4ece6Schristos             _checksum = newSum;
194aaf4ece6Schristos         }
195aaf4ece6Schristos         #endregion
196aaf4ece6Schristos 
197aaf4ece6Schristos     }
198aaf4ece6Schristos }
199