⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xchmfile.cpp

📁 okular
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		else			tagword = tag.toLower();// qDebug ("tag: '%s', tagword: '%s'\n", tag.toAscii().constData(), tagword.toAscii().constData());	 							// <OBJECT type="text/sitemap"> - a topic entry		if ( tagword == "object" && tag.indexOf ("text/sitemap", 0, Qt::CaseInsensitive) != -1 )			in_object = true;		else if ( tagword == "/object" && in_object ) 		{			// a topic entry closed. Add a tree item			if ( !name.isNull() )			{				QDomElement * item = new QDomElement();				if ( !root_created )					indent = 0;				QString url = urls.join ("|");				// Add item into the tree				if ( !indent )				{					*item = tree->createElement(name);					item->setAttribute("ViewportName",url);					item->setAttribute("Icon",imagenum);                    tree->appendChild(*item);				}				else				{					if ( !rootentry[indent-1] )						qFatal("CHMFile::ParseAndFillTopicsTree: child entry %d with no root entry!", indent-1);					*item = tree->createElement(name);					item->setAttribute("ViewportName",url);					item->setAttribute("Icon",imagenum);                    rootentry[indent-1]->appendChild(*item);				}				lastchild[indent] = item;				if ( indent == 0 || !rootentry[indent] )				{					rootentry[indent] = item;					root_created = true;				}				// There are no 'titles' in index file				if ( add2treemap  )				{					insertIntoUrlMaps(m_UrlPage,m_PageUrl,url,pnum);				}			}			else			{				if ( !urls.isEmpty() )					qDebug ("CHMFile::ParseAndFillTopicsTree: <object> tag with url \"%s\" is parsed, but name is empty.", urls[0].toAscii().constData());				else					qDebug ("CHMFile::ParseAndFillTopicsTree: <object> tag is parsed, but both name and url are empty.");				}			name = QString::null;			urls.clear();			in_object = false;			imagenum = defaultimagenum;		}		else if ( tagword == "param" && in_object )		{			// <param name="Name" value="First Page">			int offset; // strlen("param ")			QString name_pattern = "name=", value_pattern = "value=";			QString pname, pvalue;			if ( (offset = tag.indexOf (name_pattern, 0, Qt::CaseInsensitive)) == -1 )				qFatal ("CHMFile::ParseAndFillTopicsTree: bad <param> tag '%s': no name=\n", tag.toAscii().constData());			// offset+5 skips 'name='			offset = findStringInQuotes (tag, offset + name_pattern.length(), pname, true, false);			pname = pname.toLower();			if ( (offset = tag.indexOf (value_pattern, offset, Qt::CaseInsensitive)) == -1 )				qFatal ("CHMFile::ParseAndFillTopicsTree: bad <param> tag '%s': no value=\n", tag.toAscii().constData());			// offset+6 skips 'value='			findStringInQuotes (tag, offset + value_pattern.length(), pvalue, false, true);// qDebug ("<param>: name '%s', value '%s'", pname.toAscii().constData(), pvalue.toAscii().constData());			if ( pname == "name" )				name = pvalue;			else if ( pname == "local" )				urls.push_back (KCHMUrl::makeURLabsoluteIfNeeded(pvalue));			else if ( pname == "see also" && asIndex && name != pvalue )				urls.push_back (KCHMUrl::makeURLabsoluteIfNeeded(":" + pvalue));			else if ( pname == "imagenumber" )			{				bool bok;				int imgnum = pvalue.toInt (&bok);					if ( bok && imgnum >= 0 && (unsigned) imgnum < MAX_BUILTIN_ICONS )					imagenum = imgnum;			}		}		else if ( tagword == "ul" ) // increase indent level		{			// Fix for buggy help files					if ( ++indent >= MAX_NEST_DEPTH )				qFatal("CHMFile::ParseAndFillTopicsTree: max nest depth (%d) is reached, error in help file", MAX_NEST_DEPTH);							lastchild[indent] = 0;			rootentry[indent] = 0;		}		else if ( tagword == "/ul" ) // decrease indent level		{			if ( --indent < 0 )				indent = 0;							rootentry[indent] = 0;		}		pos = i;		}		return true;}bool CHMFile::ParseHhcAndFillTree (const QString& file, K3ListView *tree, bool asIndex){	chmUnitInfo ui;	const int MAX_NEST_DEPTH = 256;	if(file.isEmpty() || !ResolveObject(file, &ui))		return false;	QString src;	GetFileContentAsString(src, &ui);	if(src.isEmpty())		return false;	unsigned int defaultimagenum = asIndex ? KCHMImageType::IMAGE_INDEX : KCHMImageType::IMAGE_AUTO;	unsigned int imagenum = defaultimagenum;	int pos = 0, indent = 0;	bool in_object = false, root_created = false;	QString name;	QStringList urls;	KCHMMainTreeViewItem * rootentry[MAX_NEST_DEPTH];	KCHMMainTreeViewItem * lastchild[MAX_NEST_DEPTH];		memset (lastchild, 0, sizeof(*lastchild));	memset (rootentry, 0, sizeof(*rootentry));		// Split the HHC file by HTML tags	int stringlen = src.length();		while ( pos < stringlen 	&& (pos = src.indexOf ('<', pos)) != -1 )	{		int i, word_end = 0;				for ( i = ++pos; i < stringlen; i++ )		{			// If a " or ' is found, skip to the next one.			if ( (src[i] == '"' || src[i] == '\'') )			{				// find where quote ends, either by another quote, or by '>' symbol (some people don't know HTML)				int nextpos = src.indexOf (src[i], i+1);				if ( nextpos == -1 	&& (nextpos = src.indexOf ('>', i+1)) == -1 )				{					qWarning ("CHMFile::ParseHhcAndFillTree: corrupted TOC: %s", src.mid(i).toAscii().constData());					return false;				}				i =  nextpos;			}			else if ( src[i] == '>'  )				break;			else if ( !src[i].isLetterOrNumber() && src[i] != '/' && !word_end )				word_end = i;		}				QString tagword, tag = src.mid (pos, i - pos);		 		if ( word_end )			tagword = src.mid (pos, word_end - pos).toLower();		else			tagword = tag.toLower();//qDebug ("tag: '%s', tagword: '%s'\n", tag.toAscii().constData(), tagword.toAscii().constData());								// <OBJECT type="text/sitemap"> - a topic entry		if ( tagword == "object" && tag.indexOf ("text/sitemap", 0, Qt::CaseInsensitive) != -1 )			in_object = true;		else if ( tagword == "/object" && in_object ) 		{			// a topic entry closed. Add a tree item			if ( !name.isNull() )			{				KCHMMainTreeViewItem * item;				if ( !root_created )					indent = 0;				QString url = urls.join ("|");				// Add item into the tree				if ( !indent )				{					item = new KCHMMainTreeViewItem (tree, lastchild[indent], name, url, imagenum);				}				else				{					if ( !rootentry[indent-1] )						qFatal("CHMFile::ParseAndFillTopicsTree: child entry %d with no root entry!", indent-1);					item = new KCHMMainTreeViewItem (rootentry[indent-1], lastchild[indent], name, url,  imagenum);				}				lastchild[indent] = item;				if ( indent == 0 || !rootentry[indent] )				{					rootentry[indent] = item;					root_created = true;					if ( asIndex  )						rootentry[indent]->setOpen(true);				}			}			else			{				if ( !urls.isEmpty() )					qDebug ("CHMFile::ParseAndFillTopicsTree: <object> tag with url \"%s\" is parsed, but name is empty.", urls[0].toAscii().constData());				else					qDebug ("CHMFile::ParseAndFillTopicsTree: <object> tag is parsed, but both name and url are empty.");				}			name = QString::null;			urls.clear();			in_object = false;			imagenum = defaultimagenum;		}		else if ( tagword == "param" && in_object )		{			// <param name="Name" value="First Page">			int offset; // strlen("param ")			QString name_pattern = "name=", value_pattern = "value=";			QString pname, pvalue;			if ( (offset = tag.indexOf (name_pattern, 0, Qt::CaseInsensitive)) == -1 )				qFatal ("CHMFile::ParseAndFillTopicsTree: bad <param> tag '%s': no name=\n", tag.toAscii().constData());			// offset+5 skips 'name='			offset = findStringInQuotes (tag, offset + name_pattern.length(), pname, true, false);			pname = pname.toLower();			if ( (offset = tag.indexOf (value_pattern, offset, Qt::CaseInsensitive)) == -1 )				qFatal ("CHMFile::ParseAndFillTopicsTree: bad <param> tag '%s': no value=\n", tag.toAscii().constData());			// offset+6 skips 'value='			findStringInQuotes (tag, offset + value_pattern.length(), pvalue, false, true);//qDebug ("<param>: name '%s', value '%s'", pname.toAscii().constData(), pvalue.toAscii().constData());			if ( pname == "name" )				name = pvalue;			else if ( pname == "local" )				urls.push_back (KCHMUrl::makeURLabsoluteIfNeeded (pvalue));			else if ( pname == "see also" && asIndex && name != pvalue )				urls.push_back (":" + pvalue);			else if ( pname == "imagenumber" )			{				bool bok;				int imgnum = pvalue.toInt (&bok);					if ( bok && imgnum >= 0 && (unsigned) imgnum < MAX_BUILTIN_ICONS )					imagenum = imgnum;			}		}		else if ( tagword == "ul" ) // increase indent level		{			// Fix for buggy help files					if ( ++indent >= MAX_NEST_DEPTH )				qFatal("CHMFile::ParseAndFillTopicsTree: max nest depth (%d) is reached, error in help file", MAX_NEST_DEPTH);							lastchild[indent] = 0;			rootentry[indent] = 0;		}		else if ( tagword == "/ul" ) // decrease indent level		{			if ( --indent < 0 )				indent = 0;							rootentry[indent] = 0;		}		pos = i;		}		return true;}bool CHMFile::ParseAndFillTopicsTree(QDomDocument *tree){	return ParseHhcAndFillTree (m_topicsFile, tree, false);}bool CHMFile::ParseAndFillIndex(K3ListView *indexlist){	return ParseHhcAndFillTree (m_indexFile, indexlist, true);}bool CHMFile::SearchWord (const QString& text, bool wholeWords, bool titlesOnly, KCHMSearchProgressResults_t& results,  bool phrase_search){	bool partial = false;	if ( text.isEmpty() || !m_searchAvailable )		return false;	QString searchword = (QString) convertSearchWord (text);#define FTS_HEADER_LEN 0x32	unsigned char header[FTS_HEADER_LEN];	if ( RetrieveObject (&m_chmFIftiMain, header, 0, FTS_HEADER_LEN) == 0 )		return false;		unsigned char doc_index_s = header[0x1E], doc_index_r = header[0x1F];	unsigned char code_count_s = header[0x20], code_count_r = header[0x21];	unsigned char loc_codes_s = header[0x22], loc_codes_r = header[0x23];	if(doc_index_s != 2 || code_count_s != 2 || loc_codes_s != 2)	{		// Don't know how to use values other than 2 yet. Maybe next chmspec.		return false;	}	unsigned char* cursor32 = header + 0x14;	u_int32_t node_offset = UINT32ARRAY(cursor32);	cursor32 = header + 0x2e;	u_int32_t node_len = UINT32ARRAY(cursor32);	unsigned char* cursor16 = header + 0x18;	u_int16_t tree_depth = UINT16ARRAY(cursor16);	unsigned char word_len, pos;	QString word;	u_int32_t i = sizeof(u_int16_t);	u_int16_t free_space;	QVector<unsigned char> buffer(node_len);	node_offset = GetLeafNodeOffset (searchword, node_offset, node_len, tree_depth);	if ( !node_offset )		return false;	do	{		// got a leaf node here.		if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), node_offset, node_len) == 0 )			return false;		cursor16 = buffer.data() + 6;		free_space = UINT16ARRAY(cursor16);		i = sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int16_t);		u_int64_t wlc_count, wlc_size;		u_int32_t wlc_offset;		while (i < node_len - free_space)		{			word_len = *(buffer.data() + i);			pos = *(buffer.data() + i + 1);			char *wrd_buf = new char[word_len];			memcpy (wrd_buf, buffer.data() + i + 2, word_len - 1);			wrd_buf[word_len - 1] = 0;			if ( pos == 0 )				word = wrd_buf;			else				word = word.mid (0, pos) + wrd_buf;			delete[] wrd_buf;			i += 2 + word_len;			unsigned char title = *(buffer.data() + i - 1);			size_t encsz;			wlc_count = be_encint (buffer.data() + i, encsz);			i += encsz;					cursor32 = buffer.data() + i;			wlc_offset = UINT32ARRAY(cursor32);			i += sizeof(u_int32_t) + sizeof(u_int16_t);			wlc_size =  be_encint (buffer.data() + i, encsz);			i += encsz;			cursor32 = buffer.data();			node_offset = UINT32ARRAY(cursor32);					if ( !title && titlesOnly )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -