2 using System.Collections;
5 using System.Globalization;
7 namespace HtmlHelp.ChmDecoding
10 /// The class <c>BinaryReaderHelp</c> implements static helper methods for extracting binary data
11 /// from a binary reader object.
13 internal class BinaryReaderHelp
16 /// Internal helper method to extract null-terminated strings from a binary reader
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)
25 string strReturn = "";
28 encoder = Encoding.ASCII;
30 ArrayList nameBytes = new ArrayList();
34 binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
36 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
39 curByte = binReader.ReadByte();
40 while( (curByte != (byte)0) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
42 nameBytes.Add( curByte );
43 curByte = binReader.ReadByte();
46 byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
47 strReturn = encoder.GetString(name,0,name.Length);
53 /// Internal helper method to extract a string with a specific length from the binary reader
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)
63 string strReturn = "";
69 encoder = Encoding.ASCII;
71 ArrayList nameBytes = new ArrayList();
75 binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
77 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
80 curByte = binReader.ReadByte();
81 while( (curByte != (byte)0) && (nameBytes.Count < length) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
83 nameBytes.Add( curByte );
85 if(nameBytes.Count < length)
86 curByte = binReader.ReadByte();
89 byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
90 strReturn = encoder.GetString(name,0,name.Length);
96 /// Internal helper method to extract a string with a specific length from the binary reader
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)
107 string strReturn = "";
109 ArrayList nameBytes = new ArrayList();
113 encoder = Encoding.ASCII;
116 binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
118 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
121 curByte = binReader.ReadByte();
122 while( (curByte != (byte)0) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
124 nameBytes.Add( curByte );
125 curByte = binReader.ReadByte();
127 if( curByte == (byte)0 )
129 bFoundTerminator = true;
133 byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
134 strReturn = encoder.GetString(name,0,name.Length);
140 /// Internal helper method to extract a null-terminated UTF-16/UCS-2 strings from a binary reader
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)
149 string strReturn = "";
151 ArrayList nameBytes = new ArrayList();
156 binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
158 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
162 encoder = Encoding.Unicode;
164 curByte = binReader.ReadByte();
166 while( ((curByte != (byte)0) || (lastByte != 0) ) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
168 nameBytes.Add( curByte );
171 lastByte = (int)curByte;
173 curByte = binReader.ReadByte();
178 byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
179 strReturn = Encoding.Unicode.GetString(name,0,name.Length);
181 // apply text encoding
182 name = Encoding.Default.GetBytes(strReturn);
183 strReturn = encoder.GetString(name,0,name.Length);
189 /// Internal helper for reading ENCINT encoded integer values
191 /// <param name="binReader">reference to the reader</param>
192 /// <returns>a long value</returns>
193 internal static long ReadENCINT(ref BinaryReader binReader)
199 if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
204 buffer = binReader.ReadByte();
205 nRet |= ((long)((buffer & (byte)0x7F))) << shift;
208 }while ( (buffer & (byte)0x80) != 0);
214 /// Reads an s/r encoded value from the byte array and decodes it into an integer
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)
228 while( wclBits[nBitIndex++] == 1)
237 for(int nbits=0; nbits<q;nbits++)
239 nMask |= ( 0x01 & (int)wclBits[nBitIndex]) << (q-nbits-1);
252 for(int nbits=0; nbits<q;nbits++)
254 nMask |= ( 0x01 & (int)wclBits[nBitIndex]) << (q-nbits-1);
258 for(int nsv=0; nsv<r; nsv++)
260 nRMaxValue = nRMaxValue << 1;
264 nRMaxValue++; // startvalue of s/r encoding with 1 prefixing '1'
266 nRMaxValue *= (int) Math.Pow((double)2, (double)(nPref1Cnt-1));
268 nRet = nRMaxValue + nMask;