+++ /dev/null
-//\r
-// © Copyright Henrik Ravn 2004\r
-//\r
-// Use, modification and distribution are subject to the Boost Software License, Version 1.0. \r
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
-//\r
-\r
-using System;\r
-using System.Runtime.InteropServices;\r
-\r
-namespace DotZLib\r
-{\r
- /// <summary>\r
- /// Implements the common functionality needed for all <see cref="Codec"/>s\r
- /// </summary>\r
- public abstract class CodecBase : Codec, IDisposable\r
- {\r
-\r
- #region Data members\r
-\r
- /// <summary>\r
- /// Instance of the internal zlib buffer structure that is \r
- /// passed to all functions in the zlib dll\r
- /// </summary>\r
- internal ZStream _ztream = new ZStream();\r
-\r
- /// <summary>\r
- /// True if the object instance has been disposed, false otherwise\r
- /// </summary>\r
- protected bool _isDisposed = false;\r
-\r
- /// <summary>\r
- /// The size of the internal buffers\r
- /// </summary>\r
- protected const int kBufferSize = 16384;\r
-\r
- private byte[] _outBuffer = new byte[kBufferSize];\r
- private byte[] _inBuffer = new byte[kBufferSize];\r
-\r
- private GCHandle _hInput;\r
- private GCHandle _hOutput;\r
-\r
- private uint _checksum = 0;\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// Initializes a new instance of the <c>CodeBase</c> class. \r
- /// </summary>\r
- public CodecBase()\r
- {\r
- try\r
- {\r
- _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);\r
- _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);\r
- }\r
- catch (Exception)\r
- {\r
- CleanUp(false);\r
- throw;\r
- }\r
- }\r
-\r
-\r
- #region Codec Members\r
-\r
- /// <summary>\r
- /// Occurs when more processed data are available.\r
- /// </summary>\r
- public event DataAvailableHandler DataAvailable;\r
-\r
- /// <summary>\r
- /// Fires the <see cref="DataAvailable"/> event\r
- /// </summary>\r
- protected void OnDataAvailable()\r
- {\r
- if (_ztream.total_out > 0)\r
- {\r
- if (DataAvailable != null)\r
- DataAvailable( _outBuffer, 0, (int)_ztream.total_out); \r
- resetOutput();\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Adds more data to the codec to be processed.\r
- /// </summary>\r
- /// <param name="data">Byte array containing the data to be added to the codec</param>\r
- /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\r
- public void Add(byte[] data)\r
- {\r
- Add(data,0,data.Length);\r
- }\r
-\r
- /// <summary>\r
- /// Adds more data to the codec to be processed.\r
- /// </summary>\r
- /// <param name="data">Byte array containing the data to be added to the codec</param>\r
- /// <param name="offset">The index of the first byte to add from <c>data</c></param>\r
- /// <param name="count">The number of bytes to add</param>\r
- /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>\r
- /// <remarks>This must be implemented by a derived class</remarks>\r
- public abstract void Add(byte[] data, int offset, int count);\r
-\r
- /// <summary>\r
- /// Finishes up any pending data that needs to be processed and handled.\r
- /// </summary>\r
- /// <remarks>This must be implemented by a derived class</remarks>\r
- public abstract void Finish();\r
-\r
- /// <summary>\r
- /// Gets the checksum of the data that has been added so far\r
- /// </summary>\r
- public uint Checksum { get { return _checksum; } }\r
-\r
- #endregion\r
-\r
- #region Destructor & IDisposable stuff\r
-\r
- /// <summary>\r
- /// Destroys this instance\r
- /// </summary>\r
- ~CodecBase()\r
- {\r
- CleanUp(false);\r
- }\r
-\r
- /// <summary>\r
- /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class\r
- /// </summary>\r
- public void Dispose()\r
- {\r
- CleanUp(true);\r
- }\r
-\r
- /// <summary>\r
- /// Performs any codec specific cleanup\r
- /// </summary>\r
- /// <remarks>This must be implemented by a derived class</remarks>\r
- protected abstract void CleanUp();\r
-\r
- // performs the release of the handles and calls the dereived CleanUp()\r
- private void CleanUp(bool isDisposing)\r
- {\r
- if (!_isDisposed)\r
- {\r
- CleanUp();\r
- if (_hInput.IsAllocated)\r
- _hInput.Free();\r
- if (_hOutput.IsAllocated)\r
- _hOutput.Free();\r
-\r
- _isDisposed = true;\r
- }\r
- }\r
-\r
-\r
- #endregion\r
-\r
- #region Helper methods\r
-\r
- /// <summary>\r
- /// Copies a number of bytes to the internal codec buffer - ready for proccesing\r
- /// </summary>\r
- /// <param name="data">The byte array that contains the data to copy</param>\r
- /// <param name="startIndex">The index of the first byte to copy</param>\r
- /// <param name="count">The number of bytes to copy from <c>data</c></param>\r
- protected void copyInput(byte[] data, int startIndex, int count)\r
- {\r
- Array.Copy(data, startIndex, _inBuffer,0, count);\r
- _ztream.next_in = _hInput.AddrOfPinnedObject();\r
- _ztream.total_in = 0;\r
- _ztream.avail_in = (uint)count;\r
-\r
- }\r
-\r
- /// <summary>\r
- /// Resets the internal output buffers to a known state - ready for processing\r
- /// </summary>\r
- protected void resetOutput()\r
- {\r
- _ztream.total_out = 0;\r
- _ztream.avail_out = kBufferSize;\r
- _ztream.next_out = _hOutput.AddrOfPinnedObject();\r
- }\r
-\r
- /// <summary>\r
- /// Updates the running checksum property\r
- /// </summary>\r
- /// <param name="newSum">The new checksum value</param>\r
- protected void setChecksum(uint newSum)\r
- {\r
- _checksum = newSum;\r
- }\r
- #endregion\r
-\r
- }\r
-}\r