symbian-qemu-0.9.1-12/zlib-1.2.3/contrib/dotzlib/DotZLib/CodecBase.cs
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 
       
     8 using System;
       
     9 using System.Runtime.InteropServices;
       
    10 
       
    11 namespace 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 }