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