2 // © Copyright Henrik Ravn 2004
\r
4 // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
\r
5 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
\r
9 using System.Runtime.InteropServices;
\r
14 /// Implements the common functionality needed for all <see cref="Codec"/>s
\r
16 public abstract class CodecBase : Codec, IDisposable
\r
19 #region Data members
\r
22 /// Instance of the internal zlib buffer structure that is
\r
23 /// passed to all functions in the zlib dll
\r
25 internal ZStream _ztream = new ZStream();
\r
28 /// True if the object instance has been disposed, false otherwise
\r
30 protected bool _isDisposed = false;
\r
33 /// The size of the internal buffers
\r
35 protected const int kBufferSize = 16384;
\r
37 private byte[] _outBuffer = new byte[kBufferSize];
\r
38 private byte[] _inBuffer = new byte[kBufferSize];
\r
40 private GCHandle _hInput;
\r
41 private GCHandle _hOutput;
\r
43 private uint _checksum = 0;
\r
48 /// Initializes a new instance of the <c>CodeBase</c> class.
\r
54 _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
\r
55 _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
\r
65 #region Codec Members
\r
68 /// Occurs when more processed data are available.
\r
70 public event DataAvailableHandler DataAvailable;
\r
73 /// Fires the <see cref="DataAvailable"/> event
\r
75 protected void OnDataAvailable()
\r
77 if (_ztream.total_out > 0)
\r
79 if (DataAvailable != null)
\r
80 DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
\r
86 /// Adds more data to the codec to be processed.
\r
88 /// <param name="data">Byte array containing the data to be added to the codec</param>
\r
89 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
\r
90 public void Add(byte[] data)
\r
92 Add(data,0,data.Length);
\r
96 /// Adds more data to the codec to be processed.
\r
98 /// <param name="data">Byte array containing the data to be added to the codec</param>
\r
99 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
\r
100 /// <param name="count">The number of bytes to add</param>
\r
101 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
\r
102 /// <remarks>This must be implemented by a derived class</remarks>
\r
103 public abstract void Add(byte[] data, int offset, int count);
\r
106 /// Finishes up any pending data that needs to be processed and handled.
\r
108 /// <remarks>This must be implemented by a derived class</remarks>
\r
109 public abstract void Finish();
\r
112 /// Gets the checksum of the data that has been added so far
\r
114 public uint Checksum { get { return _checksum; } }
\r
118 #region Destructor & IDisposable stuff
\r
121 /// Destroys this instance
\r
129 /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
\r
131 public void Dispose()
\r
137 /// Performs any codec specific cleanup
\r
139 /// <remarks>This must be implemented by a derived class</remarks>
\r
140 protected abstract void CleanUp();
\r
142 // performs the release of the handles and calls the dereived CleanUp()
\r
143 private void CleanUp(bool isDisposing)
\r
148 if (_hInput.IsAllocated)
\r
150 if (_hOutput.IsAllocated)
\r
153 _isDisposed = true;
\r
160 #region Helper methods
\r
163 /// Copies a number of bytes to the internal codec buffer - ready for proccesing
\r
165 /// <param name="data">The byte array that contains the data to copy</param>
\r
166 /// <param name="startIndex">The index of the first byte to copy</param>
\r
167 /// <param name="count">The number of bytes to copy from <c>data</c></param>
\r
168 protected void copyInput(byte[] data, int startIndex, int count)
\r
170 Array.Copy(data, startIndex, _inBuffer,0, count);
\r
171 _ztream.next_in = _hInput.AddrOfPinnedObject();
\r
172 _ztream.total_in = 0;
\r
173 _ztream.avail_in = (uint)count;
\r
178 /// Resets the internal output buffers to a known state - ready for processing
\r
180 protected void resetOutput()
\r
182 _ztream.total_out = 0;
\r
183 _ztream.avail_out = kBufferSize;
\r
184 _ztream.next_out = _hOutput.AddrOfPinnedObject();
\r
188 /// Updates the running checksum property
\r
190 /// <param name="newSum">The new checksum value</param>
\r
191 protected void setChecksum(uint newSum)
\r
193 _checksum = newSum;
\r