Scale down the wallpaper to 800x600. For some reason, scaling down the image through...
[reactos.git] / irc / TechBot / CHMLibrary / CHMDecoding / BinaryReaderHelp.cs
1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Text;
5 using System.Globalization;
6
7 namespace HtmlHelp.ChmDecoding
8 {
9 /// <summary>
10 /// The class <c>BinaryReaderHelp</c> implements static helper methods for extracting binary data
11 /// from a binary reader object.
12 /// </summary>
13 internal class BinaryReaderHelp
14 {
15 /// <summary>
16 /// Internal helper method to extract null-terminated strings from a binary reader
17 /// </summary>
18 /// <param name="binReader">reference to the binary reader</param>
19 /// <param name="offset">offset in the stream</param>
20 /// <param name="noOffset">true if the offset value should be used</param>
21 /// <param name="encoder">encoder used for text encoding</param>
22 /// <returns>An extracted string value</returns>
23 internal static string ExtractString(ref BinaryReader binReader, int offset, bool noOffset, Encoding encoder)
24 {
25 string strReturn = "";
26
27 if(encoder == null)
28 encoder = Encoding.ASCII;
29
30 ArrayList nameBytes = new ArrayList();
31 byte curByte;
32
33 if(!noOffset)
34 binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
35
36 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
37 return "";
38
39 curByte = binReader.ReadByte();
40 while( (curByte != (byte)0) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
41 {
42 nameBytes.Add( curByte );
43 curByte = binReader.ReadByte();
44 }
45
46 byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
47 strReturn = encoder.GetString(name,0,name.Length);
48
49 return strReturn;
50 }
51
52 /// <summary>
53 /// Internal helper method to extract a string with a specific length from the binary reader
54 /// </summary>
55 /// <param name="binReader">reference to the binary reader</param>
56 /// <param name="length">length of the string (number of bytes)</param>
57 /// <param name="offset">offset in the stream</param>
58 /// <param name="noOffset">true if the offset value should be used</param>
59 /// <param name="encoder">encoder used for text encoding</param>
60 /// <returns>An extracted string value</returns>
61 internal static string ExtractString(ref BinaryReader binReader, int length, int offset, bool noOffset, Encoding encoder)
62 {
63 string strReturn = "";
64
65 if(length == 0)
66 return "";
67
68 if(encoder == null)
69 encoder = Encoding.ASCII;
70
71 ArrayList nameBytes = new ArrayList();
72 byte curByte;
73
74 if(!noOffset)
75 binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
76
77 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
78 return "";
79
80 curByte = binReader.ReadByte();
81 while( (curByte != (byte)0) && (nameBytes.Count < length) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
82 {
83 nameBytes.Add( curByte );
84
85 if(nameBytes.Count < length)
86 curByte = binReader.ReadByte();
87 }
88
89 byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
90 strReturn = encoder.GetString(name,0,name.Length);
91
92 return strReturn;
93 }
94
95 /// <summary>
96 /// Internal helper method to extract a string with a specific length from the binary reader
97 /// </summary>
98 /// <param name="binReader">reference to the binary reader</param>
99 /// <param name="bFoundTerminator">reference to a bool vairable which will receive true if the
100 /// string terminator \0 was found. false indicates that the end of the stream was reached.</param>
101 /// <param name="offset">offset in the stream</param>
102 /// <param name="noOffset">true if the offset value should be used</param>
103 /// <param name="encoder">encoder used for text encoding</param>
104 /// <returns>An extracted string value</returns>
105 internal static string ExtractString(ref BinaryReader binReader, ref bool bFoundTerminator, int offset, bool noOffset, Encoding encoder)
106 {
107 string strReturn = "";
108
109 ArrayList nameBytes = new ArrayList();
110 byte curByte;
111
112 if(encoder == null)
113 encoder = Encoding.ASCII;
114
115 if(!noOffset)
116 binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
117
118 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
119 return "";
120
121 curByte = binReader.ReadByte();
122 while( (curByte != (byte)0) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
123 {
124 nameBytes.Add( curByte );
125 curByte = binReader.ReadByte();
126
127 if( curByte == (byte)0 )
128 {
129 bFoundTerminator = true;
130 }
131 }
132
133 byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
134 strReturn = encoder.GetString(name,0,name.Length);
135
136 return strReturn;
137 }
138
139 /// <summary>
140 /// Internal helper method to extract a null-terminated UTF-16/UCS-2 strings from a binary reader
141 /// </summary>
142 /// <param name="binReader">reference to the binary reader</param>
143 /// <param name="offset">offset in the stream</param>
144 /// <param name="noOffset">true if the offset value should be used</param>
145 /// <param name="encoder">encoder used for text encoding</param>
146 /// <returns>An extracted string value</returns>
147 internal static string ExtractUTF16String(ref BinaryReader binReader, int offset, bool noOffset, Encoding encoder)
148 {
149 string strReturn = "";
150
151 ArrayList nameBytes = new ArrayList();
152 byte curByte;
153 int lastByte=-1;
154
155 if(!noOffset)
156 binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
157
158 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
159 return "";
160
161 if(encoder == null)
162 encoder = Encoding.Unicode;
163
164 curByte = binReader.ReadByte();
165 int nCnt = 0;
166 while( ((curByte != (byte)0) || (lastByte != 0) ) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
167 {
168 nameBytes.Add( curByte );
169
170 if(nCnt%2 == 0)
171 lastByte = (int)curByte;
172
173 curByte = binReader.ReadByte();
174
175 nCnt++;
176 }
177
178 byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
179 strReturn = Encoding.Unicode.GetString(name,0,name.Length);
180
181 // apply text encoding
182 name = Encoding.Default.GetBytes(strReturn);
183 strReturn = encoder.GetString(name,0,name.Length);
184
185 return strReturn;
186 }
187
188 /// <summary>
189 /// Internal helper for reading ENCINT encoded integer values
190 /// </summary>
191 /// <param name="binReader">reference to the reader</param>
192 /// <returns>a long value</returns>
193 internal static long ReadENCINT(ref BinaryReader binReader)
194 {
195 long nRet = 0;
196 byte buffer = 0;
197 int shift = 0;
198
199 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
200 return nRet;
201
202 do
203 {
204 buffer = binReader.ReadByte();
205 nRet |= ((long)((buffer & (byte)0x7F))) << shift;
206 shift += 7;
207
208 }while ( (buffer & (byte)0x80) != 0);
209
210 return nRet;
211 }
212
213 /// <summary>
214 /// Reads an s/r encoded value from the byte array and decodes it into an integer
215 /// </summary>
216 /// <param name="wclBits">a byte array containing all bits (contains only 0 or 1 elements)</param>
217 /// <param name="s">scale param for encoding</param>
218 /// <param name="r">root param for encoding</param>
219 /// <param name="nBitIndex">current index in the wclBits array</param>
220 /// <returns>Returns an decoded integer value.</returns>
221 internal static int ReadSRItem(byte[] wclBits, int s, int r, ref int nBitIndex)
222 {
223 int nRet = 0;
224 int q = r;
225
226 int nPref1Cnt = 0;
227
228 while( wclBits[nBitIndex++] == 1)
229 {
230 nPref1Cnt++;
231 }
232
233 if(nPref1Cnt == 0)
234 {
235 int nMask = 0;
236
237 for(int nbits=0; nbits<q;nbits++)
238 {
239 nMask |= ( 0x01 & (int)wclBits[nBitIndex]) << (q-nbits-1);
240 nBitIndex++;
241 }
242
243 nRet = nMask;
244 }
245 else
246 {
247 q += (nPref1Cnt-1);
248
249 int nMask = 0;
250 int nRMaxValue = 0;
251
252 for(int nbits=0; nbits<q;nbits++)
253 {
254 nMask |= ( 0x01 & (int)wclBits[nBitIndex]) << (q-nbits-1);
255 nBitIndex++;
256 }
257
258 for(int nsv=0; nsv<r; nsv++)
259 {
260 nRMaxValue = nRMaxValue << 1;
261 nRMaxValue |= 0x1;
262 }
263
264 nRMaxValue++; // startvalue of s/r encoding with 1 prefixing '1'
265
266 nRMaxValue *= (int) Math.Pow((double)2, (double)(nPref1Cnt-1));
267
268 nRet = nRMaxValue + nMask;
269 }
270
271 return nRet;
272 }
273 }
274 }