using System; using System.Collections; using System.IO; namespace HtmlHelp.ChmDecoding { /// <summary> /// The class <c>CHMIdxhdr</c> implements t properties which have been read from the #IDXHDR file. /// </summary> internal sealed class CHMIdxhdr : IDisposable { /// <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 the number of topic nodes including the contents and index files /// </summary> private int _numberOfTopicNodes = 0; /// <summary> /// Internal member storing the offset in the #STRINGS file of the ImageList param of the "text/site properties" object of the sitemap contents /// </summary> private int _imageListOffset = 0; /// <summary> /// True if the value of the ImageType param of the "text/site properties" object of the sitemap contents is "Folder". /// </summary> private bool _imageTypeFolder = false; /// <summary> /// Internal member storing the background value /// </summary> private int _background = 0; /// <summary> /// Internal member storing the foreground value /// </summary> private int _foreground = 0; /// <summary> /// Internal member storing the offset in the #STRINGS file of the Font param of the "text/site properties" object of the sitemap contents /// </summary> private int _fontOffset = 0; /// <summary> /// Internal member storing the offset in the #STRINGS file of the FrameName param of the "text/site properties" object of the sitemap contents /// </summary> private int _frameNameOffset = 0; /// <summary> /// Internal member storing the offset in the #STRINGS file of the WindowName param of the "text/site properties" object of the sitemap contents /// </summary> private int _windowNameOffset = 0; /// <summary> /// Internal member storing the number of merged files /// </summary> private int _numberOfMergedFiles = 0; /// <summary> /// Internal member storing the offset in the #STRINGS file of the merged file names /// </summary> private ArrayList _mergedFileOffsets = new ArrayList(); /// <summary> /// Internal member storing the associated chmfile object /// </summary> private CHMFile _associatedFile = null; /// <summary> /// Constructor of the class /// </summary> /// <param name="binaryFileData">binary file data of the #IDXHDR file</param> /// <param name="associatedFile">associated CHMFile instance</param> public CHMIdxhdr(byte[] binaryFileData, CHMFile associatedFile) { _binaryFileData = binaryFileData; _associatedFile = associatedFile; DecodeData(); } /// <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 nTemp = 0; // 4 character T#SM binReader.ReadBytes(4); // unknown timestamp DWORD nTemp = binReader.ReadInt32(); // unknown 1 nTemp = binReader.ReadInt32(); // number of topic nodes including the contents & index files _numberOfTopicNodes = binReader.ReadInt32(); // unknown DWORD nTemp = binReader.ReadInt32(); // offset in the strings file _imageListOffset = binReader.ReadInt32(); if( _imageListOffset == 0) _imageListOffset = -1; // 0/-1 = none // unknown DWORD nTemp = binReader.ReadInt32(); // 1 if the value of the ImageType param of the "text/site properties" object of the sitemap contents is "Folder". nTemp = binReader.ReadInt32(); _imageTypeFolder = (nTemp == 1); // offset in the strings file _background = binReader.ReadInt32(); // offset in the strings file _foreground = binReader.ReadInt32(); // offset in the strings file _fontOffset = binReader.ReadInt32(); // window styles DWORD nTemp = binReader.ReadInt32(); // window styles DWORD nTemp = binReader.ReadInt32(); // unknown DWORD nTemp = binReader.ReadInt32(); // offset in the strings file _frameNameOffset = binReader.ReadInt32(); if( _frameNameOffset == 0) _frameNameOffset = -1; // 0/-1 = none // offset in the strings file _windowNameOffset = binReader.ReadInt32(); if( _windowNameOffset == 0) _windowNameOffset = -1; // 0/-1 = none // informations types DWORD nTemp = binReader.ReadInt32(); // unknown DWORD nTemp = binReader.ReadInt32(); // number of merged files in the merged file list DWORD _numberOfMergedFiles = binReader.ReadInt32(); nTemp = binReader.ReadInt32(); for(int i = 0; i < _numberOfMergedFiles; i++) { // DWORD offset value of merged file nTemp = binReader.ReadInt32(); if(nTemp > 0) _mergedFileOffsets.Add(nTemp); } return bRet; } /// <summary> /// Gets the number of topic nodes including the contents and index files /// </summary> public int NumberOfTopicNodes { get { return _numberOfTopicNodes; } } /// <summary> /// Gets the offset in the #STRINGS file of the ImageList /// param of the "text/site properties" object of the sitemap contents /// </summary> public int ImageListOffset { get { return _imageListOffset; } } /// <summary> /// True if the value of the ImageType param of the /// "text/site properties" object of the sitemap contents is "Folder". /// </summary> /// <remarks>If this is set to true, the help will display folders instead of books</remarks> public bool ImageTypeFolder { get { return _imageTypeFolder; } } /// <summary> /// Gets the background setting /// </summary> public int Background { get { return _background; } } /// <summary> /// Gets the foreground setting /// </summary> public int Foreground { get { return _foreground; } } /// <summary> /// Gets the offset in the #STRINGS file of the Font /// param of the "text/site properties" object of the sitemap contents /// </summary> public int WindowNameOffset { get { return _fontOffset; } } /// <summary> /// Gets the offset in the #STRINGS file of the FrameName /// param of the "text/site properties" object of the sitemap contents /// </summary> public int FrameNameOffset { get { return _frameNameOffset; } } /// <summary> /// Gets the offset in the #STRINGS file of the WindowName /// param of the "text/site properties" object of the sitemap contents /// </summary> public int FontOffset { get { return _windowNameOffset; } } /// <summary> /// Gets an array list of offset numbers in the #STRINGS file of the /// merged file names. /// </summary> public ArrayList MergedFileOffsets { get { return _mergedFileOffsets; } } /// <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; _mergedFileOffsets = null; } } disposed = true; } } }