OSDN Git Service

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