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]