diff options
Diffstat (limited to '')
-rw-r--r-- | contrib/dotzlib/DotZLib/CodecBase.cs | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/contrib/dotzlib/DotZLib/CodecBase.cs b/contrib/dotzlib/DotZLib/CodecBase.cs new file mode 100644 index 0000000..954db7d --- /dev/null +++ b/contrib/dotzlib/DotZLib/CodecBase.cs | |||
@@ -0,0 +1,198 @@ | |||
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 | } | ||