annotate src/zlib-1.2.8/contrib/dotzlib/DotZLib/CodecBase.cs @ 168:ceec0dd9ec9c

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