2 using System.Diagnostics;
3 using System.Collections;
4 using HtmlHelp.ChmDecoding;
9 /// Enumeration for specifying the index type
14 /// Keyword links should be used
18 /// Associative links should be used
24 /// The class <c>Index</c> holds the (keyword links) KLinks and (associative links) ALinks of the htmlhelp
25 /// system. It implements methods for easy index-based searching.
29 private ArrayList _kLinks = new ArrayList();
30 private ArrayList _aLinks = new ArrayList();
33 /// Standard constructor
40 /// Constructor of the class
42 /// <param name="kLinks">arraylist with keyword links</param>
43 /// <param name="aLinks">arraylist with associative links</param>
44 public Index(ArrayList kLinks, ArrayList aLinks)
51 /// Clears the current toc
62 /// Gets the number of index items for a specific type
64 /// <param name="typeOfIndex">type of index</param>
65 /// <returns>Returns the number of index items for a specific type</returns>
66 public int Count(IndexType typeOfIndex)
68 ArrayList _index = null;
72 case IndexType.AssiciativeLinks: _index = _aLinks; break;
73 case IndexType.KeywordLinks: _index = _kLinks; break;
83 /// Gets the internal index list of keyword links
85 public ArrayList KLinks
90 _kLinks = new ArrayList();
97 /// Gets the internal index list of associative links
99 public ArrayList ALinks
104 _aLinks = new ArrayList();
111 /// Merges the the index list <c>arrIndex</c> into the current one
113 /// <param name="arrIndex">indexlist which should be merged with the current one</param>
114 /// <param name="typeOfIndex">type of index to merge</param>
115 public void MergeIndex( ArrayList arrIndex, IndexType typeOfIndex )
117 ArrayList _index = null;
121 case IndexType.AssiciativeLinks: _index = _aLinks;break;
122 case IndexType.KeywordLinks: _index = _kLinks;break;
125 foreach(IndexItem curItem in arrIndex)
127 //IndexItem searchItem = ContainsIndex(_index, curItem.KeyWordPath);
129 IndexItem searchItem = BinSearch(0, _index.Count-1, _index, curItem.KeyWordPath, false, false, ref insertIndex);
131 if(searchItem != null)
133 // extend the keywords topics
134 foreach(IndexTopic curEntry in curItem.Topics)
136 searchItem.Topics.Add( curEntry );
141 // add the item to the global collection
142 //_index.Add( curItem );
144 if(insertIndex > _index.Count)
147 _index.Insert(insertIndex, curItem);
153 /// Searches an index entry using recursive binary search algo (divide and conquer).
155 /// <param name="nStart">start index for searching</param>
156 /// <param name="nEnd">end index for searching</param>
157 /// <param name="arrIndex">arraylist containing sorted IndexItem entries</param>
158 /// <param name="keywordPath">keyword path to search</param>
159 /// <param name="searchKeyword">true if the keywordPath will only contain the keyword not the complete path</param>
160 /// <param name="caseInsensitive">True if case should be ignored</param>
161 /// <param name="insertIndex">out reference. will receive the index where the item with the
162 /// keywordPath should be inserted if not found (receives -1 if the item was found)</param>
163 /// <returns>Returns an IndexItem instance if found, otherwise null
164 /// (use insertIndex for inserting the new item in a sorted order)</returns>
165 private IndexItem BinSearch(int nStart, int nEnd, ArrayList arrIndex, string keywordPath,
166 bool searchKeyword, bool caseInsensitive, ref int insertIndex)
168 if( arrIndex.Count <= 0 )
175 keywordPath = keywordPath.ToLower();
177 if( (nEnd - nStart) > 1)
179 int nCheck = nStart + (nEnd-nStart)/2;
181 IndexItem iC = arrIndex[nCheck] as IndexItem;
183 string sCompare = iC.KeyWordPath;
186 sCompare = iC.KeyWord;
189 sCompare = sCompare.ToLower();
191 if( sCompare == keywordPath )
197 if( keywordPath.CompareTo(sCompare) < 0 )
199 return BinSearch(nStart, nCheck-1, arrIndex, keywordPath, searchKeyword, caseInsensitive, ref insertIndex);
202 if( keywordPath.CompareTo(sCompare) > 0 )
204 return BinSearch(nCheck+1, nEnd, arrIndex, keywordPath, searchKeyword, caseInsensitive, ref insertIndex);
207 else if(nEnd-nStart == 1)
209 IndexItem i1 = arrIndex[nStart] as IndexItem;
210 IndexItem i2 = arrIndex[nEnd] as IndexItem;
212 string sCompare1 = i1.KeyWordPath;
215 sCompare1 = i1.KeyWord;
218 sCompare1 = sCompare1.ToLower();
220 string sCompare2 = i2.KeyWordPath;
223 sCompare2 = i2.KeyWord;
226 sCompare2 = sCompare2.ToLower();
228 if( sCompare1 == keywordPath)
234 if( sCompare2 == keywordPath)
240 if( sCompare1.CompareTo(keywordPath) > 0)
242 insertIndex = nStart;
245 else if( sCompare2.CompareTo(keywordPath) > 0)
252 insertIndex = nEnd+1;
256 IndexItem itm = arrIndex[nEnd] as IndexItem;
258 string sCompareI = itm.KeyWordPath;
261 sCompareI = itm.KeyWord;
264 sCompareI = sCompareI.ToLower();
266 if( sCompareI.CompareTo(keywordPath) > 0)
268 insertIndex = nStart;
271 else if( sCompareI.CompareTo(keywordPath) < 0)
273 insertIndex = nEnd+1;
279 return arrIndex[nEnd] as IndexItem;
284 /// Checks if a keyword exists in a index collection
286 /// <param name="arrIndex">index to search (arraylist of IndexItems)</param>
287 /// <param name="keywordPath">keywordpath to search</param>
288 /// <returns>Returns the found IndexItem, otherwise null</returns>
289 private IndexItem ContainsIndex(ArrayList arrIndex, string keywordPath)
291 foreach(IndexItem curItem in arrIndex)
293 if(curItem.KeyWordPath == keywordPath)
301 /// Searches the alinks- or klinks-index for a specific keyword/associative
303 /// <param name="search">keyword/associative to search</param>
304 /// <param name="typeOfIndex">type of index to search</param>
305 /// <returns>Returns an ArrayList which contains IndexTopic items or null if nothing was found</returns>
306 public IndexItem SearchIndex(string search, IndexType typeOfIndex)
308 ArrayList _index = null;
310 switch( typeOfIndex )
312 case IndexType.AssiciativeLinks: _index = _aLinks;break;
313 case IndexType.KeywordLinks: _index = _kLinks;break;
317 IndexItem foundItem = BinSearch(0, _index.Count, _index, search, true, true, ref insertIdx);