/// <summary>
        /// Removes a chm file from the internal file collection
        /// </summary>
        /// <param name="chmFile">full file path of the chm file to remove</param>
        public void RemoveFile(string chmFile)
        {
            int     nIdx           = -1;
            CHMFile removeInstance = null;

            foreach (CHMFile curFile in _chmFiles)
            {
                nIdx++;

                if (curFile.ChmFilePath.ToLower() == chmFile.ToLower())
                {
                    removeInstance = curFile;
                    break;
                }
            }

            if (nIdx >= 0)
            {
                _toc.Clear();                 // forces a rebuild of the merged toc
                _index.Clear();               // force a rebuild of the merged index

                RemoveFileInfoTypesCategories(removeInstance);
                _chmFiles.RemoveAt(nIdx);
            }
        }
Exemple #2
0
        /// <summary>
        /// Parses a HHC file and returns an ArrayList with the table of contents (TOC) tree
        /// </summary>
        /// <param name="hhcFile">string content of the hhc file</param>
        /// <param name="chmFile">CHMFile instance</param>
        /// <returns>Returns an ArrayList with the table of contents (TOC) tree</returns>
        public static ArrayList ParseHHC(string hhcFile, CHMFile chmFile)
        {
            DateTime StartTime = DateTime.Now;

            ArrayList tocList = new ArrayList();

            m_text2 = hhcFile;
            m_text1 = hhcFile.ToLower();

            int idx = m_text1.IndexOf("<ul>");

            if (idx == -1)
            {
                return(null);
            }
            m_CurrentPos = idx + 4;

            ParamRE      = new Regex(RE_ParamBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            AttributesRE = new Regex(RE_QuoteAttributes, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

            ParseTree(tocList, chmFile);

            DateTime EndTime = DateTime.Now;
            TimeSpan Diff    = EndTime - StartTime;
            string   x       = Diff.ToString();

            return(tocList);
        }
Exemple #3
0
 /// <summary>
 /// Constructor of the class used during binary data extraction
 /// </summary>
 /// <param name="topicOffset">offset of the associated topic entry</param>
 /// <param name="ImageIndex">image index to use</param>
 /// <param name="associatedFile">associated chm file</param>
 public TOCItem(int topicOffset, int ImageIndex, CHMFile associatedFile)
 {
     _tocMode        = DataMode.Binary;
     _associatedFile = associatedFile;
     _chmFile        = associatedFile.ChmFilePath;
     _topicOffset    = topicOffset;
     _imageIndex     = ImageIndex;
 }
Exemple #4
0
 /// <summary>
 /// Constructor of the class
 /// </summary>
 /// <param name="uniqueID">unique id</param>
 /// <param name="entryOffset">offset of the entry</param>
 /// <param name="topicIndex">topic index</param>
 /// <param name="urlstrOffset">urlstr offset for filename</param>
 /// <param name="associatedFile">associated chm file</param>
 internal UrlTableEntry(uint uniqueID, int entryOffset, int topicIndex, int urlstrOffset, CHMFile associatedFile)
 {
     _uniqueID       = uniqueID;
     _entryOffset    = entryOffset;
     _topicsIndex    = topicIndex;
     _urlStrOffset   = urlstrOffset;
     _associatedFile = associatedFile;
 }
Exemple #5
0
        /// <summary>
        /// Sets the associated CHMFile instance
        /// </summary>
        /// <param name="associatedFile">instance to set</param>
        internal void SetCHMFile(CHMFile associatedFile)
        {
            _associatedFile = associatedFile;

            foreach (TopicEntry curEntry in _topicTable)
            {
                curEntry.SetCHMFile(associatedFile);
            }
        }
Exemple #6
0
        /// <summary>
        /// Constructor of the class
        /// </summary>
        /// <param name="binaryFileData">binary file data of the #URLTBL file</param>
        /// <param name="associatedFile">associated chm file</param>
        public CHMUrltable(byte[] binaryFileData, CHMFile associatedFile)
        {
            _binaryFileData = binaryFileData;
            _associatedFile = associatedFile;
            DecodeData();

            // clear internal binary data after extraction
            _binaryFileData = null;
        }
Exemple #7
0
        /// <summary>
        /// Sets the associated CHMFile instance
        /// </summary>
        /// <param name="associatedFile">instance to set</param>
        internal void SetCHMFile(CHMFile associatedFile)
        {
            _associatedFile = associatedFile;

            foreach (UrlTableEntry curEntry in _urlTable)
            {
                curEntry.SetCHMFile(associatedFile);
            }
        }
Exemple #8
0
        /// <summary>
        /// Internal constructor used in the class <see cref="HtmlHelp.ChmDecoding.CHMFile">CHMFile</see>.
        /// </summary>
        /// <param name="associatedFile">associated chm file</param>
        internal ChmFileInfo(CHMFile associatedFile)
        {
            _associatedFile = associatedFile;

            if (_associatedFile == null)
            {
                throw new ArgumentException("Associated CHMFile instance must not be null !", "associatedFile");
            }
        }
Exemple #9
0
 /// <summary>
 /// Constructor of the class
 /// </summary>
 /// <param name="entryOffset">offset of this entry</param>
 /// <param name="tocidxOffset">offset in the binary toc index</param>
 /// <param name="titleOffset">offset of the title (in the #STRINGS file)</param>
 /// <param name="urltableOffset">offset in the urltable containing the urlstr offset for the url</param>
 /// <param name="visibilityMode">visibility mode 2 indicates not in contents, 6 indicates that it is in the contents, 0/4 something else (unknown)</param>
 /// <param name="unknownMode">0, 2, 4, 8, 10, 12, 16, 32 (unknown)</param>
 /// <param name="associatedFile">associated chmfile object</param>
 internal TopicEntry(int entryOffset, int tocidxOffset, int titleOffset, int urltableOffset, int visibilityMode, int unknownMode, CHMFile associatedFile)
 {
     _entryOffset    = entryOffset;
     _tocidxOffset   = tocidxOffset;
     _titleOffset    = titleOffset;
     _urltableOffset = urltableOffset;
     _visibilityMode = visibilityMode;
     _unknownMode    = unknownMode;
     _associatedFile = associatedFile;
 }
Exemple #10
0
        /// <summary>
        /// Constructor of the class
        /// </summary>
        /// <param name="binaryFileData">binary file data of the $FIftiMain file</param>
        /// <param name="associatedFile">associated chm file</param>
        public FullTextEngine(byte[] binaryFileData, CHMFile associatedFile)
        {
            _binaryFileData = binaryFileData;
            _associatedFile = associatedFile;

            if (_associatedFile.SystemFile.FullTextSearch)
            {
                _header = new FTHeader(_binaryFileData);                 // reading header
            }
        }
        /// <summary>
        /// Reads the object data from a dump store
        /// </summary>
        /// <param name="reader">reader to read the data</param>
        /// <param name="filesList">filelist from helpsystem</param>
        internal bool ReadDump(ref BinaryReader reader, ArrayList filesList)
        {
            int i = 0;

            _keyWord     = reader.ReadString();
            _isSeeAlso   = reader.ReadBoolean();
            _indent      = reader.ReadInt32();
            _chmFileName = reader.ReadString();

            foreach (CHMFile curFile in filesList)
            {
                if (curFile.ChmFilePath == _chmFileName)
                {
                    _chmFile = curFile;
                    break;
                }
            }

            if (_chmFile == null)
            {
                return(false);
            }

            int nCnt = reader.ReadInt32();

            for (i = 0; i < nCnt; i++)
            {
                string sIT = reader.ReadString();
                _infoTypeStrings.Add(sIT);
            }

            nCnt = reader.ReadInt32();

            _seeAlso = new string[nCnt];

            for (i = 0; i < nCnt; i++)
            {
                _seeAlso[i] = reader.ReadString();
            }

            nCnt = reader.ReadInt32();

            for (i = 0; i < nCnt; i++)
            {
                IndexTopic topic = new IndexTopic("", "", "", "");
                topic.SetChmInfo(_chmFile.CompileFile, _chmFile.ChmFilePath);
                topic.AssociatedFile = _chmFile;
                topic.ReadDump(ref reader);

                Topics.Add(topic);
            }

            return(true);
        }
 /// <summary>
 /// Constructor of the class
 /// </summary>
 /// <param name="chmFile">associated CHMFile instance</param>
 /// <param name="keyWord">keyword</param>
 /// <param name="isSeeAlso">true if it is a see-also keyword</param>
 /// <param name="indent">indent of the entry</param>
 /// <param name="charIndex">char index of the last keyword in the separated list</param>
 /// <param name="entryIndex">index of the entry</param>
 /// <param name="seeAlsoValues">string array with see-also values</param>
 /// <param name="topicOffsets">integer array with topic offsets</param>
 internal IndexItem(CHMFile chmFile, string keyWord, bool isSeeAlso, int indent, int charIndex, int entryIndex, string[] seeAlsoValues, int[] topicOffsets)
 {
     _chmFile     = chmFile;
     _chmFileName = _chmFile.ChmFilePath;
     _keyWord     = keyWord;
     _isSeeAlso   = isSeeAlso;
     _indent      = indent;
     _charIndex   = charIndex;
     _entryIndex  = entryIndex;
     _seeAlso     = seeAlsoValues;
     _nTopics     = topicOffsets;
 }
Exemple #13
0
        /// <summary>
        /// Parses a HHC file and returns an ArrayList with the table of contents (TOC) tree
        /// </summary>
        /// <param name="hhcFile">string content of the hhc file</param>
        /// <param name="chmFile">CHMFile instance</param>
        /// <returns>Returns an ArrayList with the table of contents (TOC) tree</returns>
        public static ArrayList ParseHHC(string hhcFile, CHMFile chmFile)
        {
            _lastTopicItem = null;
            _mergeItems    = null;          // clear merged item list
            ArrayList tocList = new ArrayList();

            ulRE         = new Regex(RE_ULBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            NestedRE     = new Regex(RE_NestedBoundaries, RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            ObjectRE     = new Regex(RE_ObjectBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            ParamRE      = new Regex(RE_ParamBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            AttributesRE = new Regex(RE_QuoteAttributes, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

            int innerTextIdx = ulRE.GroupNumberFromName("innerText");

            if (ulRE.IsMatch(hhcFile, 0))
            {
                Match m = ulRE.Match(hhcFile, 0);

                int nFirstUL = 0;

                nFirstUL = hhcFile.ToLower().IndexOf("<ul>");

                if (nFirstUL == -1)
                {
                    nFirstUL = hhcFile.ToLower().IndexOf("<il>");
                }

                if (ObjectRE.IsMatch(hhcFile, 0))                  // first object block contains information types and categories
                {
                    Match mO    = ObjectRE.Match(hhcFile, 0);
                    int   iOTxt = ObjectRE.GroupNumberFromName("innerText");

                    string globalText = mO.Groups[iOTxt].Value;

                    if (mO.Groups[iOTxt].Index <= nFirstUL)
                    {
                        ParseGlobalSettings(globalText, chmFile);
                    }
                }

                // parse toc tree
                string innerText = m.Groups["innerText"].Value;

                innerText = innerText.Replace("(", "&#040;");
                innerText = innerText.Replace(")", "&#041;");
                innerText = Regex.Replace(innerText, RE_ULOpening, "(", RegexOptions.IgnoreCase);
                innerText = Regex.Replace(innerText, RE_ULClosing, ")", RegexOptions.IgnoreCase);

                ParseTree(innerText, null, tocList, chmFile);
            }

            return(tocList);
        }
Exemple #14
0
        /// <summary>
        /// Constructor of the class
        /// </summary>
        /// <param name="binaryFileData">binary file data of the #SYSTEM file</param>
        /// <param name="associatedFile">associated chm file</param>
        public CHMSystem(byte[] binaryFileData, CHMFile associatedFile)
        {
            _binaryFileData = binaryFileData;
            _associatedFile = associatedFile;
            DecodeData();

            if (_culture == null)
            {
                // Set the text encoder of the chm file to the read charset/codepage
                _associatedFile.TextEncoding = Encoding.GetEncoding(this.CodePage);
            }
        }
        /// <summary>
        /// Opens a chm file and creates
        /// </summary>
        /// <param name="chmFile">full file path of the chm file to open</param>
        /// <param name="dmpInfo">dumping info</param>
        /// <remarks>If you call this method, all existing merged files will be cleared.</remarks>
        public void OpenFile(string chmFile, DumpingInfo dmpInfo)
        {
            if (File.Exists(chmFile))
            {
                _chmFiles.Clear();
                _toc.Clear();
                _index.Clear();
                _informationTypes.Clear();
                _categories.Clear();

                CHMFile newFile = new CHMFile(this, chmFile, dmpInfo);

                _toc   = new HtmlHelpToc(newFile.TOC);
                _index = new HtmlHelpIndex(newFile.IndexKLinks, newFile.IndexALinks);

                _chmFiles.Add(newFile);
                // add all infotypes and categories of the read file to this system instance
                MergeFileInfoTypesCategories(newFile);

                // check if the file has a merged files list
                if (newFile.MergedFiles.Length > 0)
                {
                    // extract the path of the chm file (usually merged files are in the same path)
                    FileInfo fi    = new FileInfo(chmFile);
                    string   sPath = fi.DirectoryName;

                    for (int i = 0; i < newFile.MergedFiles.Length; i++)
                    {
                        string sFile = newFile.MergedFiles[i];

                        if (sFile.Length > 0)
                        {
                            if (sFile[1] != ':')                            // no full path setting
                            {
                                sFile = Path.Combine(sPath, sFile);
                            }

                            MergeFile(sFile, dmpInfo, true);
                        }
                    }

                    if (newFile.MergLinks.Count > 0)
                    {
                        RecalculateMergeLinks(newFile);
                    }

                    RemoveMergeLinks();                     // clear all merge-links which have no target !
                }
            }
        }
Exemple #16
0
        /// <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;
        }
Exemple #17
0
        /// <summary>
        /// Constructor for extrating the file information of the provided file.
        /// The constructor opens the chm-file and reads its system data.
        /// </summary>
        /// <param name="chmFile">full file name which information should be extracted</param>
        public ChmFileInfo(string chmFile)
        {
            if (!File.Exists(chmFile))
            {
                throw new ArgumentException("Chm file must exist on disk !", "chmFileName");
            }

            if (!chmFile.ToLower().EndsWith(".chm"))
            {
                throw new ArgumentException("HtmlHelp file must have the extension .chm !", "chmFile");
            }

            _chmFileName    = chmFile;
            _associatedFile = new CHMFile(null, chmFile, true);             // only load system data of chm
        }
        /// <summary>
        /// Closes all files and destroys TOC/index
        /// </summary>
        public void CloseAllFiles()
        {
            for (int i = 0; i < _chmFiles.Count; i++)
            {
                CHMFile curFile = _chmFiles[i];

                _chmFiles.RemoveAt(i);
                curFile.Dispose();
                i--;
            }

            _chmFiles.Clear();
            _toc.Clear();
            _index.Clear();
            _informationTypes.Clear();
            _categories.Clear();
        }
        /// <summary>
        /// Reads the object data from a dump store
        /// </summary>
        /// <param name="reader">reader to read the data</param>
        /// <param name="chmFile">current CHMFile instance which reads from dump</param>
        internal void ReadDump(ref BinaryReader reader, CHMFile chmFile)
        {
            _name        = reader.ReadString();
            _description = reader.ReadString();

            int nCnt = reader.ReadInt32();

            for (int i = 0; i < nCnt; i++)
            {
                string sITName = reader.ReadString();

                InformationType linkedType = chmFile.GetInformationType(sITName);

                if (linkedType != null)
                {
                    linkedType.SetCategoryFlag(true);
                    _infoTypes.Add(linkedType);
                }
            }
        }
        /// <summary>
        /// Removes the information types and categories read by the CHMFile instance
        /// </summary>
        /// <param name="chmFile">file instance</param>
        private void RemoveFileInfoTypesCategories(CHMFile chmFile)
        {
            if (chmFile.HasInformationTypes)
            {
                for (int i = 0; i < chmFile.InformationTypes.Count; i++)
                {
                    InformationType curType = chmFile.InformationTypes[i];
                    InformationType sysType = GetInformationType(curType.Name);

                    if (sysType != null)
                    {
                        sysType.ReferenceCount--;

                        if (sysType.ReferenceCount <= 0)
                        {
                            _informationTypes.Remove(sysType);
                        }
                    }
                }
            }

            if (chmFile.HasCategories)
            {
                for (int i = 0; i < chmFile.Categories.Count; i++)
                {
                    Category curCat = chmFile.Categories[i];
                    Category sysCat = GetCategory(curCat.Name);

                    if (sysCat != null)
                    {
                        sysCat.ReferenceCount--;

                        if (sysCat.ReferenceCount <= 0)
                        {
                            _categories.Remove(sysCat);
                        }
                    }
                }
            }
        }
Exemple #21
0
        /// <summary>
        /// Parses a HHK file and returns an list with the index tree
        /// </summary>
        /// <param name="hhkFile">string content of the hhk file</param>
        /// <param name="chmFile">CHMFile instance</param>
        /// <returns>Returns an list with the index tree</returns>
        public static List <HtmlHelpIndexItem> ParseHHK(string hhkFile, CHMFile chmFile)
        {
            List <HtmlHelpIndexItem> indexList = new List <HtmlHelpIndexItem>();

            ulRE         = new Regex(RE_ULBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            NestedRE     = new Regex(RE_NestedBoundaries, RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            ObjectRE     = new Regex(RE_ObjectBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            ParamRE      = new Regex(RE_ParamBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            AttributesRE = new Regex(RE_QuoteAttributes, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

            int innerTextIdx = ulRE.GroupNumberFromName("innerText");

            if (ulRE.IsMatch(hhkFile, 0))
            {
                Match m = ulRE.Match(hhkFile, 0);

                if (ObjectRE.IsMatch(hhkFile, 0))                  // first object block contains information types and categories
                {
                    Match mO    = ObjectRE.Match(hhkFile, 0);
                    int   iOTxt = ObjectRE.GroupNumberFromName("innerText");

                    string globalText = mO.Groups[iOTxt].Value;

                    ParseGlobalSettings(globalText, chmFile);
                }

                string innerText = m.Groups["innerText"].Value;

                innerText = innerText.Replace("(", "&#040;");
                innerText = innerText.Replace(")", "&#041;");
                innerText = Regex.Replace(innerText, RE_ULOpening, "(", RegexOptions.IgnoreCase);
                innerText = Regex.Replace(innerText, RE_ULClosing, ")", RegexOptions.IgnoreCase);

                ParseTree(innerText, null, indexList, chmFile);
            }

            return(indexList);
        }
Exemple #22
0
        /// <summary>
        /// Checks if the hhc file contains a global object tag.
        /// </summary>
        /// <param name="hhcFile">string content of the hhc file</param>
        /// <param name="chmFile">chm file</param>
        /// <returns>true if the hhc content contains a global object tag</returns>
        public static bool HasGlobalObjectTag(string hhcFile, CHMFile chmFile)
        {
            bool bRet = false;

            ulRE     = new Regex(RE_ULBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
            ObjectRE = new Regex(RE_ObjectBoundaries, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);

            int innerTextIdx = ulRE.GroupNumberFromName("innerText");

            if (ulRE.IsMatch(hhcFile, 0))
            {
                Match m = ulRE.Match(hhcFile, 0);

                int nFirstUL = 0;

                nFirstUL = hhcFile.ToLower().IndexOf("<ul>");

                if (nFirstUL == -1)
                {
                    nFirstUL = hhcFile.ToLower().IndexOf("<il>");
                }

                if (ObjectRE.IsMatch(hhcFile, 0))                  // first object block contains information types and categories
                {
                    Match mO    = ObjectRE.Match(hhcFile, 0);
                    int   iOTxt = ObjectRE.GroupNumberFromName("innerText");

                    string globalText = mO.Groups[iOTxt].Value;

                    if (mO.Groups[iOTxt].Index <= nFirstUL)
                    {
                        bRet = true;
                    }
                }
            }

            return(bRet);
        }
        /// <summary>
        /// Merges the information types and categories read by the CHMFile instance
        /// into the system instance
        /// </summary>
        /// <param name="chmFile">file instance</param>
        private void MergeFileInfoTypesCategories(CHMFile chmFile)
        {
            if (chmFile.HasInformationTypes)
            {
                for (int i = 0; i < chmFile.InformationTypes.Count; i++)
                {
                    InformationType curType = chmFile.InformationTypes[i];
                    InformationType sysType = GetInformationType(curType.Name);

                    if (sysType == null)
                    {
                        _informationTypes.Add(curType);
                    }
                    else
                    {
                        curType.ReferenceCount++;
                    }
                }
            }

            if (chmFile.HasCategories)
            {
                for (int i = 0; i < chmFile.Categories.Count; i++)
                {
                    Category curCat = chmFile.Categories[i];
                    Category sysCat = GetCategory(curCat.Name);

                    if (sysCat == null)
                    {
                        _categories.Add(curCat);
                    }
                    else
                    {
                        curCat.ReferenceCount++;
                    }
                }
            }
        }
Exemple #24
0
        /// <summary>
        /// Recursively parses a sitemap tree
        /// </summary>
        /// <param name="text">content text</param>
        /// <param name="parent">Parent for all read items</param>
        /// <param name="arrNodes">arraylist which receives the extracted nodes</param>
        /// <param name="chmFile">CHMFile instance</param>
        private static void ParseTree(string text, HtmlHelpIndexItem parent,
                                      List <HtmlHelpIndexItem> arrNodes, CHMFile chmFile)
        {
            string strPreItems = "", strPostItems = "";
            string innerText = "";

            int nIndex = 0;

            while (NestedRE.IsMatch(text, nIndex))
            {
                Match m = NestedRE.Match(text, nIndex);

                innerText = m.Value.Substring(1, m.Length - 2);

                strPreItems = text.Substring(nIndex, m.Index - nIndex);

                ParseItems(strPreItems, parent, arrNodes, chmFile);

                if ((arrNodes.Count > 0) && (innerText.Length > 0))
                {
                    HtmlHelpIndexItem p = ((HtmlHelpIndexItem)(arrNodes[arrNodes.Count - 1]));
                    ParseTree(innerText, p, arrNodes, chmFile);
                }

                nIndex = m.Index + m.Length;
            }

            if (nIndex == 0)
            {
                strPostItems = text.Substring(nIndex, text.Length - nIndex);
                ParseItems(strPostItems, parent, arrNodes, chmFile);
            }
            else if (nIndex < text.Length - 1)
            {
                strPostItems = text.Substring(nIndex, text.Length - nIndex);
                ParseTree(strPostItems, parent, arrNodes, chmFile);
            }
        }
        /// <summary>
        /// Merges a chm file to the current help contents
        /// </summary>
        /// <param name="chmFile">full file path of the chm file to merge</param>
        /// <param name="dmpInfo">dumping info</param>
        /// <param name="mergedFileList">true if the merge is done because a merged file list
        /// was found in the previously loaded CHM.</param>
        internal void MergeFile(string chmFile, DumpingInfo dmpInfo, bool mergedFileList)
        {
            if (File.Exists(chmFile))
            {
                if (_chmFiles.Count == 1)
                {
                    // if we open the first file, we directly point into the toc and index of this file.
                    // So that we don't merge the new toc's indexe's into the first file, we have to
                    // clone the internal arraylists first to a new instance of the toc/index holder classes.
                    IList <HtmlHelpTocItem>   atoc   = _toc.TOC;
                    IList <HtmlHelpIndexItem> alinks = _index.ALinks;
                    IList <HtmlHelpIndexItem> klinks = _index.KLinks;

                    _toc   = new HtmlHelpToc();
                    _index = new HtmlHelpIndex();

                    _toc.MergeToC(atoc);
                    _index.MergeIndex(alinks, IndexType.AssiciativeLinks);
                    _index.MergeIndex(klinks, IndexType.KeywordLinks);
                }

                CHMFile newFile = new CHMFile(this, chmFile, dmpInfo);

                if (mergedFileList)                // if we've called this method due to a merged file list merge
                {
                    RecalculateMergeLinks(newFile);

                    _toc.MergeToC(newFile.TOC, _chmFiles);
                    _index.MergeIndex(newFile.IndexALinks, IndexType.AssiciativeLinks);
                    _index.MergeIndex(newFile.IndexKLinks, IndexType.KeywordLinks);

                    _chmFiles.Add(newFile);

                    // add all infotypes and categories of the read file to this system instance
                    MergeFileInfoTypesCategories(newFile);
                }
                else
                {
                    _toc.MergeToC(newFile.TOC, _chmFiles);
                    _index.MergeIndex(newFile.IndexALinks, IndexType.AssiciativeLinks);
                    _index.MergeIndex(newFile.IndexKLinks, IndexType.KeywordLinks);

                    _chmFiles.Add(newFile);

                    // add all infotypes and categories of the read file to this system instance
                    MergeFileInfoTypesCategories(newFile);

                    // check if the file has a merged files list
                    if (newFile.MergedFiles.Length > 0)
                    {
                        // extract the path of the chm file (usually merged files are in the same path)
                        FileInfo fi    = new FileInfo(chmFile);
                        string   sPath = fi.DirectoryName;

                        for (int i = 0; i < newFile.MergedFiles.Length; i++)
                        {
                            string sFile = newFile.MergedFiles[i];

                            if (sFile.Length > 0)
                            {
                                if (sFile[1] != ':')                                // no full path setting
                                {
                                    sFile = Path.Combine(sPath, sFile);
                                }

                                MergeFile(sFile, dmpInfo, true);
                            }
                        }

                        //if(newFile.MergLinks.Count > 0)
                        //	RecalculateMergeLinks(newFile);

                        RemoveMergeLinks();                         // clear all merge-links which have no target !
                    }
                }
            }
        }
Exemple #26
0
        /// <summary>
        /// Recursively parses a sitemap tree
        /// </summary>
        /// <param name="text">content text</param>
        /// <param name="arrNodes">arraylist which receives the extracted nodes</param>
        /// <param name="chmFile">CHMFile instance</param>
        static private void ParseTree(ArrayList arrNodes, CHMFile chmFile)
        {
            bool bProcessing = true;

            do
            {
                bProcessing = false;

                // Indent
                int idxa = m_text1.IndexOf("<ul>", m_CurrentPos);
                int idxb = m_text1.IndexOf("<li>", m_CurrentPos);
                int idxc = m_text1.IndexOf("</ul>", m_CurrentPos);

                if ((idxa < idxb) && (idxa < idxc) && (idxa > -1))
                {
                    bProcessing  = true;
                    m_CurrentPos = idxa + 4;
                    if (arrNodes.Count < 1)
                    {
                        ParseTree(arrNodes, chmFile);
                    }
                    else
                    {
                        ParseTree(((TOCItem)(arrNodes[arrNodes.Count - 1])).Children, chmFile);
                    }
                    continue;
                }

                // new item
                if ((idxb < idxa) && (idxb < idxc) && (idxb > -1))
                {
                    bProcessing  = true;
                    m_CurrentPos = idxb + 4;

                    int idx2 = m_text1.IndexOf("<object", m_CurrentPos);
                    if (idx2 != -1)
                    {
                        int idx3 = m_text1.IndexOf("</object>", idx2 + 7);
                        if (idx3 != -1)
                        {
                            string text = m_text2.Substring(idx2, idx3 - idx2);

                            m_CurrentPos = idx3 + 9;

                            // Parse items in text.
                            TOCItem tocItem = ParseItems(text, chmFile);
                            if (tocItem != null)
                            {
                                arrNodes.Add(tocItem);
                            }
                        }
                    }
                }

                // Undent
                if ((idxc < idxa) && (idxc < idxb) && (idxc > -1))
                {
                    m_CurrentPos = idxc + 5;
                    bProcessing  = true;
                    return;
                }
            }while (bProcessing);
        }
        /// <summary>
        /// Checks all Merg-links read till now. Checks if the merg-link points to the
        /// file <c>currentFile</c>. If yes the link will be replaced by the contents of the
        /// merged file.
        /// </summary>
        /// <param name="currentFile">Current CHMFile instance</param>
        internal void RecalculateMergeLinks(CHMFile currentFile)
        {
            foreach (CHMFile curFile in _chmFiles)
            {
                if (curFile.MergLinks.Count > 0)
                {
                    for (int i = 0; i < curFile.MergLinks.Count; i++)
                    {
                        HtmlHelpTocItem curItem = curFile.MergLinks[i] as HtmlHelpTocItem;

                        string    sMerge = curItem.MergeLink;
                        string [] sSplit = sMerge.Split(new char[] { ':' });

                        string sFName  = "";
                        string sTarget = "";

                        if (sSplit.Length > 3)                         // merge info contains path name
                        {
                            sFName  = sSplit[0] + ":" + sSplit[1];
                            sTarget = sSplit[3];
                        }
                        else if (sSplit.Length == 3)                        // merge info contains only file name
                        {
                            FileInfo fi    = new FileInfo(currentFile.ChmFilePath);
                            string   sPath = fi.DirectoryName;

                            string sFile = sSplit[0];

                            if (sFile.Length > 0)
                            {
                                if (sFile[1] != ':')                                // no full path setting
                                {
                                    sFile = Path.Combine(sPath, sFile);
                                }
                            }

                            sFName  = sFile;
                            sTarget = sSplit[2];
                        }

                        List <HtmlHelpTocItem> arrToc = null;

                        if ((sFName.Length > 0) && (sTarget.Length > 0))
                        {
                            // if this link points into the current file
                            if (sFName.ToLower() == currentFile.ChmFilePath.ToLower())
                            {
                                if (sTarget.ToLower().IndexOf(".hhc") >= 0)
                                {
                                    string sfCheck = sTarget;

                                    // remove prefixing ./
                                    while ((sfCheck[0] == '.') || (sfCheck[0] == '/'))
                                    {
                                        sfCheck = sfCheck.Substring(1);
                                    }

                                    if (currentFile.ContentsFile.ToLower() != sfCheck)
                                    {
                                        arrToc = currentFile.ParseHHC(sTarget);

                                        if (arrToc.Count > 0)
                                        {
                                        }
                                    }
                                    else
                                    {
                                        arrToc = currentFile.TOC;
                                    }

                                    // target points to a complete TOC
                                    int nCnt = 0;

                                    foreach (HtmlHelpTocItem chkItem in arrToc)
                                    {
                                        if (nCnt == 0)
                                        {
                                            curItem.AssociatedFile = currentFile;
                                            curItem.Children       = chkItem.Children;
                                            curItem.ChmFile        = currentFile.ChmFilePath;
                                            curItem.ImageIndex     = chkItem.ImageIndex;
                                            curItem.Local          = chkItem.Local;
                                            curItem.MergeLink      = chkItem.MergeLink;
                                            curItem.Name           = chkItem.Name;
                                            curItem.TocMode        = chkItem.TocMode;
                                            curItem.TopicOffset    = chkItem.TopicOffset;

                                            MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
                                        }
                                        else
                                        {
                                            IList <HtmlHelpTocItem> checkList = null;

                                            if (curItem.Parent != null)
                                            {
                                                checkList = curItem.Parent.Children;
                                            }
                                            else
                                            {
                                                checkList = curFile.TOC;
                                            }

                                            int nIdx = checkList.IndexOf(curItem);
                                            if ((nIdx + nCnt) > checkList.Count)
                                            {
                                                checkList.Add(chkItem);
                                            }
                                            else
                                            {
                                                checkList.Insert(nIdx + nCnt, chkItem);
                                            }

                                            curFile.MergLinks.Add(chkItem);
                                            MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
                                        }

                                        nCnt++;
                                    }
                                }
                                else
                                {
                                    // target points to a single topic
                                    HtmlHelpTocItem chkItem = currentFile.GetTOCItemByLocal(sTarget);
                                    if (chkItem != null)
                                    {
                                        curItem.AssociatedFile = currentFile;
                                        curItem.Children       = chkItem.Children;
                                        curItem.ChmFile        = currentFile.ChmFilePath;
                                        curItem.ImageIndex     = chkItem.ImageIndex;
                                        curItem.Local          = chkItem.Local;
                                        curItem.MergeLink      = chkItem.MergeLink;
                                        curItem.Name           = chkItem.Name;
                                        curItem.TocMode        = chkItem.TocMode;
                                        curItem.TopicOffset    = chkItem.TopicOffset;

                                        curFile.MergLinks.Add(chkItem);
                                        MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Creates a new instance of the class (binary extraction mode)
 /// </summary>
 /// <param name="topicOffset">offset of the topic entry</param>
 /// <param name="associatedFile">associated CHMFile instance</param>
 internal IndexTopic(int topicOffset, CHMFile associatedFile)
 {
     _topicMode      = DataMode.Binary;
     _topicOffset    = topicOffset;
     _associatedFile = associatedFile;
 }
Exemple #29
0
 /// <summary>
 /// Sets the associated CHMFile instance
 /// </summary>
 /// <param name="associatedFile">instance to set</param>
 internal void SetCHMFile(CHMFile associatedFile)
 {
     _associatedFile = associatedFile;
 }
Exemple #30
0
        /// <summary>
        /// Parses tree nodes from the text
        /// </summary>
        /// <param name="itemstext">text containing the items</param>
        /// <param name="arrNodes">arraylist where the nodes should be added</param>
        /// <param name="chmFile">CHMFile instance</param>
        private static TOCItem ParseItems(string itemstext, CHMFile chmFile)
        {
            int innerPTextIdx = ParamRE.GroupNumberFromName("innerText");

            // get group-name indexes
            int nameIndex  = AttributesRE.GroupNumberFromName("attributeName");
            int valueIndex = AttributesRE.GroupNumberFromName("attributeValue");
            int tdIndex    = AttributesRE.GroupNumberFromName("attributeTD");

            TOCItem tocItem = new TOCItem();

            // read parameters
            int nParamIndex = 0;

            while (ParamRE.IsMatch(itemstext, nParamIndex))
            {
                Match mP = ParamRE.Match(itemstext, nParamIndex);

                string innerP = mP.Groups[innerPTextIdx].Value;

                string paramName  = "";
                string paramValue = "";

                int nAttrIdx = 0;

                while (AttributesRE.IsMatch(innerP, nAttrIdx))
                {
                    Match mA = AttributesRE.Match(innerP, nAttrIdx);

                    string attributeName  = mA.Groups[nameIndex].Value;
                    string attributeValue = mA.Groups[valueIndex].Value;
                    string attributeTD    = mA.Groups[tdIndex].Value;

                    if (attributeTD.Length > 0)
                    {
                        // delete the trailing textqualifier
                        if (attributeValue.Length > 0)
                        {
                            int ltqi = attributeValue.LastIndexOf(attributeTD);

                            if (ltqi >= 0)
                            {
                                attributeValue = attributeValue.Substring(0, ltqi);
                            }
                        }
                    }

                    if (attributeName.ToLower() == "name")
                    {
                        paramName = attributeValue;
                    }

                    if (attributeName.ToLower() == "value")
                    {
                        paramValue = attributeValue;
                    }

                    nAttrIdx = mA.Index + mA.Length;
                }

                tocItem.Params[paramName] = paramValue;
                switch (paramName.ToLower())
                {
                case "name":
                {
                    tocItem.Name = paramValue;
                }; break;

                case "local":
                {
                    tocItem.Local = paramValue;
                }; break;

                case "imagenumber":
                {
                    tocItem.ImageIndex = Int32.Parse(paramValue);

                    if (tocItem.ImageIndex == 2)
                    {
                        tocItem.ImageIndex = TOCItem.STD_FOLDER_HH1;
                    }
                }; break;
                }

                nParamIndex = mP.Index + mP.Length;
            }

            tocItem.ChmFile = chmFile.ChmFilePath;
            return(tocItem);
        }