19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
29e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// � Copyright Henrik Ravn 2004
39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
4381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectusing System;
99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectusing System.Runtime.InteropServices;
109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectnamespace DotZLib
129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	/// <summary>
149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	/// Implements the common functionality needed for all <see cref="Codec"/>s
159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	/// </summary>
169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	public abstract class CodecBase : Codec, IDisposable
179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project	{
189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #region Data members
209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
22381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /// Instance of the internal zlib buffer structure that is
239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// passed to all functions in the zlib dll
249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        internal ZStream _ztream = new ZStream();
269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// True if the object instance has been disposed, false otherwise
299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        protected bool _isDisposed = false;
319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// The size of the internal buffers
349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        protected const int kBufferSize = 16384;
369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private byte[] _outBuffer = new byte[kBufferSize];
389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private byte[] _inBuffer = new byte[kBufferSize];
399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private GCHandle _hInput;
419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private GCHandle _hOutput;
429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private uint _checksum = 0;
449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #endregion
469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
48381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /// Initializes a new instance of the <c>CodeBase</c> class.
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project		public CodecBase()
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project		{
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            try
539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            catch (Exception)
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                CleanUp(false);
609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                throw;
619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #region Codec Members
669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Occurs when more processed data are available.
699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public event DataAvailableHandler DataAvailable;
719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Fires the <see cref="DataAvailable"/> event
749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        protected void OnDataAvailable()
769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (_ztream.total_out > 0)
789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                if (DataAvailable != null)
80381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                    DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                resetOutput();
829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Adds more data to the codec to be processed.
879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">Byte array containing the data to be added to the codec</param>
899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public void Add(byte[] data)
919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            Add(data,0,data.Length);
939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Adds more data to the codec to be processed.
979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">Byte array containing the data to be added to the codec</param>
999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="offset">The index of the first byte to add from <c>data</c></param>
1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="count">The number of bytes to add</param>
1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <remarks>This must be implemented by a derived class</remarks>
1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public abstract void Add(byte[] data, int offset, int count);
1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Finishes up any pending data that needs to be processed and handled.
1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <remarks>This must be implemented by a derived class</remarks>
1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public abstract void Finish();
1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Gets the checksum of the data that has been added so far
1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public uint Checksum { get { return _checksum; } }
1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #endregion
1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #region Destructor & IDisposable stuff
1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Destroys this instance
1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ~CodecBase()
1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            CleanUp(false);
1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public void Dispose()
1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            CleanUp(true);
1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Performs any codec specific cleanup
1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <remarks>This must be implemented by a derived class</remarks>
1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        protected abstract void CleanUp();
1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        // performs the release of the handles and calls the dereived CleanUp()
1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private void CleanUp(bool isDisposing)
1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (!_isDisposed)
1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                CleanUp();
1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                if (_hInput.IsAllocated)
1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                    _hInput.Free();
1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                if (_hOutput.IsAllocated)
1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                    _hOutput.Free();
1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                _isDisposed = true;
1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #endregion
1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #region Helper methods
1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Copies a number of bytes to the internal codec buffer - ready for proccesing
1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">The byte array that contains the data to copy</param>
1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="startIndex">The index of the first byte to copy</param>
1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="count">The number of bytes to copy from <c>data</c></param>
1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        protected void copyInput(byte[] data, int startIndex, int count)
1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            Array.Copy(data, startIndex, _inBuffer,0, count);
1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _ztream.next_in = _hInput.AddrOfPinnedObject();
1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _ztream.total_in = 0;
1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _ztream.avail_in = (uint)count;
1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Resets the internal output buffers to a known state - ready for processing
1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        protected void resetOutput()
1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _ztream.total_out = 0;
1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _ztream.avail_out = kBufferSize;
1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _ztream.next_out = _hOutput.AddrOfPinnedObject();
1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Updates the running checksum property
1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="newSum">The new checksum value</param>
1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        protected void setChecksum(uint newSum)
1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _checksum = newSum;
1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #endregion
1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
199