all repos — mgba @ 3b353ac62190a00765812938e86e04b753196736

mGBA Game Boy Advance Emulator

src/third-party/zlib/contrib/dotzlib/DotZLib/CodecBase.cs (view raw)

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