--- /dev/null
+using System;\r
+using System.Collections;\r
+using System.IO;\r
+\r
+namespace HtmlHelp.ChmDecoding\r
+{\r
+ /// <summary>\r
+ /// The class <c>CHMIdxhdr</c> implements t properties which have been read from the #IDXHDR file.\r
+ /// </summary>\r
+ internal sealed class CHMIdxhdr : IDisposable\r
+ {\r
+ /// <summary>\r
+ /// Internal flag specifying if the object is going to be disposed\r
+ /// </summary>\r
+ private bool disposed = false;\r
+ /// <summary>\r
+ /// Internal member storing the binary file data\r
+ /// </summary>\r
+ private byte[] _binaryFileData = null;\r
+ /// <summary>\r
+ /// Internal member storing the number of topic nodes including the contents and index files\r
+ /// </summary>\r
+ private int _numberOfTopicNodes = 0;\r
+ /// <summary>\r
+ /// Internal member storing the offset in the #STRINGS file of the ImageList param of the "text/site properties" object of the sitemap contents\r
+ /// </summary>\r
+ private int _imageListOffset = 0;\r
+ /// <summary>\r
+ /// True if the value of the ImageType param of the "text/site properties" object of the sitemap contents is "Folder". \r
+ /// </summary>\r
+ private bool _imageTypeFolder = false;\r
+ /// <summary>\r
+ /// Internal member storing the background value\r
+ /// </summary>\r
+ private int _background = 0;\r
+ /// <summary>\r
+ /// Internal member storing the foreground value\r
+ /// </summary>\r
+ private int _foreground = 0;\r
+ /// <summary>\r
+ /// Internal member storing the offset in the #STRINGS file of the Font param of the "text/site properties" object of the sitemap contents\r
+ /// </summary>\r
+ private int _fontOffset = 0;\r
+ /// <summary>\r
+ /// Internal member storing the offset in the #STRINGS file of the FrameName param of the "text/site properties" object of the sitemap contents\r
+ /// </summary>\r
+ private int _frameNameOffset = 0;\r
+ /// <summary>\r
+ /// Internal member storing the offset in the #STRINGS file of the WindowName param of the "text/site properties" object of the sitemap contents\r
+ /// </summary>\r
+ private int _windowNameOffset = 0;\r
+ /// <summary>\r
+ /// Internal member storing the number of merged files\r
+ /// </summary>\r
+ private int _numberOfMergedFiles = 0;\r
+ /// <summary>\r
+ /// Internal member storing the offset in the #STRINGS file of the merged file names\r
+ /// </summary>\r
+ private ArrayList _mergedFileOffsets = new ArrayList();\r
+ /// <summary>\r
+ /// Internal member storing the associated chmfile object\r
+ /// </summary>\r
+ private CHMFile _associatedFile = null;\r
+\r
+ /// <summary>\r
+ /// Constructor of the class\r
+ /// </summary>\r
+ /// <param name="binaryFileData">binary file data of the #IDXHDR file</param>\r
+ /// <param name="associatedFile">associated CHMFile instance</param>\r
+ public CHMIdxhdr(byte[] binaryFileData, CHMFile associatedFile)\r
+ {\r
+ _binaryFileData = binaryFileData;\r
+ _associatedFile = associatedFile;\r
+ DecodeData();\r
+ }\r
+\r
+ /// <summary>\r
+ /// Decodes the binary file data and fills the internal properties\r
+ /// </summary>\r
+ /// <returns>true if succeeded</returns>\r
+ private bool DecodeData()\r
+ {\r
+ bool bRet = true;\r
+\r
+ MemoryStream memStream = new MemoryStream(_binaryFileData);\r
+ BinaryReader binReader = new BinaryReader(memStream);\r
+\r
+ int nTemp = 0;\r
+\r
+ // 4 character T#SM\r
+ binReader.ReadBytes(4);\r
+ // unknown timestamp DWORD\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ // unknown 1\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ // number of topic nodes including the contents & index files\r
+ _numberOfTopicNodes = binReader.ReadInt32();\r
+ \r
+ // unknown DWORD\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ // offset in the strings file\r
+ _imageListOffset = binReader.ReadInt32();\r
+ if( _imageListOffset == 0)\r
+ _imageListOffset = -1; // 0/-1 = none\r
+\r
+ // unknown DWORD\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ // 1 if the value of the ImageType param of the "text/site properties" object of the sitemap contents is "Folder". \r
+ nTemp = binReader.ReadInt32();\r
+ _imageTypeFolder = (nTemp == 1);\r
+\r
+ // offset in the strings file\r
+ _background = binReader.ReadInt32();\r
+ // offset in the strings file\r
+ _foreground = binReader.ReadInt32();\r
+\r
+ // offset in the strings file\r
+ _fontOffset = binReader.ReadInt32();\r
+\r
+ // window styles DWORD\r
+ nTemp = binReader.ReadInt32();\r
+ // window styles DWORD\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ // unknown DWORD\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ // offset in the strings file\r
+ _frameNameOffset = binReader.ReadInt32();\r
+ if( _frameNameOffset == 0)\r
+ _frameNameOffset = -1; // 0/-1 = none\r
+ // offset in the strings file\r
+ _windowNameOffset = binReader.ReadInt32();\r
+ if( _windowNameOffset == 0)\r
+ _windowNameOffset = -1; // 0/-1 = none\r
+\r
+ // informations types DWORD\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ // unknown DWORD\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ // number of merged files in the merged file list DWORD\r
+ _numberOfMergedFiles = binReader.ReadInt32();\r
+\r
+ nTemp = binReader.ReadInt32();\r
+\r
+ for(int i = 0; i < _numberOfMergedFiles; i++)\r
+ {\r
+ // DWORD offset value of merged file\r
+ nTemp = binReader.ReadInt32();\r
+ \r
+ if(nTemp > 0)\r
+ _mergedFileOffsets.Add(nTemp);\r
+ }\r
+\r
+ return bRet;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets the number of topic nodes including the contents and index files\r
+ /// </summary>\r
+ public int NumberOfTopicNodes\r
+ {\r
+ get { return _numberOfTopicNodes; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets the offset in the #STRINGS file of the ImageList \r
+ /// param of the "text/site properties" object of the sitemap contents\r
+ /// </summary>\r
+ public int ImageListOffset\r
+ {\r
+ get { return _imageListOffset; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// True if the value of the ImageType param of the \r
+ /// "text/site properties" object of the sitemap contents is "Folder". \r
+ /// </summary>\r
+ /// <remarks>If this is set to true, the help will display folders instead of books</remarks>\r
+ public bool ImageTypeFolder\r
+ {\r
+ get { return _imageTypeFolder; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets the background setting \r
+ /// </summary>\r
+ public int Background\r
+ {\r
+ get { return _background; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets the foreground setting \r
+ /// </summary>\r
+ public int Foreground\r
+ {\r
+ get { return _foreground; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets the offset in the #STRINGS file of the Font \r
+ /// param of the "text/site properties" object of the sitemap contents\r
+ /// </summary>\r
+ public int WindowNameOffset\r
+ {\r
+ get { return _fontOffset; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets the offset in the #STRINGS file of the FrameName \r
+ /// param of the "text/site properties" object of the sitemap contents\r
+ /// </summary>\r
+ public int FrameNameOffset\r
+ {\r
+ get { return _frameNameOffset; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets the offset in the #STRINGS file of the WindowName \r
+ /// param of the "text/site properties" object of the sitemap contents\r
+ /// </summary>\r
+ public int FontOffset\r
+ {\r
+ get { return _windowNameOffset; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Gets an array list of offset numbers in the #STRINGS file of the \r
+ /// merged file names.\r
+ /// </summary>\r
+ public ArrayList MergedFileOffsets\r
+ {\r
+ get { return _mergedFileOffsets; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Implement IDisposable.\r
+ /// </summary>\r
+ public void Dispose()\r
+ {\r
+ Dispose(true);\r
+ // This object will be cleaned up by the Dispose method.\r
+ // Therefore, you should call GC.SupressFinalize to\r
+ // take this object off the finalization queue \r
+ // and prevent finalization code for this object\r
+ // from executing a second time.\r
+ GC.SuppressFinalize(this);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Dispose(bool disposing) executes in two distinct scenarios. \r
+ /// If disposing equals true, the method has been called directly \r
+ /// or indirectly by a user's code. Managed and unmanaged resources \r
+ /// can be disposed. \r
+ /// If disposing equals false, the method has been called by the \r
+ /// runtime from inside the finalizer and you should not reference \r
+ /// other objects. Only unmanaged resources can be disposed.\r
+ /// </summary>\r
+ /// <param name="disposing">disposing flag</param>\r
+ private void Dispose(bool disposing)\r
+ {\r
+ // Check to see if Dispose has already been called.\r
+ if(!this.disposed)\r
+ {\r
+ // If disposing equals true, dispose all managed \r
+ // and unmanaged resources.\r
+ if(disposing)\r
+ {\r
+ // Dispose managed resources.\r
+ _binaryFileData = null;\r
+ _mergedFileOffsets = null;\r
+ }\r
+ \r
+ \r
+ }\r
+ disposed = true; \r
+ }\r
+ }\r
+}\r