3 using System.Collections;
4 using System.Collections.Specialized;
6 namespace HtmlHelp.ChmDecoding
9 /// The class <c>CHMTopics</c> implements functionality to decode the #TOPICS internal file
11 internal sealed class CHMTopics : IDisposable
14 /// Internal flag specifying if the object is going to be disposed
16 private bool disposed = false;
18 /// Internal member storing the binary file data
20 private byte[] _binaryFileData = null;
22 /// Internal member storing the associated chmfile object
24 private CHMFile _associatedFile = null;
26 /// Internal member storing the topic list
28 private ArrayList _topicTable = new ArrayList();
31 /// Constructor of the class
33 /// <param name="binaryFileData">binary file data of the #TOPICS file</param>
34 /// <param name="associatedFile">associated chm file</param>
35 public CHMTopics(byte[] binaryFileData, CHMFile associatedFile)
37 _binaryFileData = binaryFileData;
38 _associatedFile = associatedFile;
41 // clear internal binary data after extraction
42 _binaryFileData = null;
47 /// Standard constructor
55 /// Dump the class data to a binary writer
57 /// <param name="writer">writer to write the data</param>
58 internal void Dump(ref BinaryWriter writer)
60 writer.Write( _topicTable.Count );
61 foreach(TopicEntry curItem in _topicTable)
63 curItem.Dump(ref writer);
68 /// Reads the object data from a dump store
70 /// <param name="reader">reader to read the data</param>
71 internal void ReadDump(ref BinaryReader reader)
74 int nCnt = reader.ReadInt32();
78 TopicEntry newItem = new TopicEntry();
79 newItem.SetCHMFile(_associatedFile);
80 newItem.ReadDump(ref reader);
81 _topicTable.Add(newItem);
86 /// Sets the associated CHMFile instance
88 /// <param name="associatedFile">instance to set</param>
89 internal void SetCHMFile(CHMFile associatedFile)
91 _associatedFile = associatedFile;
93 foreach(TopicEntry curEntry in _topicTable)
95 curEntry.SetCHMFile(associatedFile);
101 /// Decodes the binary file data and fills the internal properties
103 /// <returns>true if succeeded</returns>
104 private bool DecodeData()
108 MemoryStream memStream = new MemoryStream(_binaryFileData);
109 BinaryReader binReader = new BinaryReader(memStream);
113 while( (memStream.Position < memStream.Length) && (bRet) )
115 int entryOffset = nCurOffset;
116 int tocIdx = binReader.ReadInt32();
117 int titleOffset = binReader.ReadInt32();
118 int urltablOffset = binReader.ReadInt32();
119 int visibilityMode = binReader.ReadInt16();
120 int unknownMode = binReader.ReadInt16();
122 TopicEntry newEntry = new TopicEntry(entryOffset, tocIdx, titleOffset, urltablOffset, visibilityMode, unknownMode, _associatedFile);
123 _topicTable.Add( newEntry );
125 nCurOffset = (int)memStream.Position;
132 /// Gets the arraylist containing all topic entries.
134 public ArrayList TopicTable
143 /// Gets the topic entry of a given offset
145 public TopicEntry this[int offset]
149 foreach(TopicEntry curEntry in _topicTable)
150 if(curEntry.EntryOffset == offset)
158 /// Searches a topic by the locale name
160 /// <param name="locale">locale name to search</param>
161 /// <returns>The topicentry instance if found, otherwise null</returns>
162 public TopicEntry GetByLocale(string locale)
164 foreach(TopicEntry curEntry in TopicTable)
166 if(curEntry.Locale.ToLower() == locale.ToLower())
174 /// Searches the topics for all files with a given file extension
176 /// <param name="fileExtension">extension to search</param>
177 /// <returns>An arraylist of TopicEntry instances or null if no topic was found</returns>
178 public ArrayList GetByExtension(string fileExtension)
180 ArrayList arrRet = new ArrayList();
182 foreach(TopicEntry curEntry in TopicTable)
184 if(curEntry.Locale.ToLower().EndsWith(fileExtension.ToLower()))
185 arrRet.Add(curEntry);
195 /// Implement IDisposable.
197 public void Dispose()
200 // This object will be cleaned up by the Dispose method.
201 // Therefore, you should call GC.SupressFinalize to
202 // take this object off the finalization queue
203 // and prevent finalization code for this object
204 // from executing a second time.
205 GC.SuppressFinalize(this);
209 /// Dispose(bool disposing) executes in two distinct scenarios.
210 /// If disposing equals true, the method has been called directly
211 /// or indirectly by a user's code. Managed and unmanaged resources
213 /// If disposing equals false, the method has been called by the
214 /// runtime from inside the finalizer and you should not reference
215 /// other objects. Only unmanaged resources can be disposed.
217 /// <param name="disposing">disposing flag</param>
218 private void Dispose(bool disposing)
220 // Check to see if Dispose has already been called.
223 // If disposing equals true, dispose all managed
224 // and unmanaged resources.
227 // Dispose managed resources.
228 _binaryFileData = null;