2 // © Copyright Henrik Ravn 2004
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)
9 using System
.Runtime
.InteropServices
;
14 /// Implements the common functionality needed for all <see cref="Codec"/>s
16 public abstract class CodecBase
: Codec
, IDisposable
22 /// Instance of the internal zlib buffer structure that is
23 /// passed to all functions in the zlib dll
25 internal ZStream _ztream
= new ZStream();
28 /// True if the object instance has been disposed, false otherwise
30 protected bool _isDisposed
= false;
33 /// The size of the internal buffers
35 protected const int kBufferSize
= 16384;
37 private byte[] _outBuffer
= new byte[kBufferSize
];
38 private byte[] _inBuffer
= new byte[kBufferSize
];
40 private GCHandle _hInput
;
41 private GCHandle _hOutput
;
43 private uint _checksum
= 0;
48 /// Initializes a new instance of the <c>CodeBase</c> class.
54 _hInput
= GCHandle
.Alloc(_inBuffer
, GCHandleType
.Pinned
);
55 _hOutput
= GCHandle
.Alloc(_outBuffer
, GCHandleType
.Pinned
);
68 /// Occurs when more processed data are available.
70 public event DataAvailableHandler DataAvailable
;
73 /// Fires the <see cref="DataAvailable"/> event
75 protected void OnDataAvailable()
77 if (_ztream
.total_out
> 0)
79 if (DataAvailable
!= null)
80 DataAvailable( _outBuffer
, 0, (int)_ztream
.total_out
);
86 /// Adds more data to the codec to be processed.
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
)
92 Add(data
,0,data
.Length
);
96 /// Adds more data to the codec to be processed.
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
);
106 /// Finishes up any pending data that needs to be processed and handled.
108 /// <remarks>This must be implemented by a derived class</remarks>
109 public abstract void Finish();
112 /// Gets the checksum of the data that has been added so far
114 public uint Checksum { get { return _checksum; }
}
118 #region Destructor & IDisposable stuff
121 /// Destroys this instance
129 /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
131 public void Dispose()
137 /// Performs any codec specific cleanup
139 /// <remarks>This must be implemented by a derived class</remarks>
140 protected abstract void CleanUp();
142 // performs the release of the handles and calls the dereived CleanUp()
143 private void CleanUp(bool isDisposing
)
148 if (_hInput
.IsAllocated
)
150 if (_hOutput
.IsAllocated
)
160 #region Helper methods
163 /// Copies a number of bytes to the internal codec buffer - ready for proccesing
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
)
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
;
178 /// Resets the internal output buffers to a known state - ready for processing
180 protected void resetOutput()
182 _ztream
.total_out
= 0;
183 _ztream
.avail_out
= kBufferSize
;
184 _ztream
.next_out
= _hOutput
.AddrOfPinnedObject();
188 /// Updates the running checksum property
190 /// <param name="newSum">The new checksum value</param>
191 protected void setChecksum(uint newSum
)