-revert janderwalds change until because it breaks the gcc 4.x build
[reactos.git] / irc / TechBot / CHMLibrary / CHMDecoding / DumpingInfo.cs
1 using System;
2 using System.IO;
3 using System.Text;
4 using System.Diagnostics;
5 using System.Collections.Specialized;
6
7 using ICSharpCode.SharpZipLib;
8 using ICSharpCode.SharpZipLib.Zip;
9 using ICSharpCode.SharpZipLib.Zip.Compression;
10 using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
11
12 using HtmlHelp;
13 // using HtmlHelp.Storage;
14
15 namespace HtmlHelp.ChmDecoding
16 {
17 /// <summary>
18 /// Enumeration for specifying the dumping compression
19 /// </summary>
20 public enum DumpCompression
21 {
22 /// <summary>
23 /// None - no data compression will be used.
24 /// Fastest but most memory intensive
25 /// </summary>
26 None = 0,
27 /// <summary>
28 /// Minimum - a minimum data compression will be used.
29 /// Fast but not much data reduction
30 /// </summary>
31 Minimum = 1,
32 /// <summary>
33 /// Medium - a medium data compression will be used.
34 /// Slower but medium data reduction
35 /// </summary>
36 Medium = 2,
37 /// <summary>
38 /// Maximum - a maximum data compression will be used.
39 /// Slowest but maximum data reduction
40 /// </summary>
41 Maximum = 3
42 }
43
44 /// <summary>
45 /// Flags which specify which data should be dumped
46 /// </summary>
47 [FlagsAttribute()]
48 public enum DumpingFlags
49 {
50 /// <summary>
51 /// DumpTextTOC - if this flag is set, text-based TOCs (sitemap format) will be dumped
52 /// </summary>
53 DumpTextTOC = 1,
54 /// <summary>
55 /// DumpBinaryTOC - if this flag is set, binary TOCs will be dumped
56 /// </summary>
57 DumpBinaryTOC = 2,
58 /// <summary>
59 /// DumpTextIndex - if this flag is set, the text-based index (sitemap format) will be dumped
60 /// </summary>
61 DumpTextIndex = 4,
62 /// <summary>
63 /// DumpBinaryIndex - if this flag is set, the binary index will be dumped
64 /// </summary>
65 DumpBinaryIndex = 8,
66 /// <summary>
67 /// DumpStrings - if this flag is set, the internal #STRINGS file will be dumped
68 /// </summary>
69 DumpStrings = 16,
70 /// <summary>
71 /// DumpUrlStr - if this flag is set, the internal #URLSTR file will be dumped
72 /// </summary>
73 DumpUrlStr = 32,
74 /// <summary>
75 /// DumpUrlTbl - if this flag is set, the internal #URLTBL file will be dumped
76 /// </summary>
77 DumpUrlTbl = 64,
78 /// <summary>
79 /// DumpTopics - if this flag is set, the internal #TOPICS file will be dumped
80 /// </summary>
81 DumpTopics = 128,
82 /// <summary>
83 /// DumpFullText - if this flag is set, the internal $FIftiMain file will be dumped
84 /// </summary>
85 DumpFullText = 256
86 }
87
88 /// <summary>
89 /// The class <c>DumpingInfo</c> implements information properties for the CHMFile class
90 /// if and how data dumping should be used.
91 /// </summary>
92 public sealed class DumpingInfo
93 {
94 public bool m_bAllowSaveDump=true;
95
96 private readonly static BitVector32.Section DumpFlags = BitVector32.CreateSection(512);
97
98 private const string _dumpHeader = "HtmlHelpSystem dump file 1.0";
99
100 private string _outputDir = ""; // emtpy string means, same directory as chm file
101 private DumpCompression _compressionLevel = DumpCompression.Maximum;
102 private CHMFile _chmFile = null;
103
104 private DeflaterOutputStream _outputStream = null;
105 private InflaterInputStream _inputStream = null;
106
107 private BinaryWriter _writer = null;
108 private BinaryReader _reader = null;
109
110 private BitVector32 _flags;
111
112 /// <summary>
113 /// Constructor of the class
114 /// </summary>
115 /// <param name="flags">Combine flag values to specify which data should be dumped.</param>
116 /// <param name="outputDir">output directory. emtpy string means,
117 /// same directory as chm file (only if destination = ExternalFile)</param>
118 /// <param name="compressionLevel">compression which should be used</param>
119 public DumpingInfo(DumpingFlags flags, string outputDir, DumpCompression compressionLevel)
120 {
121 _flags = new BitVector32(0);
122 int i = _flags[DumpFlags];
123 _flags[DumpFlags] = i | (int)flags;
124
125 _outputDir = outputDir;
126 _compressionLevel = compressionLevel;
127 }
128
129 /// <summary>
130 /// Gets the flag if text-based TOCs will be written to the dumping file
131 /// </summary>
132 public bool DumpTextTOC
133 {
134 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpTextTOC) != 0); }
135 }
136
137 /// <summary>
138 /// Gets the flag if binary TOCs will be written to the dumping file
139 /// </summary>
140 public bool DumpBinaryTOC
141 {
142 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpBinaryTOC) != 0); }
143 }
144
145 /// <summary>
146 /// Gets the flag if the text-based index will be written to the dumping file
147 /// </summary>
148 public bool DumpTextIndex
149 {
150 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpTextIndex) != 0); }
151 }
152
153 /// <summary>
154 /// Gets the flag if the binary index will be written to the dumping file
155 /// </summary>
156 public bool DumpBinaryIndex
157 {
158 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpBinaryIndex) != 0); }
159 }
160
161 /// <summary>
162 /// Gets the flag if the #STRINGS file will be written to the dumping file
163 /// </summary>
164 public bool DumpStrings
165 {
166 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpStrings) != 0); }
167 }
168
169 /// <summary>
170 /// Gets the flag if the #URLSTR file will be written to the dumping file
171 /// </summary>
172 public bool DumpUrlStr
173 {
174 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpUrlStr) != 0); }
175 }
176
177 /// <summary>
178 /// Gets the flag if the #URLTBL file will be written to the dumping file
179 /// </summary>
180 public bool DumpUrlTbl
181 {
182 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpUrlTbl) != 0); }
183 }
184
185 /// <summary>
186 /// Gets the flag if the #TOPICS file will be written to the dumping file
187 /// </summary>
188 public bool DumpTopics
189 {
190 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpTopics) != 0); }
191 }
192
193 /// <summary>
194 /// Gets the flag if the $FIftiMain file will be written to the dumping file
195 /// </summary>
196 public bool DumpFullText
197 {
198 get { return ((_flags[DumpFlags] & (int)DumpingFlags.DumpFullText) != 0); }
199 }
200
201 /// <summary>
202 /// Gets the dump output directory.
203 /// </summary>
204 /// <value>emtpy string means, same directory as chm file</value>
205 /// <remarks>If Destination is set to DumpingOutput.InternalFile this property will be ignored</remarks>
206 public string OutputDir
207 {
208 get { return _outputDir; }
209 }
210
211 /// <summary>
212 /// The compression level used.
213 /// </summary>
214 public DumpCompression CompressionLevel
215 {
216 get { return _compressionLevel; }
217 }
218
219 /// <summary>
220 /// Gets/Sets the CHMFile instance associated with this object
221 /// </summary>
222 internal CHMFile ChmFile
223 {
224 get { return _chmFile; }
225 set { _chmFile = value; }
226 }
227
228 /// <summary>
229 /// Translates the compression level to the deflater constants
230 /// </summary>
231 private int CompLvl
232 {
233 get
234 {
235 switch(CompressionLevel)
236 {
237 case DumpCompression.None: return Deflater.NO_COMPRESSION;
238 case DumpCompression.Minimum: return Deflater.BEST_SPEED;
239 case DumpCompression.Medium: return Deflater.DEFAULT_COMPRESSION;
240 case DumpCompression.Maximum: return Deflater.BEST_COMPRESSION;
241 }
242
243 return Deflater.BEST_COMPRESSION;
244 }
245 }
246
247 /// <summary>
248 /// Checks if a dump exists
249 /// </summary>
250 internal bool DumpExists
251 {
252 get
253 {
254 if(_flags[DumpFlags] == 0)
255 return false;
256
257 // we have a reader or writer to the dump so it must exist
258 if( (_reader != null) || (_writer != null) )
259 return true;
260
261 string sDmpFile = _chmFile.ChmFilePath;
262 sDmpFile=sDmpFile.ToLower().Replace(".chm",".CHB");
263
264 return File.Exists(sDmpFile);
265 }
266 }
267
268 /// <summary>
269 /// Gets a binary writer instance which allows you to write to the dump
270 /// </summary>
271 internal BinaryWriter Writer
272 {
273 get
274 {
275 if (m_bAllowSaveDump==false)
276 return null;
277
278 if(_flags[DumpFlags] == 0)
279 throw new InvalidOperationException("Nothing to dump. No flags have been set !");
280
281 if(_reader != null)
282 throw new InvalidOperationException("Can't write and read at the same time !");
283
284 if(_chmFile == null)
285 throw new InvalidOperationException("Only usable with an associated CHMFile instance !");
286
287 if(_writer==null)
288 {
289 string sDmpFile = _chmFile.ChmFilePath;
290 sDmpFile=sDmpFile.ToLower().Replace(".chm",".CHB");
291 StreamWriter stream = new StreamWriter(sDmpFile, false, _chmFile.TextEncoding);
292
293 // write header info uncompressed
294 BinaryWriter _hwriter = new BinaryWriter(stream.BaseStream);
295 _hwriter.Write(_dumpHeader);
296 _hwriter.Write((int)CompressionLevel);
297
298 if(_compressionLevel == DumpCompression.None)
299 {
300 _writer = new BinaryWriter(stream.BaseStream);
301 }
302 else
303 {
304 _outputStream = new DeflaterOutputStream(stream.BaseStream, new Deflater(CompLvl));
305
306 _writer = new BinaryWriter(_outputStream);
307 }
308 }
309
310 return _writer;
311
312 }
313 }
314
315 /// <summary>
316 /// Gets a binary reader which allows you to read from the dump
317 /// </summary>
318 internal BinaryReader Reader
319 {
320 get
321 {
322 if(_writer != null)
323 throw new InvalidOperationException("Can't write and read at the same time !");
324
325 if(_chmFile == null)
326 throw new InvalidOperationException("Only usable with an associated CHMFile instance !");
327
328 if(_reader==null)
329 {
330 string sDmpFile = _chmFile.ChmFilePath;
331 sDmpFile=sDmpFile.ToLower().Replace(".chm",".CHB");
332 StreamReader stream = new StreamReader(sDmpFile, _chmFile.TextEncoding);
333
334 BinaryReader _hReader = new BinaryReader(stream.BaseStream);
335 string sH = _hReader.ReadString();
336
337 if(sH != _dumpHeader)
338 {
339 _hReader.Close();
340 Debug.WriteLine("Unexpected dump-file header !");
341 throw new FormatException("DumpingInfo.Reader - Unexpected dump-file header !");
342 }
343
344 _compressionLevel = (DumpCompression)_hReader.ReadInt32();
345 // if(_compressionLevel != (DumpCompression)_hReader.ReadInt32())
346 // {
347 // _hReader.Close();
348 // return null;
349 // }
350
351 if(_compressionLevel == DumpCompression.None)
352 {
353 _reader = new BinaryReader(stream.BaseStream);
354 }
355 else
356 {
357 _inputStream = new InflaterInputStream(stream.BaseStream, new Inflater());
358
359 _reader = new BinaryReader(_inputStream);
360 }
361 }
362
363 return _reader;
364 }
365 }
366
367 /// <summary>
368 /// Saves data and closes the dump
369 /// </summary>
370 /// <returns>true if succeed</returns>
371 internal bool SaveData()
372 {
373 if (m_bAllowSaveDump==false)
374 return true;
375
376 if(_writer != null)
377 {
378 if(_writer!=null)
379 _writer.Close();
380 _outputStream = null;
381 _writer = null;
382 }
383
384 if(_reader != null)
385 {
386 if(_reader!=null)
387 _reader.Close();
388 _inputStream = null;
389 _reader = null;
390 }
391
392 return true;
393 }
394 }
395 }