Import TechBot
Added: trunk/irc/TechBot/
Added: trunk/irc/TechBot/CHMLibrary/
Added: trunk/irc/TechBot/CHMLibrary/AssemblyInfo.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/BinaryReaderHelp.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMBtree.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMFile.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMIdxhdr.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMStrings.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMSystem.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMTocidx.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMTopics.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMUrlstr.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMUrltable.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/DumpingInfo.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/FullTextEngine.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/HHCParser.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/HHCParser2.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/HHKParser.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/TopicEntry.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/UrlTableEntry.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/enumerations.cs
Added: trunk/irc/TechBot/CHMLibrary/CHMLibrary.cmbx
Added: trunk/irc/TechBot/CHMLibrary/CHMLibrary.prjx
Added: trunk/irc/TechBot/CHMLibrary/Category.cs
Added: trunk/irc/TechBot/CHMLibrary/ChmFileInfo.cs
Added: trunk/irc/TechBot/CHMLibrary/Default.build
Added: trunk/irc/TechBot/CHMLibrary/HtmlHelpSystem.cs
Added: trunk/irc/TechBot/CHMLibrary/HttpUtility.cs
Added: trunk/irc/TechBot/CHMLibrary/Index.cs
Added: trunk/irc/TechBot/CHMLibrary/IndexItem.cs
Added: trunk/irc/TechBot/CHMLibrary/IndexTopic.cs
Added: trunk/irc/TechBot/CHMLibrary/InformationType.cs
Added: trunk/irc/TechBot/CHMLibrary/Storage/
Added: trunk/irc/TechBot/CHMLibrary/Storage/CHMStream.cs
Added: trunk/irc/TechBot/CHMLibrary/TOCItem.cs
Added: trunk/irc/TechBot/CHMLibrary/TableOfContents.cs
Added: trunk/irc/TechBot/Compression/
Added: trunk/irc/TechBot/Compression/AssemblyInfo.cs
Added: trunk/irc/TechBot/Compression/Checksums/
Added: trunk/irc/TechBot/Compression/Checksums/Adler32.cs
Added: trunk/irc/TechBot/Compression/Checksums/CRC32.cs
Added: trunk/irc/TechBot/Compression/Checksums/IChecksum.cs
Added: trunk/irc/TechBot/Compression/Checksums/StrangeCRC.cs
Added: trunk/irc/TechBot/Compression/Compression.cmbx
Added: trunk/irc/TechBot/Compression/Compression.prjx
Added: trunk/irc/TechBot/Compression/Default.build
Added: trunk/irc/TechBot/Compression/Deflater.cs
Added: trunk/irc/TechBot/Compression/DeflaterConstants.cs
Added: trunk/irc/TechBot/Compression/DeflaterEngine.cs
Added: trunk/irc/TechBot/Compression/DeflaterHuffman.cs
Added: trunk/irc/TechBot/Compression/DeflaterPending.cs
Added: trunk/irc/TechBot/Compression/Inflater.cs
Added: trunk/irc/TechBot/Compression/InflaterDynHeader.cs
Added: trunk/irc/TechBot/Compression/InflaterHuffmanTree.cs
Added: trunk/irc/TechBot/Compression/PendingBuffer.cs
Added: trunk/irc/TechBot/Compression/Streams/
Added: trunk/irc/TechBot/Compression/Streams/DeflaterOutputStream.cs
Added: trunk/irc/TechBot/Compression/Streams/InflaterInputStream.cs
Added: trunk/irc/TechBot/Compression/Streams/OutputWindow.cs
Added: trunk/irc/TechBot/Compression/Streams/StreamManipulator.cs
Added: trunk/irc/TechBot/Compression/ZipException.cs
Added: trunk/irc/TechBot/Default.build
Added: trunk/irc/TechBot/TechBot/
Added: trunk/irc/TechBot/TechBot/App.config
Added: trunk/irc/TechBot/TechBot/AssemblyInfo.cs
Added: trunk/irc/TechBot/TechBot/Default.build
Added: trunk/irc/TechBot/TechBot/ServiceThread.cs
Added: trunk/irc/TechBot/TechBot/TechBot.prjx
Added: trunk/irc/TechBot/TechBot/TechBotService.cs
Added: trunk/irc/TechBot/TechBot.Console/
Added: trunk/irc/TechBot/TechBot.Console/App.config
Added: trunk/irc/TechBot/TechBot.Console/AssemblyInfo.cs
Added: trunk/irc/TechBot/TechBot.Console/Default.build
Added: trunk/irc/TechBot/TechBot.Console/Main.cs
Added: trunk/irc/TechBot/TechBot.Console/TechBot.Console.cmbx
Added: trunk/irc/TechBot/TechBot.Console/TechBot.Console.prjx
Added: trunk/irc/TechBot/TechBot.IRCLibrary/
Added: trunk/irc/TechBot/TechBot.IRCLibrary/AssemblyInfo.cs
Added: trunk/irc/TechBot/TechBot.IRCLibrary/Default.build
Added: trunk/irc/TechBot/TechBot.IRCLibrary/IRC.cs
Added: trunk/irc/TechBot/TechBot.IRCLibrary/IrcChannel.cs
Added: trunk/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs
Added: trunk/irc/TechBot/TechBot.IRCLibrary/IrcException.cs
Added: trunk/irc/TechBot/TechBot.IRCLibrary/IrcMessage.cs
Added: trunk/irc/TechBot/TechBot.IRCLibrary/IrcUser.cs
Added: trunk/irc/TechBot/TechBot.IRCLibrary/TechBot.IRCLibrary.cmbx
Added: trunk/irc/TechBot/TechBot.IRCLibrary/TechBot.IRCLibrary.prjx
Added: trunk/irc/TechBot/TechBot.Library/
Added: trunk/irc/TechBot/TechBot.Library/ApiCommand.cs
Added: trunk/irc/TechBot/TechBot.Library/AssemblyInfo.cs
Added: trunk/irc/TechBot/TechBot.Library/Default.build
Added: trunk/irc/TechBot/TechBot.Library/HelpCommand.cs
Added: trunk/irc/TechBot/TechBot.Library/HresultCommand.cs
Added: trunk/irc/TechBot/TechBot.Library/ICommand.cs
Added: trunk/irc/TechBot/TechBot.Library/IrcService.cs
Added: trunk/irc/TechBot/TechBot.Library/NtStatusCommand.cs
Added: trunk/irc/TechBot/TechBot.Library/NumberParser.cs
Added: trunk/irc/TechBot/TechBot.Library/ServiceOutput.cs
Added: trunk/irc/TechBot/TechBot.Library/SvnCommand.cs
[truncated at 100 lines; 5 more skipped]
Added: trunk/irc/TechBot/CHMLibrary/AssemblyInfo.cs
--- trunk/irc/TechBot/CHMLibrary/AssemblyInfo.cs	2005-01-15 19:15:45 UTC (rev 13063)
+++ trunk/irc/TechBot/CHMLibrary/AssemblyInfo.cs	2005-01-15 19:27:25 UTC (rev 13064)
@@ -0,0 +1,32 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all values by your own or you can build default build and revision
+// numbers with the '*' character (the default):
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes specify the key for the sign of your assembly. See the
+// .NET Framework documentation for more information about signing.
+// This is not required, if you don't want signing let these attributes like they're.
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]

Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/BinaryReaderHelp.cs
--- trunk/irc/TechBot/CHMLibrary/CHMDecoding/BinaryReaderHelp.cs	2005-01-15 19:15:45 UTC (rev 13063)
+++ trunk/irc/TechBot/CHMLibrary/CHMDecoding/BinaryReaderHelp.cs	2005-01-15 19:27:25 UTC (rev 13064)
@@ -0,0 +1,274 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+using System.Globalization;
+
+namespace HtmlHelp.ChmDecoding
+{
+	/// <summary>
+	/// The class <c>BinaryReaderHelp</c> implements static helper methods for extracting binary data 
+	/// from a binary reader object.
+	/// </summary>
+	internal class BinaryReaderHelp
+	{
+		/// <summary>
+		/// Internal helper method to extract null-terminated strings from a binary reader
+		/// </summary>
+		/// <param name="binReader">reference to the binary reader</param>
+		/// <param name="offset">offset in the stream</param>
+		/// <param name="noOffset">true if the offset value should be used</param>
+		/// <param name="encoder">encoder used for text encoding</param>
+		/// <returns>An extracted string value</returns>
+		internal static string ExtractString(ref BinaryReader binReader, int offset, bool noOffset, Encoding encoder)
+		{
+			string strReturn = "";
+
+			if(encoder == null)
+				encoder = Encoding.ASCII;
+
+			ArrayList nameBytes = new ArrayList();
+			byte curByte;
+			
+			if(!noOffset)
+				binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
+
+			if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
+				return "";
+
+			curByte = binReader.ReadByte();
+			while( (curByte != (byte)0) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
+			{	
+				nameBytes.Add( curByte );
+				curByte = binReader.ReadByte();
+			}
+
+			byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
+			strReturn = encoder.GetString(name,0,name.Length);
+
+			return strReturn;
+		}
+
+		/// <summary>
+		/// Internal helper method to extract a string with a specific length from the binary reader
+		/// </summary>
+		/// <param name="binReader">reference to the binary reader</param>
+		/// <param name="length">length of the string (number of bytes)</param>
+		/// <param name="offset">offset in the stream</param>
+		/// <param name="noOffset">true if the offset value should be used</param>
+		/// <param name="encoder">encoder used for text encoding</param>
+		/// <returns>An extracted string value</returns>
+		internal static string ExtractString(ref BinaryReader binReader, int length, int offset, bool noOffset, Encoding encoder)
+		{
+			string strReturn = "";
+
+			if(length == 0)
+				return "";
+
+			if(encoder == null)
+				encoder = Encoding.ASCII;
+
+			ArrayList nameBytes = new ArrayList();
+			byte curByte;
+			
+			if(!noOffset)
+				binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
+
+			if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
+				return "";
+
+			curByte = binReader.ReadByte();
+			while( (curByte != (byte)0) && (nameBytes.Count < length) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
+			{	
+				nameBytes.Add( curByte );
+
+				if(nameBytes.Count < length)
+					curByte = binReader.ReadByte();
+			}
+
+			byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
+			strReturn = encoder.GetString(name,0,name.Length);
+
+			return strReturn;
+		}
+
+		/// <summary>
+		/// Internal helper method to extract a string with a specific length from the binary reader
+		/// </summary>
+		/// <param name="binReader">reference to the binary reader</param>
+		/// <param name="bFoundTerminator">reference to a bool vairable which will receive true if the
+		/// string terminator \0 was found. false indicates that the end of the stream was reached.</param>
+		/// <param name="offset">offset in the stream</param>
+		/// <param name="noOffset">true if the offset value should be used</param>
+		/// <param name="encoder">encoder used for text encoding</param>
+		/// <returns>An extracted string value</returns>
+		internal static string ExtractString(ref BinaryReader binReader, ref bool bFoundTerminator, int offset, bool noOffset, Encoding encoder)
+		{
+			string strReturn = "";
+
+			ArrayList nameBytes = new ArrayList();
+			byte curByte;
+			
+			if(encoder == null)
+				encoder = Encoding.ASCII;
+
+			if(!noOffset)
+				binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
+
+			if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
+				return "";
+
+			curByte = binReader.ReadByte();
+			while( (curByte != (byte)0) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
+			{	
+				nameBytes.Add( curByte );
+				curByte = binReader.ReadByte();
+
+				if( curByte == (byte)0 )
+				{
+					bFoundTerminator = true;
+				}
+			}
+
+			byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
+			strReturn = encoder.GetString(name,0,name.Length);
+
+			return strReturn;
+		}
+
+		/// <summary>
+		/// Internal helper method to extract a null-terminated UTF-16/UCS-2 strings from a binary reader
+		/// </summary>
+		/// <param name="binReader">reference to the binary reader</param>
+		/// <param name="offset">offset in the stream</param>
+		/// <param name="noOffset">true if the offset value should be used</param>
+		/// <param name="encoder">encoder used for text encoding</param>
+		/// <returns>An extracted string value</returns>
+		internal static string ExtractUTF16String(ref BinaryReader binReader, int offset, bool noOffset, Encoding encoder)
+		{
+			string strReturn = "";
+
+			ArrayList nameBytes = new ArrayList();
+			byte curByte;
+			int lastByte=-1;
+			
+			if(!noOffset)
+				binReader.BaseStream.Seek(offset, SeekOrigin.Begin);
+
+			if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
+				return "";
+
+			if(encoder == null)
+				encoder = Encoding.Unicode;
+
+			curByte = binReader.ReadByte();
+			int nCnt = 0;
+			while( ((curByte != (byte)0) || (lastByte != 0) ) && (binReader.BaseStream.Position < binReader.BaseStream.Length) )
+			{	
+				nameBytes.Add( curByte );
+
+				if(nCnt%2 == 0)
+					lastByte = (int)curByte;
+
+				curByte = binReader.ReadByte();
+
+				nCnt++;
+			}
+
+			byte[] name = (byte[]) (nameBytes.ToArray(System.Type.GetType("System.Byte")));
+			strReturn = Encoding.Unicode.GetString(name,0,name.Length);
+
+			// apply text encoding
+			name = Encoding.Default.GetBytes(strReturn);
+			strReturn = encoder.GetString(name,0,name.Length);
+
+			return strReturn;
+		}
+
+		/// <summary>
+		/// Internal helper for reading ENCINT encoded integer values
+		/// </summary>
+		/// <param name="binReader">reference to the reader</param>
+		/// <returns>a long value</returns>
+		internal static long ReadENCINT(ref BinaryReader binReader)
+		{
+			long nRet = 0;
+			byte buffer = 0;
+			int shift = 0;
+
+			if(binReader.BaseStream.Position >= binReader.BaseStream.Length)
+				return nRet;
+			
+			do
+			{
+				buffer = binReader.ReadByte();
+				nRet |= ((long)((buffer & (byte)0x7F))) << shift;
+				shift += 7;
+
+			}while ( (buffer & (byte)0x80) != 0);
+
+			return nRet;
+		}
+
+		/// <summary>
+		/// Reads an s/r encoded value from the byte array and decodes it into an integer
+		/// </summary>
+		/// <param name="wclBits">a byte array containing all bits (contains only 0 or 1 elements)</param>
+		/// <param name="s">scale param for encoding</param>
+		/// <param name="r">root param for encoding</param>
+		/// <param name="nBitIndex">current index in the wclBits array</param>
+		/// <returns>Returns an decoded integer value.</returns>
+		internal static int ReadSRItem(byte[] wclBits, int s, int r, ref int nBitIndex)
+		{
+			int nRet = 0;
+			int q = r;
+
+			int nPref1Cnt = 0;
+
+			while( wclBits[nBitIndex++] == 1)
+			{
+				nPref1Cnt++;
+			}
+
+			if(nPref1Cnt == 0)
+			{
+				int nMask = 0;
+
+				for(int nbits=0; nbits<q;nbits++)
+				{
+					nMask |= ( 0x01 & (int)wclBits[nBitIndex]) << (q-nbits-1);
+					nBitIndex++;
+				}
+
+				nRet = nMask;
+			} 
+			else 
+			{
+				q += (nPref1Cnt-1);
+
+				int nMask = 0;
+				int nRMaxValue = 0;
+
+				for(int nbits=0; nbits<q;nbits++)
+				{
+					nMask |= ( 0x01 & (int)wclBits[nBitIndex]) << (q-nbits-1);
+					nBitIndex++;
+				}
+
+				for(int nsv=0; nsv<r; nsv++)
+				{
+					nRMaxValue = nRMaxValue << 1;
+					nRMaxValue |= 0x1;
+				}
+	
+				nRMaxValue++; // startvalue of s/r encoding with 1 prefixing '1'
+
+				nRMaxValue *= (int) Math.Pow((double)2, (double)(nPref1Cnt-1));
+
+				nRet = nRMaxValue + nMask;
+			}
+
+			return nRet;
+		}
+	}
+}

Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMBtree.cs
--- trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMBtree.cs	2005-01-15 19:15:45 UTC (rev 13063)
+++ trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMBtree.cs	2005-01-15 19:27:25 UTC (rev 13064)
@@ -0,0 +1,325 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Specialized;
+
+namespace HtmlHelp.ChmDecoding
+{
+	/// <summary>
+	/// The class <c>CHMBtree</c> implements methods/properties to decode the binary help index. 
+	/// This class automatically creates an index arraylist for the current CHMFile instance. 
+	/// It does not store the index internally !
+	/// </summary>
+	/// <remarks>The binary index can be found in the storage file $WWKeywordLinks/BTree</remarks>
+	internal sealed class CHMBtree : IDisposable
+	{
+		/// <summary>
+		/// Constant specifying the size of the string blocks
+		/// </summary>
+		private const int BLOCK_SIZE = 2048;
+		/// <summary>
+		/// Internal flag specifying if the object is going to be disposed
+		/// </summary>
+		private bool disposed = false;
+		/// <summary>
+		/// Internal member storing the binary file data
+		/// </summary>
+		private byte[] _binaryFileData = null;
+		/// <summary>
+		/// Internal member storing flags
+		/// </summary>
+		private int _flags = 0;
+		/// <summary>
+		/// Internal member storing the data format
+		/// </summary>
+		private byte[] _dataFormat = new byte[16];
+		/// <summary>
+		/// Internal member storing the index of the last listing block
+		/// </summary>
+		private int _indexOfLastListingBlock = 0;
+		/// <summary>
+		/// Internal member storing the index of the root block
+		/// </summary>
+		private int _indexOfRootBlock = 0;
+		/// <summary>
+		/// Internal member storing the number of blocks
+		/// </summary>
+		private int _numberOfBlocks = 0;
+		/// <summary>
+		/// Internal member storing the tree depth. 
+		/// (1 if no index blocks, 2 one level of index blocks, ...)
+		/// </summary>
+		private int _treeDepth = 0;
+		/// <summary>
+		/// Internal member storing the number of keywords in the file
+		/// </summary>
+		private int _numberOfKeywords = 0;
+		/// <summary>
+		/// Internal member storing the codepage
+		/// </summary>
+		private int _codePage = 0;
+		/// <summary>
+		/// true if the index is from a CHI or CHM file, else CHW
+		/// </summary>
+		private bool _isCHI_CHM = true;
+		/// <summary>
+		/// Internal member storing the associated chmfile object
+		/// </summary>
+		private CHMFile _associatedFile = null;
+		/// <summary>
+		/// Internal flag specifying if we have to read listing or index blocks
+		/// </summary>
+		private bool _readListingBlocks = true;
+		/// <summary>
+		/// Internal member storing an indexlist of the current file.
+		/// </summary>
+		private ArrayList _indexList = new ArrayList();
+
+		/// <summary>
+		/// Constructor of the class
+		/// </summary>
+		/// <param name="binaryFileData">binary file data of the $WWKeywordLinks/BTree file</param>
+		/// <param name="associatedFile">associated chm file</param>
+		public CHMBtree(byte[] binaryFileData, CHMFile associatedFile)
+		{
+			if( associatedFile == null)
+			{
+				throw new ArgumentException("CHMBtree.ctor() - Associated CHMFile must not be null !", "associatedFile");
+			}
+
+			_binaryFileData = binaryFileData;
+			_associatedFile = associatedFile;
+			DecodeData();
+
+			// clear internal binary data after extraction
+			_binaryFileData = null;
+		}
+
+		/// <summary>
+		/// Decodes the binary file data and fills the internal properties
+		/// </summary>
+		/// <returns>true if succeeded</returns>
+		private bool DecodeData()
+		{
+			bool bRet = true;
+
+			MemoryStream memStream = new MemoryStream(_binaryFileData);
+			BinaryReader binReader = new BinaryReader(memStream);
+			
+			int nCurOffset = 0;
+			int nTemp = 0;
+
+			// decode header
+			binReader.ReadChars(2); // 2chars signature (not important)
+			
+			_flags = (int)binReader.ReadInt16(); // WORD flags
+
+			binReader.ReadInt16(); // size of blocks (always 2048)
+
+			_dataFormat = binReader.ReadBytes(16);
+			
+			binReader.ReadInt32();  // unknown DWORD
+
+			_indexOfLastListingBlock = binReader.ReadInt32();
+			_indexOfRootBlock = binReader.ReadInt32();
+
+			binReader.ReadInt32(); // unknown DWORD
+
+			_numberOfBlocks = binReader.ReadInt32();
+			_treeDepth = binReader.ReadInt16();
+			_numberOfKeywords = binReader.ReadInt32();
+			_codePage = binReader.ReadInt32();
+
+			binReader.ReadInt32(); // lcid DWORD
+			
+			nTemp = binReader.ReadInt32();
+			_isCHI_CHM = (nTemp==1);
+
+			binReader.ReadInt32(); // unknown DWORD
+			binReader.ReadInt32(); // unknown DWORD
+			binReader.ReadInt32(); // unknown DWORD
+			binReader.ReadInt32(); // unknown DWORD
+
+			// end of header decode
+
+			while( (memStream.Position < memStream.Length) && (bRet) )
+			{
+				nCurOffset = (int)memStream.Position;
+				byte [] dataBlock = binReader.ReadBytes(BLOCK_SIZE);
+				bRet &= DecodeBlock(dataBlock, ref nCurOffset, _treeDepth-1);
+			}
+
+			return bRet;
+		}
+
+		/// <summary>
+		/// Decodes a block of url-string data
+		/// </summary>
+		/// <param name="dataBlock">block of data</param>
+		/// <param name="nOffset">current file offset</param>
+		/// <param name="indexBlocks">number of index blocks</param>
+		/// <returns>true if succeeded</returns>
+		private bool DecodeBlock( byte[] dataBlock, ref int nOffset, int indexBlocks )
+		{
+			bool bRet = true;
+			int nblockOffset = nOffset;
+
+			MemoryStream memStream = new MemoryStream(dataBlock);
+			BinaryReader binReader = new BinaryReader(memStream);
+
+			int freeSpace = binReader.ReadInt16(); // length of freespace
+			int nrOfEntries = binReader.ReadInt16(); // number of entries
+
+			bool bListingEndReached = false;
+
+			//while( (memStream.Position < (memStream.Length-freeSpace)) && (bRet) )
+			//{
+				int nIndexOfPrevBlock = -1;
+				int nIndexOfNextBlock = -1;
+				int nIndexOfChildBlock = 0;
+				
+				if(_readListingBlocks)
+				{
+					nIndexOfPrevBlock = binReader.ReadInt32(); // -1 if this is the header
+					nIndexOfNextBlock = binReader.ReadInt32(); // -1 if this is the last block
+				} 
+				else 
+				{
+					nIndexOfChildBlock = binReader.ReadInt32(); 
+				}
+
+				for(int nE = 0; nE < nrOfEntries; nE++)
+				{
+					if(_readListingBlocks)
+					{
+						bListingEndReached = (nIndexOfNextBlock==-1);
+
+						string keyWord = BinaryReaderHelp.ExtractUTF16String(ref binReader, 0, true, _associatedFile.TextEncoding);
+
+						bool isSeeAlsoKeyword = (binReader.ReadInt16()!=0);
+				
+						int indent = binReader.ReadInt16(); // indent of entry
+						int nCharIndex = binReader.ReadInt32();
+
+						binReader.ReadInt32();
+
+						int numberOfPairs =	binReader.ReadInt32();
+
+						int[] nTopics = new int[numberOfPairs];
+						string[] seeAlso = new string[numberOfPairs];
+
+						for(int i=0; i < numberOfPairs; i++)
+						{
+							if(isSeeAlsoKeyword)
+							{
+								seeAlso[i] = BinaryReaderHelp.ExtractUTF16String(ref binReader, 0, true, _associatedFile.TextEncoding);
+							} 
+							else 
+							{
+								nTopics[i] = binReader.ReadInt32();
+							}
+						}
+
+						binReader.ReadInt32(); // unknown
+
+						int nIndexOfThisEntry = binReader.ReadInt32();
+
+						IndexItem newItem = new IndexItem(_associatedFile, keyWord, isSeeAlsoKeyword, indent, nCharIndex, nIndexOfThisEntry, seeAlso, nTopics);
+						_indexList.Add(newItem);
+					} 
+					else 
+					{
+						string keyWord = BinaryReaderHelp.ExtractUTF16String(ref binReader, 0, true, _associatedFile.TextEncoding);
+
+						bool isSeeAlsoKeyword = (binReader.ReadInt16()!=0);
+				
+						int indent = binReader.ReadInt16(); // indent of entry
+						int nCharIndex = binReader.ReadInt32();
+
+						binReader.ReadInt32();
+
+						int numberOfPairs =	binReader.ReadInt32();
+
+						int[] nTopics = new int[numberOfPairs];
+						string[] seeAlso = new string[numberOfPairs];
+
+						for(int i=0; i < numberOfPairs; i++)
+						{
+							if(isSeeAlsoKeyword)
+							{
+								seeAlso[i] = BinaryReaderHelp.ExtractUTF16String(ref binReader, 0, true, _associatedFile.TextEncoding);
+							} 
+							else 
+							{
+								nTopics[i] = binReader.ReadInt32();
+							}
+						}
+
+						int nIndexChild = binReader.ReadInt32();
+						int nIndexOfThisEntry=-1;
+
+						IndexItem newItem = new IndexItem(_associatedFile, keyWord, isSeeAlsoKeyword, indent, nCharIndex, nIndexOfThisEntry, seeAlso, nTopics);
+						_indexList.Add(newItem);
+
+					}
+				}
+			//}
+
+			binReader.ReadBytes(freeSpace);
+			
+
+			if( bListingEndReached )
+				_readListingBlocks = false;
+
+			return bRet;
+		}
+
+		/// <summary>
+		/// Gets the internal generated index list
+		/// </summary>
+		internal ArrayList IndexList
+		{
+			get { return _indexList; }
+		}
+
+		/// <summary>
+		/// Implement IDisposable.
+		/// </summary>
+		public void Dispose()
+		{
+			Dispose(true);
+			// This object will be cleaned up by the Dispose method.
+			// Therefore, you should call GC.SupressFinalize to
+			// take this object off the finalization queue 
+			// and prevent finalization code for this object
+			// from executing a second time.
+			GC.SuppressFinalize(this);
+		}
+
+		/// <summary>
+		/// Dispose(bool disposing) executes in two distinct scenarios. 
+		/// If disposing equals true, the method has been called directly 
+		/// or indirectly by a user's code. Managed and unmanaged resources 
+		/// can be disposed. 
+		/// If disposing equals false, the method has been called by the 
+		/// runtime from inside the finalizer and you should not reference  
+		/// other objects. Only unmanaged resources can be disposed.
+		/// </summary>
+		/// <param name="disposing">disposing flag</param>
+		private void Dispose(bool disposing)
+		{
+			// Check to see if Dispose has already been called.
+			if(!this.disposed)
+			{
+				// If disposing equals true, dispose all managed 
+				// and unmanaged resources.
+				if(disposing)
+				{
+					// Dispose managed resources.
+					_binaryFileData = null;
+				}
+			}
+			disposed = true;         
+		}
+	}
+}

Added: trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMFile.cs
--- trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMFile.cs	2005-01-15 19:15:45 UTC (rev 13063)
+++ trunk/irc/TechBot/CHMLibrary/CHMDecoding/CHMFile.cs	2005-01-15 19:27:25 UTC (rev 13064)
@@ -0,0 +1,2061 @@
+using System;
+using System.Diagnostics;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Globalization;
+// using HtmlHelp.Storage;
+
+namespace HtmlHelp.ChmDecoding
+{
+	/// <summary>
+	/// Internal enumeration for specifying the type of the html-help file
+	/// </summary>
+	internal enum HtmlHelpFileType
+	{
+		/// <summary>
+		/// CHM - compiled contents file
+		/// </summary>
+		/// <remarks>A file with this extension must always exist. If the file would be too long, some parts 
+		/// can be splitted into the filestypes below.</remarks>
+		CHM = 0,
+		/// <summary>
+		/// CHI - compiled system file
+		/// </summary>
+		CHI = 1,
+		/// <summary>
+		/// CHQ - compiled fulltext search file
+		/// </summary>
+		CHQ = 2,
+		/// <summary>
+		/// CHW - compiled index file
+		/// </summary>
+		CHW = 3
+
+	}
+
+	/// <summary>
+	/// The class <c>CHMFile</c> implemts methods and properties for handling a single chmfile.
+	/// </summary>
+	public sealed class CHMFile : IDisposable
+	{
+		/// <summary>
+		/// Internal member storing a reference to the hosting HtmlHelpSystem instance
+		/// </summary>
+		private HtmlHelpSystem _systemInstance = null;
+		/// <summary>
+		/// Internal flag specifying if only system data has been loaded
+		/// </summary>
+		private bool _onlySystem = false;
+		/// <summary>
+		/// Internal flag specifying if the object is going to be disposed
+		/// </summary>
+		private bool disposed = false;
+		/// <summary>
+		/// Internal arraylist containing the table of contents
+		/// </summary>
+		private ArrayList _toc = new ArrayList();
+		/// <summary>
+		/// Internal arraylist containing items of the toc which are merge-Links
+		/// </summary>
+		private ArrayList _mergeLinks = new ArrayList();
+		/// <summary>
+		/// Internal member storing the read information types
+		/// </summary>
+		private ArrayList _informationTypes = new ArrayList();
+		/// <summary>
+		/// Internal member storing the read categories
+		/// </summary>
+		private ArrayList _categories = new ArrayList();
+		/// <summary>
+		/// Internal arraylist containing the index (klinks)
+		/// </summary>
+		private ArrayList _indexKLinks = new ArrayList();
+		/// <summary>
+		/// Internal arraylist containing the index (alinks)
+		/// </summary>
+		private ArrayList _indexALinks = new ArrayList();
+		/// <summary>
+		/// Internal member storing the full filename
+		/// </summary>
+		private string _chmFileName = "";
+		/// <summary>
+		/// Internal member storing the full filename of the chi-file (includes all system files)
+		/// The file name is zero-length if there is no chi-file
+		/// </summary>
+		private string _chiFileName = "";
+		/// <summary>
+		/// Internal member storing the full filename of the chw-file (includes the help index)
+		/// The file name is zero-length if there is no chw-file
+		/// </summary>
+		private string _chwFileName = "";
+		/// <summary>
+		/// Internal member storing the full filename of the chq-file (includes the fulltext contents)
+		/// The file name is zero-length if there is no chq-file
+		/// </summary>
+		private string _chqFileName = "";
+		/// <summary>
+		/// Internal member storing the decoded information from the internal #SYSTEM file
+		/// </summary>
+		private CHMSystem _systemFile = null;
+		/// <summary>
+		/// Internal member storing the decoded information from the internal #IDXHDR file
+		/// </summary>
+		private CHMIdxhdr _idxhdrFile = null;
+		/// <summary>
+		/// Internal member storing the decoded information from the internal #STRINGS file
+		/// </summary>
+		private CHMStrings _stringsFile = null;
+		/// <summary>
+		/// Internal member storing the decoded information from the internal #URLSTR file
+		/// </summary>
+		private CHMUrlstr _urlstrFile = null;
+		/// <summary>
+		/// Internal member storing the decoded information from the internal #URLTBL file
+		/// </summary>
+		private CHMUrltable _urltblFile = null;
+		/// <summary>
+		/// Internal member storing the decoded information from the internal #TOPICS file
+		/// </summary>
+		private CHMTopics _topicsFile = null;
+		/// <summary>
+		/// Internal member storing the decoded information from the internal #TOCIDX file
+		/// </summary>
+		private CHMTocidx _tocidxFile = null;
+		/// <summary>
+		/// Internal member storing the decoded information from the internal binary index file (KLinks).
+		/// </summary>
+		private CHMBtree _kLinks = null;
+		/// <summary>
+		/// Internal member storing the decoded information from the internal binary index file (ALinks).
+		/// </summary>
+		private CHMBtree _aLinks = null;
+		/// <summary>
+		/// Internal member storing the fulltext searcher for this file
+		/// </summary>
+		private FullTextEngine _ftSearcher = null;
+		/// <summary>
+		/// Internal member storing the default encoder
+		/// </summary>
+		private Encoding _textEncoding = Encoding.GetEncoding(1252); // standard windows-1252 encoder
+		/// <summary>
+		/// Internal memebr storing the chm file info
+		/// </summary>
+		private ChmFileInfo _chmFileInfo = null;
+		/// <summary>
+		/// Internal flag specifying if the dump must be written (if enabled)
+		/// </summary>
+		private bool _mustWriteDump = false;
+		/// <summary>
+		/// Internal flag specifying if data was read using the dump
+		/// </summary>
+		private bool _dumpRead = false;
+		/// <summary>
+		/// Internal member for specifying the number of dump-reading trys.
+		/// If dump-reading fails, this is used that it will not be opened a second time
+		/// (in CHM-Systems with CHM, CHI, etc. files)
+		/// </summary>
+		private int _dumpReadTrys = 0;
+		/// <summary>
+		/// Internal member storing the dumping info instance
+		/// </summary>
+		private DumpingInfo _dmpInfo = null;
+
+		private CHMStream.CHMStream _currentWrapper;
+		private CHMStream.CHMStream _baseStream=null;
+		public CHMStream.CHMStream BaseStream
+		{
+			get 
+			{ 
+				if (_baseStream==null)
+					_baseStream=new CHMStream.CHMStream(this.ChmFilePath);
+				return _baseStream; 
+			}
+		}
+
+		/// <summary>
+		/// Creates a new instance of the class
+		/// </summary>
+		/// <param name="systemInstance">a reference to the hosting HtmlHelpSystem instance</param>
+		/// <param name="chmFile">chm file to read</param>
+		public CHMFile(HtmlHelpSystem systemInstance, string chmFile) : this(systemInstance, chmFile, false, null)
+		{
+		}
+
+		/// <summary>
+		/// Creates a new instance of the class
+		/// </summary>
+		/// <param name="systemInstance">a reference to the hosting HtmlHelpSystem instance</param>
+		/// <param name="chmFile">chm file to read</param>
+		/// <param name="dmpInfo">A dumping info class</param>
+		public CHMFile(HtmlHelpSystem systemInstance, string chmFile, DumpingInfo dmpInfo) : this(systemInstance, chmFile, false, dmpInfo)
+		{
+		}
+
+		/// <summary>
+		/// Creates a new instance of the class
+		/// </summary>
+		/// <param name="systemInstance">a reference to the hosting HtmlHelpSystem instance</param>
+		/// <param name="chmFile">chm file to read</param>
+		/// <param name="onlySystemData">true if only system data should be extracted (no index or toc)</param>
+		internal CHMFile(HtmlHelpSystem systemInstance, string chmFile, bool onlySystemData) : this(systemInstance, chmFile, onlySystemData, null)
+		{
+		}
+
+		/// <summary>
+		/// Creates a new instance of the class
+		/// </summary>
+		/// <param name="systemInstance">a reference to the hosting HtmlHelpSystem instance</param>
+		/// <param name="chmFile">chm file to read</param>
+		/// <param name="onlySystemData">true if only system data should be extracted (no index or toc)</param>
+		/// <param name="dmpInfo">A dumping info class</param>
+		internal CHMFile(HtmlHelpSystem systemInstance, string chmFile, bool onlySystemData, DumpingInfo dmpInfo)
+		{
+			_systemInstance = systemInstance;
+			_dumpReadTrys=0;
+
+			_dmpInfo = dmpInfo;
+			if(dmpInfo != null)
+			{
+				dmpInfo.ChmFile = this;
+			}
+
+			if( ! chmFile.ToLower().EndsWith(".chm") )
+			{
+				throw new ArgumentException("HtmlHelp file must have the extension .chm !", "chmFile");
+			}
+
+			_chmFileName = chmFile;
+			_chiFileName = "";
+
+			// Read the IStorage file system
+			if( File.Exists(chmFile) )
+			{
+				_onlySystem = onlySystemData;
+				
+				DateTime dtStartHH = DateTime.Now;
+
+				string sCHIName = _chmFileName.Substring(0, _chmFileName.Length-3) + "chi";
+				string sCHQName = _chmFileName.Substring(0, _chmFileName.Length-3) + "chq";
+				string sCHWName = _chmFileName.Substring(0, _chmFileName.Length-3) + "chw";
+
+				// If there is a CHI file present (this file includes the internal system files for the current chm file)
+				if( File.Exists(sCHIName) )
+				{
+					_chiFileName = sCHIName;
+				
+					ReadFile(_chiFileName, HtmlHelpFileType.CHI);
+				}
+
+				// If there is a CHW file present (this file includes the internal binary index of the help)
+				if(( File.Exists(sCHWName) ) && (!_onlySystem) )
+				{
+					_chwFileName = sCHWName;
+				
+					ReadFile(_chwFileName, HtmlHelpFileType.CHW);
+				}
+
+				// If there is a CHQ file present (this file includes the fulltext-search data)
+				if(( File.Exists(sCHQName) ) && (!_onlySystem) )
+				{
+					_chqFileName = sCHQName;
+				
+					ReadFile(_chqFileName, HtmlHelpFileType.CHQ);
+				}
+
+				ReadFile(chmFile, HtmlHelpFileType.CHM);
+
+				if(_mustWriteDump)
+				{					
+					_mustWriteDump = !SaveDump(dmpInfo);
+
+				}
+
+				// check the default-topic setting
+				if(_systemFile.DefaultTopic.Length > 0)
+				{
+					CHMStream.CHMStream iw=null;
+					iw = new CHMStream.CHMStream(chmFile);
+					_currentWrapper=iw;
+
+					// tryo to open the topic file
+					MemoryStream fileObject = iw.OpenStream( _systemFile.DefaultTopic);
+					if( fileObject != null)
+					{
+						// if succeed, the topic default topic is OK
+						fileObject.Close();
+					} 
+					else 
+					{
+						// set the first topic of the toc-tree as default topic
+						if(_toc.Count > 0)
+						{
+							_systemFile.SetDefaultTopic( ((TOCItem) _toc[0]).Local );
+						}
+					}
+					_currentWrapper=null;
+				} 
+				else 
+				{
+					// set the first topic of the toc-tree as default topic
+					if(_toc.Count > 0)
+					{
+						_systemFile.SetDefaultTopic( ((TOCItem) _toc[0]).Local );
+					}
+				}
+
+				_chmFileInfo = new ChmFileInfo(this);
+			} 
+			else 
+			{
+				throw new ArgumentException("File '" + chmFile + "' not found !", "chmFile");
+			}
+		}
+
+		/// <summary>
+		/// Read a IStorage file
+		/// </summary>
+		/// <param name="fname">filename</param>
+		/// <param name="type">type of file</param>
+		private void ReadFile(string fname, HtmlHelpFileType type)
+		{
+			CHMStream.CHMStream iw=null;
+			iw=new CHMStream.CHMStream();			
+			iw.OpenCHM(fname);
+			_currentWrapper=iw;
+			MemoryStream fileObject=null;			
+
+			// ITStorageWrapper iw = null;
+
+			// Open the internal chm system files and parse their content
+			// FileObject fileObject = null;
+			// iw = new ITStorageWrapper(fname, false);			
+
+			if( (type != HtmlHelpFileType.CHQ) && (type != HtmlHelpFileType.CHW) )
+			{				
+				fileObject = iw.OpenStream("#SYSTEM");
+				if ((fileObject != null) && (fileObject.Length>0))
+					_systemFile = new CHMSystem(fileObject.ToArray(), this);									
+
+				fileObject = iw.OpenStream("#IDXHDR");
+				if ((fileObject != null) && (fileObject.Length>0))
+					_idxhdrFile = new CHMIdxhdr(fileObject.ToArray(), this);					
+				
+				// try to read Dump
+				if((!_dumpRead)&&(CheckDump(_dmpInfo))&&(_dumpReadTrys==0))
+				{
+					_dumpReadTrys++;
[truncated at 1000 lines; 23868 more skipped]